Compare commits
124 Commits
v7.0.0.3-b
...
v7.1.1.5-b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8bd00fd2f1 | ||
|
|
61958aba2c | ||
|
|
3fa6f44828 | ||
|
|
31be72efb2 | ||
|
|
405c20f056 | ||
|
|
5f0fb4ebc3 | ||
|
|
c6a2b06fdf | ||
|
|
8f38eba23e | ||
|
|
79164aae72 | ||
|
|
e5d3ac0d92 | ||
|
|
f7c8c16344 | ||
|
|
b1fccbf175 | ||
|
|
cc1e4bc9f8 | ||
|
|
3812f3031c | ||
|
|
837f97d491 | ||
|
|
2dab825af4 | ||
|
|
a78c1ba50d | ||
|
|
50aea3b5ba | ||
|
|
6a971595f7 | ||
|
|
a1d944a9a0 | ||
|
|
8b49312bad | ||
|
|
95b279b0e9 | ||
|
|
01477d8b25 | ||
|
|
4e5182eb73 | ||
|
|
8d0b70a5dc | ||
|
|
37a241f136 | ||
|
|
ace7566c2a | ||
|
|
0b646cedb5 | ||
|
|
a0d2fb6a4e | ||
|
|
59a556794f | ||
|
|
cca474a5a5 | ||
|
|
ae05b997c7 | ||
|
|
88a6e18e78 | ||
|
|
3de72df806 | ||
|
|
da176085cd | ||
|
|
2b0ac7c087 | ||
|
|
94ecf4a069 | ||
|
|
9355e2f50c | ||
|
|
058ae3d185 | ||
|
|
3c1e6395a4 | ||
|
|
236d10c14a | ||
|
|
53f350da9a | ||
|
|
bb6819f240 | ||
|
|
8f53254dbc | ||
|
|
8ed73f6ae0 | ||
|
|
d59ccd7beb | ||
|
|
aeb11c9be1 | ||
|
|
a1c8e93034 | ||
|
|
00a11ea076 | ||
|
|
9115f707dc | ||
|
|
a2ec8de976 | ||
|
|
be7e5aa7d2 | ||
|
|
27124c9cdd | ||
|
|
44079ed69c | ||
|
|
07749cb2cc | ||
|
|
9d30acaba6 | ||
|
|
f3fdef780d | ||
|
|
1243d1381b | ||
|
|
3602f627e8 | ||
|
|
97fab64d32 | ||
|
|
e7b7f33b1b | ||
|
|
01c2171a62 | ||
|
|
321dc13531 | ||
|
|
4032e8be7b | ||
|
|
e52de1d1a7 | ||
|
|
7c38e823c1 | ||
|
|
e6defd3e55 | ||
|
|
3caf4f2cb3 | ||
|
|
3f897b12cf | ||
|
|
12d0126dd5 | ||
|
|
b218619b2b | ||
|
|
ae80076f36 | ||
|
|
ae9c69e469 | ||
|
|
cfd2919e88 | ||
|
|
985460d98e | ||
|
|
7596d988b9 | ||
|
|
50cad04b47 | ||
|
|
457d93b5c4 | ||
|
|
bb2af95344 | ||
|
|
34e76946f3 | ||
|
|
3f52c1255e | ||
|
|
924e32f027 | ||
|
|
2f735215e0 | ||
|
|
23ed1457d5 | ||
|
|
52214c1e15 | ||
|
|
09de4a5e05 | ||
|
|
69a6754483 | ||
|
|
078756600e | ||
|
|
5e2c7055d4 | ||
|
|
eb265be0a4 | ||
|
|
ad74acae0f | ||
|
|
d325cf1165 | ||
|
|
39bace76d3 | ||
|
|
44e8ef7cd8 | ||
|
|
85e4e3f9df | ||
|
|
ad94042a2c | ||
|
|
304fe58f27 | ||
|
|
edcd8be662 | ||
|
|
3970d5c0c2 | ||
|
|
4451eafe71 | ||
|
|
1c799fd474 | ||
|
|
17e25619da | ||
|
|
a4376b1492 | ||
|
|
d41faad9d9 | ||
|
|
0e6116b478 | ||
|
|
789127e8ff | ||
|
|
6ef9f32d4f | ||
|
|
1048dbed40 | ||
|
|
86c823bfde | ||
|
|
764f00ed3a | ||
|
|
3e4ea03437 | ||
|
|
0ef679e00d | ||
|
|
7f2bf2e905 | ||
|
|
ab8a8d5a35 | ||
|
|
a3b9c653fa | ||
|
|
ed48f5c559 | ||
|
|
d328f6b7ec | ||
|
|
16ba94d67d | ||
|
|
7978170133 | ||
|
|
ab313eb442 | ||
|
|
f40008d94a | ||
|
|
75e19d8d18 | ||
|
|
9bb978f612 | ||
|
|
3af5b458ba |
@@ -50,17 +50,17 @@ jobs:
|
||||
msbuild MpvNet.sln /m /p:Configuration=Debug
|
||||
- name: Create .mo files for localization
|
||||
shell: pwsh
|
||||
run: Install-Package Gettext.Tools -Force; .\lang\create-mo-files.ps1
|
||||
run: Install-Package Gettext.Tools -Force; $env:Path = ((Get-Package Gettext.Tools).Source | Split-Path) + '\tools\bin;' + $env:Path; .\lang\create-mo-files.ps1
|
||||
- name: Download libmpv # In principle, only update this binary file when significant feature changes occur in mpv/mpv.net
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
wget -nv -O libmpv.7z https://downloads.sourceforge.net/mpv-player-windows/mpv-dev-x86_64-20231203-git-f551a9d.7z
|
||||
wget -nv -O libmpv.7z https://github.com/zhongfly/mpv-winbuild/releases/download/2025-05-03-e663cbc/mpv-dev-x86_64-20250503-git-e663cbc.7z
|
||||
7z x -y libmpv.7z -olibmpv
|
||||
cp -f libmpv/libmpv-2.dll src/MpvNet.Windows/bin/Debug/ || true
|
||||
- name: Download MediaInfo
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
wget -nv -O MediaInfo.7z https://mediaarea.net/download/binary/libmediainfo0/23.11/MediaInfo_DLL_23.11_Windows_x64_WithoutInstaller.7z
|
||||
wget -nv -O MediaInfo.7z https://mediaarea.net/download/binary/libmediainfo0/24.03/MediaInfo_DLL_24.03_Windows_x64_WithoutInstaller.7z
|
||||
7z x -y MediaInfo.7z -oMediaInfo
|
||||
cp -f MediaInfo/MediaInfo.dll src/MpvNet.Windows/bin/Debug/ || true
|
||||
- name: Download mpvnet.com file
|
||||
@@ -69,7 +69,7 @@ jobs:
|
||||
wget -nv -O mpvnet.com https://github.com/mpvnet-player/file-host/releases/download/tag/mpvnet.com.txt
|
||||
cp -f mpvnet.com src/MpvNet.Windows/bin/Debug/ || true
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "mpv.net-win64"
|
||||
path: src/MpvNet.Windows/bin/Debug/
|
||||
32
README.md
@@ -6,7 +6,7 @@
|
||||
🎞 mpv.net
|
||||
==========
|
||||
|
||||
mpv.net is a media player for Windows that has a modern GUI.
|
||||
mpv.net is a media player for Windows with a modern GUI.
|
||||
|
||||
The player is based on the popular [mpv](https://mpv.io) media player.
|
||||
mpv.net is designed to be mpv compatible, almost all mpv features are available,
|
||||
@@ -56,6 +56,7 @@ Table of contents
|
||||
- [Download](#download)
|
||||
- [Manual](#manual)
|
||||
- [Screenshots](#screenshots)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
|
||||
Features that mpv and mpv.net have in common
|
||||
@@ -66,7 +67,7 @@ Features that mpv and mpv.net have in common
|
||||
- JSON IPC to control the player with a external programs
|
||||
- On Screen Controller (OSC, play control buttons) with modern flat design
|
||||
- Command Line Interface
|
||||
- Started from a terminal status, error and debug output is printed on the terminal
|
||||
- Started from a terminal, status, error and debug output is printed on the terminal
|
||||
- DXVA2 video decoding acceleration
|
||||
- Video output capable of features loved by videophiles, such as video scaling with popular high quality algorithms, color management, frame timing, interpolation, HDR, and more
|
||||
- Browser extensions to start mpv.net from the browser
|
||||
@@ -85,14 +86,11 @@ Features exclusive to mpv.net
|
||||
|
||||
- Very high degree of mpv compatibility, almost all mpv features are available
|
||||
- Modern graphical user interface with customizable color themes
|
||||
- Customizable context menu defined in the same file as the key bindings
|
||||
- Customizable context menu
|
||||
- Searchable config editor
|
||||
- Searchable input (shorcut keys) editor
|
||||
- C# and PowerShell Scripting
|
||||
- Global keyboard shortcuts
|
||||
- Extension API for .NET languages (C#, VB.NET and F#)
|
||||
- Portable, MS Store or WinGet download and installation
|
||||
- File history feature to log time and filename
|
||||
- Files can be enqueued from File Explorer
|
||||
|
||||
|
||||
@@ -111,6 +109,11 @@ Features exclusive to mpv.net
|
||||
[The mpv.net documentation.](docs/manual.md)
|
||||
|
||||
|
||||
## [Contributing](docs/contributing.md)
|
||||
|
||||
[Contributing section of the manual.](docs/manual.md#contributing)
|
||||
|
||||
|
||||
Screenshots
|
||||
-----------
|
||||
|
||||
@@ -121,27 +124,16 @@ Screenshots
|
||||
|
||||
#### Context Menu
|
||||
|
||||
Context menu using dark mode.
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
#### Config Editor
|
||||
|
||||
Searchable config editor as alternative to edit the conf file manually.
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
#### Terminal
|
||||
|
||||
OSD console and status printed on the terminal.
|
||||
|
||||

|
||||
|
||||
|
||||
#### Input Editor
|
||||
|
||||
Searchable key and mouse binding editor.
|
||||
|
||||

|
||||

|
||||
|
||||
@@ -1,4 +1,150 @@
|
||||
|
||||
# v7.1.1.5 Beta (2025-11-20)
|
||||
|
||||
- Same as in mpv the `?` and `t-4` keys can be used to show the active
|
||||
key bindings on-screen, it supports scrolling and searching.
|
||||
In the context menu it's located at:
|
||||
`View > More > Show Active Bindings On-Screen`
|
||||
- Bindings of select.lua menus have changed:
|
||||
`F1` On-Screen menu
|
||||
`F2` Bindings
|
||||
`F3` Properties
|
||||
`F4` Commands
|
||||
- The German, Chinese, Japanese and Turkish translations were updated. Thanks to the translators!
|
||||
- Users need to install .NET 10 LTS (Long Term Support), it should run on Windows 10.
|
||||
It was requested by users to prefer LTS over STS (Short Term Support).
|
||||
- libmpv and MediaInfo was updated.
|
||||
|
||||
# v7.1.1.4 Beta (2025-10-05)
|
||||
|
||||
- Support for select.lua has been added. It's a new Lua script built
|
||||
directly into mpv like the osc or console script. It's similar to command_palete.lua.
|
||||
- Fix --script-opt not working.
|
||||
- The mpv.net manual was updated.
|
||||
- The Turkish translation was updated. A Bulgarian translation was added.
|
||||
Thanks to the translators!
|
||||
- The required Dotnet version changed from 6.0 to 9.0. This drops Win 7 support
|
||||
unfortunately. It was done to use new C# language features and make
|
||||
the mpv.net project more attractive for new developers to contribute.
|
||||
Also most users prefer having the newest runtime.
|
||||
- auto build has been disabled because it requires updating libmpv and
|
||||
mediainfo all the time which is too much manual work.
|
||||
- The script src/Tools/update-mpv.ps1 has been improved. It's the easiest way
|
||||
update mpv and libmpv (x64 and ARM64). Shinshiro has a update script too,
|
||||
but it's a lot longer and more complex.
|
||||
- mediainfo and libmpv have been updated.
|
||||
|
||||
# v7.1.1.3 Beta (2024-10-20)
|
||||
|
||||
- Support for autocreate-playlist, video-exts, audio-exts, image-exts.
|
||||
Windows 7 support should still work, but needs auto-load-folder to be enabled
|
||||
or autoload.lua.
|
||||
- The command palette user script is installable from the context menu under
|
||||
`Settings > Setup > Install Command Palette`. The command palette features
|
||||
are shown in the menu under 'View > Command Palette'.
|
||||
- New command to select the stream quality `Video > Stream Quality (Alt+q)`,
|
||||
this calls the Stream Quality feature of the command palette.
|
||||
- The Command Palette interacts with mpv.net to enable the Recent Files
|
||||
feature in the Command Palette.
|
||||
- New zhongfly libmpv x64 build.
|
||||
- New Andarwinux libmpv ARM64 build.
|
||||
|
||||
|
||||
# v7.1.1.2 Beta (2024-10-10)
|
||||
|
||||
- Polish translation fixed. German, Turkish and Japanese translation updated.
|
||||
French translation added! Thanks to the translation team!
|
||||
- Support of relative folders from command line.
|
||||
- Support for the mpv option `cursor-autohide`.
|
||||
- A issue with the support of the mpv property `title-bar` has been fixed,
|
||||
at the moment this is most useful for users of the popular uosc user script,
|
||||
the mpv built-in OSC doesn't fully support it yet.
|
||||
- `media-controls=yes` is now enabled by default, this enables play controls
|
||||
in the `KDE Connect` android app.
|
||||
- The mpv.net option `auto-load-folder` by default is now disabled and the
|
||||
option is deprecated. The reason for this is mpv has new native support
|
||||
for it using `autocreate-playlist`, which mpv.net uses now instead by default.
|
||||
- New zhongfly libmpv x64 build.
|
||||
- New Andarwinux libmpv ARM64 build.
|
||||
|
||||
|
||||
# v7.1.1.1 Beta (2024-07-20)
|
||||
|
||||
- Korean, Russian and Turkish translation added, Japanese translation fixed. Thanks to the translation team!
|
||||
- Action/Workflow/Auto build fix and update.
|
||||
- New default bindings and menu items for select.lua which is a new simple mpv built-in command palette script.
|
||||
In the context menu select.lua features can be found under `View > On Screen Menu`.
|
||||
https://github.com/mpv-player/mpv/blob/master/player/lua/select.lua
|
||||
- New PowerShell script 'Tools\release-mpv.net.ps1' used to releases mpv.net on GitHub.
|
||||
- Fix DVD ISO file support.
|
||||
- MediaInfo updated to version v24.6.
|
||||
- New ARM64 support.
|
||||
- New zhongfly libmpv x64 build.
|
||||
- New Andarwinux libmpv ARM64 build.
|
||||
|
||||
|
||||
# v7.1.1.0 (2024-02-03)
|
||||
|
||||
- Chinese and Japanese translation updated. Thanks to the translation team!
|
||||
- Fix command line arguments being ignored in some situations.
|
||||
|
||||
|
||||
# v7.1.0.0 (2024-01-12)
|
||||
|
||||
- The menu item that shows profiles was moved into the menu item that lists profiles.
|
||||
- Fix geometry not working when used from mpv.conf and the conf editor.
|
||||
- GitHub Auto/Action/Workflow builds use a newer libmpv build.
|
||||
- German and Chinese translation updated. Japanese translation added. Thanks to our translation team!
|
||||
- New PowerShell script Tools/update-mpv-and-libmpv.ps1 to update mpv and libmpv.
|
||||
- Context menu supports audio device selection (Audio > Audio Device)
|
||||
- New option `remember-audio-device` to save and restore the audio device chosen in the context menu.
|
||||
- New zhongfly libmpv build.
|
||||
|
||||
|
||||
# v7.0.0.6 Beta (2024-01-02)
|
||||
|
||||
- Improved backward compatibility with input.conf files created by old versions.
|
||||
|
||||
|
||||
# v7.0.0.5 Beta (2023-12-28)
|
||||
|
||||
- Fix mpv.net option `language` not working from command line.
|
||||
- Chinese and German translation updated.
|
||||
- More libplacebo options added.
|
||||
- Support of the mpv option `title-bar`.
|
||||
- Video being less often rendered with black line at the bottom.
|
||||
- The conf file reader/writer detects if the user prefers space before and after the equal sign.
|
||||
- The portable download includes like the installer debug symbols.
|
||||
- Setup questions on startup removed.
|
||||
- Pressing shift while drag and drop appends instead of replaces
|
||||
files in the playlist. mpv supports this as well.
|
||||
- New menu item and binding: `File > Add files to playlist from clipboard` `Ctrl+Shift+v`.
|
||||
- All list operation suffixes are available on the command line.
|
||||
- Improved layout in conf editor.
|
||||
- New zhongfly libmpv build.
|
||||
|
||||
|
||||
# v7.0.0.4 Beta (2023-12-19)
|
||||
|
||||
- When mpv.net is started for the first time from a new startup location,
|
||||
it asks if file associations should be registered.
|
||||
- Setup supports installing per user in non admin mode.
|
||||
- Command line parser supports list options with `-add` suffix.
|
||||
- Fix window sometimes shown with wrong size.
|
||||
- Limited support for the mpv option `geometry`, it supports location in percent,
|
||||
for size use `autofit`. Read the instructions in the mpv.net manual or in the conf editor.
|
||||
- Improved manual.
|
||||
- Improved bindings.
|
||||
- Conf editor reorganized according to options categories used in mpv manual.
|
||||
- mpv.net is available via command line package manager winget.
|
||||
- New libplacebo config editor options added.
|
||||
- The conf editor uses a newly developed combo box control (dropdown menu)
|
||||
instead of radio buttons whenever an option has more than 3 items,
|
||||
this improves the look and feel, usability and performance.
|
||||
The navigation tree view was improved.
|
||||
- New zhongfly libmpv build.
|
||||
|
||||
|
||||
# v7.0.0.3 Beta (2023-12-15)
|
||||
|
||||
- New conf editor option `Video/libplacebo/preset`.
|
||||
@@ -13,7 +159,8 @@
|
||||
- Conf editor support added for the mpv options:
|
||||
`reset-on-next-file`, `input-ipc-server`, `background`, `title`
|
||||
- Conf editor crash fixed.
|
||||
- When mpv.net is started for the first time from a new startup location, it asks if mpv.net should be added to the Path environment variable.
|
||||
- When mpv.net is started for the first time from a new startup location,
|
||||
it asks if mpv.net should be added to the Path environment variable.
|
||||
|
||||
# v7.0.0.2 Beta (2023-12-13)
|
||||
|
||||
@@ -38,7 +185,7 @@
|
||||
- Fix message box exceding working area size.
|
||||
- C# and PowerShell scripting was removed because of a compatibility problem
|
||||
with the .NET 6 platform. .NET extensions are supported with a new host
|
||||
(not backward compatible). A example extension is available under \src\MpvNet.Extension\ExampleExtension
|
||||
(not backward compatible). An example extension is available under \src\MpvNet.Extension\ExampleExtension
|
||||
- Redesigned bindings and context menu.
|
||||
- auto-play option removed, mpv supports it with the option reset-on-next-file.
|
||||
- Dark mode title bar enabled on Windows 10.0.18985 or higher.
|
||||
@@ -1019,4 +1166,4 @@ stable release, no changes since the last beta
|
||||
|
||||
- new feature added to manage file associations from within the app. It can be found in the menu at: Tools > Manage... [Default Binding](https://github.com/mpvnet-player/mpv.net/blob/main/mpv.net/Resources/input.conf.txt#L149)
|
||||
- new zip download option added
|
||||
- new x86 download option added
|
||||
- new x86 download option added
|
||||
|
||||
|
Before Width: | Height: | Size: 272 KiB |
BIN
docs/img/ConfEditor.webp
Normal file
|
After Width: | Height: | Size: 243 KiB |
|
Before Width: | Height: | Size: 251 KiB |
|
Before Width: | Height: | Size: 442 KiB After Width: | Height: | Size: 429 KiB |
|
Before Width: | Height: | Size: 536 KiB |
BIN
docs/img/Menu.webp
Normal file
|
After Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 355 KiB |
BIN
docs/img/Terminal.webp
Normal file
|
After Width: | Height: | Size: 139 KiB |
972
docs/manual.md
@@ -1,34 +1,20 @@
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$PoFiles = Get-ChildItem $PSScriptRoot/po
|
||||
$ExeFolder = "$PSScriptRoot/../src/MpvNet.Windows/bin/Debug"
|
||||
|
||||
function CreateFolder
|
||||
{
|
||||
param($path)
|
||||
|
||||
if (-not (Test-Path $path))
|
||||
{
|
||||
mkdir $path
|
||||
}
|
||||
|
||||
if (-not (Test-Path $path))
|
||||
{
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($it in $PoFiles)
|
||||
{
|
||||
$folder = "$ExeFolder/Locale/$($it.BaseName)/LC_MESSAGES"
|
||||
New-Item -ItemType Directory -Path $folder
|
||||
$moPath = "$folder/mpvnet.mo"
|
||||
New-Item -ItemType File -Path $moPath
|
||||
msgfmt --output-file=$moPath $it.FullName
|
||||
|
||||
if ($LASTEXITCODE -ne 0)
|
||||
if (-not (Test-Path $folder))
|
||||
{
|
||||
throw
|
||||
New-Item -ItemType Directory -Path $folder | Out-Null
|
||||
}
|
||||
|
||||
$moPath = "$folder/mpvnet.mo"
|
||||
msgfmt --output-file=$moPath $it.FullName
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
$moPath
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ D:\Projects\CS\mpv.net\src\MpvNet\AppInfo.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet\Binding.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet\Chapter.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet\Command.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet\CommandLine.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet\ExtensionLoader.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet\FileTypes.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet\Folder.cs
|
||||
@@ -14,6 +15,7 @@ D:\Projects\CS\mpv.net\src\MpvNet\MediaTrack.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet\MpvClient.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet\Player.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet\Settings.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet\StringPair.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet\Terminal.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet\Translator.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet\ExtensionMethod\ObjectExtension.cs
|
||||
@@ -35,15 +37,12 @@ D:\Projects\CS\mpv.net\src\MpvNet.Windows\GlobalUsings.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\Program.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\Settings.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\StringPair.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\Help\RegistryHelp.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\Help\WinMpvHelp.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\Help\WinApiHelp.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\Native\StockIcon.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\Native\Taskbar.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\Native\WinApi.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\Properties\Resources.Designer.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\UI\CommandPalette.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\UI\CommandPaletteItem.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\UI\GlobalHotkey.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\UI\Theme.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\UI\TreeNode.cs
|
||||
@@ -51,6 +50,7 @@ D:\Projects\CS\mpv.net\src\MpvNet.Windows\WinForms\MainForm.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WinForms\MainForm.Designer.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WinForms\SnapManager.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\BindingProxy.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\ComboBoxTemplateSelector.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\ConfWindow.xaml.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\InputWindow.xaml.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\ISettingControl.cs
|
||||
@@ -59,7 +59,7 @@ D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\MenuHelp.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\Msg.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\WpfApplication.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\WpfTranslator.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\Controls\CommandPaletteControl.xaml.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\Controls\ComboBoxSettingControl.xaml.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\Controls\HyperlinkEx.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\Controls\OptionSettingControl.xaml.cs
|
||||
D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\Controls\SearchControl.xaml.cs
|
||||
|
||||
1013
lang/po/bg.po
Normal file
1520
lang/po/de.po
1028
lang/po/fr.po
Normal file
997
lang/po/ja.po
Normal file
@@ -0,0 +1,997 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
# Translators:
|
||||
# ever_green, 2025
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-10-06 00:24+0200\n"
|
||||
"PO-Revision-Date: 2023-12-08 00:34+0000\n"
|
||||
"Last-Translator: ever_green, 2025\n"
|
||||
"Language-Team: Japanese (https://app.transifex.com/stax76/teams/179964/ja/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ja\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:12
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:13
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:14
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:15
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:16
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:17
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:18
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:19
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:20
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:21
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:22
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:23
|
||||
msgid "File"
|
||||
msgstr "ファイル"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:12
|
||||
msgid "Open Files..."
|
||||
msgstr "ファイルを開く..."
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:13
|
||||
msgid "Open URL or file from clipboard"
|
||||
msgstr "クリップボードから URL またはファイルを開く"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:14
|
||||
msgid "Open DVD/Blu-ray Drive/Folder..."
|
||||
msgstr "DVD/Blu-ray ドライブ/フォルダを開く..."
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:16
|
||||
msgid "Add external audio files..."
|
||||
msgstr "外部オーディオファイルを追加..."
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:17
|
||||
msgid "Add external subtitle files..."
|
||||
msgstr "外部字幕ファイルを追加..."
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:19
|
||||
msgid "Add files to playlist..."
|
||||
msgstr "プレイリストへファイルを追加..."
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:20
|
||||
msgid "Add files/URLs to playlist from clipboard"
|
||||
msgstr "クリップボードからプレイリストへファイル/URL を追加"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:22
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\WinForms\MainForm.cs:372
|
||||
msgid "Recent Files"
|
||||
msgstr "最近のファイル"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:23
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:201
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:233
|
||||
msgid "Exit"
|
||||
msgstr "終了"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:25
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:26
|
||||
msgid "Playback"
|
||||
msgstr "再生"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:25
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:203
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:204
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:205
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:206
|
||||
msgid "Play/Pause"
|
||||
msgstr "再生/一時停止"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:26
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:207
|
||||
msgid "Stop"
|
||||
msgstr "停止"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:28
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:29
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:30
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:31
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:32
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:34
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:35
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:36
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:37
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:38
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:39
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:40
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:41
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:42
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:43
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:44
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:45
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:46
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:47
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:48
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:49
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:50
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:51
|
||||
msgid "Navigate"
|
||||
msgstr "操作"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:28
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:214
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:216
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:218
|
||||
msgid "Previous File"
|
||||
msgstr "前のファイル"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:29
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:215
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:217
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:219
|
||||
msgid "Next File"
|
||||
msgstr "次のファイル"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:31
|
||||
msgid "First File"
|
||||
msgstr "最初のファイル"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:32
|
||||
msgid "Last File"
|
||||
msgstr "最後のファイル"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:35
|
||||
msgid "Next Chapter"
|
||||
msgstr "次のチャプター"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:36
|
||||
msgid "Previous Chapter"
|
||||
msgstr "前のチャプター"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:38
|
||||
msgid "Jump To Next Frame"
|
||||
msgstr "次のフレームへ進む"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:39
|
||||
msgid "Jump To Previous Frame"
|
||||
msgstr "前のフレームへ戻る"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:41
|
||||
msgid "Jump 5 sec forward"
|
||||
msgstr "5 秒進む"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:42
|
||||
msgid "Jump 5 sec backward"
|
||||
msgstr "5 秒戻る"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:44
|
||||
msgid "Jump 30 sec forward"
|
||||
msgstr "30 秒進む"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:45
|
||||
msgid "Jump 30 sec backward"
|
||||
msgstr "30 秒戻る"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:47
|
||||
msgid "Jump 5 min forward"
|
||||
msgstr "5 分進む"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:48
|
||||
msgid "Jump 5 min backward"
|
||||
msgstr "5 分戻る"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:50
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\WinForms\MainForm.cs:393
|
||||
msgid "Title"
|
||||
msgstr "タイトル"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:51
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\WinForms\MainForm.cs:351
|
||||
msgid "Chapter"
|
||||
msgstr "チャプター"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:53
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:54
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:55
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:56
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:57
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:58
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:59
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:60
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:61
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:62
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:63
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:64
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:65
|
||||
msgid "Pan & Scan"
|
||||
msgstr "パン&スキャン"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:53
|
||||
msgid "Decrease Size"
|
||||
msgstr "サイズを縮小"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:54
|
||||
msgid "Increase Size"
|
||||
msgstr "サイズを拡大"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:56
|
||||
msgid "Move Left"
|
||||
msgstr "左へ移動"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:57
|
||||
msgid "Move Right"
|
||||
msgstr "右へ移動"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:59
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:97
|
||||
msgid "Move Up"
|
||||
msgstr "上へ移動"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:60
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:98
|
||||
msgid "Move Down"
|
||||
msgstr "下へ移動"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:62
|
||||
msgid "Decrease Height"
|
||||
msgstr "高さを縮小"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:63
|
||||
msgid "Increase Height"
|
||||
msgstr "高さを拡大"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:65
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:118
|
||||
msgid "Reset"
|
||||
msgstr "リセット"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:67
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:68
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:69
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:70
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:71
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:72
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:73
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:74
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:75
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:76
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:77
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:78
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:79
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:80
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:81
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:82
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:83
|
||||
msgid "Video"
|
||||
msgstr "ビデオ"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:67
|
||||
msgid "Decrease Contrast"
|
||||
msgstr "コントラストを下げる"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:68
|
||||
msgid "Increase Contrast"
|
||||
msgstr "コントラストを上げる"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:70
|
||||
msgid "Decrease Brightness"
|
||||
msgstr "明るさを下げる"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:71
|
||||
msgid "Increase Brightness"
|
||||
msgstr "明るさを上げる"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:73
|
||||
msgid "Decrease Gamma"
|
||||
msgstr "ガンマ値を下げる"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:74
|
||||
msgid "Increase Gamma"
|
||||
msgstr "ガンマ値を上げる"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:76
|
||||
msgid "Decrease Saturation"
|
||||
msgstr "彩度を下げる"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:77
|
||||
msgid "Increase Saturation"
|
||||
msgstr "彩度を上げる"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:79
|
||||
msgid "Take Screenshot"
|
||||
msgstr "スクリーンショットを撮る"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:80
|
||||
msgid "Take Screenshot without subtitles"
|
||||
msgstr "字幕なしでスクリーンショットを撮る"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:81
|
||||
msgid "Toggle Deinterlace"
|
||||
msgstr "インターレース解除の切り替え"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:82
|
||||
msgid "Change Aspect Ratio"
|
||||
msgstr "アスペクト比を変更"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:83
|
||||
msgid "Rotate Video"
|
||||
msgstr "ビデオを回転"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:85
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:86
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:87
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:88
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:89
|
||||
msgid "Audio"
|
||||
msgstr "オーディオ"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:85
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\WinForms\MainForm.cs:453
|
||||
msgid "Audio Device"
|
||||
msgstr "オーディオデバイス"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:86
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:91
|
||||
msgid "Next Track"
|
||||
msgstr "次のトラック"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:88
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:95
|
||||
msgid "Delay +0.1"
|
||||
msgstr "遅延 +0.1"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:89
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:94
|
||||
msgid "Delay -0.1"
|
||||
msgstr "遅延 -0.1"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:91
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:92
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:93
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:94
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:95
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:96
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:97
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:98
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:99
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:100
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:101
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:102
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:103
|
||||
msgid "Subtitle"
|
||||
msgstr "字幕"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:92
|
||||
msgid "Toggle Visibility"
|
||||
msgstr "表示の切り替え"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:100
|
||||
msgid "Decrease Font Size"
|
||||
msgstr "フォントサイズを縮小"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:101
|
||||
msgid "Increase Font Size"
|
||||
msgstr "フォントサイズを拡大"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:103
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:142
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:143
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:144
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:145
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:146
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:147
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:148
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:149
|
||||
msgid "More"
|
||||
msgstr "詳細"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:103
|
||||
msgid "Toggle overriding SSA/ASS styles with normal styles"
|
||||
msgstr "SSA/ASS スタイルを通常のスタイルで上書きする"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:105
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\WinForms\MainForm.cs:289
|
||||
msgid "Track"
|
||||
msgstr "トラック"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:107
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:108
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:109
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:110
|
||||
msgid "Volume"
|
||||
msgstr "音量"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:107
|
||||
msgctxt "Volume"
|
||||
msgid "Up"
|
||||
msgstr "上げる"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:108
|
||||
msgctxt "Volume"
|
||||
msgid "Down"
|
||||
msgstr "下げる"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:110
|
||||
msgid "Mute"
|
||||
msgstr "ミュート"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:112
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:113
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:114
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:115
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:116
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:117
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:118
|
||||
msgid "Speed"
|
||||
msgstr "再生速度"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:112
|
||||
msgid "-10%"
|
||||
msgstr "-10%"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:113
|
||||
msgid "+10%"
|
||||
msgstr "+10%"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:115
|
||||
msgid "Half"
|
||||
msgstr "1/2"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:116
|
||||
msgid "Double"
|
||||
msgstr "2 倍"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:120
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:121
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:122
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:123
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:124
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:125
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:126
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:127
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:128
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:129
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:130
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:131
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:132
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:133
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:134
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:135
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:136
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:137
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:138
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:139
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:140
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:141
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:142
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:143
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:144
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:145
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:146
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:147
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:148
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:149
|
||||
msgid "View"
|
||||
msgstr "表示"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:120
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:127
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:234
|
||||
msgid "Playlist"
|
||||
msgstr "プレイリスト"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:121
|
||||
msgid "Toggle Statistics"
|
||||
msgstr "統計情報の切り替え"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:122
|
||||
msgid "Toggle OSC Visibility"
|
||||
msgstr "OSC 表示の切り替え"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:123
|
||||
msgid "Media Info On-Screen"
|
||||
msgstr "画面メディア情報"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:124
|
||||
msgid "Media Info Message Box"
|
||||
msgstr "メッセージメディア情報"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:125
|
||||
msgid "Progress"
|
||||
msgstr "再生位置"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:126
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:127
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:128
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:129
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:130
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:131
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:132
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:133
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:134
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:135
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:136
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:137
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:138
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:139
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:140
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:248
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:249
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:250
|
||||
msgid "On-Screen Menu"
|
||||
msgstr "画面メニュー"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:128
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:246
|
||||
msgid "Bindings"
|
||||
msgstr "バインディング"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:129
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:247
|
||||
msgid "Properties"
|
||||
msgstr "プロパティ"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:130
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:240
|
||||
msgid "Chapters"
|
||||
msgstr "チャプター"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:131
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:239
|
||||
msgid "Tracks"
|
||||
msgstr "トラック"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:132
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:237
|
||||
msgid "Audio Tracks"
|
||||
msgstr "オーディオトラック"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:133
|
||||
msgid "Subtitle Tracks"
|
||||
msgstr "字幕トラック"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:134
|
||||
msgid "Secondary Subtitle"
|
||||
msgstr "セカンダリ字幕"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:135
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:238
|
||||
msgid "Video Tracks"
|
||||
msgstr "ビデオトラック"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:136
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:241
|
||||
msgid "Editions"
|
||||
msgstr "エディション"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:137
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:242
|
||||
msgid "Subtitle Lines"
|
||||
msgstr "字幕ライン"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:138
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:243
|
||||
msgid "Audio Devices"
|
||||
msgstr "オーディオデバイス"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:139
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:244
|
||||
msgid "Watch History"
|
||||
msgstr "再生履歴"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:140
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:245
|
||||
msgid "Watch Later"
|
||||
msgstr "後で再生"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:142
|
||||
msgid "Console"
|
||||
msgstr "コンソール"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:143
|
||||
msgid "Commands"
|
||||
msgstr "コマンド"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:144
|
||||
msgid "Active Bindings In Text Editor"
|
||||
msgstr "キーバインドをエディタで編集"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:145
|
||||
msgid "Active Bindings On-Screen"
|
||||
msgstr "キーバインドを画面に表示"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:146
|
||||
msgid "Keys"
|
||||
msgstr "キー"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:147
|
||||
msgid "Protocols"
|
||||
msgstr "プロトコル"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:148
|
||||
msgid "Decoders"
|
||||
msgstr "デコーダー"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:149
|
||||
msgid "Demuxers"
|
||||
msgstr "デマルチプレクサ"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:151
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:152
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:153
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:154
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:155
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:156
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:157
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:158
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:159
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:160
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:161
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:162
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:163
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:164
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:165
|
||||
msgid "Window"
|
||||
msgstr "ウィンドウ"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:151
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:221
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:222
|
||||
msgid "Fullscreen"
|
||||
msgstr "フルスクリーン"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:152
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:153
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:154
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:155
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:156
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:157
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:158
|
||||
msgid "Zoom"
|
||||
msgstr "ズーム"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:152
|
||||
msgid "Enlarge"
|
||||
msgstr "拡大"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:153
|
||||
msgid "Shrink"
|
||||
msgstr "縮小"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:155
|
||||
msgid "50 %"
|
||||
msgstr "50 %"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:156
|
||||
msgid "100 %"
|
||||
msgstr "100 %"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:157
|
||||
msgid "200 %"
|
||||
msgstr "200 %"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:158
|
||||
msgid "300 %"
|
||||
msgstr "300 %"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:159
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:160
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:161
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:162
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:163
|
||||
msgid "Move"
|
||||
msgstr "移動"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:159
|
||||
msgctxt "Move"
|
||||
msgid "Left"
|
||||
msgstr "左へ"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:160
|
||||
msgctxt "Move"
|
||||
msgid "Right"
|
||||
msgstr "右へ"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:161
|
||||
msgctxt "Move"
|
||||
msgid "Up"
|
||||
msgstr "上へ"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:162
|
||||
msgctxt "Move"
|
||||
msgid "Down"
|
||||
msgstr "下へ"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:163
|
||||
msgctxt "Move"
|
||||
msgid "Center"
|
||||
msgstr "中央"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:164
|
||||
msgid "Toggle Border"
|
||||
msgstr "ボーダーの切り替え"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:165
|
||||
msgid "Toggle On Top"
|
||||
msgstr "常に手前に表示"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:167
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\WinForms\MainForm.cs:426
|
||||
msgid "Profile"
|
||||
msgstr "プロファイル"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:169
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:170
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:171
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:172
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:173
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:174
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:175
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:176
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:177
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:178
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:179
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:180
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:181
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:182
|
||||
msgid "Config"
|
||||
msgstr "設定"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:169
|
||||
msgid "Show Config Editor"
|
||||
msgstr "構成エディターを表示"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:170
|
||||
msgid "Show Input Editor"
|
||||
msgstr "入力エディターを表示"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:172
|
||||
msgid "Edit mpv.conf"
|
||||
msgstr "mpv.conf の編集"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:173
|
||||
msgid "Edit input.conf"
|
||||
msgstr "input.conf の編集"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:175
|
||||
msgid "Open Config Folder"
|
||||
msgstr "構成フォルダを開く"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:176
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:177
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:178
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:179
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:180
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:181
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:182
|
||||
msgid "Setup"
|
||||
msgstr "セットアップ"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:176
|
||||
msgid "Register video file associations"
|
||||
msgstr "ビデオファイルの関連付けを登録"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:177
|
||||
msgid "Register audio file associations"
|
||||
msgstr "オーディオファイルの関連付けを登録"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:178
|
||||
msgid "Register image file associations"
|
||||
msgstr "画像ファイルの関連付けを登録"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:179
|
||||
msgid "Unregister file associations"
|
||||
msgstr "ファイルの関連付けの登録解除"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:181
|
||||
msgid "Add mpv.net to Path environment variable"
|
||||
msgstr "mpv.net を Path 環境変数へ追加"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:182
|
||||
msgid "Remove mpv.net from Path environment variable"
|
||||
msgstr "mpv.net を Path 環境変数から削除"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:184
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:185
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:186
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:187
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:188
|
||||
msgid "Tools"
|
||||
msgstr "ツール"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:184
|
||||
msgid "Set/clear A-B loop points"
|
||||
msgstr "A-B 区間ループの設定/解除"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:185
|
||||
msgid "Toggle infinite file looping"
|
||||
msgstr "無限ファイルループの切り替え"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:186
|
||||
msgid "Shuffle Playlist"
|
||||
msgstr "プレイリストをシャッフル"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:187
|
||||
msgid "Toggle Hardware Decoding"
|
||||
msgstr "ハードウェアデコードの切り替え"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:188
|
||||
msgid "Exit Watch Later"
|
||||
msgstr "後で再生を解除"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:190
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\WinForms\MainForm.cs:477
|
||||
msgid "Custom"
|
||||
msgstr "カスタム"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:192
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:193
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:194
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:195
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:196
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:197
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:198
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:199
|
||||
msgid "Help"
|
||||
msgstr "ヘルプ"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:192
|
||||
msgid "Website mpv"
|
||||
msgstr "mpv ウェブサイト"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:193
|
||||
msgid "Website mpv.net"
|
||||
msgstr "mpv.net ウェブサイト"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:195
|
||||
msgid "Manual mpv"
|
||||
msgstr "mpv マニュアル"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:196
|
||||
msgid "Manual mpv.net"
|
||||
msgstr "mpv.net マニュアル"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:198
|
||||
msgid "awesome-mpv"
|
||||
msgstr "awesome-mpv"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:199
|
||||
msgid "About mpv.net"
|
||||
msgstr "mpv.net のバージョン情報"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:202
|
||||
msgid "Show Menu"
|
||||
msgstr "メニューを表示"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:208
|
||||
msgid "Forward"
|
||||
msgstr "進む"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:209
|
||||
msgid "Backward"
|
||||
msgstr "戻る"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:210
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:212
|
||||
msgid "Volume Up"
|
||||
msgstr "音量を上げる"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:211
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:213
|
||||
msgid "Volume Down"
|
||||
msgstr "音量を下げる"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:220
|
||||
msgid "Ignore left mouse butten"
|
||||
msgstr "マウスの左ボタンを無視"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:223
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:225
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:231
|
||||
msgid "Seek Forward"
|
||||
msgstr "早送り"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:224
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:226
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:232
|
||||
msgid "Seek Backward"
|
||||
msgstr "早戻し"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:227
|
||||
msgid "Undo previous (or marked) seek"
|
||||
msgstr "直前の (またはマークした) シークを元に戻す"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:228
|
||||
msgid "Mark position for revert-seek"
|
||||
msgstr "戻り位置をマーク"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:229
|
||||
msgid "Seek to previous subtitle"
|
||||
msgstr "前の字幕へ戻る"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:230
|
||||
msgid "Seek to next subtitle"
|
||||
msgstr "次の字幕へ進む"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:235
|
||||
msgid "Subtitles"
|
||||
msgstr "字幕"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet\InputHelp.cs:236
|
||||
msgid "Secondary Subtitles"
|
||||
msgstr "セカンダリ字幕"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs:192
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs:214
|
||||
msgid "Files/URLs were added to the playlist"
|
||||
msgstr "ファイル/URL がプレイリストへ追加されました"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs:207
|
||||
msgid "The clipboard does not contain a valid URL or file."
|
||||
msgstr "クリップボードに有効な URL またはファイルが含まれていません。"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs:262
|
||||
msgid "File Explorer icons will refresh after process restart."
|
||||
msgstr "ファイルエクスプローラーのアイコンは、プロセスの再起動後に更新されます。"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs:265
|
||||
msgid "File associations were successfully removed."
|
||||
msgstr "ファイルの関連付けは正常に削除されました。"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs:267
|
||||
msgid "File associations were successfully created."
|
||||
msgstr "ファイルの関連付けが正常に作成されました。"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs:270
|
||||
msgid "Error creating file associations."
|
||||
msgstr "ファイルの関連付けの作成中にエラーが発生しました。"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs:387
|
||||
msgid "mpv.net is already in the Path environment variable."
|
||||
msgstr "mpv.net は既に Path 環境変数にあります。"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs:395
|
||||
msgid "mpv.net was successfully added to the Path environment variable."
|
||||
msgstr "mpv.net が Path 環境変数へ正常に追加されました。"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs:404
|
||||
msgid "mpv.net was not found in the Path environment variable."
|
||||
msgstr "mpv.net が Path 環境変数に見つかりませんでした。"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs:413
|
||||
msgid "mpv.net was successfully removed from the Path environment variable."
|
||||
msgstr "mpv.net は Path 環境変数から正常に削除されました。"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs:418
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs:423
|
||||
msgid "This feature was removed, but there are user scripts:"
|
||||
msgstr "この機能は削除されましたが、ユーザースクリプトがあります:"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\GuiCommand.cs:427
|
||||
msgid "This feature was removed."
|
||||
msgstr "この機能は削除されました。"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\Properties\Resources.Designer.cs:79
|
||||
msgid "editor_conf"
|
||||
msgstr "editor_conf"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\Properties\Resources.Designer.cs:114
|
||||
msgid "theme"
|
||||
msgstr "テーマ"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\WinForms\MainForm.cs:388
|
||||
msgid "Clear List"
|
||||
msgstr "リストをクリア"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\WinForms\MainForm.cs:448
|
||||
msgid "Show Profiles"
|
||||
msgstr "プロファイルを表示"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\WinForms\MainForm.cs:1432
|
||||
msgid "Shutdown thread failed to complete within 10 seconds."
|
||||
msgstr "シャットダウン スレッドが 10 秒以内に完了しませんでした。"
|
||||
|
||||
#: D:\Projects\CS\mpv.net\src\MpvNet.Windows\WPF\InputWindow.xaml.cs:116
|
||||
msgid "Changes will be available on next startup."
|
||||
msgstr "変更は次回の起動時に利用可能になります。"
|
||||
1020
lang/po/ko.po
Normal file
1022
lang/po/pl.po
Normal file
1022
lang/po/ru.po
Normal file
1024
lang/po/tr.po
Normal file
1292
lang/po/zh_CN.po
1269
lang/source.pot
@@ -1,4 +1,6 @@
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# Write list of .cs files into cs-files.txt file
|
||||
Get-ChildItem $PSScriptRoot/.. -Recurse -File -Filter '*.cs' |
|
||||
Where-Object { $_ -notmatch '[/\\]obj[/\\]' } |
|
||||
@@ -6,7 +8,8 @@ Get-ChildItem $PSScriptRoot/.. -Recurse -File -Filter '*.cs' |
|
||||
Out-File $PSScriptRoot/cs-files.txt
|
||||
|
||||
# Create .pot file
|
||||
xgettext --force-po --from-code=UTF-8 '--language=c#' -o $PSScriptRoot/source.pot --files-from=$PSScriptRoot/cs-files.txt --keyword=_
|
||||
xgettext -k_ -k_n:1,2 -k_p:1c,2 -k_pn:1c,2,3 --force-po --from-code=UTF-8 '--language=c#' -o $PSScriptRoot/source.pot --files-from=$PSScriptRoot/cs-files.txt --keyword=_
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
|
||||
# Backup .po files
|
||||
$BackupTargetFolder = $env:TEMP + '/mpv.net po backup ' + (Get-Date -Format 'yyyy-MM-dd HH_mm_ss')
|
||||
@@ -16,3 +19,5 @@ Copy-Item $PSScriptRoot/po $BackupTargetFolder -Force -Recurse
|
||||
# Update .po files
|
||||
(Get-ChildItem $PSScriptRoot/PO -Filter '*.po').FullName |
|
||||
ForEach-Object { msgmerge --sort-output --backup=none --update $_ $PSScriptRoot/source.pot }
|
||||
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
|
||||
@@ -5,3 +5,6 @@ csharp_style_implicit_object_creation_when_type_is_apparent = true
|
||||
|
||||
# IDE0090: Use 'new(...)'
|
||||
dotnet_diagnostic.IDE0090.severity = silent
|
||||
|
||||
# WFO1000: A property should determine its property content serialization with the DesignerSerializationVisibilityAttribute, DefaultValueAttribute or the ShouldSerializeProperty method
|
||||
dotnet_diagnostic.WFO1000.severity = silent
|
||||
6
src/Directory.Build.props
Normal file
@@ -0,0 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Product>mpv.net</Product>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
10
src/Directory.Packages.props
Normal file
@@ -0,0 +1,10 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageVersion Include="NGettext" Version="0.6.7" />
|
||||
<PackageVersion Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -53,6 +53,7 @@ public class Conf
|
||||
if (section.HasName("help")) baseSetting.Help = section.GetValue("help");
|
||||
if (section.HasName("url")) baseSetting.URL = section.GetValue("url");
|
||||
if (section.HasName("width")) baseSetting.Width = Convert.ToInt32(section.GetValue("width"));
|
||||
if (section.HasName("option-name-width")) baseSetting.OptionNameWidth = Convert.ToInt32(section.GetValue("option-name-width"));
|
||||
if (section.HasName("type")) baseSetting.Type = section.GetValue("type");
|
||||
|
||||
if (baseSetting.Help.ContainsEx("\\n"))
|
||||
@@ -100,8 +101,8 @@ public class ConfParser
|
||||
}
|
||||
else if (line.Contains('='))
|
||||
{
|
||||
string name = line[..line.IndexOf("=")].Trim();
|
||||
string value = line[(line.IndexOf("=") + 1)..].Trim();
|
||||
string name = line[..line.IndexOf('=')].Trim();
|
||||
string value = line[(line.IndexOf('=') + 1)..].Trim();
|
||||
|
||||
currentGroup?.Items.Add(new StringPair(name, value));
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ public static class FileAssociation
|
||||
string exeFilename = Path.GetFileName(exePath);
|
||||
string exeFilenameNoExt = Path.GetFileNameWithoutExtension(exePath);
|
||||
|
||||
string[] protocols = { "ytdl", "rtsp", "srt", "srtp" };
|
||||
string[] protocols = ["ytdl", "rtsp", "srt", "srtp"];
|
||||
|
||||
if (perceivedType != "unreg")
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Globalization;
|
||||
using System.Windows.Forms;
|
||||
@@ -11,9 +12,8 @@ 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;
|
||||
using MpvNet.Help;
|
||||
|
||||
namespace MpvNet;
|
||||
|
||||
@@ -30,44 +30,53 @@ public class GuiCommand
|
||||
|
||||
public Dictionary<string, Action<IList<string>>> Commands => _commands ??= new()
|
||||
{
|
||||
["show-about"] = args => ShowDialog(typeof(AboutWindow)),
|
||||
["show-conf-editor"] = args => ShowDialog(typeof(ConfWindow)),
|
||||
["show-input-editor"] = args => ShowDialog(typeof(InputWindow)),
|
||||
["show-audio-devices"] = args => Msg.ShowInfo(Player.GetPropertyOsdString("audio-device-list")),
|
||||
["show-profiles"] = args => Msg.ShowInfo(Player.GetProfiles()),
|
||||
["load-sub"] = LoadSubtitle,
|
||||
["open-files"] = OpenFiles,
|
||||
["open-optical-media"] = Open_DVD_Or_BD_Folder,
|
||||
["load-audio"] = LoadAudio,
|
||||
["open-clipboard"] = OpenFromClipboard,
|
||||
["reg-file-assoc"] = RegisterFileAssociations,
|
||||
["scale-window"] = args => ScaleWindow?.Invoke(float.Parse(args[0], CultureInfo.InvariantCulture)),
|
||||
["show-media-info"] = ShowMediaInfo,
|
||||
["move-window"] = args => MoveWindow?.Invoke(args[0]),
|
||||
["window-scale"] = args => WindowScaleNet?.Invoke(float.Parse(args[0], CultureInfo.InvariantCulture)),
|
||||
["show-menu"] = args => ShowMenu?.Invoke(),
|
||||
["show-bindings"] = args => ShowBindings(),
|
||||
["show-playlist"] = args => ShowPlaylist(),
|
||||
["add-to-path"] = args => AddToPath(),
|
||||
["edit-conf-file"] = EditCongFile,
|
||||
["load-audio"] = LoadAudio,
|
||||
["load-sub"] = LoadSubtitle,
|
||||
["move-window"] = args => MoveWindow?.Invoke(args[0]),
|
||||
["open-clipboard"] = OpenFromClipboard,
|
||||
["open-files"] = OpenFiles,
|
||||
["open-optical-media"] = Open_DVD_Or_BD_Folder,
|
||||
["reg-file-assoc"] = RegisterFileAssociations,
|
||||
["remove-from-path"] = args => RemoveFromPath(),
|
||||
["scale-window"] = args => ScaleWindow?.Invoke(float.Parse(args[0], CultureInfo.InvariantCulture)),
|
||||
["show-about"] = args => ShowDialog(typeof(AboutWindow)),
|
||||
["show-bindings"] = args => ShowBindings(),
|
||||
["show-commands"] = args => ShowCommands(),
|
||||
["show-conf-editor"] = args => ShowDialog(typeof(ConfWindow)),
|
||||
["show-decoders"] = args => ShowDecoders(),
|
||||
["show-demuxers"] = args => ShowDemuxers(),
|
||||
["show-info"] = args => ShowMediaInfo(new[] { "osd" }),
|
||||
["show-input-editor"] = args => ShowDialog(typeof(InputWindow)),
|
||||
["show-keys"] = args => ShowKeys(),
|
||||
["show-media-info"] = ShowMediaInfo,
|
||||
["show-menu"] = args => ShowMenu?.Invoke(),
|
||||
["show-profiles"] = args => Msg.ShowInfo(Player.GetProfiles()),
|
||||
["show-properties"] = args => Player.Command("script-binding select/show-properties"),
|
||||
["show-protocols"] = args => ShowProtocols(),
|
||||
["window-scale"] = args => WindowScaleNet?.Invoke(float.Parse(args[0], CultureInfo.InvariantCulture)),
|
||||
|
||||
|
||||
// deprecated
|
||||
["show-info"] = args => ShowMediaInfo(new[] { "osd" }), // deprecated
|
||||
["show-recent"] = args => ShowRemoved(), // deprecated
|
||||
["quick-bookmark"] = args => QuickBookmark(), // deprecated
|
||||
["show-history"] = args => ShowHistory(), // deprecated
|
||||
["show-command-palette"] = args => ShowCommandPalette(), // deprecated
|
||||
["show-playlist"] = args => Player.Command("script-binding select/select-playlist"), // deprecated
|
||||
["show-command-palette"] = args => Player.Command("script-binding select/select-binding"), // deprecated
|
||||
["show-audio-tracks"] = args => Player.Command("script-binding select/select-aid"), // deprecated
|
||||
["show-subtitle-tracks"] = args => Player.Command("script-binding select/select-sid"), // deprecated
|
||||
["show-audio-devices"] = args => Player.Command("script-binding select/select-audio-device"), // deprecated
|
||||
};
|
||||
|
||||
public void ShowDialog(Type winType)
|
||||
void ShowDialog(Type winType)
|
||||
{
|
||||
Window? win = Activator.CreateInstance(winType) as Window;
|
||||
new WindowInteropHelper(win).Owner = MainForm.Instance!.Handle;
|
||||
win?.ShowDialog();
|
||||
}
|
||||
|
||||
public void LoadSubtitle(IList<string> args)
|
||||
void LoadSubtitle(IList<string> args)
|
||||
{
|
||||
using var dialog = new OpenFileDialog();
|
||||
string path = Player.GetPropertyString("path");
|
||||
@@ -82,7 +91,7 @@ public class GuiCommand
|
||||
Player.CommandV("sub-add", filename);
|
||||
}
|
||||
|
||||
public void OpenFiles(IList<string> args)
|
||||
void OpenFiles(IList<string> args)
|
||||
{
|
||||
bool append = false;
|
||||
|
||||
@@ -96,7 +105,7 @@ public class GuiCommand
|
||||
Player.LoadFiles(dialog.FileNames, true, append);
|
||||
}
|
||||
|
||||
public void Open_DVD_Or_BD_Folder(IList<string> args)
|
||||
void Open_DVD_Or_BD_Folder(IList<string> args)
|
||||
{
|
||||
var dialog = new FolderBrowserDialog();
|
||||
|
||||
@@ -104,15 +113,23 @@ public class GuiCommand
|
||||
Player.LoadDiskFolder(dialog.SelectedPath);
|
||||
}
|
||||
|
||||
public void EditCongFile(IList<string> args)
|
||||
void EditCongFile(IList<string> args)
|
||||
{
|
||||
string file = Player.ConfigFolder + args[0];
|
||||
|
||||
if (!File.Exists(file))
|
||||
{
|
||||
string msg = $"{args[0]} does not exist. Would you like to create it?";
|
||||
|
||||
if (Msg.ShowQuestion(msg) == MessageBoxResult.OK)
|
||||
File.WriteAllText(file, "");
|
||||
}
|
||||
|
||||
if (File.Exists(file))
|
||||
ProcessHelp.ShellExecute(WinApiHelp.GetAppPathForExtension("txt"), "\"" + file + "\"");
|
||||
}
|
||||
|
||||
public static void ShowTextWithEditor(string name, string text)
|
||||
void ShowTextWithEditor(string name, string text)
|
||||
{
|
||||
string file = Path.Combine(Path.GetTempPath(), name + ".txt");
|
||||
App.TempFiles.Add(file);
|
||||
@@ -120,7 +137,7 @@ public class GuiCommand
|
||||
ProcessHelp.ShellExecute(WinApiHelp.GetAppPathForExtension("txt"), "\"" + file + "\"");
|
||||
}
|
||||
|
||||
public static void ShowCommands()
|
||||
void ShowCommands()
|
||||
{
|
||||
string json = Core.GetPropertyString("command-list");
|
||||
var enumerator = JsonDocument.Parse(json).RootElement.EnumerateArray();
|
||||
@@ -145,39 +162,60 @@ public class GuiCommand
|
||||
}
|
||||
|
||||
string header = BR +
|
||||
"https://mpv.io/manual/master/#list-of-input-commands" + BR2 +
|
||||
"https://github.com/stax76/mpv-scripts#command_palette" + BR;
|
||||
"https://mpv.io/manual/master/#list-of-input-commands" + BR;
|
||||
|
||||
ShowTextWithEditor("Input Commands", header + sb.ToString());
|
||||
}
|
||||
|
||||
public void OpenFromClipboard(IList<string> args)
|
||||
void ShowKeys() =>
|
||||
ShowTextWithEditor("Keys", Core.GetPropertyString("input-key-list").Replace(",", BR));
|
||||
|
||||
void ShowProtocols() =>
|
||||
ShowTextWithEditor("Protocols", Core.GetPropertyString("protocol-list").Replace(",", BR));
|
||||
|
||||
void ShowDecoders() =>
|
||||
ShowTextWithEditor("Decoders", Core.GetPropertyOsdString("decoder-list").Replace(",", BR));
|
||||
|
||||
void ShowDemuxers() =>
|
||||
ShowTextWithEditor("Demuxers", Core.GetPropertyOsdString("demuxer-lavf-list").Replace(",", BR));
|
||||
|
||||
void OpenFromClipboard(IList<string> args)
|
||||
{
|
||||
bool append = args.Count == 1 && args[0] == "append";
|
||||
|
||||
if (System.Windows.Forms.Clipboard.ContainsFileDropList())
|
||||
{
|
||||
string[] files = System.Windows.Forms.Clipboard.GetFileDropList().Cast<string>().ToArray();
|
||||
Player.LoadFiles(files, false, false);
|
||||
Player.LoadFiles(files, false, append);
|
||||
|
||||
if (append)
|
||||
Player.CommandV("show-text", _("Files/URLs were added to the playlist"));
|
||||
}
|
||||
else
|
||||
{
|
||||
string clipboard = System.Windows.Forms.Clipboard.GetText();
|
||||
List<string> files = new List<string>();
|
||||
List<string> files = [];
|
||||
|
||||
foreach (string i in clipboard.Split(BR.ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (i.Contains("://") || File.Exists(i))
|
||||
files.Add(i);
|
||||
}
|
||||
|
||||
if (files.Count == 0)
|
||||
{
|
||||
Terminal.WriteError("The clipboard does not contain a valid URL or file.");
|
||||
Terminal.WriteError(_("The clipboard does not contain a valid URL or file."));
|
||||
return;
|
||||
}
|
||||
|
||||
Player.LoadFiles(files.ToArray(), false, false);
|
||||
Player.LoadFiles(files.ToArray(), false, append);
|
||||
|
||||
if (append)
|
||||
Player.CommandV("show-text", _("Files/URLs were added to the playlist"));
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadAudio(IList<string> args)
|
||||
void LoadAudio(IList<string> args)
|
||||
{
|
||||
using var dialog = new OpenFileDialog();
|
||||
string path = Player.GetPropertyString("path");
|
||||
@@ -187,21 +225,25 @@ public class GuiCommand
|
||||
|
||||
dialog.Multiselect = true;
|
||||
|
||||
if (dialog.ShowDialog() == DialogResult.OK)
|
||||
foreach (string i in dialog.FileNames)
|
||||
Player.CommandV("audio-add", i);
|
||||
if (dialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
foreach (string i in dialog.FileNames)
|
||||
{
|
||||
Player.CommandV("audio-add", i);
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterFileAssociations(IList<string> args)
|
||||
void RegisterFileAssociations(IList<string> args)
|
||||
{
|
||||
string perceivedType = args[0];
|
||||
string[] extensions = Array.Empty<string>();
|
||||
|
||||
switch (perceivedType)
|
||||
{
|
||||
case "video": extensions = FileTypes.Video; break;
|
||||
case "audio": extensions = FileTypes.Audio; break;
|
||||
case "image": extensions = FileTypes.Image; break;
|
||||
case "video": extensions = FileTypes.GetVideoExts(); break;
|
||||
case "audio": extensions = FileTypes.GetAudioExts(); break;
|
||||
case "image": extensions = FileTypes.GetImgExts(); break;
|
||||
}
|
||||
|
||||
try
|
||||
@@ -230,7 +272,21 @@ public class GuiCommand
|
||||
catch { }
|
||||
}
|
||||
|
||||
public void ShowMediaInfo(IList<string> args)
|
||||
class Obj
|
||||
{
|
||||
public string title { get; set; } = "";
|
||||
public int selected_index { get; set; } = 0;
|
||||
public Item[] items { get; set; } = [];
|
||||
}
|
||||
|
||||
class Item
|
||||
{
|
||||
public string[] value { get; set; } = [];
|
||||
public string title { get; set; } = "";
|
||||
public string hint { get; set; } = "";
|
||||
}
|
||||
|
||||
void ShowMediaInfo(IList<string> args)
|
||||
{
|
||||
if (Player.PlaylistPos == -1)
|
||||
return;
|
||||
@@ -247,13 +303,13 @@ public class GuiCommand
|
||||
|
||||
if (File.Exists(path) && osd)
|
||||
{
|
||||
if (FileTypes.Audio.Contains(path.Ext()))
|
||||
if (FileTypes.IsAudio(path.Ext()))
|
||||
{
|
||||
text = Player.GetPropertyOsdString("filtered-metadata");
|
||||
Player.CommandV("show-text", text, "5000");
|
||||
return;
|
||||
}
|
||||
else if (FileTypes.Image.Contains(path.Ext()))
|
||||
else if (FileTypes.IsImage(path.Ext()))
|
||||
{
|
||||
fileSize = new FileInfo(path).Length;
|
||||
|
||||
@@ -287,15 +343,21 @@ public class GuiCommand
|
||||
}
|
||||
|
||||
if (App.MediaInfo && !osd && File.Exists(path) && !path.Contains(@"\\.\pipe\"))
|
||||
using (MediaInfo mediaInfo = new MediaInfo(path))
|
||||
text = Regex.Replace(mediaInfo.GetSummary(full, raw), "Unique ID.+", "");
|
||||
{
|
||||
using MediaInfo mediaInfo = new MediaInfo(path);
|
||||
text = Regex.Replace(mediaInfo.GetSummary(full, raw), "Unique ID.+", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
Player.UpdateExternalTracks();
|
||||
text = "N: " + Player.GetPropertyString("filename") + BR;
|
||||
lock (Player.MediaTracksLock)
|
||||
{
|
||||
foreach (MediaTrack track in Player.MediaTracks)
|
||||
{
|
||||
text += track.Text + BR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text = text.TrimEx();
|
||||
@@ -312,17 +374,17 @@ public class GuiCommand
|
||||
}
|
||||
}
|
||||
|
||||
public static string FormatTime(double value) => ((int)value).ToString("00");
|
||||
string FormatTime(double value) => ((int)value).ToString("00");
|
||||
|
||||
public void ShowBindings() => ShowTextWithEditor("Bindings", Player.UsedInputConfContent);
|
||||
void ShowBindings() => ShowTextWithEditor("Bindings", Player.UsedInputConfContent);
|
||||
|
||||
public void AddToPath()
|
||||
void AddToPath()
|
||||
{
|
||||
string path = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.User)!;
|
||||
|
||||
if (path.ToLower().Contains(Folder.Startup.TrimEnd(Path.DirectorySeparatorChar).ToLower()))
|
||||
if (path.Contains(Folder.Startup.TrimEnd(Path.DirectorySeparatorChar), StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
Msg.ShowWarning("mpv.net is already in Path.");
|
||||
Msg.ShowWarning(_("mpv.net is already in the Path environment variable."));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -330,63 +392,37 @@ public class GuiCommand
|
||||
Folder.Startup.TrimEnd(Path.DirectorySeparatorChar) + ";" + path,
|
||||
EnvironmentVariableTarget.User);
|
||||
|
||||
Msg.ShowInfo("mpv.net successfully was added to Path.");
|
||||
Msg.ShowInfo(_("mpv.net was successfully added to the Path environment variable."));
|
||||
}
|
||||
|
||||
public void ShowPlaylist()
|
||||
void RemoveFromPath()
|
||||
{
|
||||
var count = Player.GetPropertyInt("playlist-count");
|
||||
string path = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.User)!;
|
||||
|
||||
if (count < 1)
|
||||
return;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
if (!path.Contains(Folder.Startup.TrimEnd(Path.DirectorySeparatorChar)))
|
||||
{
|
||||
string name = Player.GetPropertyString($"playlist/{i}/title");
|
||||
|
||||
if (string.IsNullOrEmpty(name))
|
||||
name = Player.GetPropertyString($"playlist/{i}/filename").FileName();
|
||||
|
||||
sb.AppendLine(name);
|
||||
Msg.ShowWarning(_("mpv.net was not found in the Path environment variable."));
|
||||
return;
|
||||
}
|
||||
|
||||
string header = BR + "For a playlist menu the following user scripts exist:" + BR2 +
|
||||
"https://github.com/stax76/mpv-scripts#command_palette" + BR +
|
||||
"https://github.com/stax76/mpv-scripts#search_menu" + BR +
|
||||
"https://github.com/tomasklaen/uosc" + BR +
|
||||
"https://github.com/jonniek/mpv-playlistmanager" + BR2;
|
||||
path = path.Replace(Folder.Startup.TrimEnd(Path.DirectorySeparatorChar), "");
|
||||
path = path.Replace(";;", ";").Trim(';');
|
||||
|
||||
Msg.ShowInfo(header + sb.ToString().TrimEnd());
|
||||
Environment.SetEnvironmentVariable("Path", path, EnvironmentVariableTarget.User);
|
||||
|
||||
Msg.ShowInfo(_("mpv.net was successfully removed from the Path environment variable."));
|
||||
}
|
||||
|
||||
// deprecated
|
||||
public void QuickBookmark() =>
|
||||
Msg.ShowInfo("This feature was moved to a user script,\nwhich can be found here:\n\n" +
|
||||
void QuickBookmark() =>
|
||||
Msg.ShowInfo(_("This feature was removed, but there are user scripts:") + BR2 +
|
||||
"https://github.com/stax76/mpv-scripts/blob/main/misc.lua");
|
||||
|
||||
// deprecated
|
||||
public void ShowHistory() =>
|
||||
Msg.ShowInfo("This feature was moved to a user script,\nwhich can be found here:\n\n" +
|
||||
void ShowHistory() =>
|
||||
Msg.ShowInfo(_("This feature was removed, but there are user scripts:") + BR2 +
|
||||
"https://github.com/stax76/mpv-scripts/blob/main/history.lua");
|
||||
|
||||
// deprecated
|
||||
public void ShowCommandPalette() =>
|
||||
Msg.ShowInfo(
|
||||
"This feature was removed but is still available in the form of user scripts:" + BR2 +
|
||||
"https://github.com/stax76/mpv-scripts#command_palette" + BR +
|
||||
"https://github.com/stax76/mpv-scripts#search_menu" + BR +
|
||||
"https://github.com/tomasklaen/uosc");
|
||||
void ShowRemoved() => Msg.ShowInfo(_("This feature was removed."));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//public void ShowCommandPalette()
|
||||
//{
|
||||
// MainForm.Instance?.BeginInvoke(() => {
|
||||
// CommandPalette.Instance.SetItems(CommandPalette.GetItems());
|
||||
// MainForm.Instance.ShowCommandPalette();
|
||||
// CommandPalette.Instance.SelectFirst();
|
||||
// });
|
||||
//}
|
||||
@@ -7,7 +7,7 @@ using static MpvNet.Windows.Native.WinApi;
|
||||
|
||||
namespace MpvNet.Windows.Help;
|
||||
|
||||
public class WinApiHelp
|
||||
public static class WinApiHelp
|
||||
{
|
||||
public static Version WindowsTen1607 { get; } = new Version(10, 0, 14393); // Windows 10 1607
|
||||
|
||||
@@ -27,31 +27,51 @@ public class WinApiHelp
|
||||
}
|
||||
}
|
||||
|
||||
public static void SubtractWindowBorders(IntPtr hwnd, ref Rect rc, int dpi)
|
||||
public static void AdjustWindowRectangle(IntPtr hwnd, ref RECT rc, int dpi)
|
||||
{
|
||||
Rect r = new Rect(0, 0, 0, 0);
|
||||
AddWindowBorders(hwnd, ref r, dpi);
|
||||
uint style = (uint)GetWindowLongPtr(hwnd, -16); // GWL_STYLE
|
||||
uint styleEx = (uint)GetWindowLongPtr(hwnd, -20); // GWL_EXSTYLE
|
||||
|
||||
if (Environment.OSVersion.Version >= WindowsTen1607)
|
||||
AdjustWindowRectExForDpi(ref rc, style, false, styleEx, (uint)dpi);
|
||||
else
|
||||
AdjustWindowRect(ref rc, style, false);
|
||||
}
|
||||
|
||||
public static void AddWindowBorders(IntPtr hwnd, ref RECT rc, int dpi, bool changeTop)
|
||||
{
|
||||
RECT win = rc;
|
||||
AdjustWindowRectangle(hwnd, ref rc, dpi);
|
||||
|
||||
if (changeTop)
|
||||
{
|
||||
int top = rc.Top;
|
||||
top -= rc.Top - win.Top;
|
||||
rc = new RECT(rc.Left, top, rc.Right, rc.Bottom);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SubtractWindowBorders(IntPtr hwnd, ref RECT rc, int dpi, bool changeTop)
|
||||
{
|
||||
RECT r = new RECT();
|
||||
AddWindowBorders(hwnd, ref r, dpi, changeTop);
|
||||
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)
|
||||
public static int GetTitleBarHeight(IntPtr hwnd, 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);
|
||||
RECT rect = new RECT();
|
||||
AdjustWindowRectangle(hwnd, ref rect, dpi);
|
||||
return -rect.Top;
|
||||
}
|
||||
|
||||
public static Rectangle GetWorkingArea(IntPtr handle, Rectangle workingArea)
|
||||
{
|
||||
if (handle != IntPtr.Zero && GetDwmWindowRect(handle, out Rect dwmRect) &&
|
||||
GetWindowRect(handle, out Rect rect))
|
||||
if (handle != IntPtr.Zero && GetDwmWindowRect(handle, out RECT dwmRect) &&
|
||||
GetWindowRect(handle, out RECT rect))
|
||||
{
|
||||
int left = workingArea.Left;
|
||||
int top = workingArea.Top;
|
||||
@@ -69,28 +89,12 @@ public class WinApiHelp
|
||||
return workingArea;
|
||||
}
|
||||
|
||||
public static bool GetDwmWindowRect(IntPtr handle, out Rect rect)
|
||||
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);
|
||||
out rect, (uint)Marshal.SizeOf<RECT>());
|
||||
}
|
||||
|
||||
public static string GetAppPathForExtension(params string[] extensions)
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
|
||||
using System.Windows;
|
||||
|
||||
using MpvNet.Windows.WPF;
|
||||
|
||||
namespace MpvNet.Windows.Help;
|
||||
|
||||
public class WinMpvHelp
|
||||
{
|
||||
public static void AddToPath()
|
||||
{
|
||||
string path = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.User)!;
|
||||
|
||||
if (path.ToLower().Contains(Folder.Startup.TrimEnd(Path.DirectorySeparatorChar).ToLower()))
|
||||
return;
|
||||
|
||||
string dir = RegistryHelp.GetString("PathEnvVarCheck");
|
||||
|
||||
if (dir == Folder.Startup)
|
||||
return;
|
||||
|
||||
var result = Msg.ShowQuestion("Would you like to add mpv.net to the Path environment variable?",
|
||||
MessageBoxButton.YesNo);
|
||||
|
||||
if (result == MessageBoxResult.Yes)
|
||||
{
|
||||
Environment.SetEnvironmentVariable("Path",
|
||||
Folder.Startup.TrimEnd(Path.DirectorySeparatorChar) + ";" + path,
|
||||
EnvironmentVariableTarget.User);
|
||||
|
||||
Msg.ShowInfo("mpv.net was added successfully to Path.");
|
||||
}
|
||||
|
||||
RegistryHelp.SetString("PathEnvVarCheck", Folder.Startup);
|
||||
}
|
||||
}
|
||||
@@ -1,49 +1,47 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<RootNamespace>MpvNet.Windows</RootNamespace>
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net10.0-windows7.0</TargetFramework>
|
||||
<RootNamespace>MpvNet.Windows</RootNamespace>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<PublishSingleFile>true</PublishSingleFile>
|
||||
<AssemblyName>mpvnet</AssemblyName>
|
||||
<UseWPF>true</UseWPF>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ApplicationIcon>mpv-icon.ico</ApplicationIcon>
|
||||
<Product>mpv.net</Product>
|
||||
<FileVersion>7.0.0.3</FileVersion>
|
||||
<AssemblyVersion>7.0.0.3</AssemblyVersion>
|
||||
<InformationalVersion>7.0.0.3</InformationalVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<AssemblyName>mpvnet</AssemblyName>
|
||||
<UseWPF>true</UseWPF>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ApplicationIcon>mpv-icon.ico</ApplicationIcon>
|
||||
<FileVersion>7.1.1.5</FileVersion>
|
||||
<AssemblyVersion>7.1.1.5</AssemblyVersion>
|
||||
<InformationalVersion>7.1.1.5</InformationalVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Misc\**" />
|
||||
<EmbeddedResource Remove="Misc\**" />
|
||||
<None Remove="Misc\**" />
|
||||
<Page Remove="Misc\**" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="Misc\**" />
|
||||
<EmbeddedResource Remove="Misc\**" />
|
||||
<None Remove="Misc\**" />
|
||||
<Page Remove="Misc\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="mpv-icon.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="mpv-icon.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MpvNet\MpvNet.csproj" />
|
||||
<ProjectReference Include="..\NGettext.Wpf\NGettext.Wpf.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MpvNet\MpvNet.csproj" />
|
||||
<ProjectReference Include="..\NGettext.Wpf\NGettext.Wpf.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="WPF\Views\AboutWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<XamlRuntime>Wpf</XamlRuntime>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="WPF\Views\AboutWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<XamlRuntime>Wpf</XamlRuntime>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.77" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using static HandyControl.Tools.Interop.InteropValues;
|
||||
|
||||
namespace MpvNet.Windows.Native;
|
||||
|
||||
@@ -20,7 +21,7 @@ public static class WinApi
|
||||
public static extern uint ActivateKeyboardLayout(IntPtr hkl, uint flags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool GetWindowRect(IntPtr hwnd, out Rect lpRect);
|
||||
public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr FindWindowEx(
|
||||
@@ -48,28 +49,19 @@ public static class WinApi
|
||||
public static extern int GetDpiForWindow(IntPtr hwnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool AdjustWindowRect(ref Rect lpRect, uint dwStyle, bool bMenu);
|
||||
public static extern bool AdjustWindowRect(ref RECT lpRect, uint dwStyle, bool bMenu);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool AdjustWindowRectExForDpi(
|
||||
ref Rect lpRect, uint dwStyle, bool bMenu, uint dwExStyle, uint dpi);
|
||||
ref RECT lpRect, uint dwStyle, bool bMenu, uint dwExStyle, uint dpi);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool SetWindowPos(
|
||||
IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||
public static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
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);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
|
||||
|
||||
@@ -79,17 +71,17 @@ public static class WinApi
|
||||
|
||||
[DllImport("dwmapi.dll")]
|
||||
public static extern int DwmGetWindowAttribute(
|
||||
IntPtr hwnd, uint dwAttribute, out Rect pvAttribute, uint cbAttribute);
|
||||
IntPtr hwnd, uint dwAttribute, out RECT pvAttribute, uint cbAttribute);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Rect
|
||||
public struct RECT
|
||||
{
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
|
||||
public Rect(Rectangle r)
|
||||
public RECT(Rectangle r)
|
||||
{
|
||||
Left = r.Left;
|
||||
Top = r.Top;
|
||||
@@ -97,7 +89,7 @@ public static class WinApi
|
||||
Bottom = r.Bottom;
|
||||
}
|
||||
|
||||
public Rect(int left, int top, int right, int bottom)
|
||||
public RECT(int left, int top, int right, int bottom)
|
||||
{
|
||||
Left = left;
|
||||
Top = top;
|
||||
@@ -110,9 +102,9 @@ public static class WinApi
|
||||
public int Width => Right - Left;
|
||||
public int Height => Bottom - Top;
|
||||
|
||||
public static Rect FromRectangle(Rectangle rect)
|
||||
public static RECT FromRectangle(Rectangle rect)
|
||||
{
|
||||
return new Rect(rect.X, rect.Y, rect.X + rect.Width, rect.Y + rect.Height);
|
||||
return new RECT(rect.X, rect.Y, rect.X + rect.Width, rect.Y + rect.Height);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@@ -121,6 +113,20 @@ public static class WinApi
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct NCCALCSIZE_PARAMS
|
||||
{
|
||||
public NCCALCSIZE_PARAMS(RECT[] r, WINDOWPOS wp)
|
||||
{
|
||||
rgrc = r;
|
||||
lppos = wp;
|
||||
}
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public RECT[] rgrc;
|
||||
public WINDOWPOS lppos;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct CopyDataStruct
|
||||
{
|
||||
|
||||
@@ -7,7 +7,6 @@ using MpvNet.Help;
|
||||
using MpvNet.Windows.UI;
|
||||
using MpvNet.Windows.Help;
|
||||
using MpvNet.Windows.WPF;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace MpvNet.Windows;
|
||||
|
||||
@@ -42,7 +41,7 @@ static class Program
|
||||
Theme.Init();
|
||||
Mutex mutex = new Mutex(true, StringHelp.GetMD5Hash(App.ConfPath), out bool isFirst);
|
||||
|
||||
if (Control.ModifierKeys.HasFlag(Keys.Shift) ||
|
||||
if (Control.ModifierKeys == Keys.Shift ||
|
||||
App.CommandLine.Contains("--process-instance=multi") ||
|
||||
App.CommandLine.Contains("--o="))
|
||||
{
|
||||
@@ -97,11 +96,14 @@ static class Program
|
||||
return;
|
||||
}
|
||||
|
||||
if (App.CommandLine.Contains("--o="))
|
||||
if (ProcessCommandLineArguments())
|
||||
Environment.GetCommandLineArgs();
|
||||
else if (App.CommandLine.Contains("--o="))
|
||||
{
|
||||
App.AutoLoadFolder = false;
|
||||
Player.Init(IntPtr.Zero);
|
||||
Player.ProcessCommandLineFiles();
|
||||
Player.Init(IntPtr.Zero, true);
|
||||
CommandLine.ProcessCommandLineArgsPostInit();
|
||||
CommandLine.ProcessCommandLineFiles();
|
||||
Player.SetPropertyString("idle", "no");
|
||||
Player.EventLoop();
|
||||
Player.Destroy();
|
||||
@@ -119,4 +121,48 @@ static class Program
|
||||
Terminal.WriteError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
static bool ProcessCommandLineArguments()
|
||||
{
|
||||
foreach (string arg in Environment.GetCommandLineArgs().Skip(1))
|
||||
{
|
||||
if (arg == "--profile=help")
|
||||
{
|
||||
Player.Init(IntPtr.Zero, false);
|
||||
Console.WriteLine(Player.GetProfiles());
|
||||
Player.Destroy();
|
||||
return true;
|
||||
}
|
||||
else if (arg == "--vd=help" || arg == "--ad=help")
|
||||
{
|
||||
Player.Init(IntPtr.Zero, false);
|
||||
Console.WriteLine(Player.GetDecoders());
|
||||
Player.Destroy();
|
||||
return true;
|
||||
}
|
||||
else if (arg == "--audio-device=help")
|
||||
{
|
||||
Player.Init(IntPtr.Zero, false);
|
||||
Console.WriteLine(Player.GetPropertyOsdString("audio-device-list"));
|
||||
Player.Destroy();
|
||||
return true;
|
||||
}
|
||||
else if (arg == "--input-keylist")
|
||||
{
|
||||
Player.Init(IntPtr.Zero, false);
|
||||
Console.WriteLine(Player.GetPropertyString("input-key-list").Replace(",", BR));
|
||||
Player.Destroy();
|
||||
return true;
|
||||
}
|
||||
else if (arg == "--version")
|
||||
{
|
||||
Player.Init(IntPtr.Zero, false);
|
||||
Console.WriteLine(AppClass.About);
|
||||
Player.Destroy();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
7
src/MpvNet.Windows/Properties/launchSettings.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"profiles": {
|
||||
"MpvNet.Windows": {
|
||||
"commandName": "Project"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ public abstract class Setting
|
||||
public string? Value { get; set; }
|
||||
|
||||
public int Width { get; set; }
|
||||
public int OptionNameWidth { get; set; } = 100;
|
||||
|
||||
public ConfItem? ConfItem { get; set; }
|
||||
}
|
||||
@@ -35,12 +36,13 @@ public class OptionSettingOption
|
||||
|
||||
public string? Name { get; set; }
|
||||
public string? Help { get; set; }
|
||||
public int Width { get => OptionSetting!.OptionNameWidth; }
|
||||
|
||||
public OptionSetting? OptionSetting { get; set; }
|
||||
|
||||
public string? Text
|
||||
{
|
||||
get => string.IsNullOrEmpty(_text) ? Name : _text;
|
||||
get => _text ?? Name;
|
||||
set => _text = value;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
using MpvNet.Windows.WPF.Controls;
|
||||
|
||||
namespace MpvNet.Windows.UI;
|
||||
|
||||
public class CommandPalette
|
||||
{
|
||||
public static CommandPaletteControl Instance { get; } = new CommandPaletteControl();
|
||||
|
||||
public static IEnumerable<CommandPaletteItem> GetItems()
|
||||
{
|
||||
return InputHelp.GetBindingsFromContent(App.InputConf.GetContent())
|
||||
.Where(i => i.Command != "")
|
||||
.Select(i => new CommandPaletteItem()
|
||||
{
|
||||
Text = i.Comment,
|
||||
SecondaryText = i.Input,
|
||||
Action = () => Core.Command(i.Command),
|
||||
Binding = i
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
|
||||
namespace MpvNet.Windows.UI;
|
||||
|
||||
public class CommandPaletteItem
|
||||
{
|
||||
public CommandPaletteItem() { }
|
||||
|
||||
public CommandPaletteItem(string text, Action action)
|
||||
{
|
||||
Text = text;
|
||||
Action = action;
|
||||
}
|
||||
|
||||
public CommandPaletteItem(string text, string secondaryText, Action action)
|
||||
{
|
||||
Text = text;
|
||||
Action = action;
|
||||
SecondaryText = secondaryText;
|
||||
}
|
||||
|
||||
public string Text { get; set; } = "";
|
||||
public string SecondaryText { get; set; } = "";
|
||||
public Action? Action { get; set; }
|
||||
public Binding? Binding { get; set; }
|
||||
}
|
||||
18
src/MpvNet.Windows/WPF/ComboBoxTemplateSelector.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
using System.Windows.Controls;
|
||||
using System.Windows;
|
||||
|
||||
namespace MpvNet.Windows.WPF;
|
||||
|
||||
public class ComboBoxTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
public override DataTemplate SelectTemplate(object item, DependencyObject container)
|
||||
{
|
||||
ContentPresenter presenter = (ContentPresenter)container;
|
||||
|
||||
if (presenter.TemplatedParent is ComboBox)
|
||||
return (DataTemplate)presenter.FindResource("ComboBoxCollapsedDataTemplate");
|
||||
else // Templated parent is ComboBoxItem
|
||||
return (DataTemplate)presenter.FindResource("ComboBoxExpandedDataTemplate");
|
||||
}
|
||||
}
|
||||
@@ -28,8 +28,8 @@
|
||||
<KeyBinding Key="n" Modifiers="Ctrl" Command="{Binding ShowMpvNetSpecificSettingsCommand}"/>
|
||||
<KeyBinding Key="F5" Command="{Binding PreviewMpvConfFileCommand}"/>
|
||||
<KeyBinding Key="F6" Command="{Binding PreviewMpvNetConfFileCommand}"/>
|
||||
<KeyBinding Key="F1" Command="{Binding ShowMpvManualCommand}"/>
|
||||
<KeyBinding Key="F2" Command="{Binding ShowMpvNetManualCommand}"/>
|
||||
<KeyBinding Key="F1" Modifiers="Ctrl" Command="{Binding ShowMpvManualCommand}"/>
|
||||
<KeyBinding Key="F2" Modifiers="Ctrl" Command="{Binding ShowMpvNetManualCommand}"/>
|
||||
</Window.InputBindings>
|
||||
|
||||
<Grid>
|
||||
@@ -40,7 +40,7 @@
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="170" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
x:Name="SearchControl"
|
||||
HintText="Find a setting (Ctrl+F)"
|
||||
Margin="20,20,0,10"
|
||||
MaxWidth="190"
|
||||
Text="{Binding SearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
/>
|
||||
|
||||
@@ -135,12 +136,12 @@
|
||||
<Separator />
|
||||
<MenuItem
|
||||
Header="Show mpv manual"
|
||||
InputGestureText="F1"
|
||||
InputGestureText="Ctrl+F1"
|
||||
Command="{Binding Data.ShowMpvManualCommand, Source={StaticResource BindingProxy}}"
|
||||
/>
|
||||
<MenuItem
|
||||
Header="Show mpv.net manual"
|
||||
InputGestureText="F2"
|
||||
InputGestureText="Ctrl+F2"
|
||||
Command="{Binding Data.ShowMpvNetManualCommand, Source={StaticResource BindingProxy}}"
|
||||
/>
|
||||
</ContextMenu>
|
||||
|
||||
@@ -20,13 +20,16 @@ namespace MpvNet.Windows.WPF;
|
||||
|
||||
public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
{
|
||||
List<Setting> Settings = Conf.LoadConf(Properties.Resources.editor_conf.TrimEnd());
|
||||
List<ConfItem> ConfItems = new List<ConfItem>();
|
||||
public ObservableCollection<string> FilterStrings { get; } = new();
|
||||
string InitialContent;
|
||||
string ThemeConf = GetThemeConf();
|
||||
List<Setting> _settings = Conf.LoadConf(Properties.Resources.editor_conf.TrimEnd());
|
||||
List<ConfItem> _confItems = new List<ConfItem>();
|
||||
string _initialContent;
|
||||
string _themeConf = GetThemeConf();
|
||||
string? _searchText;
|
||||
List<NodeViewModel>? _nodes;
|
||||
bool _shown;
|
||||
int _useSpace;
|
||||
int _useNoSpace;
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
public ConfWindow()
|
||||
@@ -37,7 +40,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
LoadConf(App.ConfPath);
|
||||
LoadLibplaceboConf();
|
||||
LoadSettings();
|
||||
InitialContent = GetCompareString();
|
||||
_initialContent = GetCompareString();
|
||||
|
||||
if (string.IsNullOrEmpty(App.Settings.ConfigEditorSearch))
|
||||
SearchText = "General:";
|
||||
@@ -48,9 +51,11 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
SelectNodeFromSearchText(node);
|
||||
|
||||
foreach (var node in Nodes)
|
||||
ExpandNode(node);
|
||||
node.IsExpanded = true;
|
||||
}
|
||||
|
||||
public ObservableCollection<string> FilterStrings { get; } = new();
|
||||
|
||||
public Theme? Theme => Theme.Current;
|
||||
|
||||
public string SearchText
|
||||
@@ -72,7 +77,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
{
|
||||
var rootNode = new TreeNode();
|
||||
|
||||
foreach (Setting setting in Settings)
|
||||
foreach (Setting setting in _settings)
|
||||
AddNode(rootNode.Children, setting.Directory!);
|
||||
|
||||
_nodes = new NodeViewModel(rootNode).Children;
|
||||
@@ -125,16 +130,18 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
|
||||
void LoadSettings()
|
||||
{
|
||||
foreach (Setting setting in Settings)
|
||||
foreach (Setting setting in _settings)
|
||||
{
|
||||
setting.StartValue = setting.Value;
|
||||
|
||||
if (!FilterStrings.Contains(setting.Directory!))
|
||||
FilterStrings.Add(setting.Directory!);
|
||||
|
||||
foreach (ConfItem item in ConfItems)
|
||||
foreach (ConfItem item in _confItems)
|
||||
{
|
||||
if (setting.Name == item.Name && item.Section == "" && !item.IsSectionItem)
|
||||
if (setting.Name == item.Name &&
|
||||
setting.File == item.File &&
|
||||
item.Section == "" && !item.IsSectionItem)
|
||||
{
|
||||
setting.Value = item.Value;
|
||||
setting.StartValue = setting.Value;
|
||||
@@ -149,7 +156,10 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
MainStackPanel.Children.Add(new StringSettingControl(s) { Visibility = Visibility.Collapsed });
|
||||
break;
|
||||
case OptionSetting s:
|
||||
MainStackPanel.Children.Add(new OptionSettingControl(s) { Visibility = Visibility.Collapsed });
|
||||
if (s.Options.Count > 3)
|
||||
MainStackPanel.Children.Add(new ComboBoxSettingControl(s) { Visibility = Visibility.Collapsed });
|
||||
else
|
||||
MainStackPanel.Children.Add(new OptionSettingControl(s) { Visibility = Visibility.Collapsed });
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -157,65 +167,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
|
||||
static string GetThemeConf() => Theme.DarkMode + App.DarkTheme + App.LightTheme;
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
base.OnClosed(e);
|
||||
App.Settings.ConfigEditorSearch = SearchText;
|
||||
|
||||
if (InitialContent == GetCompareString())
|
||||
return;
|
||||
|
||||
foreach (Setting setting in Settings)
|
||||
{
|
||||
if (setting.Name == "libplacebo-opts")
|
||||
{
|
||||
setting.Value = GetKeyValueContent("libplacebo");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
File.WriteAllText(Player.ConfPath, GetContent("mpv"));
|
||||
File.WriteAllText(App.ConfPath, GetContent("mpvnet"));
|
||||
|
||||
foreach (Setting it in Settings)
|
||||
{
|
||||
if (it.Value != it.StartValue)
|
||||
{
|
||||
if (it.File == "mpv")
|
||||
{
|
||||
Player.ProcessProperty(it.Name, it.Value);
|
||||
Player.SetPropertyString(it.Name!, it.Value!);
|
||||
}
|
||||
else if (it.File == "mpvnet")
|
||||
App.ProcessProperty(it.Name ?? "", it.Value ?? "", true);
|
||||
}
|
||||
}
|
||||
|
||||
Theme.Init();
|
||||
Theme.UpdateWpfColors();
|
||||
|
||||
if (ThemeConf != GetThemeConf())
|
||||
MessageBox.Show("Changed theme settings require mpv.net being restarted.", "Info");
|
||||
}
|
||||
|
||||
bool _shown;
|
||||
|
||||
protected override void OnContentRendered(EventArgs e)
|
||||
{
|
||||
base.OnContentRendered(e);
|
||||
|
||||
if (_shown)
|
||||
return;
|
||||
|
||||
_shown = true;
|
||||
|
||||
Application.Current.Dispatcher.BeginInvoke(() => {
|
||||
SearchControl.SearchTextBox.SelectAll();
|
||||
},
|
||||
DispatcherPriority.Background);
|
||||
}
|
||||
|
||||
string GetCompareString() => string.Join("", Settings.Select(item => item.Name + item.Value).ToArray());
|
||||
string GetCompareString() => string.Join("", _settings.Select(item => item.Name + item.Value).ToArray());
|
||||
|
||||
void LoadConf(string file)
|
||||
{
|
||||
@@ -227,9 +179,12 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
|
||||
bool isSectionItem = false;
|
||||
|
||||
foreach (string currentLine in File.ReadAllLines(file))
|
||||
foreach (string it in File.ReadAllLines(file))
|
||||
{
|
||||
string line = currentLine.Trim();
|
||||
string line = it.Trim();
|
||||
|
||||
if (line.StartsWith("-"))
|
||||
line = line.TrimStart('-');
|
||||
|
||||
if (line == "")
|
||||
comment += "\r\n";
|
||||
@@ -238,8 +193,8 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
else if (line.StartsWith("[") && line.Contains(']'))
|
||||
{
|
||||
if (!isSectionItem && comment != "" && comment != "\r\n")
|
||||
ConfItems.Add(new ConfItem() {
|
||||
Comment = comment, File = System.IO.Path.GetFileNameWithoutExtension(file)});
|
||||
_confItems.Add(new ConfItem() {
|
||||
Comment = comment, File = Path.GetFileNameWithoutExtension(file)});
|
||||
|
||||
section = line.Substring(0, line.IndexOf("]") + 1);
|
||||
comment = "";
|
||||
@@ -248,17 +203,30 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
else if (line.Contains('=') || Regex.Match(line, "^[\\w-]+$").Success)
|
||||
{
|
||||
if (!line.Contains('='))
|
||||
line += "=yes";
|
||||
{
|
||||
if (line.StartsWith("no-"))
|
||||
{
|
||||
line = line.Substring(3);
|
||||
line += "=no";
|
||||
}
|
||||
else
|
||||
line += "=yes";
|
||||
}
|
||||
|
||||
if (line.Contains(" =") || line.Contains("= "))
|
||||
_useSpace += 1;
|
||||
else
|
||||
_useNoSpace += 1;
|
||||
|
||||
ConfItem item = new();
|
||||
item.File = System.IO.Path.GetFileNameWithoutExtension(file);
|
||||
item.File = Path.GetFileNameWithoutExtension(file);
|
||||
item.IsSectionItem = isSectionItem;
|
||||
item.Comment = comment;
|
||||
comment = "";
|
||||
item.Section = section;
|
||||
section = "";
|
||||
|
||||
if (line.Contains('#') && !line.Contains("'") && !line.Contains("\""))
|
||||
if (line.Contains('#') && !line.Contains('\'') && !line.Contains('"'))
|
||||
{
|
||||
item.LineComment = line.Substring(line.IndexOf("#")).Trim();
|
||||
line = line.Substring(0, line.IndexOf("#")).Trim();
|
||||
@@ -282,7 +250,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
|
||||
item.Name = left;
|
||||
item.Value = right;
|
||||
ConfItems.Add(item);
|
||||
_confItems.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -291,7 +259,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
{
|
||||
List<string> pairs = new();
|
||||
|
||||
foreach (Setting setting in Settings)
|
||||
foreach (Setting setting in _settings)
|
||||
{
|
||||
if (filename != setting.File)
|
||||
continue;
|
||||
@@ -305,7 +273,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
|
||||
void LoadLibplaceboConf()
|
||||
{
|
||||
foreach (ConfItem item in ConfItems.ToArray())
|
||||
foreach (ConfItem item in _confItems.ToArray())
|
||||
if (item.Name == "libplacebo-opts")
|
||||
LoadKeyValueList(item.Value, "libplacebo");
|
||||
}
|
||||
@@ -327,7 +295,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
item.Name = left;
|
||||
item.Value = right;
|
||||
item.File = file;
|
||||
ConfItems.Add(item);
|
||||
_confItems.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,8 +320,9 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<string> namesWritten = new List<string>();
|
||||
string equalString = _useSpace > _useNoSpace ? " = " : "=";
|
||||
|
||||
foreach (ConfItem item in ConfItems)
|
||||
foreach (ConfItem item in _confItems)
|
||||
{
|
||||
if (filename != item.File || item.Section != "" || item.IsSectionItem)
|
||||
continue;
|
||||
@@ -365,7 +334,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
{
|
||||
if (item.Name != "")
|
||||
{
|
||||
sb.Append(item.Name + " = " + EscapeValue(item.Value));
|
||||
sb.Append(item.Name + equalString + EscapeValue(item.Value));
|
||||
|
||||
if (item.LineComment != "")
|
||||
sb.Append(" " + item.LineComment);
|
||||
@@ -376,7 +345,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
}
|
||||
else if ((item.SettingBase.Value ?? "") != item.SettingBase.Default)
|
||||
{
|
||||
sb.Append(item.Name + " = " + EscapeValue(item.SettingBase.Value!));
|
||||
sb.Append(item.Name + equalString + EscapeValue(item.SettingBase.Value!));
|
||||
|
||||
if (item.LineComment != "")
|
||||
sb.Append(" " + item.LineComment);
|
||||
@@ -386,16 +355,16 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Setting setting in Settings)
|
||||
foreach (Setting setting in _settings)
|
||||
{
|
||||
if (filename != setting.File || namesWritten.Contains(setting.Name!))
|
||||
continue;
|
||||
|
||||
if ((setting.Value ?? "") != setting.Default)
|
||||
sb.AppendLine(setting.Name + " = " + EscapeValue(setting.Value!));
|
||||
sb.AppendLine(setting.Name + equalString + EscapeValue(setting.Value!));
|
||||
}
|
||||
|
||||
foreach (ConfItem item in ConfItems)
|
||||
foreach (ConfItem item in _confItems)
|
||||
{
|
||||
if (filename != item.File || (item.Section == "" && !item.IsSectionItem))
|
||||
continue;
|
||||
@@ -411,7 +380,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
if (item.Comment != "")
|
||||
sb.Append(item.Comment);
|
||||
|
||||
sb.Append(item.Name + " = " + EscapeValue(item.Value));
|
||||
sb.Append(item.Name + equalString + EscapeValue(item.Value));
|
||||
|
||||
if (item.LineComment != "")
|
||||
sb.Append(" " + item.LineComment);
|
||||
@@ -461,6 +430,47 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
i.Update();
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
base.OnClosed(e);
|
||||
App.Settings.ConfigEditorSearch = SearchText;
|
||||
|
||||
if (_initialContent == GetCompareString())
|
||||
return;
|
||||
|
||||
foreach (Setting setting in _settings)
|
||||
{
|
||||
if (setting.Name == "libplacebo-opts")
|
||||
{
|
||||
setting.Value = GetKeyValueContent("libplacebo");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
File.WriteAllText(Player.ConfPath, GetContent("mpv"));
|
||||
File.WriteAllText(App.ConfPath, GetContent("mpvnet"));
|
||||
|
||||
foreach (Setting it in _settings)
|
||||
{
|
||||
if (it.Value != it.StartValue)
|
||||
{
|
||||
if (it.File == "mpv")
|
||||
{
|
||||
Player.ProcessProperty(it.Name, it.Value);
|
||||
Player.SetPropertyString(it.Name!, it.Value!);
|
||||
}
|
||||
else if (it.File == "mpvnet")
|
||||
App.ProcessProperty(it.Name ?? "", it.Value ?? "", true);
|
||||
}
|
||||
}
|
||||
|
||||
Theme.Init();
|
||||
Theme.UpdateWpfColors();
|
||||
|
||||
if (_themeConf != GetThemeConf())
|
||||
MessageBox.Show("Changed theme settings require mpv.net being restarted.", "Info");
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
@@ -475,9 +485,22 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnPropertyChanged([CallerMemberName] string? name = null)
|
||||
{
|
||||
protected void OnPropertyChanged([CallerMemberName] string? name = null) =>
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||
|
||||
protected override void OnContentRendered(EventArgs e)
|
||||
{
|
||||
base.OnContentRendered(e);
|
||||
|
||||
if (_shown)
|
||||
return;
|
||||
|
||||
_shown = true;
|
||||
|
||||
Application.Current.Dispatcher.BeginInvoke(() => {
|
||||
SearchControl.SearchTextBox.SelectAll();
|
||||
},
|
||||
DispatcherPriority.Background);
|
||||
}
|
||||
|
||||
void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
||||
@@ -498,6 +521,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
if (node.Path + ":" == SearchText)
|
||||
{
|
||||
node.IsSelected = true;
|
||||
node.IsExpanded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -514,14 +538,6 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
|
||||
UnselectNode(it);
|
||||
}
|
||||
|
||||
void ExpandNode(NodeViewModel node)
|
||||
{
|
||||
node.IsExpanded = true;
|
||||
|
||||
foreach (var it in node.Children)
|
||||
ExpandNode(it);
|
||||
}
|
||||
|
||||
[RelayCommand] void ShowMpvNetSpecificSettings() => SearchText = "mpv.net";
|
||||
|
||||
[RelayCommand] void PreviewMpvConfFile() => Msg.ShowInfo(GetContent("mpv"));
|
||||
|
||||
72
src/MpvNet.Windows/WPF/Controls/ComboBoxSettingControl.xaml
Normal file
@@ -0,0 +1,72 @@
|
||||
<UserControl
|
||||
x:Name="ComboBoxSettingControl1"
|
||||
x:Class="MpvNet.Windows.WPF.ComboBoxSettingControl"
|
||||
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:local="clr-namespace:MpvNet.Windows.WPF"
|
||||
mc:Ignorable="d"
|
||||
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800">
|
||||
|
||||
<Grid Margin="20,0">
|
||||
<StackPanel>
|
||||
<TextBox
|
||||
x:Name="TitleTextBox"
|
||||
FontSize="24"
|
||||
Margin="0,10"
|
||||
BorderThickness="0"
|
||||
IsReadOnly="True"
|
||||
Foreground="{Binding Theme.Heading}"
|
||||
Background="{Binding Theme.Background}"
|
||||
/>
|
||||
|
||||
<ComboBox
|
||||
Name="ComboBoxControl"
|
||||
Width="200"
|
||||
HorizontalAlignment="Left"
|
||||
MaxDropDownHeight="2000"
|
||||
Foreground="{Binding Theme.Foreground}"
|
||||
Background="{Binding Theme.Background}"
|
||||
|
||||
SelectionChanged="ComboBoxControl_SelectionChanged"
|
||||
>
|
||||
<ComboBox.ItemTemplateSelector>
|
||||
<local:ComboBoxTemplateSelector/>
|
||||
</ComboBox.ItemTemplateSelector>
|
||||
|
||||
<ComboBox.ItemContainerStyle>
|
||||
<Style TargetType="ComboBoxItem">
|
||||
<Style.Resources>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="CornerRadius" Value="3"/>
|
||||
</Style>
|
||||
</Style.Resources>
|
||||
</Style>
|
||||
</ComboBox.ItemContainerStyle>
|
||||
</ComboBox>
|
||||
|
||||
<TextBox
|
||||
x:Name="HelpTextBox"
|
||||
TextWrapping="WrapWithOverflow"
|
||||
BorderThickness="0"
|
||||
IsReadOnly="True"
|
||||
Margin="0,10,0,0"
|
||||
Foreground="{Binding Theme.Foreground}"
|
||||
Background="{Binding Theme.Background}"
|
||||
/>
|
||||
|
||||
<TextBlock
|
||||
x:Name="LinkTextBlock"
|
||||
Margin="2,0"
|
||||
>
|
||||
<local:HyperlinkEx
|
||||
x:Name="Link"
|
||||
Foreground="{Binding Theme.Heading}"
|
||||
/>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,69 @@
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
using MpvNet.Windows.UI;
|
||||
|
||||
namespace MpvNet.Windows.WPF;
|
||||
|
||||
public partial class ComboBoxSettingControl : UserControl, ISettingControl
|
||||
{
|
||||
OptionSetting OptionSetting;
|
||||
|
||||
public ComboBoxSettingControl(OptionSetting optionSetting)
|
||||
{
|
||||
OptionSetting = optionSetting;
|
||||
InitializeComponent();
|
||||
DataContext = this;
|
||||
TitleTextBox.Text = optionSetting.Name;
|
||||
|
||||
if (string.IsNullOrEmpty(optionSetting.Help))
|
||||
HelpTextBox.Visibility = Visibility.Collapsed;
|
||||
|
||||
HelpTextBox.Text = optionSetting.Help;
|
||||
ComboBoxControl.ItemsSource = optionSetting.Options;
|
||||
|
||||
foreach (var item in optionSetting.Options)
|
||||
if (item.Name == optionSetting.Value)
|
||||
ComboBoxControl.SelectedItem = item;
|
||||
|
||||
if (string.IsNullOrEmpty(optionSetting.URL))
|
||||
LinkTextBlock.Visibility = Visibility.Collapsed;
|
||||
|
||||
Link.SetURL(optionSetting.URL);
|
||||
}
|
||||
|
||||
public Theme? Theme => Theme.Current;
|
||||
|
||||
public Setting Setting => OptionSetting;
|
||||
|
||||
public bool Contains(string searchString) => ContainsInternal(searchString.ToLower());
|
||||
|
||||
public bool ContainsInternal(string search)
|
||||
{
|
||||
if (TitleTextBox.Text.IndexOf(search, StringComparison.InvariantCultureIgnoreCase) > -1)
|
||||
return true;
|
||||
|
||||
if (HelpTextBox.Text.IndexOf(search, StringComparison.InvariantCultureIgnoreCase) > -1)
|
||||
return true;
|
||||
|
||||
foreach (var i in OptionSetting.Options)
|
||||
{
|
||||
if (i.Text?.IndexOf(search, StringComparison.InvariantCultureIgnoreCase) > -1)
|
||||
return true;
|
||||
|
||||
if (i.Help?.IndexOf(search, StringComparison.InvariantCultureIgnoreCase) > -1)
|
||||
return true;
|
||||
|
||||
if (i.Name?.IndexOf(search, StringComparison.InvariantCultureIgnoreCase) > -1)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ComboBoxControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
OptionSetting.Value = (ComboBoxControl.SelectedItem as OptionSettingOption)?.Name;
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
<UserControl
|
||||
x:Class="MpvNet.Windows.WPF.Controls.CommandPaletteControl"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:controls="clr-namespace:MpvNet.Windows.WPF.Controls"
|
||||
mc:Ignorable="d"
|
||||
|
||||
FontSize="13"
|
||||
Loaded="OnLoaded"
|
||||
Background="#111111"
|
||||
>
|
||||
|
||||
<UserControl.InputBindings>
|
||||
<KeyBinding Gesture="Esc" Command="{Binding EscapeCommand}"/>
|
||||
<KeyBinding Gesture="Enter" Command="{Binding ExecuteCommand}"/>
|
||||
</UserControl.InputBindings>
|
||||
|
||||
<Border Name="MainBorder"
|
||||
BorderThickness="1,0,1,1"
|
||||
CornerRadius="0,0,5,5"
|
||||
Padding="0,0,0,5"
|
||||
BorderBrush="{Binding Theme.MenuHighlight}"
|
||||
Background="{Binding Theme.Background}"
|
||||
SnapsToDevicePixels="True"
|
||||
>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border BorderBrush="{Binding Theme.Heading}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="3"
|
||||
Margin="7"
|
||||
>
|
||||
|
||||
<controls:SearchControl
|
||||
HintText="Search"
|
||||
x:Name="SearchControl"
|
||||
Grid.ColumnSpan="2"
|
||||
Padding="1,1,1,0"
|
||||
/>
|
||||
</Border>
|
||||
|
||||
<ListView
|
||||
Name="MainListView"
|
||||
Grid.Row="1"
|
||||
Foreground="{Binding Theme.Foreground}"
|
||||
Background="{Binding Theme.Background}"
|
||||
BorderThickness="0"
|
||||
MaxHeight="202"
|
||||
SizeChanged="MainListView_SizeChanged"
|
||||
MouseUp="MainListView_MouseUp"
|
||||
>
|
||||
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
|
||||
<Setter Property="Height" Value="25"></Setter>
|
||||
<Setter Property="BorderThickness" Value="0"></Setter>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ListBoxItem}">
|
||||
<Border x:Name="BD"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
SnapsToDevicePixels="true">
|
||||
|
||||
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsMouseOver" Value="True" />
|
||||
</MultiTrigger.Conditions>
|
||||
<Setter Property="Background" TargetName="BD" Value="{DynamicResource HighlightBrush}" />
|
||||
</MultiTrigger>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="Selector.IsSelectionActive" Value="False" />
|
||||
<Condition Property="IsSelected" Value="True" />
|
||||
</MultiTrigger.Conditions>
|
||||
<Setter Property="Background" TargetName="BD" Value="{DynamicResource BorderBrush}" />
|
||||
</MultiTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
<Style.Resources>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="CornerRadius" Value="3"/>
|
||||
</Style>
|
||||
</Style.Resources>
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Text="{Binding Text}"></TextBlock>
|
||||
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
Text="{Binding SecondaryText}"
|
||||
HorizontalAlignment="Right"
|
||||
/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@@ -1,151 +0,0 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
using MpvNet.Windows.UI;
|
||||
using MpvNet.Windows.WinForms;
|
||||
|
||||
namespace MpvNet.Windows.WPF.Controls;
|
||||
|
||||
public partial class CommandPaletteControl : UserControl
|
||||
{
|
||||
public ICollectionView CollectionView { get; set; }
|
||||
public CollectionViewSource CollectionViewSource { get; }
|
||||
public ObservableCollection<CommandPaletteItem> Items { get; } = new ObservableCollection<CommandPaletteItem>();
|
||||
|
||||
public CommandPaletteControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = this;
|
||||
CollectionViewSource = new CollectionViewSource() { Source = Items };
|
||||
CollectionView = CollectionViewSource.View;
|
||||
CollectionView.Filter = new Predicate<object>(item => Filter((CommandPaletteItem)item));
|
||||
MainListView.ItemsSource = CollectionView;
|
||||
|
||||
SearchControl.SearchTextBox.PreviewKeyDown += SearchTextBox_PreviewKeyDown;
|
||||
SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged;
|
||||
SearchControl.HideClearButton = true;
|
||||
|
||||
if (Environment.OSVersion.Version < new Version(10, 0))
|
||||
MainBorder.CornerRadius = new CornerRadius(0);
|
||||
}
|
||||
|
||||
void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
CollectionView.Refresh();
|
||||
SelectFirst();
|
||||
}
|
||||
|
||||
void SearchTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Up:
|
||||
{
|
||||
int index = MainListView.SelectedIndex;
|
||||
index -= 1;
|
||||
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
|
||||
MainListView.SelectedIndex = index;
|
||||
MainListView.ScrollIntoView(MainListView.SelectedItem);
|
||||
}
|
||||
break;
|
||||
case Key.Down:
|
||||
{
|
||||
int index = MainListView.SelectedIndex;
|
||||
|
||||
if (++index > MainListView.Items.Count - 1)
|
||||
index = MainListView.Items.Count - 1;
|
||||
|
||||
MainListView.SelectedIndex = index;
|
||||
MainListView.ScrollIntoView(MainListView.SelectedItem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MainListView_SizeChanged(object sender, SizeChangedEventArgs e) => AdjustHeight();
|
||||
|
||||
void MainListView_MouseUp(object sender, MouseButtonEventArgs e) => ExecuteInternal();
|
||||
|
||||
[RelayCommand]
|
||||
void Escape(object param) => MainForm.Instance?.HideCommandPalette();
|
||||
|
||||
[RelayCommand]
|
||||
void Execute() => ExecuteInternal();
|
||||
|
||||
void OnLoaded(object sender, RoutedEventArgs e) => Keyboard.Focus(SearchControl.SearchTextBox);
|
||||
|
||||
public Theme Theme => Theme.Current!;
|
||||
|
||||
bool Filter(CommandPaletteItem item)
|
||||
{
|
||||
string filter = SearchControl.SearchTextBox.Text.ToLower();
|
||||
|
||||
if (item.Binding != null)
|
||||
{
|
||||
// TODO: CommandItem.Alias
|
||||
//if (item.CommandItem.Alias.ContainsEx(filter))
|
||||
// return true;
|
||||
|
||||
if (filter.Length == 1)
|
||||
return item.Binding.Input.ToLower()
|
||||
.Replace("ctrl+", "")
|
||||
.Replace("shift+", "")
|
||||
.Replace("alt+", "") == filter.ToLower();
|
||||
|
||||
if (item.Binding.Command.ToLower().Contains(filter))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (filter == "" || item.Text.ToLower().Contains(filter) ||
|
||||
item.SecondaryText.ToLower().Contains(filter))
|
||||
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SelectFirst()
|
||||
{
|
||||
if (MainListView.Items.Count > 0)
|
||||
{
|
||||
MainListView.SelectedIndex = 0;
|
||||
MainListView.ScrollIntoView(MainListView.SelectedItem);
|
||||
}
|
||||
}
|
||||
|
||||
void ExecuteInternal()
|
||||
{
|
||||
if (MainListView.SelectedItem != null)
|
||||
{
|
||||
CommandPaletteItem? item = MainListView.SelectedItem as CommandPaletteItem;
|
||||
MainForm.Instance?.HideCommandPalette();
|
||||
item?.Action?.Invoke();
|
||||
//MainForm.Instance.Voodoo(); //TODO: Voodoo
|
||||
}
|
||||
}
|
||||
|
||||
public void SetItems(IEnumerable<CommandPaletteItem> items)
|
||||
{
|
||||
Items.Clear();
|
||||
|
||||
foreach (var i in items)
|
||||
Items.Add(i);
|
||||
}
|
||||
|
||||
public void AdjustHeight()
|
||||
{
|
||||
double actualHeight = SearchControl.ActualHeight + MainListView.ActualHeight + 5 + 16;
|
||||
int dpi = MainForm.GetDpi(MainForm.Instance!.Handle);
|
||||
MainForm.Instance.CommandPaletteHost.Height = (int)(actualHeight / 96.0 * dpi);
|
||||
}
|
||||
}
|
||||
@@ -65,9 +65,15 @@
|
||||
Foreground="{Binding Theme.Foreground}"
|
||||
Background="{Binding Theme.Background}"
|
||||
/>
|
||||
|
||||
<TextBlock x:Name="LinkTextBlock" Margin="0,10">
|
||||
<local:HyperlinkEx x:Name="Link"></local:HyperlinkEx>
|
||||
|
||||
<TextBlock
|
||||
x:Name="LinkTextBlock"
|
||||
Margin="2,0,0,0"
|
||||
>
|
||||
<local:HyperlinkEx
|
||||
x:Name="Link"
|
||||
Foreground="{Binding Theme.Heading}"
|
||||
/>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -21,6 +21,10 @@ public partial class OptionSettingControl : UserControl, ISettingControl
|
||||
HelpTextBox.Visibility = Visibility.Collapsed;
|
||||
|
||||
HelpTextBox.Text = optionSetting.Help;
|
||||
|
||||
if (string.IsNullOrEmpty(optionSetting.Help))
|
||||
LinkTextBlock.Margin = new Thickness(2, 6, 0, 0);
|
||||
|
||||
ItemsControl.ItemsSource = optionSetting.Options;
|
||||
|
||||
if (string.IsNullOrEmpty(optionSetting.URL))
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
Name="SearchTextBox"
|
||||
Height="25"
|
||||
BorderThickness="2"
|
||||
Padding="2"
|
||||
Padding="2,2,20,2"
|
||||
Background="Transparent"
|
||||
Foreground="{Binding Theme.Foreground}"
|
||||
CaretBrush="{Binding Theme.Foreground}"
|
||||
|
||||
@@ -39,10 +39,16 @@ public partial class SearchControl : UserControl
|
||||
{
|
||||
HintTextBlock.Text = string.IsNullOrEmpty(Text) ? HintText : "";
|
||||
|
||||
if (string.IsNullOrEmpty(Text) || HideClearButton || Text.Length > 21)
|
||||
if (string.IsNullOrEmpty(Text) || HideClearButton || Text.Length > 30)
|
||||
{
|
||||
SearchTextBox.Padding = new Thickness(2);
|
||||
SearchClearButton.Visibility = Visibility.Hidden;
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchTextBox.Padding = new Thickness(2, 2, 20, 2);
|
||||
SearchClearButton.Visibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
public string Text
|
||||
|
||||
@@ -60,8 +60,14 @@
|
||||
Background="{Binding Theme.Background}"
|
||||
/>
|
||||
|
||||
<TextBlock x:Name="LinkTextBlock" Margin="0,10">
|
||||
<local:HyperlinkEx x:Name="Link"></local:HyperlinkEx>
|
||||
<TextBlock
|
||||
x:Name="LinkTextBlock"
|
||||
Margin="2,0"
|
||||
>
|
||||
<local:HyperlinkEx
|
||||
x:Name="Link"
|
||||
Foreground="{Binding Theme.Heading}"
|
||||
/>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -33,6 +33,9 @@ public partial class StringSettingControl : UserControl, ISettingControl
|
||||
|
||||
if (string.IsNullOrEmpty(stringSetting.URL))
|
||||
LinkTextBlock.Visibility = Visibility.Collapsed;
|
||||
|
||||
if (string.IsNullOrEmpty(stringSetting.Help))
|
||||
HelpTextBox.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public Theme? Theme => Theme.Current;
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Windows;
|
||||
|
||||
namespace HandyControl.Tools.Interop
|
||||
{
|
||||
internal class InteropValues
|
||||
public class InteropValues
|
||||
{
|
||||
internal static class ExternDll
|
||||
{
|
||||
@@ -290,7 +290,7 @@ namespace HandyControl.Tools.Interop
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal class WINDOWPOS
|
||||
public class WINDOWPOS
|
||||
{
|
||||
public IntPtr hwnd;
|
||||
public IntPtr hwndInsertAfter;
|
||||
|
||||
@@ -6,6 +6,183 @@
|
||||
xmlns:local="clr-namespace:MpvNet.Windows.WPF"
|
||||
>
|
||||
|
||||
<DataTemplate x:Key="ComboBoxCollapsedDataTemplate" >
|
||||
<TextBlock Text="{Binding Text}"/>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ComboBoxExpandedDataTemplate" >
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Bottom">
|
||||
<Border>
|
||||
<TextBlock
|
||||
Text="{Binding Text}"
|
||||
Width="{Binding Width}"
|
||||
VerticalAlignment="Center"
|
||||
TextWrapping="Wrap"
|
||||
/>
|
||||
</Border>
|
||||
<Border>
|
||||
<TextBlock
|
||||
Text="{Binding Help}"
|
||||
MaxWidth="400"
|
||||
Padding="0,3"
|
||||
VerticalAlignment="Center"
|
||||
TextWrapping="Wrap"
|
||||
/>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
|
||||
<Style x:Key="ComboBoxToggleButton" TargetType="ToggleButton">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToggleButton">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="32" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border
|
||||
x:Name="Border"
|
||||
Grid.ColumnSpan="2"
|
||||
CornerRadius="3"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="1"
|
||||
/>
|
||||
|
||||
<Path
|
||||
x:Name="Arrow"
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Data="M 1,1.5 L 4.5,5 L 8,1.5"
|
||||
SnapsToDevicePixels="false"
|
||||
Stroke="{TemplateBinding Foreground}"
|
||||
StrokeThickness="1.5"
|
||||
/>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<ControlTemplate x:Key="ComboBoxTextBox" TargetType="TextBox">
|
||||
<Border x:Name="PART_ContentHost" Focusable="True" />
|
||||
</ControlTemplate>
|
||||
|
||||
<Style TargetType="{x:Type ComboBox}">
|
||||
<Setter Property="Foreground" Value="#333" />
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryTextBrush}" />
|
||||
<Setter Property="SnapsToDevicePixels" Value="true"/>
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
|
||||
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
|
||||
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
<Setter Property="MinWidth" Value="150"/>
|
||||
<Setter Property="MinHeight" Value="25"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ComboBox">
|
||||
<Grid>
|
||||
<ToggleButton
|
||||
Cursor="Hand"
|
||||
Name="ToggleButton"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
Background="{TemplateBinding Background}"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
Style="{StaticResource ComboBoxToggleButton}"
|
||||
Grid.Column="2"
|
||||
Focusable="false"
|
||||
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
|
||||
ClickMode="Press"
|
||||
/>
|
||||
|
||||
<ContentPresenter
|
||||
Name="ContentSite"
|
||||
IsHitTestVisible="False"
|
||||
Content="{TemplateBinding SelectionBoxItem}"
|
||||
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
|
||||
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
|
||||
Margin="10,3,30,3"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left"
|
||||
/>
|
||||
|
||||
<TextBox
|
||||
x:Name="PART_EditableTextBox"
|
||||
Style="{x:Null}"
|
||||
Template="{StaticResource ComboBoxTextBox}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Margin="3,3,23,3"
|
||||
Focusable="True"
|
||||
Visibility="Hidden"
|
||||
IsReadOnly="{TemplateBinding IsReadOnly}"
|
||||
/>
|
||||
|
||||
<Popup
|
||||
Name="Popup"
|
||||
Placement="Bottom"
|
||||
IsOpen="{TemplateBinding IsDropDownOpen}"
|
||||
AllowsTransparency="True"
|
||||
Focusable="False"
|
||||
PopupAnimation="Slide"
|
||||
>
|
||||
|
||||
<Grid
|
||||
Name="DropDown"
|
||||
SnapsToDevicePixels="True"
|
||||
MinWidth="{TemplateBinding ActualWidth}"
|
||||
MaxHeight="{TemplateBinding MaxDropDownHeight}"
|
||||
>
|
||||
|
||||
<Border
|
||||
CornerRadius="3"
|
||||
x:Name="DropDownBorder"
|
||||
Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}, Path=Background}"
|
||||
BorderBrush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}, Path=Foreground}"
|
||||
BorderThickness="1"
|
||||
/>
|
||||
|
||||
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
|
||||
<StackPanel
|
||||
IsItemsHost="True"
|
||||
KeyboardNavigation.DirectionalNavigation="Contained" />
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Popup>
|
||||
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="HasItems" Value="false">
|
||||
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsGrouping" Value="true">
|
||||
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEditable" Value="true">
|
||||
<Setter Property="IsTabStop" Value="false"/>
|
||||
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
|
||||
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Opacity" Value="0.56"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter Property="BorderBrush" Value="#FF7EB4EA"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsFocused" Value="true">
|
||||
<Setter Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Theme.Heading}"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="local:HyperlinkEx">
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
@@ -53,20 +230,23 @@
|
||||
</Style>
|
||||
|
||||
<Style TargetType="TextBox">
|
||||
<Setter Property="MinHeight" Value="25" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type TextBox}">
|
||||
<Border x:Name="border"
|
||||
BorderBrush="{DynamicResource PrimaryTextBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}"
|
||||
CornerRadius="3"
|
||||
SnapsToDevicePixels="True">
|
||||
<Border
|
||||
x:Name="border"
|
||||
BorderBrush="{DynamicResource PrimaryTextBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}"
|
||||
CornerRadius="3"
|
||||
SnapsToDevicePixels="True">
|
||||
|
||||
<ScrollViewer x:Name="PART_ContentHost"
|
||||
Focusable="false"
|
||||
HorizontalScrollBarVisibility="Hidden"
|
||||
VerticalScrollBarVisibility="Hidden"/>
|
||||
<ScrollViewer
|
||||
x:Name="PART_ContentHost"
|
||||
Focusable="false"
|
||||
HorizontalScrollBarVisibility="Hidden"
|
||||
VerticalScrollBarVisibility="Hidden"/>
|
||||
</Border>
|
||||
|
||||
<ControlTemplate.Triggers>
|
||||
@@ -1042,5 +1222,5 @@
|
||||
<Style BasedOn="{StaticResource MenuItemBaseStyle}" TargetType="MenuItem"/>
|
||||
|
||||
<Style BasedOn="{StaticResource MenuBaseStyle}" TargetType="Menu"/>
|
||||
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -7,10 +7,19 @@ namespace MpvNet.Windows.WPF;
|
||||
|
||||
public class WpfTranslator : ITranslator
|
||||
{
|
||||
string _localizerLangauge = "";
|
||||
|
||||
static Language[] Languages { get; } = new Language[] {
|
||||
new("english", "en", "en"),
|
||||
new("bulgarian", "bg", "bg"),
|
||||
new("chinese-china", "zh-CN", "zh"), // Chinese (Simplified)
|
||||
new("english", "en", "en"),
|
||||
new("french", "fr", "fr"),
|
||||
new("german", "de", "de"),
|
||||
new("japanese", "ja", "ja"),
|
||||
new("korean", "ko", "ko"),
|
||||
new("polish", "pl", "pl"),
|
||||
new("russian", "ru", "ru"),
|
||||
new("turkish", "tr", "tr"),
|
||||
};
|
||||
|
||||
public string Gettext(string msgId)
|
||||
@@ -19,10 +28,19 @@ public class WpfTranslator : ITranslator
|
||||
return Translation._(msgId);
|
||||
}
|
||||
|
||||
public string GetParticularString(string context, string text)
|
||||
{
|
||||
InitNGettextWpf();
|
||||
return Translation.GetParticularString(context, text);
|
||||
}
|
||||
|
||||
void InitNGettextWpf()
|
||||
{
|
||||
if (Translation.Localizer == null)
|
||||
if (Translation.Localizer == null || _localizerLangauge != App.Language)
|
||||
{
|
||||
CompositionRoot.Compose("mpvnet", GetCulture(App.Language), Folder.Startup + "Locale");
|
||||
_localizerLangauge = App.Language;
|
||||
}
|
||||
}
|
||||
|
||||
string GetSystemLanguage()
|
||||
|
||||
2
src/MpvNet.Windows/WinForms/MainForm.Designer.cs
generated
@@ -38,7 +38,7 @@ partial class MainForm
|
||||
// CursorTimer
|
||||
//
|
||||
CursorTimer.Enabled = true;
|
||||
CursorTimer.Interval = 1000;
|
||||
CursorTimer.Interval = 500;
|
||||
CursorTimer.Tick += CursorTimer_Tick;
|
||||
//
|
||||
// ProgressTimer
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Threading;
|
||||
using System.Windows.Forms.Integration;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using MpvNet.Windows.WPF;
|
||||
using MpvNet.Windows.UI;
|
||||
@@ -18,7 +18,7 @@ using WpfControls = System.Windows.Controls;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
|
||||
using static MpvNet.Windows.Native.WinApi;
|
||||
using MpvNet.Windows.Help;
|
||||
using static MpvNet.Windows.Help.WinApiHelp;
|
||||
|
||||
namespace MpvNet.Windows.WinForms;
|
||||
|
||||
@@ -26,7 +26,6 @@ public partial class MainForm : Form
|
||||
{
|
||||
public SnapManager SnapManager = new SnapManager();
|
||||
public IntPtr MpvWindowHandle { get; set; }
|
||||
public ElementHost? CommandPaletteHost { get; set; }
|
||||
public bool WasShown { get; set; }
|
||||
public static MainForm? Instance { get; set; }
|
||||
WpfControls.ContextMenu ContextMenu { get; } = new WpfControls.ContextMenu();
|
||||
@@ -39,16 +38,18 @@ public partial class MainForm : Form
|
||||
int _lastCursorChanged;
|
||||
int _lastCycleFullscreen;
|
||||
int _taskbarButtonCreatedMessage;
|
||||
int _cursorAutohide = 1000;
|
||||
|
||||
bool _contextMenuIsReady;
|
||||
bool _wasMaximized;
|
||||
bool _maxSizeSet;
|
||||
bool _isCursorVisible = true;
|
||||
|
||||
public MainForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
if (Environment.OSVersion.Version >= new Version(10, 0, 18985) && Theme.DarkMode)
|
||||
DwmSetWindowAttribute(Handle, 20, new[] { 1 }, 4); // DWMWA_USE_IMMERSIVE_DARK_MODE = 20
|
||||
UpdateDarkMode();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -67,8 +68,30 @@ public partial class MainForm : Form
|
||||
GuiCommand.Current.WindowScaleNet += GuiCommand_WindowScaleNet;
|
||||
GuiCommand.Current.ShowMenu += GuiCommand_ShowMenu;
|
||||
|
||||
if (Player.GPUAPI != "vulkan")
|
||||
Init();
|
||||
Player.Init(Handle, true);
|
||||
|
||||
Player.ObserveProperty("window-maximized", PropChangeWindowMaximized); // bool methods not working correctly
|
||||
Player.ObserveProperty("window-minimized", PropChangeWindowMinimized); // bool methods not working correctly
|
||||
Player.ObserveProperty("cursor-autohide", PropChangeCursorAutohide);
|
||||
|
||||
Player.ObservePropertyBool("border", PropChangeBorder);
|
||||
Player.ObservePropertyBool("fullscreen", PropChangeFullscreen);
|
||||
Player.ObservePropertyBool("keepaspect-window", value => Player.KeepaspectWindow = value);
|
||||
Player.ObservePropertyBool("ontop", PropChangeOnTop);
|
||||
Player.ObservePropertyBool("title-bar", PropChangeTitleBar);
|
||||
|
||||
Player.ObservePropertyString("sid", PropChangeSid);
|
||||
Player.ObservePropertyString("aid", PropChangeAid);
|
||||
Player.ObservePropertyString("vid", PropChangeVid);
|
||||
|
||||
Player.ObservePropertyString("title", PropChangeTitle);
|
||||
|
||||
Player.ObservePropertyInt("edition", PropChangeEdition);
|
||||
|
||||
Player.ObservePropertyDouble("window-scale", PropChangeWindowScale);
|
||||
|
||||
CommandLine.ProcessCommandLineArgsPostInit();
|
||||
CommandLine.ProcessCommandLineFiles();
|
||||
|
||||
_taskbarButtonCreatedMessage = RegisterWindowMessage("TaskbarButtonCreated");
|
||||
|
||||
@@ -125,6 +148,12 @@ public partial class MainForm : Form
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateDarkMode()
|
||||
{
|
||||
if (Environment.OSVersion.Version >= new Version(10, 0, 18985))
|
||||
DwmSetWindowAttribute(Handle, 20, new[] { Theme.DarkMode ? 1 : 0 }, 4); // DWMWA_USE_IMMERSIVE_DARK_MODE = 20
|
||||
}
|
||||
|
||||
void Player_ClientMessage(string[] args)
|
||||
{
|
||||
if (Command.Current.Commands.ContainsKey(args[0]))
|
||||
@@ -139,32 +168,6 @@ public partial class MainForm : Form
|
||||
SetTitle();
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
Player.Init(Handle);
|
||||
|
||||
// bool methods not working correctly
|
||||
Player.ObserveProperty("window-maximized", PropChangeWindowMaximized);
|
||||
Player.ObserveProperty("window-minimized", PropChangeWindowMinimized);
|
||||
|
||||
Player.ObservePropertyBool("border", PropChangeBorder);
|
||||
Player.ObservePropertyBool("fullscreen", PropChangeFullscreen);
|
||||
Player.ObservePropertyBool("keepaspect-window", value => Player.KeepaspectWindow = value);
|
||||
Player.ObservePropertyBool("ontop", PropChangeOnTop);
|
||||
|
||||
Player.ObservePropertyString("sid", PropChangeSid);
|
||||
Player.ObservePropertyString("aid", PropChangeAid);
|
||||
Player.ObservePropertyString("vid", PropChangeVid);
|
||||
|
||||
Player.ObservePropertyString("title", PropChangeTitle);
|
||||
|
||||
Player.ObservePropertyInt("edition", PropChangeEdition);
|
||||
|
||||
Player.ObservePropertyDouble("window-scale", PropChangeWindowScale);
|
||||
|
||||
Player.ProcessCommandLineFiles();
|
||||
}
|
||||
|
||||
void PropChangeWindowScale(double scale)
|
||||
{
|
||||
if (!WasShown)
|
||||
@@ -173,13 +176,13 @@ public partial class MainForm : Form
|
||||
BeginInvoke(() => {
|
||||
SetSize(
|
||||
(int)(Player.VideoSize.Width * scale),
|
||||
(int)Math.Ceiling(Player.VideoSize.Height * scale),
|
||||
(int)Math.Floor(Player.VideoSize.Height * scale),
|
||||
Screen.FromControl(this), false);
|
||||
});
|
||||
}
|
||||
|
||||
void Player_Shutdown() => BeginInvoke(Close);
|
||||
|
||||
|
||||
void Player_VideoSizeChanged(Size value) => BeginInvoke(() =>
|
||||
{
|
||||
if (!KeepSize())
|
||||
@@ -199,7 +202,7 @@ public partial class MainForm : Form
|
||||
else
|
||||
{
|
||||
w = (int)(ClientSize.Width * scale);
|
||||
h = (int)Math.Ceiling(w * Player.VideoSize.Height / (double)Player.VideoSize.Width);
|
||||
h = (int)Math.Floor(w * Player.VideoSize.Height / (double)Player.VideoSize.Width);
|
||||
}
|
||||
|
||||
SetSize(w, h, Screen.FromControl(this), false);
|
||||
@@ -210,7 +213,7 @@ public partial class MainForm : Form
|
||||
{
|
||||
BeginInvoke(() => {
|
||||
Screen screen = Screen.FromControl(this);
|
||||
Rectangle workingArea = WinApiHelp.GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle workingArea = GetWorkingArea(Handle, screen.WorkingArea);
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
@@ -239,7 +242,7 @@ public partial class MainForm : Form
|
||||
BeginInvoke(() => {
|
||||
SetSize(
|
||||
(int)(Player.VideoSize.Width * scale),
|
||||
(int)Math.Ceiling(Player.VideoSize.Height * scale),
|
||||
(int)Math.Floor(Player.VideoSize.Height * scale),
|
||||
Screen.FromControl(this), false);
|
||||
Player.Command($"show-text \"window-scale {scale.ToString(CultureInfo.InvariantCulture)}\"");
|
||||
});
|
||||
@@ -277,8 +280,6 @@ public partial class MainForm : Form
|
||||
pos.Y > ClientSize.Height * 0.78;
|
||||
}
|
||||
|
||||
bool IsCommandPaletteVissible() => CommandPaletteHost != null && CommandPaletteHost.Visible;
|
||||
|
||||
void UpdateMenu()
|
||||
{
|
||||
Player.UpdateExternalTracks();
|
||||
@@ -380,12 +381,11 @@ public partial class MainForm : Form
|
||||
var menuItem = MenuHelp.Add(recentMenuItem.Items, file.Title.ShortPath(100));
|
||||
|
||||
if (menuItem != null)
|
||||
menuItem.Click += (sender, args) =>
|
||||
Player.LoadFiles(new[] { file.Path }, true, false);
|
||||
menuItem.Click += (sender, args) => Player.LoadFiles(new[] { file.Path }, true, false);
|
||||
}
|
||||
|
||||
recentMenuItem.Items.Add(new WpfControls.Separator());
|
||||
var clearMenuItem = new WpfControls.MenuItem() { Header = "Clear List" };
|
||||
var clearMenuItem = new WpfControls.MenuItem() { Header = _("Clear List") };
|
||||
clearMenuItem.Click += (sender, args) => App.Settings.RecentFiles.Clear();
|
||||
recentMenuItem.Items.Add(clearMenuItem);
|
||||
}
|
||||
@@ -443,34 +443,60 @@ public partial class MainForm : Form
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
profilesMenuItem.Items.Add(new WpfControls.Separator());
|
||||
var showProfilesMenuItem = new WpfControls.MenuItem() { Header = _("Show Profiles") };
|
||||
showProfilesMenuItem.Click += (sender, args) => Player.Command("script-message-to mpvnet show-profiles");
|
||||
profilesMenuItem.Items.Add(showProfilesMenuItem);
|
||||
}
|
||||
|
||||
var audioDevicesMenuItem = FindMenuItem(_("Audio Device"), "Audio Device");
|
||||
|
||||
if (audioDevicesMenuItem != null)
|
||||
{
|
||||
audioDevicesMenuItem.Items.Clear();
|
||||
|
||||
foreach (var pair in Player.AudioDevices)
|
||||
{
|
||||
var menuItem = MenuHelp.Add(audioDevicesMenuItem.Items, pair.Value);
|
||||
|
||||
if (menuItem != null)
|
||||
{
|
||||
menuItem.IsChecked = pair.Name == Player.GetPropertyString("audio-device");
|
||||
|
||||
menuItem.Click += (sender, args) =>
|
||||
{
|
||||
Player.SetPropertyString("audio-device", pair.Name);
|
||||
Player.CommandV("show-text", pair.Value);
|
||||
App.Settings.AudioDevice = pair.Name;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var customMenuItem = FindMenuItem(_("Custom"), "Custom");
|
||||
|
||||
if (customMenuItem != null)
|
||||
if (customMenuItem != null && !customMenuItem.HasItems)
|
||||
{
|
||||
if (!customMenuItem.HasItems)
|
||||
var customBindings = _confBindings!.Where(it => it.IsCustomMenu);
|
||||
|
||||
if (customBindings.Any())
|
||||
{
|
||||
var customBindings = _confBindings!.Where(it => it.IsCustomMenu);
|
||||
|
||||
if (customBindings.Any())
|
||||
foreach (Binding binding in customBindings)
|
||||
{
|
||||
foreach (Binding binding in customBindings)
|
||||
{
|
||||
var menuItem = MenuHelp.Add(customMenuItem.Items, binding.Comment);
|
||||
var menuItem = MenuHelp.Add(customMenuItem.Items, binding.Comment);
|
||||
|
||||
if (menuItem != null)
|
||||
{
|
||||
menuItem.Click += (sender, args) => Player.Command(binding.Command);
|
||||
menuItem.InputGestureText = binding.Input;
|
||||
}
|
||||
if (menuItem != null)
|
||||
{
|
||||
menuItem.Click += (sender, args) => Player.Command(binding.Command);
|
||||
menuItem.InputGestureText = binding.Input;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ContextMenu.Items.Contains(customMenuItem))
|
||||
ContextMenu.Items.Remove(customMenuItem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ContextMenu.Items.Contains(customMenuItem))
|
||||
ContextMenu.Items.Remove(customMenuItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -506,7 +532,7 @@ public partial class MainForm : Form
|
||||
return null;
|
||||
}
|
||||
|
||||
void SetFormPosAndSize(bool force = false, bool checkAutofit = true)
|
||||
void SetFormPosAndSize(bool force = false, bool checkAutofit = true, bool load = false)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
@@ -521,7 +547,7 @@ public partial class MainForm : Form
|
||||
}
|
||||
|
||||
Screen screen = Screen.FromControl(this);
|
||||
Rectangle workingArea = WinApiHelp.GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle workingArea = GetWorkingArea(Handle, screen.WorkingArea);
|
||||
int autoFitHeight = Convert.ToInt32(workingArea.Height * Player.Autofit);
|
||||
|
||||
if (App.AutofitAudio > 1)
|
||||
@@ -564,12 +590,12 @@ public partial class MainForm : Form
|
||||
else if (App.StartSize == "height-always" || App.StartSize == "height-session")
|
||||
{
|
||||
height = ClientSize.Height;
|
||||
width = height * videoSize.Width / videoSize.Height;
|
||||
width = (int)Math.Ceiling(height * videoSize.Width / (double)videoSize.Height);
|
||||
}
|
||||
else if (App.StartSize == "width-always" || App.StartSize == "width-session")
|
||||
{
|
||||
width = ClientSize.Width;
|
||||
height = (int)Math.Ceiling(width * videoSize.Height / (double)videoSize.Width);
|
||||
height = (int)Math.Floor(width * videoSize.Height / (double)videoSize.Width);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -579,38 +605,38 @@ public partial class MainForm : Form
|
||||
if (App.StartSize == "height-always" && windowSize.Height != 0)
|
||||
{
|
||||
height = windowSize.Height;
|
||||
width = height * videoSize.Width / videoSize.Height;
|
||||
width = (int)Math.Ceiling(height * videoSize.Width / (double)videoSize.Height);
|
||||
}
|
||||
else if (App.StartSize == "height-session" || App.StartSize == "session")
|
||||
{
|
||||
height = autoFitHeight;
|
||||
width = height * videoSize.Width / videoSize.Height;
|
||||
width = (int)Math.Ceiling(height * videoSize.Width / (double)videoSize.Height);
|
||||
}
|
||||
else if(App.StartSize == "width-always" && windowSize.Height != 0)
|
||||
{
|
||||
width = windowSize.Width;
|
||||
height = (int)Math.Ceiling(width * videoSize.Height / (double)videoSize.Width);
|
||||
height = (int)Math.Floor(width * videoSize.Height / (double)videoSize.Width);
|
||||
}
|
||||
else if (App.StartSize == "width-session")
|
||||
{
|
||||
width = autoFitHeight / 9 * 16;
|
||||
height = (int)Math.Ceiling(width * videoSize.Height / (double)videoSize.Width);
|
||||
height = (int)Math.Floor(width * videoSize.Height / (double)videoSize.Width);
|
||||
}
|
||||
else if (App.StartSize == "always" && windowSize.Height != 0)
|
||||
{
|
||||
height = windowSize.Height;
|
||||
width = windowSize.Width;
|
||||
}
|
||||
|
||||
|
||||
Player.WasInitialSizeSet = true;
|
||||
}
|
||||
|
||||
SetSize(width, height, screen, checkAutofit);
|
||||
SetSize(width, height, screen, checkAutofit, load);
|
||||
}
|
||||
|
||||
void SetSize(int width, int height, Screen screen, bool checkAutofit = true)
|
||||
void SetSize(int width, int height, Screen screen, bool checkAutofit = true, bool load = false)
|
||||
{
|
||||
Rectangle workingArea = WinApiHelp.GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle workingArea = GetWorkingArea(Handle, screen.WorkingArea);
|
||||
|
||||
int maxHeight = workingArea.Height - (Height - ClientSize.Height) - 2;
|
||||
int maxWidth = workingArea.Width - (Width - ClientSize.Width);
|
||||
@@ -622,71 +648,115 @@ public partial class MainForm : Form
|
||||
{
|
||||
if (height < maxHeight * Player.AutofitSmaller)
|
||||
{
|
||||
height = Convert.ToInt32(maxHeight * Player.AutofitSmaller);
|
||||
width = Convert.ToInt32(height * startWidth / (double)startHeight);
|
||||
height = (int)(maxHeight * Player.AutofitSmaller);
|
||||
width = (int)Math.Ceiling(height * startWidth / (double)startHeight);
|
||||
}
|
||||
|
||||
if (height > maxHeight * Player.AutofitLarger)
|
||||
{
|
||||
height = Convert.ToInt32(maxHeight * Player.AutofitLarger);
|
||||
width = Convert.ToInt32(height * startWidth / (double)startHeight);
|
||||
height = (int)(maxHeight * Player.AutofitLarger);
|
||||
width = (int)Math.Ceiling(height * startWidth / (double)startHeight);
|
||||
}
|
||||
}
|
||||
|
||||
if (width > maxWidth)
|
||||
{
|
||||
width = maxWidth;
|
||||
height = (int)Math.Ceiling(width * startHeight / (double)startWidth);
|
||||
height = (int)Math.Floor(width * startHeight / (double)startWidth);
|
||||
}
|
||||
|
||||
if (height > maxHeight)
|
||||
{
|
||||
height = maxHeight;
|
||||
width = Convert.ToInt32(height * startWidth / (double)startHeight);
|
||||
width = (int)Math.Ceiling(height * startWidth / (double)startHeight);
|
||||
}
|
||||
|
||||
if (height < maxHeight * 0.1)
|
||||
{
|
||||
height = Convert.ToInt32(maxHeight * 0.1);
|
||||
width = Convert.ToInt32(height * startWidth / (double)startHeight);
|
||||
height = (int)(maxHeight * 0.1);
|
||||
width = (int)Math.Ceiling(height * startWidth / (double)startHeight);
|
||||
}
|
||||
|
||||
Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
|
||||
var rect = new Rect(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height));
|
||||
WinApiHelp.AddWindowBorders(Handle, ref rect, GetDpi(Handle));
|
||||
var rect = new RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height));
|
||||
|
||||
int left = middlePos.X - rect.Width / 2;
|
||||
int top = middlePos.Y - rect.Height / 2;
|
||||
AddWindowBorders(Handle, ref rect, GetDpi(Handle), !Player.TitleBar);
|
||||
|
||||
width = rect.Width;
|
||||
height = rect.Height;
|
||||
|
||||
int left = Convert.ToInt32(middlePos.X - width / 2.0);
|
||||
int top = Convert.ToInt32(middlePos.Y - height / 2.0);
|
||||
|
||||
if (!Player.TitleBar)
|
||||
top -= Convert.ToInt32(GetTitleBarHeight(Handle, GetDpi(Handle)) / 2.0);
|
||||
|
||||
Rectangle currentRect = new Rectangle(Left, Top, Width, Height);
|
||||
|
||||
if (GetHorizontalLocation(screen) == -1) left = Left;
|
||||
if (GetHorizontalLocation(screen) == 1) left = currentRect.Right - rect.Width;
|
||||
if (GetHorizontalLocation(screen) == 1) left = currentRect.Right - width;
|
||||
|
||||
if (GetVerticalLocation(screen) == -1) top = Top;
|
||||
if (GetVerticalLocation(screen) == 1) top = currentRect.Bottom - rect.Height;
|
||||
if (GetVerticalLocation(screen) == 1) top = currentRect.Bottom - height;
|
||||
|
||||
Screen[] screens = Screen.AllScreens;
|
||||
|
||||
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();
|
||||
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();
|
||||
|
||||
if (load)
|
||||
{
|
||||
string geometryString = Player.GetPropertyString("geometry");
|
||||
|
||||
if (!string.IsNullOrEmpty(geometryString))
|
||||
{
|
||||
var pos = ParseGeometry(geometryString, width, height);
|
||||
|
||||
if (pos.X != int.MaxValue)
|
||||
left = pos.X;
|
||||
|
||||
if (pos.Y != int.MaxValue)
|
||||
top = pos.Y;
|
||||
}
|
||||
}
|
||||
|
||||
if (left < minLeft)
|
||||
left = minLeft;
|
||||
|
||||
if (left + rect.Width > maxRight)
|
||||
left = maxRight - rect.Width;
|
||||
if (left + width > maxRight)
|
||||
left = maxRight - width;
|
||||
|
||||
if (top < minTop)
|
||||
top = minTop;
|
||||
|
||||
if (top + rect.Height > maxBottom)
|
||||
top = maxBottom - rect.Height;
|
||||
if (top + height > maxBottom)
|
||||
top = maxBottom - height;
|
||||
|
||||
uint SWP_NOACTIVATE = 0x0010;
|
||||
SetWindowPos(Handle, IntPtr.Zero, left, top, rect.Width, rect.Height, SWP_NOACTIVATE);
|
||||
SetWindowPos(Handle, IntPtr.Zero, left, top, width, height, SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
Point ParseGeometry(string input, int width, int height)
|
||||
{
|
||||
int x = int.MaxValue;
|
||||
int y = int.MaxValue;
|
||||
|
||||
Match match = Regex.Match(input, @"^\+(\d+)%?\+(\d+)%?$");
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
Rectangle workingArea = GetWorkingArea(Handle, Screen.FromHandle(Handle).WorkingArea);
|
||||
|
||||
x = int.Parse(match.Groups[1].Value);
|
||||
y = int.Parse(match.Groups[2].Value);
|
||||
|
||||
x = workingArea.Left + Convert.ToInt32((workingArea.Width - width) / 100.0 * x);
|
||||
y = workingArea.Top + Convert.ToInt32((workingArea.Height - height) / 100.0 * y);
|
||||
}
|
||||
|
||||
return new Point(x, y);
|
||||
}
|
||||
|
||||
public void CycleFullscreen(bool enabled)
|
||||
@@ -719,7 +789,7 @@ public partial class MainForm : Form
|
||||
else
|
||||
{
|
||||
WindowState = FormWindowState.Normal;
|
||||
|
||||
|
||||
if (!Player.WasInitialSizeSet)
|
||||
SetFormPosAndSize();
|
||||
}
|
||||
@@ -734,7 +804,7 @@ public partial class MainForm : Form
|
||||
|
||||
public int GetHorizontalLocation(Screen screen)
|
||||
{
|
||||
Rectangle workingArea = WinApiHelp.GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle workingArea = 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 +821,7 @@ public partial class MainForm : Form
|
||||
|
||||
public int GetVerticalLocation(Screen screen)
|
||||
{
|
||||
Rectangle workingArea = WinApiHelp.GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle workingArea = GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle rect = new Rectangle(Left - workingArea.X, Top - workingArea.Y, Width, Height);
|
||||
|
||||
if (workingArea.Height / (float)Height < 1.1)
|
||||
@@ -781,7 +851,7 @@ public partial class MainForm : Form
|
||||
|
||||
if (!binding.IsMenu)
|
||||
continue;
|
||||
|
||||
|
||||
var menuItem = MenuHelp.Add(ContextMenu.Items, tempBinding.Comment);
|
||||
|
||||
if (menuItem != null)
|
||||
@@ -837,7 +907,7 @@ public partial class MainForm : Form
|
||||
path = path + "|" + title;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(path) && path != @"bd://" && path != @"dvd://")
|
||||
if (!string.IsNullOrEmpty(path) && path != "-" && path != @"bd://" && path != @"dvd://")
|
||||
{
|
||||
if (App.Settings.RecentFiles.Contains(path))
|
||||
App.Settings.RecentFiles.Remove(path);
|
||||
@@ -970,16 +1040,20 @@ public partial class MainForm : Form
|
||||
m.Result = SendMessage(MpvWindowHandle, m.Msg, m.WParam, m.LParam);
|
||||
}
|
||||
break;
|
||||
case 0x001A: // WM_SETTINGCHANGE
|
||||
UpdateDarkMode();
|
||||
break;
|
||||
case 0x51: // WM_INPUTLANGCHANGE
|
||||
ActivateKeyboardLayout(m.LParam, 0x00000100u /*KLF_SETFORPROCESS*/);
|
||||
break;
|
||||
case 0x319: // WM_APPCOMMAND
|
||||
{
|
||||
string? value = MpvHelp.WM_APPCOMMAND_to_mpv_key((int)(m.LParam.ToInt64() >> 16 & ~0xf000));
|
||||
string? key = MpvHelp.WM_APPCOMMAND_to_mpv_key((int)(m.LParam.ToInt64() >> 16 & ~0xf000));
|
||||
bool inputMediaKeys = Player.GetPropertyBool("input-media-keys");
|
||||
|
||||
if (value != null)
|
||||
if (key != null && inputMediaKeys)
|
||||
{
|
||||
Player.Command("keypress " + value);
|
||||
Player.Command("keypress " + key);
|
||||
m.Result = new IntPtr(1);
|
||||
return;
|
||||
}
|
||||
@@ -1009,16 +1083,46 @@ public partial class MainForm : Form
|
||||
if (!WasShown)
|
||||
break;
|
||||
|
||||
Rect rect = Marshal.PtrToStructure<Rect>(m.LParam);
|
||||
RECT rect = Marshal.PtrToStructure<RECT>(m.LParam);
|
||||
SetWindowPos(Handle, IntPtr.Zero, rect.Left, rect.Top, rect.Width, rect.Height, 0);
|
||||
}
|
||||
break;
|
||||
case 0x0112: // WM_SYSCOMMAND
|
||||
{
|
||||
// with title-bar=no when the window is restored from minimizing the height is too high
|
||||
if (!Player.TitleBar)
|
||||
{
|
||||
int SC_MINIMIZE = 0xF020;
|
||||
|
||||
if (m.WParam == (nint)SC_MINIMIZE)
|
||||
{
|
||||
MaximumSize = Size;
|
||||
_maxSizeSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x0083: // WM_NCCALCSIZE
|
||||
if ((int)m.WParam == 1 && !Player.TitleBar && !IsFullscreen)
|
||||
{
|
||||
var nccalcsize_params = Marshal.PtrToStructure<NCCALCSIZE_PARAMS>(m.LParam);
|
||||
RECT[] rects = nccalcsize_params.rgrc;
|
||||
int h = GetTitleBarHeight(Handle, GetDpi(Handle));
|
||||
rects[0].Top = rects[0].Top - h;
|
||||
Marshal.StructureToPtr(nccalcsize_params, m.LParam, false);
|
||||
}
|
||||
break;
|
||||
case 0x231: // WM_ENTERSIZEMOVE
|
||||
case 0x005: // WM_SIZE
|
||||
if (Player.SnapWindow)
|
||||
SnapManager.OnSizeAndEnterSizeMove(this);
|
||||
break;
|
||||
case 0x214: // WM_SIZING
|
||||
if (Player.KeepaspectWindow)
|
||||
{
|
||||
Rect rc = Marshal.PtrToStructure<Rect>(m.LParam);
|
||||
Rect r = rc;
|
||||
WinApiHelp.SubtractWindowBorders(Handle, ref r, GetDpi(Handle));
|
||||
RECT rc = Marshal.PtrToStructure<RECT>(m.LParam);
|
||||
RECT r = rc;
|
||||
SubtractWindowBorders(Handle, ref r, GetDpi(Handle), !Player.TitleBar);
|
||||
|
||||
int c_w = r.Right - r.Left, c_h = r.Bottom - r.Top;
|
||||
Size videoSize = Player.VideoSize;
|
||||
@@ -1026,48 +1130,25 @@ public partial class MainForm : Form
|
||||
if (videoSize == Size.Empty)
|
||||
videoSize = new Size(16, 9);
|
||||
|
||||
float aspect = videoSize.Width / (float)videoSize.Height;
|
||||
int d_w = (int)(c_h * aspect - c_w);
|
||||
int d_h = (int)(c_w / aspect - c_h);
|
||||
double aspect = videoSize.Width / (double)videoSize.Height;
|
||||
int d_w = (int)Math.Ceiling(c_h * aspect - c_w);
|
||||
int d_h = (int)Math.Floor(c_w / aspect - c_h);
|
||||
|
||||
int[] d_corners = { d_w, d_h, -d_w, -d_h };
|
||||
int[] corners = { rc.Left, rc.Top, rc.Right, rc.Bottom };
|
||||
int corner = WinApiHelp.GetResizeBorder(m.WParam.ToInt32());
|
||||
int corner = GetResizeBorder(m.WParam.ToInt32());
|
||||
|
||||
if (corner >= 0)
|
||||
corners[corner] -= d_corners[corner];
|
||||
|
||||
Marshal.StructureToPtr(new Rect(corners[0], corners[1], corners[2], corners[3]), m.LParam, false);
|
||||
Marshal.StructureToPtr(new RECT(corners[0], corners[1], corners[2], corners[3]), m.LParam, false);
|
||||
m.Result = new IntPtr(1);
|
||||
}
|
||||
return;
|
||||
case 0x4A: // WM_COPYDATA
|
||||
{
|
||||
var copyData = (CopyDataStruct)m.GetLParam(typeof(CopyDataStruct))!;
|
||||
string[] args = copyData.lpData.Split('\n');
|
||||
string mode = args[0];
|
||||
args = args.Skip(1).ToArray();
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case "single":
|
||||
Player.LoadFiles(args, true, false);
|
||||
break;
|
||||
case "queue":
|
||||
foreach (string file in args)
|
||||
Player.CommandV("loadfile", file, "append");
|
||||
break;
|
||||
case "command":
|
||||
Player.Command(args[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
Activate();
|
||||
}
|
||||
return;
|
||||
case 0x84: // WM_NCHITTEST
|
||||
// resize borderless window
|
||||
if (!Player.Border && !Player.Fullscreen) {
|
||||
if ((!Player.Border || !Player.TitleBar) && !Player.Fullscreen)
|
||||
{
|
||||
const int HTCLIENT = 1;
|
||||
const int HTLEFT = 10;
|
||||
const int HTRIGHT = 11;
|
||||
@@ -1106,11 +1187,30 @@ public partial class MainForm : Form
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x231: // WM_ENTERSIZEMOVE
|
||||
case 0x005: // WM_SIZE
|
||||
if (Player.SnapWindow)
|
||||
SnapManager.OnSizeAndEnterSizeMove(this);
|
||||
break;
|
||||
case 0x4A: // WM_COPYDATA
|
||||
{
|
||||
var copyData = (CopyDataStruct)m.GetLParam(typeof(CopyDataStruct))!;
|
||||
string[] args = copyData.lpData.Split('\n');
|
||||
string mode = args[0];
|
||||
args = args.Skip(1).ToArray();
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case "single":
|
||||
Player.LoadFiles(args, true, false);
|
||||
break;
|
||||
case "queue":
|
||||
foreach (string file in args)
|
||||
Player.CommandV("loadfile", file, "append");
|
||||
break;
|
||||
case "command":
|
||||
Player.Command(args[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
Activate();
|
||||
}
|
||||
return;
|
||||
case 0x216: // WM_MOVING
|
||||
if (Player.SnapWindow)
|
||||
SnapManager.OnMoving(ref m);
|
||||
@@ -1128,6 +1228,25 @@ public partial class MainForm : Form
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
protected override void OnActivated(EventArgs e)
|
||||
{
|
||||
base.OnActivated(e);
|
||||
|
||||
if (_maxSizeSet)
|
||||
{
|
||||
TaskHelp.Run(() => {
|
||||
Thread.Sleep(200);
|
||||
BeginInvoke(() => {
|
||||
if (!IsDisposed && !Disposing)
|
||||
{
|
||||
MaximumSize = new Size(int.MaxValue, int.MaxValue);
|
||||
_maxSizeSet = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void CursorTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if (IsCursorPosDifferent(_lastCursorPosition))
|
||||
@@ -1135,11 +1254,9 @@ public partial class MainForm : Form
|
||||
_lastCursorPosition = MousePosition;
|
||||
_lastCursorChanged = Environment.TickCount;
|
||||
}
|
||||
else if ((Environment.TickCount - _lastCursorChanged > 1500 ||
|
||||
Environment.TickCount - _lastCursorChanged > 5000) &&
|
||||
else if ((Environment.TickCount - _lastCursorChanged > _cursorAutohide) &&
|
||||
ClientRectangle.Contains(PointToClient(MousePosition)) &&
|
||||
ActiveForm == this && !ContextMenu.IsVisible && !IsMouseInOsc() &&
|
||||
!IsCommandPaletteVissible())
|
||||
ActiveForm == this && !ContextMenu.IsVisible && !IsMouseInOsc())
|
||||
|
||||
HideCursor();
|
||||
}
|
||||
@@ -1196,6 +1313,18 @@ public partial class MainForm : Form
|
||||
});
|
||||
}
|
||||
|
||||
void PropChangeCursorAutohide()
|
||||
{
|
||||
string strValue = Player.GetPropertyString("cursor-autohide");
|
||||
|
||||
if (strValue == "no")
|
||||
_cursorAutohide = 0;
|
||||
else if (strValue == "always")
|
||||
_cursorAutohide = -1;
|
||||
else if (int.TryParse(strValue, out var intValue))
|
||||
_cursorAutohide = intValue;
|
||||
}
|
||||
|
||||
void PropChangeBorder(bool enabled) {
|
||||
Player.Border = enabled;
|
||||
|
||||
@@ -1211,6 +1340,20 @@ public partial class MainForm : Form
|
||||
});
|
||||
}
|
||||
|
||||
void PropChangeTitleBar(bool enabled)
|
||||
{
|
||||
if (enabled == Player.TitleBar)
|
||||
return;
|
||||
|
||||
Player.TitleBar = enabled;
|
||||
|
||||
BeginInvoke(() => {
|
||||
SetSize(ClientSize.Width, ClientSize.Height, Screen.FromControl(this), false);
|
||||
Height += 1;
|
||||
Height -= 1;
|
||||
});
|
||||
}
|
||||
|
||||
void Player_Pause()
|
||||
{
|
||||
if (_taskbar != null && Player.TaskbarProgress)
|
||||
@@ -1220,10 +1363,8 @@ public partial class MainForm : Form
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
if (Player.GPUAPI != "vulkan")
|
||||
Player.VideoSizeAutoResetEvent.WaitOne(App.StartThreshold);
|
||||
_lastCycleFullscreen = Environment.TickCount;
|
||||
SetFormPosAndSize();
|
||||
SetFormPosAndSize(false, true, true);
|
||||
}
|
||||
|
||||
protected override void OnLostFocus(EventArgs e)
|
||||
@@ -1236,9 +1377,6 @@ public partial class MainForm : Form
|
||||
{
|
||||
base.OnShown(e);
|
||||
|
||||
if (Player.GPUAPI == "vulkan")
|
||||
Init();
|
||||
|
||||
if (WindowState == FormWindowState.Maximized)
|
||||
Player.SetPropertyBool("window-maximized", true);
|
||||
|
||||
@@ -1250,14 +1388,8 @@ public partial class MainForm : Form
|
||||
InitAndBuildContextMenu();
|
||||
Cursor.Position = new Point(Cursor.Position.X + 1, Cursor.Position.Y);
|
||||
GlobalHotkey.RegisterGlobalHotkeys(Handle);
|
||||
WasShown = true;
|
||||
StrongReferenceMessenger.Default.Send(new MainWindowIsLoadedMessage());
|
||||
|
||||
TaskHelp.Run(() => {
|
||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(() => {
|
||||
WinMpvHelp.AddToPath();
|
||||
}, DispatcherPriority.Background);
|
||||
});
|
||||
WasShown = true;
|
||||
}
|
||||
|
||||
void ContextMenu_Closed(object sender, System.Windows.RoutedEventArgs e) => MenuAutoResetEvent.Set();
|
||||
@@ -1305,11 +1437,7 @@ public partial class MainForm : Form
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseDown(e);
|
||||
|
||||
_mouseDownLocation = PointToScreen(e.Location);
|
||||
|
||||
if (Width - e.Location.X < 10 && e.Location.Y < 10)
|
||||
Player.CommandV("quit");
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
@@ -1346,10 +1474,12 @@ public partial class MainForm : Form
|
||||
{
|
||||
base.OnDragDrop(e);
|
||||
|
||||
bool append = ModifierKeys == Keys.Shift;
|
||||
|
||||
if (e.Data!.GetDataPresent(DataFormats.FileDrop))
|
||||
Player.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as string[], true, false);
|
||||
Player.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as string[], true, append);
|
||||
else if (e.Data.GetDataPresent(DataFormats.Text))
|
||||
Player.LoadFiles(new[] { e.Data.GetData(DataFormats.Text)!.ToString()! }, true, false);
|
||||
Player.LoadFiles(new[] { e.Data.GetData(DataFormats.Text)!.ToString()! }, true, append);
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
@@ -1361,20 +1491,18 @@ public partial class MainForm : Form
|
||||
base.OnKeyDown(e);
|
||||
}
|
||||
|
||||
static bool _isCursorVisible = true;
|
||||
|
||||
static void ShowCursor()
|
||||
void ShowCursor()
|
||||
{
|
||||
if (!_isCursorVisible)
|
||||
if (!_isCursorVisible && _cursorAutohide != -1)
|
||||
{
|
||||
Cursor.Show();
|
||||
_isCursorVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void HideCursor()
|
||||
void HideCursor()
|
||||
{
|
||||
if (_isCursorVisible)
|
||||
if (_isCursorVisible && _cursorAutohide != 0)
|
||||
{
|
||||
Cursor.Hide();
|
||||
_isCursorVisible = false;
|
||||
@@ -1389,7 +1517,7 @@ public partial class MainForm : Form
|
||||
|
||||
public static int GetDpi(IntPtr hwnd)
|
||||
{
|
||||
if (Environment.OSVersion.Version >= WinApiHelp.WindowsTen1607 && hwnd != IntPtr.Zero)
|
||||
if (Environment.OSVersion.Version >= WindowsTen1607 && hwnd != IntPtr.Zero)
|
||||
return GetDpiForWindow(hwnd);
|
||||
else
|
||||
using (Graphics gx = Graphics.FromHwnd(hwnd))
|
||||
@@ -1398,103 +1526,4 @@ public partial class MainForm : Form
|
||||
|
||||
[DllImport("DwmApi")]
|
||||
static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, int[] attrValue, int attrSize);
|
||||
|
||||
//protected override void OnLayout(LayoutEventArgs args)
|
||||
//{
|
||||
// base.OnLayout(args);
|
||||
// AdjustCommandPaletteLeftAndWidth();
|
||||
//}
|
||||
|
||||
//class ElementHostEx : ElementHost
|
||||
//{
|
||||
// protected override void OnHandleCreated(EventArgs e)
|
||||
// {
|
||||
// base.OnHandleCreated(e);
|
||||
// const int LWA_ColorKey = 1;
|
||||
|
||||
// if (Environment.OSVersion.Version > new Version(10, 0))
|
||||
// SetLayeredWindowAttributes(Handle, 0x111111, 255, LWA_ColorKey);
|
||||
// }
|
||||
|
||||
// protected override CreateParams CreateParams
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// CreateParams cp = base.CreateParams;
|
||||
|
||||
// if (Environment.OSVersion.Version > new Version(10, 0))
|
||||
// cp.ExStyle |= 0x00080000; // WS_EX_LAYERED
|
||||
|
||||
// cp.ExStyle |= 0x00000008; // WS_EX_TOPMOST
|
||||
|
||||
// cp.Style |= 0x04000000; //WS_CLIPSIBLINGS
|
||||
// cp.Style |= 0x02000000; //WS_CLIPCHILDREN
|
||||
|
||||
// return cp;
|
||||
// }
|
||||
// }
|
||||
|
||||
// protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// return base.ProcessCmdKey(ref msg, keyData);
|
||||
// }
|
||||
// catch (Exception)
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
|
||||
// [DllImport("user32.dll")]
|
||||
// public static extern bool SetLayeredWindowAttributes(IntPtr hWnd, int crKey, byte alpha, int dwFlags);
|
||||
//}
|
||||
|
||||
//public void ShowCommandPalette()
|
||||
//{
|
||||
// if (CommandPaletteHost == null)
|
||||
// {
|
||||
// CommandPaletteHost = new ElementHostEx();
|
||||
// CommandPaletteHost.Dock = DockStyle.Fill;
|
||||
// CommandPaletteHost.BackColor = Color.FromArgb(0x111111);
|
||||
|
||||
// AdjustCommandPaletteLeftAndWidth();
|
||||
// CommandPaletteHost.Child = CommandPalette.Instance;
|
||||
// CommandPalette.Instance.AdjustHeight();
|
||||
// Controls.Add(CommandPaletteHost);
|
||||
// CommandPaletteHost.BringToFront();
|
||||
// }
|
||||
//}
|
||||
|
||||
public void HideCommandPalette()
|
||||
{
|
||||
if (CommandPaletteHost != null)
|
||||
{
|
||||
CommandPaletteHost.Visible = false;
|
||||
|
||||
CommandPalette.Instance.Items.Clear();
|
||||
CommandPalette.Instance.SearchControl.SearchTextBox.Text = "";
|
||||
CommandPalette.Instance.UpdateLayout();
|
||||
|
||||
ActiveControl = null;
|
||||
Controls.Remove(CommandPaletteHost);
|
||||
|
||||
CommandPaletteHost.Child = null;
|
||||
CommandPaletteHost.Dispose();
|
||||
CommandPaletteHost = null;
|
||||
}
|
||||
}
|
||||
|
||||
//void AdjustCommandPaletteLeftAndWidth()
|
||||
//{
|
||||
// if (CommandPaletteHost == null)
|
||||
// return;
|
||||
|
||||
// CommandPaletteHost.Width = FontHeight * 26;
|
||||
|
||||
// if (CommandPaletteHost.Width > ClientSize.Width)
|
||||
// CommandPaletteHost.Width = ClientSize.Width;
|
||||
|
||||
// CommandPaletteHost.Left = (ClientSize.Width - CommandPaletteHost.Size.Width) / 2;
|
||||
//}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class SnapManager
|
||||
if (Handle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
WinApi.Rect boundsLtrb = Marshal.PtrToStructure<WinApi.Rect>(m.LParam);
|
||||
WinApi.RECT boundsLtrb = Marshal.PtrToStructure<WinApi.RECT>(m.LParam);
|
||||
Rectangle bounds = boundsLtrb.ToRectangle();
|
||||
// This is where the window _would_ be located if snapping
|
||||
// had not occurred. This prevents the cursor from sliding
|
||||
@@ -62,7 +62,7 @@ public class SnapManager
|
||||
bounds.Width,
|
||||
bounds.Height);
|
||||
FindSnap(ref effectiveBounds);
|
||||
WinApi.Rect newLtrb = WinApi.Rect.FromRectangle(effectiveBounds);
|
||||
WinApi.RECT newLtrb = WinApi.RECT.FromRectangle(effectiveBounds);
|
||||
Marshal.StructureToPtr(newLtrb, m.LParam, false);
|
||||
m.Result = new IntPtr(1);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2F97C77E-32E3-46FA-8D7C-3940FD9AA384}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
Directory.Build.props = Directory.Build.props
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NGettext.Wpf", "NGettext.Wpf\NGettext.Wpf.csproj", "{0B7958FD-2138-482A-A21B-481AE7A0F851}"
|
||||
|
||||
@@ -10,7 +10,6 @@ namespace MpvNet;
|
||||
public class AppClass
|
||||
{
|
||||
public List<string> TempFiles { get; } = new ();
|
||||
public Dictionary<string, string> CommandLineArguments { get; } = new ();
|
||||
|
||||
public string ConfPath { get => Player.ConfigFolder + "mpvnet.conf"; }
|
||||
public string ProcessInstance { get; set; } = "single";
|
||||
@@ -22,16 +21,16 @@ public class AppClass
|
||||
public string CommandLine { get; set; } = Environment.CommandLine;
|
||||
public string MenuSyntax { get; set; } = "#menu:";
|
||||
|
||||
public bool AutoLoadFolder { get; set; } = true;
|
||||
public bool AutoLoadFolder { get; set; }
|
||||
public bool DebugMode { get; set; }
|
||||
public bool Exit { get; set; }
|
||||
public bool IsTerminalAttached { get; } = Environment.GetEnvironmentVariable("_started_from_console") == "yes";
|
||||
public bool MediaInfo { get; set; } = true;
|
||||
public bool Queue { get; set; }
|
||||
public bool RememberAudioDevice { get; set; } = true;
|
||||
public bool RememberVolume { get; set; } = true;
|
||||
public bool RememberWindowPosition { get; set; }
|
||||
|
||||
public int StartThreshold { get; set; } = 1500;
|
||||
public int RecentCount { get; set; } = 15;
|
||||
|
||||
public float AutofitAudio { get; set; } = 0.7f;
|
||||
@@ -78,20 +77,14 @@ public class AppClass
|
||||
Player.Initialized += Player_Initialized;
|
||||
}
|
||||
|
||||
public static string About => "Copyright (C) 2000-2023 mpv.net/mpv/mplayer\n" +
|
||||
$"{AppInfo.Product} {AppInfo.Version}" + GetLastWriteTime(Environment.ProcessPath!) + "\n" +
|
||||
public static string About => "Copyright (C) 2000-2024 mpv.net/mpv/mplayer\n" +
|
||||
$"{AppInfo.Product} v{AppInfo.Version}" + GetLastWriteTime(Environment.ProcessPath!) + "\n" +
|
||||
$"{Player.GetPropertyString("mpv-version")}" + GetLastWriteTime(Folder.Startup + "libmpv-2.dll") + "\n" +
|
||||
$"ffmpeg {Player.GetPropertyString("ffmpeg-version")}\n" + "\nGPL v2 License";
|
||||
$"ffmpeg {Player.GetPropertyString("ffmpeg-version")}\n" +
|
||||
$"MediaInfo v{FileVersionInfo.GetVersionInfo(Folder.Startup + "MediaInfo.dll").FileVersion}" +
|
||||
$"{GetLastWriteTime(Folder.Startup + "MediaInfo.dll")}" + "\n" + "GPL v2 License";
|
||||
|
||||
static string GetLastWriteTime(string path)
|
||||
{
|
||||
if (IsStoreVersion)
|
||||
return "";
|
||||
|
||||
return $" ({File.GetLastWriteTime(path).ToShortDateString()})";
|
||||
}
|
||||
|
||||
static bool IsStoreVersion => Folder.Startup.Contains("FrankSkare.mpvnet");
|
||||
static string GetLastWriteTime(string path) => $" ({File.GetLastWriteTime(path).ToShortDateString()})";
|
||||
|
||||
void Player_Initialized()
|
||||
{
|
||||
@@ -100,6 +93,9 @@ public class AppClass
|
||||
Player.SetPropertyInt("volume", Settings.Volume);
|
||||
Player.SetPropertyString("mute", Settings.Mute);
|
||||
}
|
||||
|
||||
if (RememberAudioDevice && Settings.AudioDevice != "")
|
||||
Player.SetPropertyString("audio-device", Settings.AudioDevice);
|
||||
}
|
||||
|
||||
void Player_Shutdown()
|
||||
@@ -135,14 +131,12 @@ public class AppClass
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case "audio-file-extensions": FileTypes.Audio = value.Split(" ,;".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); return true;
|
||||
case "auto-load-folder": AutoLoadFolder = value == "yes"; return true;
|
||||
case "autofit-audio": AutofitAudio = value.Trim('%').ToInt(70) / 100f; return true;
|
||||
case "autofit-image": AutofitImage = value.Trim('%').ToInt(80) / 100f; return true;
|
||||
case "dark-mode": DarkMode = value; return true;
|
||||
case "dark-theme": DarkTheme = value.Trim('\'', '"'); return true;
|
||||
case "debug-mode": DebugMode = value == "yes"; return true;
|
||||
case "image-file-extensions": FileTypes.Image = value.Split(" ,;".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); return true;
|
||||
case "language": Language = value; return true;
|
||||
case "light-theme": LightTheme = value.Trim('\'', '"'); return true;
|
||||
case "media-info": MediaInfo = value == "yes"; return true;
|
||||
@@ -152,11 +146,10 @@ public class AppClass
|
||||
case "process-instance": ProcessInstance = value; return true;
|
||||
case "queue": Queue = value == "yes"; return true;
|
||||
case "recent-count": RecentCount = value.ToInt(15); return true;
|
||||
case "remember-audio-device": RememberAudioDevice = value == "yes"; return true;
|
||||
case "remember-volume": RememberVolume = value == "yes"; return true;
|
||||
case "remember-window-position": RememberWindowPosition = value == "yes"; return true;
|
||||
case "start-size": StartSize = value; return true;
|
||||
case "start-threshold": StartThreshold = value.ToInt(1500); return true;
|
||||
case "video-file-extensions": FileTypes.Video = value.Split(" ,;".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); return true;
|
||||
|
||||
default:
|
||||
if (writeError)
|
||||
|
||||
@@ -19,7 +19,7 @@ public class Chapter
|
||||
_timeDisplay = TimeSpan.FromSeconds(Time).ToString();
|
||||
|
||||
if (_timeDisplay.ContainsEx("."))
|
||||
_timeDisplay = _timeDisplay[.._timeDisplay.LastIndexOf(".")];
|
||||
_timeDisplay = _timeDisplay[.._timeDisplay.LastIndexOf('.')];
|
||||
}
|
||||
|
||||
return _timeDisplay;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using MpvNet.Help;
|
||||
|
||||
namespace MpvNet;
|
||||
@@ -26,13 +24,13 @@ public class Command
|
||||
|
||||
// deprecated
|
||||
["playlist-add"] = args => PlaylistAdd(Convert.ToInt32(args[0])), // deprecated
|
||||
["show-progress"] = args => ShowProgress(), // deprecated
|
||||
["show-progress"] = args => Player.Command("show-progress"), // deprecated
|
||||
["playlist-random"] = args => PlaylistRandom(), // deprecated
|
||||
};
|
||||
|
||||
public string FormatTime(double value) => ((int)value).ToString("00");
|
||||
static string FormatTime(double value) => ((int)value).ToString("00");
|
||||
|
||||
public static void PlayPause(IList<string> args)
|
||||
void PlayPause(IList<string> args)
|
||||
{
|
||||
int count = Player.GetPropertyInt("playlist-count");
|
||||
|
||||
@@ -44,7 +42,7 @@ public class Command
|
||||
{
|
||||
if (i.Contains("://") || File.Exists(i))
|
||||
{
|
||||
Player.LoadFiles(new[] { i }, true, false);
|
||||
Player.LoadFiles([i], true, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -66,7 +64,7 @@ public class Command
|
||||
"}${osd-ass-cc/1}" + text + "\" " + duration);
|
||||
}
|
||||
|
||||
public static void CycleAudio()
|
||||
void CycleAudio()
|
||||
{
|
||||
Player.UpdateExternalTracks();
|
||||
|
||||
@@ -94,7 +92,7 @@ public class Command
|
||||
}
|
||||
}
|
||||
|
||||
public static void CycleSubtitles()
|
||||
void CycleSubtitles()
|
||||
{
|
||||
Player.UpdateExternalTracks();
|
||||
|
||||
@@ -126,7 +124,7 @@ public class Command
|
||||
}
|
||||
|
||||
// deprecated
|
||||
public static void PlaylistAdd(int value)
|
||||
void PlaylistAdd(int value)
|
||||
{
|
||||
int pos = Player.PlaylistPos;
|
||||
int count = Player.GetPropertyInt("playlist-count");
|
||||
@@ -145,13 +143,13 @@ public class Command
|
||||
Player.SetPropertyInt("playlist-pos", pos);
|
||||
}
|
||||
|
||||
public static void PlaylistFirst()
|
||||
void PlaylistFirst()
|
||||
{
|
||||
if (Player.PlaylistPos != 0)
|
||||
Player.SetPropertyInt("playlist-pos", 0);
|
||||
}
|
||||
|
||||
public static void PlaylistLast()
|
||||
void PlaylistLast()
|
||||
{
|
||||
int count = Player.GetPropertyInt("playlist-count");
|
||||
|
||||
@@ -160,14 +158,14 @@ public class Command
|
||||
}
|
||||
|
||||
// deprecated
|
||||
public static void PlaylistRandom()
|
||||
void PlaylistRandom()
|
||||
{
|
||||
int count = Player.GetPropertyInt("playlist-count");
|
||||
Player.SetPropertyInt("playlist-pos", new Random().Next(count));
|
||||
}
|
||||
|
||||
// deprecated
|
||||
public void ShowProgress()
|
||||
void ShowProgress()
|
||||
{
|
||||
TimeSpan position = TimeSpan.FromSeconds(Player.GetPropertyDouble("time-pos"));
|
||||
TimeSpan duration = TimeSpan.FromSeconds(Player.GetPropertyDouble("duration"));
|
||||
|
||||
159
src/MpvNet/CommandLine.cs
Normal file
@@ -0,0 +1,159 @@
|
||||
|
||||
namespace MpvNet;
|
||||
|
||||
public class CommandLine
|
||||
{
|
||||
static List<StringPair>? _arguments;
|
||||
|
||||
static string[] _preInitProperties { get; } = {
|
||||
"input-terminal", "terminal", "input-file", "config", "o", "config-dir", "input-conf",
|
||||
"load-scripts", "scripts", "script-opts", "player-operation-mode", "idle", "log-file",
|
||||
"msg-color", "dump-stats", "msg-level", "really-quiet" };
|
||||
|
||||
public static List<StringPair> Arguments
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_arguments != null)
|
||||
return _arguments;
|
||||
|
||||
_arguments = [];
|
||||
|
||||
foreach (string i in Environment.GetCommandLineArgs().Skip(1))
|
||||
{
|
||||
string arg = i;
|
||||
|
||||
if (!arg.StartsWith("--"))
|
||||
continue;
|
||||
|
||||
if (!arg.Contains('='))
|
||||
{
|
||||
if (arg.Contains("--no-"))
|
||||
{
|
||||
arg = arg.Replace("--no-", "--");
|
||||
arg += "=no";
|
||||
}
|
||||
else
|
||||
arg += "=yes";
|
||||
}
|
||||
|
||||
string left = arg[2..arg.IndexOf('=')];
|
||||
string right = arg[(left.Length + 3)..];
|
||||
|
||||
if (string.IsNullOrEmpty(left))
|
||||
continue;
|
||||
|
||||
switch (left)
|
||||
{
|
||||
case "script": left = "scripts"; break;
|
||||
case "script-opt": left = "script-opts"; break;
|
||||
case "audio-file": left = "audio-files"; break;
|
||||
case "sub-file": left = "sub-files"; break;
|
||||
case "external-file": left = "external-files"; break;
|
||||
}
|
||||
|
||||
_arguments.Add(new StringPair(left, right));
|
||||
}
|
||||
|
||||
return _arguments;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ProcessCommandLineArgsPreInit()
|
||||
{
|
||||
foreach (var pair in Arguments)
|
||||
{
|
||||
if (pair.Name.EndsWith("-add") ||
|
||||
pair.Name.EndsWith("-set") ||
|
||||
pair.Name.EndsWith("-pre") ||
|
||||
pair.Name.EndsWith("-clr") ||
|
||||
pair.Name.EndsWith("-append") ||
|
||||
pair.Name.EndsWith("-remove") ||
|
||||
pair.Name.EndsWith("-toggle"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Player.ProcessProperty(pair.Name, pair.Value);
|
||||
|
||||
if (!App.ProcessProperty(pair.Name, pair.Value))
|
||||
Player.SetPropertyString(pair.Name, pair.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ProcessCommandLineArgsPostInit()
|
||||
{
|
||||
foreach (var pair in Arguments)
|
||||
{
|
||||
if (_preInitProperties.Contains(pair.Name))
|
||||
continue;
|
||||
|
||||
if (pair.Name.EndsWith("-add"))
|
||||
Player.CommandV("change-list", pair.Name[..^4], "add", pair.Value);
|
||||
else if (pair.Name.EndsWith("-set"))
|
||||
Player.CommandV("change-list", pair.Name[..^4], "set", pair.Value);
|
||||
else if (pair.Name.EndsWith("-append"))
|
||||
Player.CommandV("change-list", pair.Name[..^7], "append", pair.Value);
|
||||
else if (pair.Name.EndsWith("-pre"))
|
||||
Player.CommandV("change-list", pair.Name[..^4], "pre", pair.Value);
|
||||
else if (pair.Name.EndsWith("-clr"))
|
||||
Player.CommandV("change-list", pair.Name[..^4], "clr", "");
|
||||
else if (pair.Name.EndsWith("-remove"))
|
||||
Player.CommandV("change-list", pair.Name[..^7], "remove", pair.Value);
|
||||
else if (pair.Name.EndsWith("-toggle"))
|
||||
Player.CommandV("change-list", pair.Name[..^7], "toggle", pair.Value);
|
||||
else
|
||||
{
|
||||
Player.ProcessProperty(pair.Name, pair.Value);
|
||||
|
||||
if (!App.ProcessProperty(pair.Name, pair.Value))
|
||||
Player.SetPropertyString(pair.Name, pair.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ProcessCommandLineFiles()
|
||||
{
|
||||
List<string> files = [];
|
||||
|
||||
foreach (string arg in Environment.GetCommandLineArgs().Skip(1))
|
||||
{
|
||||
if (!arg.StartsWith("--") && (arg == "-" || arg.Contains("://") ||
|
||||
arg.Contains(":\\") || arg.StartsWith("\\\\") || arg.StartsWith('.') ||
|
||||
File.Exists(arg)))
|
||||
{
|
||||
files.Add(arg);
|
||||
}
|
||||
}
|
||||
|
||||
Player.LoadFiles([.. files], !App.Queue, App.Queue);
|
||||
|
||||
if (App.CommandLine.Contains("--shuffle"))
|
||||
{
|
||||
Player.Command("playlist-shuffle");
|
||||
Player.SetPropertyInt("playlist-pos", 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Contains(string name)
|
||||
{
|
||||
foreach (StringPair pair in Arguments)
|
||||
{
|
||||
if (pair.Name == name)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string GetValue(string name)
|
||||
{
|
||||
foreach (StringPair pair in Arguments)
|
||||
{
|
||||
if (pair.Name == name)
|
||||
return pair.Value;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ public class ExtensionLoader
|
||||
{
|
||||
public event Action<Exception>? UnhandledException;
|
||||
|
||||
readonly List<object?> _refs = new();
|
||||
readonly List<object?> _refs = [];
|
||||
|
||||
void LoadDll(string path)
|
||||
{
|
||||
@@ -31,8 +31,12 @@ public class ExtensionLoader
|
||||
public void LoadFolder(string path)
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
foreach (string dir in Directory.GetDirectories(path))
|
||||
{
|
||||
LoadDll(dir.AddSep() + Path.GetFileName(dir) + ".dll");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,12 +32,12 @@ public static class PathStringExtension
|
||||
int index = instance.LastIndexOf('\\');
|
||||
|
||||
if (index > -1)
|
||||
return instance.Substring(index + 1);
|
||||
return instance[(index + 1)..];
|
||||
|
||||
index = instance.LastIndexOf('/');
|
||||
|
||||
if (index > -1)
|
||||
return instance.Substring(index + 1);
|
||||
return instance[(index + 1)..];
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -5,16 +5,49 @@ namespace MpvNet;
|
||||
|
||||
public static class FileTypes
|
||||
{
|
||||
public static string[] Video { get; set; } = "mkv mp4 avi mov flv mpg webm wmv ts vob 264 265 asf avc avs dav h264 h265 hevc m2t m2ts m2v m4v mpeg mpv mts vpy y4m".Split(' ');
|
||||
public static string[] Audio { get; set; } = "mp3 flac m4a mka mp2 ogg opus aac ac3 dts dtshd dtshr dtsma eac3 mpa mpc thd w64 wav".Split(' ');
|
||||
public static string[] Image { get; set; } = { "jpg", "bmp", "png", "gif", "webp" };
|
||||
public static string[] Subtitle { get; } = { "srt", "ass", "idx", "sub", "sup", "ttxt", "txt", "ssa", "smi", "mks" };
|
||||
public static string[] Subtitle { get; } = ["srt", "ass", "idx", "sub", "sup", "ttxt", "txt", "ssa", "smi", "mks"];
|
||||
|
||||
public static bool IsImage(string extension) => Image.Contains(extension);
|
||||
public static bool IsAudio(string extension) => Audio.Contains(extension);
|
||||
public static bool IsVideo(string[] exts, string ext) => exts?.Contains(ext) ?? false;
|
||||
public static bool IsAudio(string[] exts, string ext) => exts?.Contains(ext) ?? false;
|
||||
public static bool IsImage(string[] exts, string ext) => exts?.Contains(ext) ?? false;
|
||||
|
||||
public static bool IsMedia(string extension) =>
|
||||
Video.Contains(extension) || Audio.Contains(extension) || Image.Contains(extension);
|
||||
public static bool IsVideo(string ext) => GetVideoExts().Contains(ext);
|
||||
public static bool IsAudio(string ext) => GetAudioExts().Contains(ext);
|
||||
public static bool IsImage(string ext) => GetImgExts().Contains(ext);
|
||||
|
||||
public static IEnumerable<string> GetMediaFiles(IEnumerable<string> files) => files.Where(i => IsMedia(i.Ext()));
|
||||
public static string[] GetVideoExts()
|
||||
{
|
||||
string exts = Player.GetPropertyString("video-exts");
|
||||
|
||||
if (string.IsNullOrEmpty(exts))
|
||||
return ["mkv", "mp4", "avi", "mov", "flv", "mpg", "webm", "wmv", "ts", "vob", "264", "265", "asf", "avc", "avs", "dav", "h264", "h265", "hevc", "m2t", "m2ts", "m2v", "m4v", "mpeg", "mpv", "mts", "vpy", "y4m"];
|
||||
|
||||
return exts.Split(" ,;".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public static string[] GetAudioExts()
|
||||
{
|
||||
string exts = Player.GetPropertyString("audio-exts");
|
||||
|
||||
if (string.IsNullOrEmpty(exts))
|
||||
return ["mp3", "flac", "m4a", "mka", "mp2", "ogg", "opus", "aac", "ac3", "dts", "dtshd", "dtshr", "dtsma", "eac3", "mpa", "mpc", "thd", "w64", "wav"];
|
||||
|
||||
return exts.Split(" ,;".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public static string[] GetImgExts()
|
||||
{
|
||||
string exts = Player.GetPropertyString("image-exts");
|
||||
|
||||
if (string.IsNullOrEmpty(exts))
|
||||
return ["jpg", "bmp", "png", "gif", "webp"];
|
||||
|
||||
return exts.Split(" ,;".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public static bool IsMedia(string[] exts, string ext) =>
|
||||
IsVideo(exts, ext) || IsAudio(exts, ext) || IsImage(exts, ext);
|
||||
|
||||
public static IEnumerable<string> GetMediaFiles(string[] files) =>
|
||||
files.Where(i => IsMedia(files, i.Ext()));
|
||||
}
|
||||
|
||||
@@ -10,4 +10,5 @@ public static class Global
|
||||
public static readonly AppClass App = new AppClass();
|
||||
|
||||
public static string _(string value) => Translator.Current!.Gettext(value);
|
||||
public static string _p(string context, string value) => Translator.Current!.GetParticularString(context, value);
|
||||
}
|
||||
|
||||
@@ -8,9 +8,7 @@ public static class StringHelp
|
||||
{
|
||||
public static string GetMD5Hash(string txt)
|
||||
{
|
||||
using MD5 md5 = MD5.Create();
|
||||
byte[] inputBuffer = Encoding.UTF8.GetBytes(txt);
|
||||
byte[] hashBuffer = md5.ComputeHash(inputBuffer);
|
||||
return BitConverter.ToString(md5.ComputeHash(inputBuffer)).Replace("-", "");
|
||||
return Convert.ToHexString(MD5.HashData(inputBuffer));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
using MpvNet.ExtensionMethod;
|
||||
using MpvNet.Help;
|
||||
|
||||
namespace MpvNet;
|
||||
@@ -15,8 +14,11 @@ public class InputConf
|
||||
public string Path {
|
||||
get => _path ?? "";
|
||||
set {
|
||||
_path = value;
|
||||
Content = File.Exists(_path) ? FileHelp.ReadTextFile(_path) : "";
|
||||
if (_path != value)
|
||||
{
|
||||
_path = value;
|
||||
Content = File.Exists(_path) ? FileHelp.ReadTextFile(_path) : "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,17 +34,25 @@ public class InputConf
|
||||
var defaultBindings = InputHelp.GetDefaults();
|
||||
|
||||
foreach (Binding defaultBinding in defaultBindings)
|
||||
{
|
||||
foreach (Binding confBinding in confbindings)
|
||||
{
|
||||
if (defaultBinding.Input == confBinding.Input &&
|
||||
defaultBinding.Command != confBinding.Command)
|
||||
{
|
||||
defaultBinding.Input = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Binding defaultBinding in defaultBindings)
|
||||
{
|
||||
foreach (Binding confBinding in confbindings)
|
||||
{
|
||||
if (defaultBinding.Command == confBinding.Command)
|
||||
defaultBinding.Input = confBinding.Input;
|
||||
}
|
||||
}
|
||||
|
||||
return (defaultBindings, confbindings);
|
||||
}
|
||||
@@ -50,7 +60,29 @@ public class InputConf
|
||||
public string GetContent()
|
||||
{
|
||||
if (HasMenu)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (App.Settings.MenuUpdateVersion != 1)
|
||||
{
|
||||
string updatedContent = UpdateContent(Content);
|
||||
|
||||
if (updatedContent != Content)
|
||||
{
|
||||
File.Copy(Path, Path + ".backup", true);
|
||||
File.WriteAllText(Path, Content = updatedContent);
|
||||
}
|
||||
|
||||
App.Settings.MenuUpdateVersion = 1;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Terminal.WriteError("Failed to update menu." + BR + ex.Message);
|
||||
}
|
||||
|
||||
return Content;
|
||||
}
|
||||
else
|
||||
{
|
||||
var defaults = InputHelp.GetDefaults();
|
||||
@@ -58,19 +90,30 @@ public class InputConf
|
||||
var conf = InputHelp.Parse(Content);
|
||||
|
||||
foreach (Binding defaultBinding in defaults)
|
||||
{
|
||||
foreach (Binding confBinding in conf)
|
||||
{
|
||||
if (defaultBinding.Command == confBinding.Command &&
|
||||
defaultBinding.Comment == confBinding.Comment)
|
||||
{
|
||||
defaultBinding.Input = confBinding.Input;
|
||||
removed.Add(confBinding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Binding binding in removed)
|
||||
{
|
||||
conf.Remove(binding);
|
||||
}
|
||||
|
||||
defaults.AddRange(conf);
|
||||
return InputHelp.ConvertToString(defaults);
|
||||
}
|
||||
}
|
||||
|
||||
static string UpdateContent(string content) => content
|
||||
.Replace("script-message mpv.net", "script-message-to mpvnet")
|
||||
.Replace("/docs/Manual.md", "/docs/manual.md")
|
||||
.Replace("https://github.com/stax76/mpv.net", "https://github.com/mpvnet-player/mpv.net");
|
||||
}
|
||||
|
||||
@@ -7,216 +7,251 @@ public static class InputHelp
|
||||
{
|
||||
public static List<Binding> GetDefaults()
|
||||
{
|
||||
List<Binding> bindings = new List<Binding>()
|
||||
{
|
||||
new (_("File"), _("Open Files..."), "script-message-to mpvnet open-files", "o"),
|
||||
new (_("File"), _("Open URL or file from clipboard"), "script-message-to mpvnet open-clipboard", "Ctrl+v"),
|
||||
new (_("File"), _("Open DVD/Blu-ray Drive/Folder..."), "script-message-to mpvnet open-optical-media"),
|
||||
new (_("File"), "-"),
|
||||
new (_("File"), _("Add external audio files..."), "script-message-to mpvnet load-audio", "Alt+a"),
|
||||
new (_("File"), _("Add external subtitle files..."), "script-message-to mpvnet load-sub", "Alt+s"),
|
||||
new (_("File"), "-"),
|
||||
new (_("File"), _("Add files to playlist..."), "script-message-to mpvnet open-files append"),
|
||||
new (_("File"), _("Recent Files")),
|
||||
new (_("File"), "-"),
|
||||
new (_("File"), _("Exit"), "quit", "Esc"),
|
||||
List<Binding> b = [];
|
||||
|
||||
new (_("Playback"), _("Play/Pause"), "script-message-to mpvnet play-pause", "Space"),
|
||||
new (_("Playback"), _("Stop"), "stop", "Ctrl+s"),
|
||||
Add(b, new (_("File"), _("Open Files..."), "script-message-to mpvnet open-files", "o"));
|
||||
Add(b, new (_("File"), _("Open URL or file from clipboard"), "script-message-to mpvnet open-clipboard", "Ctrl+v"));
|
||||
Add(b, new (_("File"), _("Open DVD/Blu-ray Drive/Folder..."), "script-message-to mpvnet open-optical-media"));
|
||||
Add(b, new (_("File"), "-"));
|
||||
Add(b, new (_("File"), _("Add external audio files..."), "script-message-to mpvnet load-audio"));
|
||||
Add(b, new (_("File"), _("Add external subtitle files..."), "script-message-to mpvnet load-sub"));
|
||||
Add(b, new (_("File"), "-"));
|
||||
Add(b, new (_("File"), _("Add files to playlist..."), "script-message-to mpvnet open-files append"));
|
||||
Add(b, new (_("File"), _("Add files/URLs to playlist from clipboard"), "script-message-to mpvnet open-clipboard append", "Ctrl+Shift+v"));
|
||||
Add(b, new (_("File"), "-"));
|
||||
Add(b, new (_("File"), _("Recent Files")));
|
||||
Add(b, new (_("File"), _("Exit"), "quit", "Esc"));
|
||||
|
||||
new (_("Navigate"), _("Previous File"), "playlist-prev", "F11"),
|
||||
new (_("Navigate"), _("Next File"), "playlist-next", "F12"),
|
||||
new (_("Navigate"), "-"),
|
||||
new (_("Navigate"), _("First File"), "script-message-to mpvnet playlist-first", "Home"),
|
||||
new (_("Navigate"), _("Last File"), "script-message-to mpvnet playlist-last", "End"),
|
||||
Add(b, new (_("Playback"), _("Play/Pause"), "script-message-to mpvnet play-pause", "Space"));
|
||||
Add(b, new (_("Playback"), _("Stop"), "stop", "Ctrl+s"));
|
||||
|
||||
new (_("Navigate"), "-"),
|
||||
new (_("Navigate"), _("Next Chapter"), "add chapter 1", "PGUP"),
|
||||
new (_("Navigate"), _("Previous Chapter"), "add chapter -1", "PGDWN"),
|
||||
new (_("Navigate"), "-"),
|
||||
new (_("Navigate"), _("Jump To Next Frame"), "frame-step", "."),
|
||||
new (_("Navigate"), _("Jump To Previous Frame"), "frame-back-step", ","),
|
||||
new (_("Navigate"), "-"),
|
||||
new (_("Navigate"), _("Jump 5 sec forward"), "seek 5", "Right"),
|
||||
new (_("Navigate"), _("Jump 5 sec backward"), "seek -5", "Left"),
|
||||
new (_("Navigate"), "-"),
|
||||
new (_("Navigate"), _("Jump 30 sec forward"), "seek 30", "Up"),
|
||||
new (_("Navigate"), _("Jump 30 sec backward"), "seek -30", "Down"),
|
||||
new (_("Navigate"), "-"),
|
||||
new (_("Navigate"), _("Jump 5 min forward"), "seek 300", "Ctrl+Right"),
|
||||
new (_("Navigate"), _("Jump 5 min backward"), "seek -300", "Ctrl+Left"),
|
||||
new (_("Navigate"), "-"),
|
||||
new (_("Navigate"), _("Title")),
|
||||
new (_("Navigate"), _("Chapter")),
|
||||
Add(b, new (_("Navigate"), _("Previous File"), "playlist-prev", "F11"));
|
||||
Add(b, new (_("Navigate"), _("Next File"), "playlist-next", "F12"));
|
||||
Add(b, new (_("Navigate"), "-"));
|
||||
Add(b, new (_("Navigate"), _("First File"), "script-message-to mpvnet playlist-first", "Home"));
|
||||
Add(b, new (_("Navigate"), _("Last File"), "script-message-to mpvnet playlist-last", "End"));
|
||||
|
||||
new (_("Pan & Scan"), _("Decrease Size"), "add video-zoom -0.1", "Ctrl+-"),
|
||||
new (_("Pan & Scan"), _("Increase Size"), "add video-zoom 0.1", "Ctrl++"),
|
||||
new (_("Pan & Scan"), "-"),
|
||||
new (_("Pan & Scan"), _("Move Left"), "add video-pan-x -0.01", "Ctrl+KP4"),
|
||||
new (_("Pan & Scan"), _("Move Right"), "add video-pan-x 0.01", "Ctrl+KP6"),
|
||||
new (_("Pan & Scan"), "-"),
|
||||
new (_("Pan & Scan"), _("Move Up"), "add video-pan-y -0.01", "Ctrl+KP8"),
|
||||
new (_("Pan & Scan"), _("Move Down"), "add video-pan-y 0.01", "Ctrl+KP2"),
|
||||
new (_("Pan & Scan"), "-"),
|
||||
new (_("Pan & Scan"), _("Decrease Height"), "add panscan -0.1", "w"),
|
||||
new (_("Pan & Scan"), _("Increase Height"), "add panscan 0.1", "W"),
|
||||
new (_("Pan & Scan"), "-"),
|
||||
new (_("Pan & Scan"), _("Reset"), "set video-zoom 0; set video-pan-x 0; set video-pan-y 0", "Ctrl+BS"),
|
||||
Add(b, new (_("Navigate"), "-"));
|
||||
Add(b, new (_("Navigate"), _("Next Chapter"), "add chapter 1", "PGUP"));
|
||||
Add(b, new (_("Navigate"), _("Previous Chapter"), "add chapter -1", "PGDWN"));
|
||||
Add(b, new (_("Navigate"), "-"));
|
||||
Add(b, new (_("Navigate"), _("Jump To Next Frame"), "frame-step", "."));
|
||||
Add(b, new (_("Navigate"), _("Jump To Previous Frame"), "frame-back-step", ","));
|
||||
Add(b, new (_("Navigate"), "-"));
|
||||
Add(b, new (_("Navigate"), _("Jump 5 sec forward"), "seek 5", "Right"));
|
||||
Add(b, new (_("Navigate"), _("Jump 5 sec backward"), "seek -5", "Left"));
|
||||
Add(b, new (_("Navigate"), "-"));
|
||||
Add(b, new (_("Navigate"), _("Jump 30 sec forward"), "seek 30", "Up"));
|
||||
Add(b, new (_("Navigate"), _("Jump 30 sec backward"), "seek -30", "Down"));
|
||||
Add(b, new (_("Navigate"), "-"));
|
||||
Add(b, new (_("Navigate"), _("Jump 5 min forward"), "seek 300", "Ctrl+Right"));
|
||||
Add(b, new (_("Navigate"), _("Jump 5 min backward"), "seek -300", "Ctrl+Left"));
|
||||
Add(b, new (_("Navigate"), "-"));
|
||||
Add(b, new (_("Navigate"), _("Title")));
|
||||
Add(b, new (_("Navigate"), _("Chapter")));
|
||||
|
||||
new (_("Video"), _("Decrease Contrast"), "add contrast -1", "Ctrl+1"),
|
||||
new (_("Video"), _("Increase Contrast"), "add contrast 1", "Ctrl+2"),
|
||||
new (_("Video"), "-"),
|
||||
new (_("Video"), _("Decrease Brightness"), "add brightness -1", "Ctrl+3"),
|
||||
new (_("Video"), _("Increase Brightness"), "add brightness 1", "Ctrl+4"),
|
||||
new (_("Video"), "-"),
|
||||
new (_("Video"), _("Decrease Gamma"), "add gamma -1", "Ctrl+5"),
|
||||
new (_("Video"), _("Increase Gamma"), "add gamma 1", "Ctrl+6"),
|
||||
new (_("Video"), "-"),
|
||||
new (_("Video"), _("Decrease Saturation"), "add saturation -1", "Ctrl+7"),
|
||||
new (_("Video"), _("Increase Saturation"), "add saturation 1", "Ctrl+8"),
|
||||
new (_("Video"), "-"),
|
||||
new (_("Video"), _("Take Screenshot"), "async screenshot", "s"),
|
||||
new (_("Video"), _("Take Screenshot without subtitles"), "async screenshot video", "S"),
|
||||
new (_("Video"), _("Toggle Deinterlace"), "cycle deinterlace", "d"),
|
||||
new (_("Video"), _("Change Aspect Ratio"), "cycle-values video-aspect-override 16:9 4:3 2.35:1 -1", "a"),
|
||||
new (_("Video"), _("Rotate Video"), "cycle-values video-rotate 90 180 270 0", "Ctrl+r"),
|
||||
Add(b, new (_("Pan & Scan"), _("Decrease Size"), "add video-zoom -0.1", "Ctrl+-"));
|
||||
Add(b, new (_("Pan & Scan"), _("Increase Size"), "add video-zoom 0.1", "Ctrl++"));
|
||||
Add(b, new (_("Pan & Scan"), "-"));
|
||||
Add(b, new (_("Pan & Scan"), _("Move Left"), "add video-pan-x -0.01", "Ctrl+KP4"));
|
||||
Add(b, new (_("Pan & Scan"), _("Move Right"), "add video-pan-x 0.01", "Ctrl+KP6"));
|
||||
Add(b, new (_("Pan & Scan"), "-"));
|
||||
Add(b, new (_("Pan & Scan"), _("Move Up"), "add video-pan-y -0.01", "Ctrl+KP8"));
|
||||
Add(b, new (_("Pan & Scan"), _("Move Down"), "add video-pan-y 0.01", "Ctrl+KP2"));
|
||||
Add(b, new (_("Pan & Scan"), "-"));
|
||||
Add(b, new (_("Pan & Scan"), _("Decrease Height"), "add panscan -0.1", "w"));
|
||||
Add(b, new (_("Pan & Scan"), _("Increase Height"), "add panscan 0.1", "W"));
|
||||
Add(b, new (_("Pan & Scan"), "-"));
|
||||
Add(b, new (_("Pan & Scan"), _("Reset"), "set video-zoom 0; set video-pan-x 0; set video-pan-y 0", "Ctrl+BS"));
|
||||
|
||||
new (_("Audio"), _("Next Track"), "script-message-to mpvnet cycle-audio", "KP7"),
|
||||
new (_("Audio"), "-"),
|
||||
new (_("Audio"), _("Delay +0.1"), "add audio-delay 0.1", "Ctrl+d"),
|
||||
new (_("Audio"), _("Delay -0.1"), "add audio-delay -0.1", "Ctrl+D"),
|
||||
Add(b, new (_("Video"), _("Decrease Contrast"), "add contrast -1", "Ctrl+1"));
|
||||
Add(b, new (_("Video"), _("Increase Contrast"), "add contrast 1", "Ctrl+2"));
|
||||
Add(b, new (_("Video"), "-"));
|
||||
Add(b, new (_("Video"), _("Decrease Brightness"), "add brightness -1", "Ctrl+3"));
|
||||
Add(b, new (_("Video"), _("Increase Brightness"), "add brightness 1", "Ctrl+4"));
|
||||
Add(b, new (_("Video"), "-"));
|
||||
Add(b, new (_("Video"), _("Decrease Gamma"), "add gamma -1", "Ctrl+5"));
|
||||
Add(b, new (_("Video"), _("Increase Gamma"), "add gamma 1", "Ctrl+6"));
|
||||
Add(b, new (_("Video"), "-"));
|
||||
Add(b, new (_("Video"), _("Decrease Saturation"), "add saturation -1", "Ctrl+7"));
|
||||
Add(b, new (_("Video"), _("Increase Saturation"), "add saturation 1", "Ctrl+8"));
|
||||
Add(b, new (_("Video"), "-"));
|
||||
Add(b, new (_("Video"), _("Take Screenshot"), "async screenshot", "s"));
|
||||
Add(b, new (_("Video"), _("Take Screenshot without subtitles"), "async screenshot video", "S"));
|
||||
Add(b, new (_("Video"), _("Toggle Deinterlace"), "cycle deinterlace", "d"));
|
||||
Add(b, new (_("Video"), _("Change Aspect Ratio"), "cycle-values video-aspect-override 16:9 4:3 2.35:1 0 -1", "a"));
|
||||
Add(b, new (_("Video"), _("Rotate Video"), "cycle-values video-rotate 90 180 270 0", "Ctrl+r"));
|
||||
|
||||
new (_("Subtitle"), _("Next Track"), "script-message-to mpvnet cycle-subtitles", "KP8"),
|
||||
new (_("Subtitle"), _("Toggle Visibility"), "cycle sub-visibility", "v"),
|
||||
new (_("Subtitle"), "-"),
|
||||
new (_("Subtitle"), _("Delay -0.1"), "add sub-delay -0.1", "z"),
|
||||
new (_("Subtitle"), _("Delay +0.1"), "add sub-delay 0.1", "Z"),
|
||||
new (_("Subtitle"), "-"),
|
||||
new (_("Subtitle"), _("Move Up"), "add sub-pos -1", "r"),
|
||||
new (_("Subtitle"), _("Move Down"), "add sub-pos 1", "R"),
|
||||
new (_("Subtitle"), "-"),
|
||||
new (_("Subtitle"), _("Decrease Font Size"), "add sub-scale -0.1", "F"),
|
||||
new (_("Subtitle"), _("Increase Font Size"), "add sub-scale 0.1", "G"),
|
||||
new (_("Subtitle"), "-"),
|
||||
new (_("Subtitle") + " > " + _("More"), _("Toggle overriding SSA/ASS styles with normal styles"), "cycle-values sub-ass-override force no", "u"),
|
||||
Add(b, new (_("Audio"), _("Audio Device")));
|
||||
Add(b, new (_("Audio"), _("Next Track"), "script-message-to mpvnet cycle-audio", "KP7"));
|
||||
Add(b, new (_("Audio"), "-"));
|
||||
Add(b, new (_("Audio"), _("Delay +0.1"), "add audio-delay 0.1", "Ctrl+d"));
|
||||
Add(b, new (_("Audio"), _("Delay -0.1"), "add audio-delay -0.1", "Ctrl+D"));
|
||||
|
||||
new ("", _("Track")),
|
||||
Add(b, new (_("Subtitle"), _("Next Track"), "script-message-to mpvnet cycle-subtitles", "KP8"));
|
||||
Add(b, new (_("Subtitle"), _("Toggle Visibility"), "cycle sub-visibility", "v"));
|
||||
Add(b, new (_("Subtitle"), "-"));
|
||||
Add(b, new (_("Subtitle"), _("Delay -0.1"), "add sub-delay -0.1", "z"));
|
||||
Add(b, new (_("Subtitle"), _("Delay +0.1"), "add sub-delay 0.1", "Z"));
|
||||
Add(b, new (_("Subtitle"), "-"));
|
||||
Add(b, new (_("Subtitle"), _("Move Up"), "add sub-pos -1", "r"));
|
||||
Add(b, new (_("Subtitle"), _("Move Down"), "add sub-pos 1", "R"));
|
||||
Add(b, new (_("Subtitle"), "-"));
|
||||
Add(b, new (_("Subtitle"), _("Decrease Font Size"), "add sub-scale -0.1", "F"));
|
||||
Add(b, new (_("Subtitle"), _("Increase Font Size"), "add sub-scale 0.1", "G"));
|
||||
Add(b, new (_("Subtitle"), "-"));
|
||||
Add(b, new (_("Subtitle") + " > " + _("More"), _("Toggle overriding SSA/ASS styles with normal styles"), "cycle-values sub-ass-override force no", "u"));
|
||||
|
||||
new (_("Volume"), _("Up"), "add volume 2", "+"),
|
||||
new (_("Volume"), _("Down"), "add volume -2", "-"),
|
||||
new (_("Volume"), "-"),
|
||||
new (_("Volume"), _("Mute"), "cycle mute", "m"),
|
||||
Add(b, new ("", _("Track")));
|
||||
|
||||
new (_("Speed"), _("-10%"), "multiply speed 1/1.1", "["),
|
||||
new (_("Speed"), _("+10%"), "multiply speed 1.1", "]"),
|
||||
new (_("Speed"), "-"),
|
||||
new (_("Speed"), _("Half"), "multiply speed 0.5", "{"),
|
||||
new (_("Speed"), _("Double"), "multiply speed 2.0", "}"),
|
||||
new (_("Speed"), "-"),
|
||||
new (_("Speed"), _("Reset"), "set speed 1", "BS"),
|
||||
Add(b, new (_("Volume"), _p("Volume", "Up"), "add volume 2", "+"));
|
||||
Add(b, new (_("Volume"), _p("Volume", "Down"), "add volume -2", "-"));
|
||||
Add(b, new (_("Volume"), "-"));
|
||||
Add(b, new (_("Volume"), _("Mute"), "cycle mute", "m"));
|
||||
|
||||
new (_("View"), _("Show Playlist"), "script-message-to mpvnet show-playlist", "F8"),
|
||||
new (_("View"), _("Show Profiles"), "script-message-to mpvnet show-profiles", "Ctrl+P"),
|
||||
new (_("View"), _("Toggle Statistics"), "script-binding stats/display-stats-toggle", "t"),
|
||||
new (_("View"), _("Toggle OSC Visibility"), "script-binding osc/visibility", "Del"),
|
||||
new (_("View"), _("Show Media Info On-Screen"), "script-message-to mpvnet show-media-info osd", "i"),
|
||||
new (_("View"), _("Show Media Info Message Box"), "script-message-to mpvnet show-media-info msgbox", "Ctrl+m"),
|
||||
new (_("View"), _("Show Progress"), "show-progress", "p"),
|
||||
new (_("View") + " > " + _("More"), _("Show Console"), "script-binding console/enable", "`"),
|
||||
new (_("View") + " > " + _("More"), _("Show Audio Devices"), "script-message-to mpvnet show-audio-devices"),
|
||||
new (_("View") + " > " + _("More"), _("Show Commands"), "script-message-to mpvnet show-commands", "F2"),
|
||||
new (_("View") + " > " + _("More"), _("Show Demuxers"), "script-message-to mpvnet show-demuxers"),
|
||||
new (_("View") + " > " + _("More"), _("Show Decoders"), "script-message-to mpvnet show-decoders"),
|
||||
new (_("View") + " > " + _("More"), _("Show Bindings"), "script-message-to mpvnet show-bindings"),
|
||||
Add(b, new (_("Speed"), _("-10%"), "multiply speed 1/1.1", "["));
|
||||
Add(b, new (_("Speed"), _("+10%"), "multiply speed 1.1", "]"));
|
||||
Add(b, new (_("Speed"), "-"));
|
||||
Add(b, new (_("Speed"), _("Half"), "multiply speed 0.5", "{"));
|
||||
Add(b, new (_("Speed"), _("Double"), "multiply speed 2.0", "}"));
|
||||
Add(b, new (_("Speed"), "-"));
|
||||
Add(b, new (_("Speed"), _("Reset"), "set speed 1", "BS"));
|
||||
|
||||
new (_("Window"), _("Fullscreen"), "cycle fullscreen", "Enter"),
|
||||
new (_("Window") + " > " + _("Zoom"), _("Enlarge"), "script-message-to mpvnet scale-window 1.2", "Alt++"),
|
||||
new (_("Window") + " > " + _("Zoom"), _("Shrink"), "script-message-to mpvnet scale-window 0.8", "Alt+-"),
|
||||
new (_("Window") + " > " + _("Zoom"), "-"),
|
||||
new (_("Window") + " > " + _("Zoom"), _("50 %"), "script-message-to mpvnet window-scale 0.5", "Alt+0"),
|
||||
new (_("Window") + " > " + _("Zoom"), _("100 %"), "script-message-to mpvnet window-scale 1.0", "Alt+1"),
|
||||
new (_("Window") + " > " + _("Zoom"), _("200 %"), "script-message-to mpvnet window-scale 2.0", "Alt+2"),
|
||||
new (_("Window") + " > " + _("Zoom"), _("300 %"), "script-message-to mpvnet window-scale 3.0", "Alt+3"),
|
||||
new (_("Window") + " > " + _("Move"), _("Left"), "script-message-to mpvnet move-window left", "Alt+Left"),
|
||||
new (_("Window") + " > " + _("Move"), _("Right"), "script-message-to mpvnet move-window right", "Alt+Right"),
|
||||
new (_("Window") + " > " + _("Move"), _("Up"), "script-message-to mpvnet move-window top", "Alt+Up"),
|
||||
new (_("Window") + " > " + _("Move"), _("Down"), "script-message-to mpvnet move-window bottom", "Alt+Down"),
|
||||
new (_("Window") + " > " + _("Move"), _("Center"), "script-message-to mpvnet move-window center", "Alt+BS"),
|
||||
new (_("Window"), _("Toggle Border"), "cycle border", "b"),
|
||||
new (_("Window"), _("Toggle On Top"), "cycle ontop", "Ctrl+t"),
|
||||
Add(b, new (_("View"), _("Playlist"), "script-binding select/select-playlist", "F8"));
|
||||
Add(b, new (_("View"), _("Toggle Statistics"), "script-binding stats/display-stats-toggle", "t"));
|
||||
Add(b, new (_("View"), _("Toggle OSC Visibility"), "script-binding osc/visibility", "Del"));
|
||||
Add(b, new (_("View"), _("Media Info On-Screen"), "script-message-to mpvnet show-media-info osd", "i"));
|
||||
Add(b, new (_("View"), _("Media Info Message Box"), "script-message-to mpvnet show-media-info msgbox", "Ctrl+m"));
|
||||
Add(b, new (_("View"), _("Progress"), "show-progress", "p"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("On-Screen Menu"), "script-binding select/menu", "F1"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("Playlist"), "script-binding select/select-playlist", "F8"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("Bindings"), "script-binding select/select-binding", "F2"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("Properties"), "script-binding select/show-properties", "F3"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("Chapters"), "script-binding select/select-chapter", "Alt+c"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("Tracks"), "script-binding select/select-track", "F9"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("Audio Tracks"), "script-binding select/select-aid", "Alt+a"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("Subtitle Tracks"), "script-binding select/select-sid", "Alt+s"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("Secondary Subtitle"), "script-binding select/select-secondary-sid", "Alt+b"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("Video Tracks"), "script-binding select/select-vid", "Alt+v"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("Editions"), "script-binding select/select-edition", "Alt+e"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("Subtitle Lines"), "script-binding select/select-subtitle-line", "Alt+l"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("Audio Devices"), "script-binding select/select-audio-device", "Alt+d"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("Watch History"), "script-binding select/select-watch-history", "Alt+h"));
|
||||
Add(b, new (_("View") + " > " + _("On-Screen Menu"), _("Watch Later"), "script-binding select/select-watch-later"));
|
||||
Add(b, new (_("View"), "-"));
|
||||
Add(b, new (_("View") + " > " + _("More"), _("Console"), "script-binding console/enable", "`"));
|
||||
Add(b, new (_("View") + " > " + _("More"), _("Commands"), "script-message-to mpvnet show-commands", "F4"));
|
||||
Add(b, new (_("View") + " > " + _("More"), _("Active Bindings In Text Editor"), "script-message-to mpvnet show-bindings"));
|
||||
Add(b, new (_("View") + " > " + _("More"), _("Active Bindings On-Screen"), "script-binding stats/display-page-4-toggle", "?"));
|
||||
Add(b, new (_("View") + " > " + _("More"), _("Keys"), "script-message-to mpvnet show-keys", "Alt+k"));
|
||||
Add(b, new (_("View") + " > " + _("More"), _("Protocols"), "script-message-to mpvnet show-protocols", "Alt+p"));
|
||||
Add(b, new (_("View") + " > " + _("More"), _("Decoders"), "script-message-to mpvnet show-decoders"));
|
||||
Add(b, new (_("View") + " > " + _("More"), _("Demuxers"), "script-message-to mpvnet show-demuxers"));
|
||||
|
||||
new ("", _("Profile")),
|
||||
|
||||
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"),
|
||||
new (_("Settings") + " > " + _("Setup"), _("Register image file associations"), "script-message-to mpvnet reg-file-assoc image"),
|
||||
new (_("Settings") + " > " + _("Setup"), _("Unregister file associations"), "script-message-to mpvnet reg-file-assoc unreg"),
|
||||
new (_("Settings") + " > " + _("Setup"), _("Add mpv.net to Path environment variable"), "script-message-to mpvnet add-to-path"),
|
||||
|
||||
new (_("Tools"), _("Set/clear A-B loop points"), "ab-loop", "l"),
|
||||
new (_("Tools"), _("Toggle infinite file looping"), "cycle-values loop-file inf no", "L"),
|
||||
new (_("Tools"), _("Shuffle Playlist"), "playlist-shuffle"),
|
||||
new (_("Tools"), _("Toggle Hardware Decoding"), "cycle-values hwdec auto no", "Ctrl+h"),
|
||||
new (_("Tools"), _("Exit Watch Later"), "quit-watch-later", "Q"),
|
||||
|
||||
new ("", _("Custom")),
|
||||
Add(b, new (_("Window"), _("Fullscreen"), "cycle fullscreen", "Enter"));
|
||||
Add(b, new (_("Window") + " > " + _("Zoom"), _("Enlarge"), "script-message-to mpvnet scale-window 1.2", "Alt++"));
|
||||
Add(b, new (_("Window") + " > " + _("Zoom"), _("Shrink"), "script-message-to mpvnet scale-window 0.8", "Alt+-"));
|
||||
Add(b, new (_("Window") + " > " + _("Zoom"), "-"));
|
||||
Add(b, new (_("Window") + " > " + _("Zoom"), _("50 %"), "script-message-to mpvnet window-scale 0.5", "Alt+0"));
|
||||
Add(b, new (_("Window") + " > " + _("Zoom"), _("100 %"), "script-message-to mpvnet window-scale 1.0", "Alt+1"));
|
||||
Add(b, new (_("Window") + " > " + _("Zoom"), _("200 %"), "script-message-to mpvnet window-scale 2.0", "Alt+2"));
|
||||
Add(b, new (_("Window") + " > " + _("Zoom"), _("300 %"), "script-message-to mpvnet window-scale 3.0", "Alt+3"));
|
||||
Add(b, new (_("Window") + " > " + _("Move"), _p("Move", "Left"), "script-message-to mpvnet move-window left", "Alt+Left"));
|
||||
Add(b, new (_("Window") + " > " + _("Move"), _p("Move", "Right"), "script-message-to mpvnet move-window right", "Alt+Right"));
|
||||
Add(b, new (_("Window") + " > " + _("Move"), _p("Move", "Up"), "script-message-to mpvnet move-window top", "Alt+Up"));
|
||||
Add(b, new (_("Window") + " > " + _("Move"), _p("Move", "Down"), "script-message-to mpvnet move-window bottom", "Alt+Down"));
|
||||
Add(b, new (_("Window") + " > " + _("Move"), _p("Move", "Center"), "script-message-to mpvnet move-window center", "Alt+BS"));
|
||||
Add(b, new (_("Window"), _("Toggle Border"), "cycle border", "b"));
|
||||
Add(b, new (_("Window"), _("Toggle On Top"), "cycle ontop", "Ctrl+t"));
|
||||
|
||||
new (_("Help"), _("Website mpv"), "script-message-to mpvnet shell-execute https://mpv.io", "Ctrl+Home"),
|
||||
new (_("Help"), _("Website mpv.net"), "script-message-to mpvnet shell-execute https://github.com/mpvnet-player/mpv.net"),
|
||||
new (_("Help"), "-"),
|
||||
new (_("Help"), _("Manual mpv"), "script-message-to mpvnet shell-execute https://mpv.io/manual/stable", "Ctrl+F1"),
|
||||
new (_("Help"), _("Manual mpv.net"), "script-message-to mpvnet shell-execute https://github.com/mpvnet-player/mpv.net/blob/main/docs/manual.md", "Ctrl+F2"),
|
||||
new (_("Help"), "-"),
|
||||
new (_("Help"), _("awesome-mpv"), "script-message-to mpvnet shell-execute https://github.com/stax76/awesome-mpv", "Ctrl+a"),
|
||||
new (_("Help"), _("About mpv.net"), "script-message-to mpvnet show-about"),
|
||||
Add(b, new ("", _("Profile")));
|
||||
|
||||
new ("", "", "quit", "q", _("Exit")),
|
||||
new ("", "", "script-message-to mpvnet show-menu", "MBTN_Right", _("Show Menu")),
|
||||
new ("", "", "script-message-to mpvnet play-pause", "Play", _("Play/Pause")),
|
||||
new ("", "", "script-message-to mpvnet play-pause", "Pause", _("Play/Pause")),
|
||||
new ("", "", "script-message-to mpvnet play-pause", "PlayPause", _("Play/Pause")),
|
||||
new ("", "", "script-message-to mpvnet play-pause", "MBTN_Mid", _("Play/Pause")),
|
||||
new ("", "", "stop", "Stop", _("Stop")),
|
||||
new ("", "", "seek 60", "Forward", _("Forward")),
|
||||
new ("", "", "seek -60", "Rewind", _("Backward")),
|
||||
new ("", "", "add volume 2", "Wheel_Up", _("Volume Up")),
|
||||
new ("", "", "add volume -2", "Wheel_Down", _("Volume Down")),
|
||||
new ("", "", "add volume 2", "Wheel_Right", _("Volume Up")),
|
||||
new ("", "", "add volume -2", "Wheel_Left", _("Volume Down")),
|
||||
new ("", "", "playlist-prev", "Prev", _("Previous File")),
|
||||
new ("", "", "playlist-next", "Next", _("Next File")),
|
||||
new ("", "", "playlist-prev", "MBTN_Back", _("Previous File")),
|
||||
new ("", "", "playlist-next", "MBTN_Forward", _("Next File")),
|
||||
new ("", "", "playlist-prev", "<", _("Previous File")),
|
||||
new ("", "", "playlist-next", ">", _("Next File")),
|
||||
new ("", "", "ignore", "MBTN_Left", _("Ignore left mouse butten")),
|
||||
new ("", "", "cycle fullscreen", "f", _("Fullscreen")),
|
||||
new ("", "", "cycle fullscreen", "MBTN_Left_DBL", _("Fullscreen")),
|
||||
new ("", "", "no-osd seek 1 exact", "Shift+Right", _("Seek Forward")),
|
||||
new ("", "", "no-osd seek -1 exact", "Shift+Left", _("Seek Backward")),
|
||||
new ("", "", "no-osd seek 5 exact", "Shift+Up", _("Seek Forward")),
|
||||
new ("", "", "no-osd seek -5 exact", "Shift+Down", _("Seek Backward")),
|
||||
new ("", "", "revert-seek", "Shift+BS", _("Undo previous (or marked) seek")),
|
||||
new ("", "", "revert-seek mark", "Shift+Ctrl+BS", _("Mark position for revert-seek")),
|
||||
new ("", "", "no-osd sub-seek -1", "Ctrl+Shift+Left", _("Seek to previous subtitle")),
|
||||
new ("", "", "no-osd sub-seek 1", "Ctrl+Shift+Right", _("Seek to next subtitle")),
|
||||
new ("", "", "no-osd seek 5", "Ctrl+Wheel_Up", _("Seek Forward")),
|
||||
new ("", "", "no-osd seek -5", "Ctrl+Wheel_Down", _("Seek Backward")),
|
||||
new ("", "", "quit 4", "Esc", _("Quit encoding")),
|
||||
new ("", "", "quit 4", "q", _("Quit encoding")),
|
||||
new ("", "", "quit", "Power", _("Exit")),
|
||||
Add(b, new (_("Config"), _("Show Config Editor"), "script-message-to mpvnet show-conf-editor", "Ctrl+,"));
|
||||
Add(b, new (_("Config"), _("Show Input Editor"), "script-message-to mpvnet show-input-editor", "Ctrl+i"));
|
||||
Add(b, new (_("Config"), "-"));
|
||||
Add(b, new (_("Config"), _("Edit mpv.conf"), "script-message-to mpvnet edit-conf-file mpv.conf", "c"));
|
||||
Add(b, new (_("Config"), _("Edit input.conf"), "script-message-to mpvnet edit-conf-file input.conf", "k"));
|
||||
Add(b, new (_("Config"), "-"));
|
||||
Add(b, new (_("Config"), _("Open Config Folder"), "script-message-to mpvnet open-conf-folder", "Ctrl+f"));
|
||||
Add(b, new (_("Config") + " > " + _("Setup"), _("Register video file associations"), "script-message-to mpvnet reg-file-assoc video"));
|
||||
Add(b, new (_("Config") + " > " + _("Setup"), _("Register audio file associations"), "script-message-to mpvnet reg-file-assoc audio"));
|
||||
Add(b, new (_("Config") + " > " + _("Setup"), _("Register image file associations"), "script-message-to mpvnet reg-file-assoc image"));
|
||||
Add(b, new (_("Config") + " > " + _("Setup"), _("Unregister file associations"), "script-message-to mpvnet reg-file-assoc unreg"));
|
||||
Add(b, new (_("Config") + " > " + _("Setup"), "-"));
|
||||
Add(b, new (_("Config") + " > " + _("Setup"), _("Add mpv.net to Path environment variable"), "script-message-to mpvnet add-to-path"));
|
||||
Add(b, new (_("Config") + " > " + _("Setup"), _("Remove mpv.net from Path environment variable"), "script-message-to mpvnet remove-from-path"));
|
||||
|
||||
//new (_("Command Palette"), _("Commands"), "script-message-to mpvnet show-command-palette", "F1"),
|
||||
};
|
||||
Add(b, new (_("Tools"), _("Set/clear A-B loop points"), "ab-loop", "l"));
|
||||
Add(b, new (_("Tools"), _("Toggle infinite file looping"), "cycle-values loop-file inf no", "L"));
|
||||
Add(b, new (_("Tools"), _("Shuffle Playlist"), "playlist-shuffle"));
|
||||
Add(b, new (_("Tools"), _("Toggle Hardware Decoding"), "cycle-values hwdec auto no", "Ctrl+h"));
|
||||
Add(b, new (_("Tools"), _("Exit Watch Later"), "quit-watch-later", "Q"));
|
||||
|
||||
return bindings;
|
||||
Add(b, new ("", _("Custom")));
|
||||
|
||||
Add(b, new (_("Help"), _("Website mpv"), "script-message-to mpvnet shell-execute https://mpv.io", "Ctrl+Home"));
|
||||
Add(b, new (_("Help"), _("Website mpv.net"), "script-message-to mpvnet shell-execute https://github.com/mpvnet-player/mpv.net"));
|
||||
Add(b, new (_("Help"), "-"));
|
||||
Add(b, new (_("Help"), _("Manual mpv"), "script-message-to mpvnet shell-execute https://mpv.io/manual/stable", "Ctrl+F1"));
|
||||
Add(b, new (_("Help"), _("Manual mpv.net"), "script-message-to mpvnet shell-execute https://github.com/mpvnet-player/mpv.net/blob/main/docs/manual.md", "Ctrl+F2"));
|
||||
Add(b, new (_("Help"), "-"));
|
||||
Add(b, new (_("Help"), _("awesome-mpv"), "script-message-to mpvnet shell-execute https://github.com/stax76/awesome-mpv", "Ctrl+a"));
|
||||
Add(b, new (_("Help"), _("About mpv.net"), "script-message-to mpvnet show-about"));
|
||||
|
||||
Add(b, new ("", "", "quit", "q", _("Exit")));
|
||||
Add(b, new ("", "", "script-message-to mpvnet show-menu", "MBTN_Right", _("Show Menu")));
|
||||
Add(b, new("", "", "script-message-to mpvnet play-pause", "Play", _("Play/Pause")));
|
||||
Add(b, new("", "", "script-message-to mpvnet play-pause", "Pause", _("Play/Pause")));
|
||||
Add(b, new("", "", "script-message-to mpvnet play-pause", "PlayPause", _("Play/Pause")));
|
||||
Add(b, new("", "", "script-message-to mpvnet play-pause", "MBTN_Mid", _("Play/Pause")));
|
||||
Add(b, new ("", "", "stop", "Stop", _("Stop")));
|
||||
Add(b, new ("", "", "seek 60", "Forward", _("Forward")));
|
||||
Add(b, new ("", "", "seek -60", "Rewind", _("Backward")));
|
||||
Add(b, new ("", "", "add volume 2", "Wheel_Up", _("Volume Up")));
|
||||
Add(b, new ("", "", "add volume -2", "Wheel_Down", _("Volume Down")));
|
||||
Add(b, new ("", "", "add volume 2", "Wheel_Right", _("Volume Up")));
|
||||
Add(b, new ("", "", "add volume -2", "Wheel_Left", _("Volume Down")));
|
||||
Add(b, new ("", "", "playlist-prev", "Prev", _("Previous File")));
|
||||
Add(b, new ("", "", "playlist-next", "Next", _("Next File")));
|
||||
Add(b, new ("", "", "playlist-prev", "MBTN_Back", _("Previous File")));
|
||||
Add(b, new ("", "", "playlist-next", "MBTN_Forward", _("Next File")));
|
||||
Add(b, new ("", "", "playlist-prev", "<", _("Previous File")));
|
||||
Add(b, new ("", "", "playlist-next", ">", _("Next File")));
|
||||
Add(b, new ("", "", "ignore", "MBTN_Left", _("Ignore left mouse butten")));
|
||||
Add(b, new ("", "", "cycle fullscreen", "f", _("Fullscreen")));
|
||||
Add(b, new ("", "", "cycle fullscreen", "MBTN_Left_DBL", _("Fullscreen")));
|
||||
Add(b, new ("", "", "no-osd seek 1 exact", "Shift+Right", _("Seek Forward")));
|
||||
Add(b, new ("", "", "no-osd seek -1 exact", "Shift+Left", _("Seek Backward")));
|
||||
Add(b, new ("", "", "no-osd seek 5 exact", "Shift+Up", _("Seek Forward")));
|
||||
Add(b, new ("", "", "no-osd seek -5 exact", "Shift+Down", _("Seek Backward")));
|
||||
Add(b, new ("", "", "revert-seek", "Shift+BS", _("Undo previous (or marked) seek")));
|
||||
Add(b, new ("", "", "revert-seek mark", "Shift+Ctrl+BS", _("Mark position for revert-seek")));
|
||||
Add(b, new ("", "", "no-osd sub-seek -1", "Ctrl+Shift+Left", _("Seek to previous subtitle")));
|
||||
Add(b, new ("", "", "no-osd sub-seek 1", "Ctrl+Shift+Right", _("Seek to next subtitle")));
|
||||
Add(b, new ("", "", "no-osd seek 5", "Ctrl+Wheel_Up", _("Seek Forward")));
|
||||
Add(b, new ("", "", "no-osd seek -5", "Ctrl+Wheel_Down", _("Seek Backward")));
|
||||
Add(b, new ("", "", "quit", "Power", _("Exit")));
|
||||
Add(b, new ("", "", "script-binding select/select-playlist", "g-p", _("Playlist")));
|
||||
Add(b, new ("", "", "script-binding select/select-sid", "g-s", _("Subtitles")));
|
||||
Add(b, new ("", "", "script-binding select/select-secondary-sid", "g-S", _("Secondary Subtitles")));
|
||||
Add(b, new ("", "", "script-binding select/select-aid", "g-a", _("Audio Tracks")));
|
||||
Add(b, new ("", "", "script-binding select/select-vid", "g-v", _("Video Tracks")));
|
||||
Add(b, new ("", "", "script-binding select/select-track", "g-t", _("Tracks")));
|
||||
Add(b, new ("", "", "script-binding select/select-chapter", "g-c", _("Chapters")));
|
||||
Add(b, new ("", "", "script-binding select/select-edition", "g-e", _("Editions")));
|
||||
Add(b, new ("", "", "script-binding select/select-subtitle-line", "g-l", _("Subtitle Lines")));
|
||||
Add(b, new ("", "", "script-binding select/select-audio-device", "g-d", _("Audio Devices")));
|
||||
Add(b, new ("", "", "script-binding select/select-watch-history", "g-h", _("Watch History")));
|
||||
Add(b, new ("", "", "script-binding select/select-watch-later", "g-w", _("Watch Later")));
|
||||
Add(b, new ("", "", "script-binding select/select-binding", "g-b", _("Bindings")));
|
||||
Add(b, new ("", "", "script-binding select/show-properties", "g-r", _("Properties")));
|
||||
Add(b, new ("", "", "script-binding select/menu", "g-m", _("On-Screen Menu")));
|
||||
Add(b, new ("", "", "script-binding select/menu", "MENU", _("On-Screen Menu")));
|
||||
Add(b, new ("", "", "script-binding select/menu", "Ctrl+p", _("On-Screen Menu")));
|
||||
|
||||
return b;
|
||||
|
||||
static void Add(List<Binding> bindings, Binding b) => bindings.Add(b);
|
||||
}
|
||||
|
||||
public static string ConvertToString(List<Binding> bindings)
|
||||
@@ -286,6 +321,9 @@ public static class InputHelp
|
||||
if (string.IsNullOrEmpty(content))
|
||||
return bindings;
|
||||
|
||||
if (content.Contains('\t'))
|
||||
content = content.Replace('\t', ' ');
|
||||
|
||||
foreach (string it in content.Split('\n'))
|
||||
{
|
||||
string line = it.Trim();
|
||||
@@ -325,7 +363,7 @@ public static class InputHelp
|
||||
if (binding.Input.Contains("alt+"))
|
||||
binding.Input = binding.Input.Replace("alt+", "Alt+");
|
||||
|
||||
line = line[(line.IndexOf(" ") + 1)..];
|
||||
line = line[(line.IndexOf(' ') + 1)..];
|
||||
|
||||
if (line.Contains(App.MenuSyntax))
|
||||
{
|
||||
@@ -341,8 +379,8 @@ public static class InputHelp
|
||||
}
|
||||
else if (line.Contains('#'))
|
||||
{
|
||||
binding.Comment = line[(line.IndexOf("#") + 1)..].Trim();
|
||||
line = line[..line.IndexOf("#")];
|
||||
binding.Comment = line[(line.IndexOf('#') + 1)..].Trim();
|
||||
line = line[..line.IndexOf('#')];
|
||||
}
|
||||
|
||||
binding.Command = line.Trim();
|
||||
@@ -406,57 +444,9 @@ public static class InputHelp
|
||||
return defaults;
|
||||
}
|
||||
|
||||
// only used by dead command palette
|
||||
public static List<Binding> GetBindingsFromContent(string content)
|
||||
{
|
||||
var bindings = new List<Binding>();
|
||||
|
||||
if (!string.IsNullOrEmpty(content))
|
||||
{
|
||||
foreach (string line in content.Split('\r', '\n'))
|
||||
{
|
||||
string value = line.Trim();
|
||||
|
||||
if (value.StartsWith("#"))
|
||||
continue;
|
||||
|
||||
if (!value.Contains(' '))
|
||||
continue;
|
||||
|
||||
Binding binding = new Binding();
|
||||
binding.Input = value[..value.IndexOf(" ")];
|
||||
|
||||
if (binding.Input == "_")
|
||||
binding.Input = "";
|
||||
|
||||
value = value[(value.IndexOf(" ") + 1)..];
|
||||
|
||||
if (value.Contains(App.MenuSyntax))
|
||||
{
|
||||
binding.Comment = value[(value.IndexOf(App.MenuSyntax) + App.MenuSyntax.Length)..].Trim();
|
||||
value = value[..value.IndexOf(App.MenuSyntax)];
|
||||
|
||||
if (binding.Comment.Contains(';'))
|
||||
binding.Comment = binding.Comment[(binding.Comment.IndexOf(";") + 1)..].Trim();
|
||||
}
|
||||
|
||||
binding.Command = value.Trim();
|
||||
|
||||
if (binding.Command == "")
|
||||
continue;
|
||||
|
||||
if (binding.Command.ToLower() == "ignore")
|
||||
binding.Command = "";
|
||||
|
||||
bindings.Add(binding);
|
||||
}
|
||||
}
|
||||
return bindings;
|
||||
}
|
||||
|
||||
public static Dictionary<string, Binding> GetActiveBindings(List<Binding> bindings)
|
||||
{
|
||||
Dictionary<string, Binding> ret = new();
|
||||
Dictionary<string, Binding> ret = [];
|
||||
|
||||
foreach (Binding binding in bindings)
|
||||
{
|
||||
@@ -481,7 +471,7 @@ public static class InputHelp
|
||||
|
||||
Binding binding = it.Value;
|
||||
|
||||
if (!keys.Contains(binding.Input) && (charCount + binding.Input.Length) < 20 && keys.Count < 2)
|
||||
if (!keys.Contains(binding.Input) && (charCount + binding.Input.Length) < 30)
|
||||
{
|
||||
keys.Add(binding.Input);
|
||||
charCount += binding.Input.Length;
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
|
||||
namespace MpvNet.MVVM;
|
||||
|
||||
public class MainWindowIsLoadedMessage { }
|
||||
|
||||
//public class ScaleWindowMessage : ValueChangedMessage<float>
|
||||
//{
|
||||
// public ScaleWindowMessage(float value) : base(value)
|
||||
// {
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -21,11 +21,11 @@ public class MpvClient
|
||||
public event Action? Seek; // seek MPV_EVENT_SEEK
|
||||
public event Action? PlaybackRestart; // playback-restart MPV_EVENT_PLAYBACK_RESTART
|
||||
|
||||
public Dictionary<string, List<Action>> PropChangeActions { get; set; } = new Dictionary<string, List<Action>>();
|
||||
public Dictionary<string, List<Action<int>>> IntPropChangeActions { get; set; } = new Dictionary<string, List<Action<int>>>();
|
||||
public Dictionary<string, List<Action<bool>>> BoolPropChangeActions { get; set; } = new Dictionary<string, List<Action<bool>>>();
|
||||
public Dictionary<string, List<Action<double>>> DoublePropChangeActions { get; set; } = new Dictionary<string, List<Action<double>>>();
|
||||
public Dictionary<string, List<Action<string>>> StringPropChangeActions { get; set; } = new Dictionary<string, List<Action<string>>>();
|
||||
public Dictionary<string, List<Action>> PropChangeActions { get; set; } = [];
|
||||
public Dictionary<string, List<Action<int>>> IntPropChangeActions { get; set; } = [];
|
||||
public Dictionary<string, List<Action<bool>>> BoolPropChangeActions { get; set; } = [];
|
||||
public Dictionary<string, List<Action<double>>> DoublePropChangeActions { get; set; } = [];
|
||||
public Dictionary<string, List<Action<string>>> StringPropChangeActions { get; set; } = [];
|
||||
|
||||
public nint Handle { get; set; }
|
||||
|
||||
@@ -64,7 +64,7 @@ public class MpvClient
|
||||
OnEndFile(data);
|
||||
}
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_FILE_LOADED:
|
||||
case mpv_event_id.MPV_EVENT_FILE_LOADED: // triggered after MPV_EVENT_START_FILE
|
||||
OnFileLoaded();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_PROPERTY_CHANGE:
|
||||
@@ -82,7 +82,7 @@ public class MpvClient
|
||||
case mpv_event_id.MPV_EVENT_COMMAND_REPLY:
|
||||
OnCommandReply();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_START_FILE:
|
||||
case mpv_event_id.MPV_EVENT_START_FILE: // triggered before MPV_EVENT_FILE_LOADED
|
||||
OnStartFile();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_AUDIO_RECONFIG:
|
||||
@@ -132,46 +132,72 @@ public class MpvClient
|
||||
else if (data.format == mpv_format.MPV_FORMAT_STRING)
|
||||
{
|
||||
lock (StringPropChangeActions)
|
||||
{
|
||||
foreach (var pair in StringPropChangeActions)
|
||||
{
|
||||
if (pair.Key == data.name)
|
||||
{
|
||||
string value = ConvertFromUtf8(Marshal.PtrToStructure<IntPtr>(data.data));
|
||||
|
||||
foreach (var action in pair.Value)
|
||||
{
|
||||
action.Invoke(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data.format == mpv_format.MPV_FORMAT_INT64)
|
||||
{
|
||||
lock (IntPropChangeActions)
|
||||
{
|
||||
foreach (var pair in IntPropChangeActions)
|
||||
{
|
||||
if (pair.Key == data.name)
|
||||
{
|
||||
int value = Marshal.PtrToStructure<int>(data.data);
|
||||
|
||||
foreach (var action in pair.Value)
|
||||
{
|
||||
action.Invoke(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data.format == mpv_format.MPV_FORMAT_NONE)
|
||||
{
|
||||
lock (PropChangeActions)
|
||||
{
|
||||
foreach (var pair in PropChangeActions)
|
||||
{
|
||||
if (pair.Key == data.name)
|
||||
{
|
||||
foreach (var action in pair.Value)
|
||||
{
|
||||
action.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data.format == mpv_format.MPV_FORMAT_DOUBLE)
|
||||
{
|
||||
lock (DoublePropChangeActions)
|
||||
{
|
||||
foreach (var pair in DoublePropChangeActions)
|
||||
{
|
||||
if (pair.Key == data.name)
|
||||
{
|
||||
double value = Marshal.PtrToStructure<double>(data.data);
|
||||
|
||||
foreach (var action in pair.Value)
|
||||
{
|
||||
action.Invoke(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,7 +273,9 @@ public class MpvClient
|
||||
mpv_error err = mpv_command_ret(Handle, rootPtr, resultNodePtr);
|
||||
|
||||
foreach (IntPtr ptr in pointers)
|
||||
{
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
|
||||
Marshal.FreeHGlobal(rootPtr);
|
||||
|
||||
@@ -346,6 +374,9 @@ public class MpvClient
|
||||
|
||||
public string GetPropertyString(string name)
|
||||
{
|
||||
if (Handle == IntPtr.Zero)
|
||||
return "";
|
||||
|
||||
mpv_error err = mpv_get_property(Handle, GetUtf8Bytes(name),
|
||||
mpv_format.MPV_FORMAT_STRING, out IntPtr lpBuffer);
|
||||
|
||||
@@ -364,6 +395,12 @@ public class MpvClient
|
||||
|
||||
public void SetPropertyString(string name, string value)
|
||||
{
|
||||
if (Handle == IntPtr.Zero)
|
||||
{
|
||||
Terminal.WriteError($"error setting property: {name} = {value}");
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] bytes = GetUtf8Bytes(value);
|
||||
mpv_error err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, ref bytes);
|
||||
|
||||
@@ -400,7 +437,7 @@ public class MpvClient
|
||||
if (err < 0)
|
||||
HandleError(err, "error observing property: " + name);
|
||||
else
|
||||
IntPropChangeActions[name] = new List<Action<int>>();
|
||||
IntPropChangeActions[name] = [];
|
||||
}
|
||||
|
||||
if (IntPropChangeActions.ContainsKey(name))
|
||||
@@ -419,7 +456,7 @@ public class MpvClient
|
||||
if (err < 0)
|
||||
HandleError(err, "error observing property: " + name);
|
||||
else
|
||||
DoublePropChangeActions[name] = new List<Action<double>>();
|
||||
DoublePropChangeActions[name] = [];
|
||||
}
|
||||
|
||||
if (DoublePropChangeActions.ContainsKey(name))
|
||||
@@ -438,7 +475,7 @@ public class MpvClient
|
||||
if (err < 0)
|
||||
HandleError(err, "error observing property: " + name);
|
||||
else
|
||||
BoolPropChangeActions[name] = new List<Action<bool>>();
|
||||
BoolPropChangeActions[name] = [];
|
||||
}
|
||||
|
||||
if (BoolPropChangeActions.ContainsKey(name))
|
||||
@@ -457,7 +494,7 @@ public class MpvClient
|
||||
if (err < 0)
|
||||
HandleError(err, "error observing property: " + name);
|
||||
else
|
||||
StringPropChangeActions[name] = new List<Action<string>>();
|
||||
StringPropChangeActions[name] = [];
|
||||
}
|
||||
|
||||
if (StringPropChangeActions.ContainsKey(name))
|
||||
@@ -476,7 +513,7 @@ public class MpvClient
|
||||
if (err < 0)
|
||||
HandleError(err, "error observing property: " + name);
|
||||
else
|
||||
PropChangeActions[name] = new List<Action>();
|
||||
PropChangeActions[name] = [];
|
||||
}
|
||||
|
||||
if (PropChangeActions.ContainsKey(name))
|
||||
|
||||
@@ -1,29 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<AssemblyName>libmpvnet</AssemblyName>
|
||||
<Product>mpv.net</Product>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>MpvNet</RootNamespace>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
</PropertyGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\..\docs\changelog.md" Link="Docs\changelog.md" />
|
||||
<None Include="..\..\docs\manual.md" Link="Docs\manual.md" />
|
||||
<None Include="..\..\README.md" Link="Docs\README.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\docs\changelog.md" Link="Docs\changelog.md" />
|
||||
<None Include="..\..\docs\manual.md" Link="Docs\manual.md" />
|
||||
<None Include="..\..\README.md" Link="Docs\README.md" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Extension\" />
|
||||
<Folder Include="Input\" />
|
||||
<Folder Include="Docs\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Docs\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||
<PackageReference Include="NGettext" Version="0.6.7" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||
<PackageReference Include="NGettext" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -36,6 +36,7 @@ public class MainPlayer : MpvClient
|
||||
public bool Paused { get; set; }
|
||||
public bool SnapWindow { get; set; }
|
||||
public bool TaskbarProgress { get; set; } = true;
|
||||
public bool TitleBar { get; set; } = true;
|
||||
public bool WasInitialSizeSet;
|
||||
public bool WindowMaximized { get; set; }
|
||||
public bool WindowMinimized { get; set; }
|
||||
@@ -50,7 +51,6 @@ public class MainPlayer : MpvClient
|
||||
public float AutofitLarger { get; set; } = 0.8f;
|
||||
|
||||
public AutoResetEvent ShutdownAutoResetEvent { get; } = new AutoResetEvent(false);
|
||||
public AutoResetEvent VideoSizeAutoResetEvent { get; } = new AutoResetEvent(false);
|
||||
public nint MainHandle { get; set; }
|
||||
public List<MediaTrack> MediaTracks { get; set; } = new List<MediaTrack>();
|
||||
public List<TimeSpan> BluRayTitles { get; } = new List<TimeSpan>();
|
||||
@@ -59,22 +59,26 @@ public class MainPlayer : MpvClient
|
||||
public TimeSpan Duration;
|
||||
public List<MpvClient> Clients { get; } = new List<MpvClient>();
|
||||
|
||||
List<StringPair>? _audioDevices;
|
||||
|
||||
public event Action? Initialized;
|
||||
public event Action? Pause;
|
||||
public event Action<int>? PlaylistPosChanged;
|
||||
public event Action<Size>? VideoSizeChanged;
|
||||
|
||||
public void Init(IntPtr formHandle)
|
||||
public void Init(IntPtr formHandle, bool processCommandLine)
|
||||
{
|
||||
App.ApplyShowMenuFix();
|
||||
|
||||
MainHandle = mpv_create();
|
||||
Handle = MainHandle;
|
||||
|
||||
var events = Enum.GetValues(typeof(mpv_event_id)).Cast<mpv_event_id>();
|
||||
var events = Enum.GetValues<mpv_event_id>().Cast<mpv_event_id>();
|
||||
|
||||
foreach (mpv_event_id i in events)
|
||||
{
|
||||
mpv_request_event(MainHandle, i, 0);
|
||||
}
|
||||
|
||||
mpv_request_log_messages(MainHandle, "no");
|
||||
|
||||
@@ -91,30 +95,37 @@ public class MainPlayer : MpvClient
|
||||
}
|
||||
|
||||
if (formHandle != IntPtr.Zero)
|
||||
{
|
||||
SetPropertyString("force-window", "yes");
|
||||
SetPropertyLong("wid", formHandle.ToInt64());
|
||||
}
|
||||
|
||||
SetPropertyInt("osd-duration", 2000);
|
||||
|
||||
SetPropertyBool("input-default-bindings", true);
|
||||
SetPropertyBool("input-builtin-bindings", false);
|
||||
SetPropertyBool("input-media-keys", true);
|
||||
|
||||
SetPropertyString("autocreate-playlist", "filter");
|
||||
SetPropertyString("media-controls", "yes");
|
||||
SetPropertyString("idle", "yes");
|
||||
SetPropertyString("screenshot-directory", "~~desktop/");
|
||||
SetPropertyString("osd-playing-msg", "${media-title}");
|
||||
SetPropertyString("osc", "yes");
|
||||
SetPropertyString("force-window", "yes");
|
||||
SetPropertyString("config-dir", ConfigFolder);
|
||||
SetPropertyString("config", "yes");
|
||||
|
||||
|
||||
UsedInputConfContent = App.InputConf.GetContent();
|
||||
|
||||
if (!string.IsNullOrEmpty(UsedInputConfContent))
|
||||
SetPropertyString("input-conf", @"memory://" + UsedInputConfContent);
|
||||
|
||||
ProcessCommandLineArgs();
|
||||
if (processCommandLine)
|
||||
CommandLine.ProcessCommandLineArgsPreInit();
|
||||
|
||||
if (App.CommandLineArguments.ContainsKey("config-dir"))
|
||||
if (CommandLine.Contains("config-dir"))
|
||||
{
|
||||
string configDir = App.CommandLineArguments["config-dir"];
|
||||
string configDir = CommandLine.GetValue("config-dir");
|
||||
string fullPath = System.IO.Path.GetFullPath(configDir);
|
||||
App.InputConf.Path = fullPath.AddSep() + "input.conf";
|
||||
string content = App.InputConf.GetContent();
|
||||
@@ -130,10 +141,6 @@ public class MainPlayer : MpvClient
|
||||
if (err < 0)
|
||||
throw new Exception("mpv_initialize error" + BR2 + GetError(err) + BR);
|
||||
|
||||
SetPropertyString("user-data/frontend/name", "mpv.net");
|
||||
SetPropertyString("user-data/frontend/version", AppInfo.Version.ToString());
|
||||
SetPropertyString("user-data/frontend/process-path", Environment.ProcessPath!);
|
||||
|
||||
string idle = GetPropertyString("idle");
|
||||
App.Exit = idle == "no" || idle == "once";
|
||||
|
||||
@@ -151,16 +158,24 @@ public class MainPlayer : MpvClient
|
||||
// this means Lua scripts that use idle might not work correctly
|
||||
SetPropertyString("idle", "yes");
|
||||
|
||||
ObservePropertyString("path", value => Path = value);
|
||||
SetPropertyString("user-data/frontend/name", "mpv.net");
|
||||
SetPropertyString("user-data/frontend/version", AppInfo.Version.ToString());
|
||||
SetPropertyString("user-data/frontend/process-path", Environment.ProcessPath!);
|
||||
|
||||
ObservePropertyBool("pause", value => {
|
||||
Paused = value;
|
||||
Pause?.Invoke();
|
||||
});
|
||||
|
||||
ObservePropertyInt("video-rotate", value => {
|
||||
VideoRotate = value;
|
||||
UpdateVideoSize("dwidth", "dheight");
|
||||
VideoRotate = GetPropertyInt("video-rotate");
|
||||
|
||||
ObservePropertyInt("video-rotate", value =>
|
||||
{
|
||||
if (VideoRotate != value)
|
||||
{
|
||||
VideoRotate = value;
|
||||
UpdateVideoSize("dwidth", "dheight");
|
||||
}
|
||||
});
|
||||
|
||||
ObservePropertyInt("playlist-pos", value => {
|
||||
@@ -172,9 +187,6 @@ public class MainPlayer : MpvClient
|
||||
CommandV("quit");
|
||||
});
|
||||
|
||||
if (!GetPropertyBool("osd-scale-by-window"))
|
||||
App.StartThreshold = 0;
|
||||
|
||||
Initialized?.Invoke();
|
||||
}
|
||||
|
||||
@@ -184,7 +196,9 @@ public class MainPlayer : MpvClient
|
||||
mpv_destroy(Handle);
|
||||
|
||||
foreach (var client in Clients)
|
||||
{
|
||||
mpv_destroy(client.Handle);
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessProperty(string? name, string? value)
|
||||
@@ -220,6 +234,7 @@ public class MainPlayer : MpvClient
|
||||
case "vo": VO = value!; break;
|
||||
case "window-maximized": WindowMaximized = value == "yes"; break;
|
||||
case "window-minimized": WindowMinimized = value == "yes"; break;
|
||||
case "title-bar": TitleBar = value == "yes"; break;
|
||||
}
|
||||
|
||||
if (AutofitLarger > 1)
|
||||
@@ -243,20 +258,7 @@ public class MainPlayer : MpvClient
|
||||
_configFolder = Folder.AppData + "mpv.net";
|
||||
|
||||
if (!Directory.Exists(_configFolder))
|
||||
{
|
||||
try {
|
||||
using Process proc = new Process();
|
||||
proc.StartInfo.UseShellExecute = false;
|
||||
proc.StartInfo.CreateNoWindow = true;
|
||||
proc.StartInfo.FileName = "powershell.exe";
|
||||
proc.StartInfo.Arguments = $@"-Command New-Item -Path '{_configFolder}' -ItemType Directory";
|
||||
proc.Start();
|
||||
proc.WaitForExit();
|
||||
} catch (Exception) {}
|
||||
|
||||
if (!Directory.Exists(_configFolder))
|
||||
Directory.CreateDirectory(_configFolder);
|
||||
}
|
||||
Directory.CreateDirectory(_configFolder);
|
||||
|
||||
_configFolder = _configFolder.AddSep();
|
||||
}
|
||||
@@ -265,6 +267,8 @@ public class MainPlayer : MpvClient
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Regex ConfRegex = new Regex("^[\\w-]+$", RegexOptions.Compiled);
|
||||
|
||||
Dictionary<string, string>? _Conf;
|
||||
|
||||
public Dictionary<string, string> Conf {
|
||||
@@ -275,7 +279,7 @@ public class MainPlayer : MpvClient
|
||||
|
||||
App.ApplyInputDefaultBindingsFix();
|
||||
|
||||
_Conf = new Dictionary<string, string>();
|
||||
_Conf = [];
|
||||
|
||||
if (File.Exists(ConfPath))
|
||||
{
|
||||
@@ -283,12 +287,12 @@ public class MainPlayer : MpvClient
|
||||
{
|
||||
string line = it.TrimStart(' ', '-').TrimEnd();
|
||||
|
||||
if (line.StartsWith("#"))
|
||||
if (line.StartsWith('#'))
|
||||
continue;
|
||||
|
||||
if (!line.Contains('='))
|
||||
{
|
||||
if (Regex.Match(line, "^[\\w-]+$").Success)
|
||||
if (ConfRegex.Match(line).Success)
|
||||
line += "=yes";
|
||||
else
|
||||
continue;
|
||||
@@ -307,7 +311,9 @@ public class MainPlayer : MpvClient
|
||||
}
|
||||
|
||||
foreach (var i in _Conf)
|
||||
{
|
||||
ProcessProperty(i.Key, i.Value);
|
||||
}
|
||||
|
||||
return _Conf;
|
||||
}
|
||||
@@ -315,26 +321,27 @@ public class MainPlayer : MpvClient
|
||||
|
||||
void UpdateVideoSize(string w, string h)
|
||||
{
|
||||
Size size = new Size(GetPropertyInt(w), GetPropertyInt(h));
|
||||
|
||||
if (size.Width == 0 || size.Height == 0)
|
||||
if (string.IsNullOrEmpty(Path))
|
||||
return;
|
||||
|
||||
Size size = new Size(GetPropertyInt(w), GetPropertyInt(h));
|
||||
|
||||
if (VideoRotate == 90 || VideoRotate == 270)
|
||||
size = new Size(size.Height, size.Width);
|
||||
|
||||
if (VideoSize != size)
|
||||
if (size != VideoSize && size != Size.Empty)
|
||||
{
|
||||
VideoSize = size;
|
||||
VideoSizeChanged?.Invoke(size);
|
||||
VideoSizeAutoResetEvent.Set();
|
||||
}
|
||||
}
|
||||
|
||||
public void MainEventLoop()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
mpv_wait_event(MainHandle, -1);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnShutdown()
|
||||
@@ -357,24 +364,27 @@ public class MainPlayer : MpvClient
|
||||
base.OnLogMessage(data);
|
||||
}
|
||||
|
||||
protected override void OnVideoReconfig()
|
||||
{
|
||||
UpdateVideoSize("dwidth", "dheight");
|
||||
base.OnVideoReconfig();
|
||||
}
|
||||
|
||||
protected override void OnEndFile(mpv_event_end_file data)
|
||||
{
|
||||
base.OnEndFile(data);
|
||||
FileEnded = true;
|
||||
}
|
||||
|
||||
protected override void OnVideoReconfig()
|
||||
{
|
||||
UpdateVideoSize("dwidth", "dheight");
|
||||
base.OnVideoReconfig();
|
||||
}
|
||||
|
||||
// executed before OnFileLoaded
|
||||
protected override void OnStartFile()
|
||||
{
|
||||
Path = GetPropertyString("path");
|
||||
base.OnStartFile();
|
||||
TaskHelp.Run(LoadFolder);
|
||||
}
|
||||
|
||||
// executed after OnStartFile
|
||||
protected override void OnFileLoaded()
|
||||
{
|
||||
Duration = TimeSpan.FromSeconds(GetPropertyDouble("duration"));
|
||||
@@ -382,14 +392,6 @@ public class MainPlayer : MpvClient
|
||||
if (App.StartSize == "video")
|
||||
WasInitialSizeSet = false;
|
||||
|
||||
string path = GetPropertyString("path");
|
||||
|
||||
if (!FileTypes.Video.Contains(path.Ext()) || FileTypes.Audio.Contains(path.Ext()))
|
||||
{
|
||||
UpdateVideoSize("width", "height");
|
||||
VideoSizeAutoResetEvent.Set();
|
||||
}
|
||||
|
||||
TaskHelp.Run(UpdateTracks);
|
||||
|
||||
base.OnFileLoaded();
|
||||
@@ -415,105 +417,6 @@ public class MainPlayer : MpvClient
|
||||
|
||||
public void SetBluRayTitle(int id) => LoadFiles(new[] { @"bd://" + id }, false, false);
|
||||
|
||||
public void ProcessCommandLineArgs()
|
||||
{
|
||||
foreach (string i in Environment.GetCommandLineArgs().Skip(1))
|
||||
{
|
||||
string arg = i;
|
||||
|
||||
if (!arg.StartsWith("--"))
|
||||
continue;
|
||||
|
||||
if (arg == "--profile=help")
|
||||
{
|
||||
Console.WriteLine(GetProfiles());
|
||||
continue;
|
||||
}
|
||||
else if (arg == "--vd=help" || arg == "--ad=help")
|
||||
{
|
||||
Console.WriteLine(GetDecoders());
|
||||
continue;
|
||||
}
|
||||
else if (arg == "--audio-device=help")
|
||||
{
|
||||
Console.WriteLine(GetPropertyOsdString("audio-device-list"));
|
||||
continue;
|
||||
}
|
||||
else if (arg == "--version")
|
||||
{
|
||||
Console.WriteLine(AppClass.About);
|
||||
continue;
|
||||
}
|
||||
else if (arg == "--input-keylist")
|
||||
{
|
||||
Console.WriteLine(GetPropertyString("input-key-list").Replace(",", BR));
|
||||
continue;
|
||||
}
|
||||
else if (arg.StartsWith("--command="))
|
||||
{
|
||||
Command(arg[10..]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!arg.Contains('='))
|
||||
{
|
||||
if (arg.Contains("--no-"))
|
||||
{
|
||||
arg = arg.Replace("--no-", "--");
|
||||
arg += "=no";
|
||||
}
|
||||
else
|
||||
arg += "=yes";
|
||||
}
|
||||
|
||||
string left = arg[2..arg.IndexOf("=")];
|
||||
string right = arg[(left.Length + 3)..];
|
||||
|
||||
if (string.IsNullOrEmpty(left))
|
||||
continue;
|
||||
|
||||
switch (left)
|
||||
{
|
||||
case "script": left = "scripts"; break;
|
||||
case "audio-file": left = "audio-files"; break;
|
||||
case "sub-file": left = "sub-files"; break;
|
||||
case "external-file": left = "external-files"; break;
|
||||
}
|
||||
|
||||
App.CommandLineArguments[left] = right;
|
||||
|
||||
ProcessProperty(left, right);
|
||||
|
||||
if (!App.ProcessProperty(left, right))
|
||||
SetPropertyString(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessCommandLineFiles()
|
||||
{
|
||||
List<string> files = new List<string>();
|
||||
|
||||
foreach (string arg in Environment.GetCommandLineArgs().Skip(1))
|
||||
if (!arg.StartsWith("--") && (arg == "-" || arg.Contains("://") ||
|
||||
arg.Contains(":\\") || arg.StartsWith("\\\\") || File.Exists(arg)))
|
||||
|
||||
files.Add(arg);
|
||||
|
||||
LoadFiles(files.ToArray(), !App.Queue, false || App.Queue);
|
||||
|
||||
if (App.CommandLine.Contains("--shuffle"))
|
||||
{
|
||||
Command("playlist-shuffle");
|
||||
SetPropertyInt("playlist-pos", 0);
|
||||
}
|
||||
|
||||
if (files.Count == 0 || files[0].Contains("://"))
|
||||
{
|
||||
VideoSizeChanged?.Invoke(VideoSize);
|
||||
VideoSizeAutoResetEvent.Set();
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime LastLoad;
|
||||
|
||||
public void LoadFiles(string[]? files, bool loadFolder, bool append)
|
||||
@@ -550,17 +453,9 @@ public class MainPlayer : MpvClient
|
||||
}
|
||||
|
||||
if (ext == "iso")
|
||||
LoadBluRayISO(file);
|
||||
LoadISO(file);
|
||||
else if(FileTypes.Subtitle.Contains(ext))
|
||||
CommandV("sub-add", file);
|
||||
else if (!FileTypes.IsMedia(ext) && !file.Contains("://") && Directory.Exists(file) &&
|
||||
File.Exists(System.IO.Path.Combine(file, "BDMV\\index.bdmv")))
|
||||
{
|
||||
Command("stop");
|
||||
Thread.Sleep(500);
|
||||
SetPropertyString("bluray-device", file);
|
||||
CommandV("loadfile", @"bd://");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i == 0 && !append)
|
||||
@@ -585,12 +480,24 @@ public class MainPlayer : MpvClient
|
||||
return path;
|
||||
}
|
||||
|
||||
public void LoadBluRayISO(string path)
|
||||
public void LoadISO(string path)
|
||||
{
|
||||
Command("stop");
|
||||
Thread.Sleep(500);
|
||||
SetPropertyString("bluray-device", path);
|
||||
LoadFiles(new[] { @"bd://" }, false, false);
|
||||
using var mi = new MediaInfo(path);
|
||||
|
||||
if (mi.GetGeneral("Format") == "ISO 9660 / DVD Video")
|
||||
{
|
||||
Command("stop");
|
||||
Thread.Sleep(500);
|
||||
SetPropertyString("dvd-device", path);
|
||||
LoadFiles([@"dvd://"], false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Command("stop");
|
||||
Thread.Sleep(500);
|
||||
SetPropertyString("bluray-device", path);
|
||||
LoadFiles([@"bd://"], false, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadDiskFolder(string path)
|
||||
@@ -601,12 +508,12 @@ public class MainPlayer : MpvClient
|
||||
if (Directory.Exists(path + "\\BDMV"))
|
||||
{
|
||||
SetPropertyString("bluray-device", path);
|
||||
LoadFiles(new[] { @"bd://" }, false, false);
|
||||
LoadFiles([@"bd://"], false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPropertyString("dvd-device", path);
|
||||
LoadFiles(new[] { @"dvd://" }, false, false);
|
||||
LoadFiles([@"dvd://"], false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,7 +542,7 @@ public class MainPlayer : MpvClient
|
||||
dir = System.IO.Path.GetDirectoryName(path)!;
|
||||
|
||||
List<string> files = FileTypes.GetMediaFiles(Directory.GetFiles(dir)).ToList();
|
||||
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
files.Sort(new StringLogicalComparer());
|
||||
|
||||
@@ -704,8 +611,10 @@ public class MainPlayer : MpvClient
|
||||
static string GetNativeLanguage(string name)
|
||||
{
|
||||
foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.NeutralCultures))
|
||||
{
|
||||
if (ci.EnglishName == name)
|
||||
return ci.NativeName;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
@@ -727,6 +636,26 @@ public class MainPlayer : MpvClient
|
||||
}
|
||||
}
|
||||
|
||||
public List<StringPair> AudioDevices {
|
||||
get {
|
||||
if (_audioDevices != null)
|
||||
return _audioDevices;
|
||||
|
||||
_audioDevices = [];
|
||||
string json = GetPropertyString("audio-device-list");
|
||||
var enumerator = JsonDocument.Parse(json).RootElement.EnumerateArray();
|
||||
|
||||
foreach (var element in enumerator)
|
||||
{
|
||||
string name = element.GetProperty("name").GetString()!;
|
||||
string description = element.GetProperty("description").GetString()!;
|
||||
_audioDevices.Add(new StringPair(name, description));
|
||||
}
|
||||
|
||||
return _audioDevices;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Chapter> GetChapters() {
|
||||
List<Chapter> chapters = new List<Chapter>();
|
||||
int count = GetPropertyInt("chapter-list/count");
|
||||
@@ -763,6 +692,8 @@ public class MainPlayer : MpvClient
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Regex TitleRegex = new Regex(@"^[\._\-]", RegexOptions.Compiled);
|
||||
|
||||
public List<MediaTrack> GetTracks(bool includeInternal = true, bool includeExternal = true)
|
||||
{
|
||||
List<MediaTrack> tracks = new List<MediaTrack>();
|
||||
@@ -780,7 +711,7 @@ public class MainPlayer : MpvClient
|
||||
string filename = GetPropertyString($"filename/no-ext");
|
||||
string title = GetPropertyString($"track-list/{i}/title").Replace(filename, "");
|
||||
|
||||
title = Regex.Replace(title, @"^[\._\-]", "");
|
||||
title = TitleRegex.Replace(title, "");
|
||||
|
||||
if (type == "video")
|
||||
{
|
||||
@@ -1126,7 +1057,7 @@ public class MainPlayer : MpvClient
|
||||
if (_profileNames != null)
|
||||
return _profileNames;
|
||||
|
||||
string[] ignore = { "builtin-pseudo-gui", "encoding", "libmpv", "pseudo-gui", "default" };
|
||||
string[] ignore = ["builtin-pseudo-gui", "encoding", "libmpv", "pseudo-gui", "default"];
|
||||
string json = GetPropertyString("profile-list");
|
||||
return _profileNames = JsonDocument.Parse(json).RootElement.EnumerateArray()
|
||||
.Select(it => it.GetProperty("name").GetString())
|
||||
|
||||
7
src/MpvNet/Properties/launchSettings.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"profiles": {
|
||||
"MpvNet": {
|
||||
"commandName": "Project"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,13 +11,16 @@ public class AppSettings
|
||||
{
|
||||
public bool InputDefaultBindingsFixApplied;
|
||||
public bool ShowMenuFixApplied;
|
||||
public int MenuUpdateVersion;
|
||||
public int Volume = 70;
|
||||
public List<string> RecentFiles = new List<string>();
|
||||
public Point WindowLocation;
|
||||
public Point WindowPosition;
|
||||
public Size WindowSize;
|
||||
public string AudioDevice = "";
|
||||
public string ConfigEditorSearch = "Video:";
|
||||
public string Mute = "no";
|
||||
public string StartupFolder = "";
|
||||
}
|
||||
|
||||
class SettingsManager
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
namespace MpvNet.Windows;
|
||||
|
||||
namespace MpvNet;
|
||||
|
||||
public class StringPair
|
||||
{
|
||||
@@ -9,4 +9,5 @@ public class Translator
|
||||
public interface ITranslator
|
||||
{
|
||||
public string Gettext(string msgId);
|
||||
public string GetParticularString(string context, string text);
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0-windows7.0</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.77" />
|
||||
<PackageReference Include="NGettext" Version="0.6.7" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" />
|
||||
<PackageReference Include="NGettext" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -11,16 +11,18 @@ AppVersion={#MyAppVersion}
|
||||
AppPublisher=Frank Skare (stax76)
|
||||
ArchitecturesInstallIn64BitMode=x64
|
||||
Compression=lzma2
|
||||
DefaultDirName={commonpf}\{#MyAppName}
|
||||
OutputBaseFilename=mpv.net-v{#MyAppVersion}-setup
|
||||
DefaultDirName={autopf}\{#MyAppName}
|
||||
OutputBaseFilename=mpv.net-v{#MyAppVersion}-setup-x64
|
||||
OutputDir=E:\Desktop
|
||||
DefaultGroupName={#MyAppName}
|
||||
SetupIconFile=..\..\MpvNet.Windows\mpv-icon.ico
|
||||
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||
PrivilegesRequired=admin
|
||||
PrivilegesRequiredOverridesAllowed=dialog
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||
|
||||
[Files]
|
||||
Source: "{#MyAppSourceDir}\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "{#MyAppSourceDir}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs;
|
||||
Source: "{#MyAppSourceDir}\*"; DestDir: "{app}"; Excludes: "win-x64,win-arm64"; Flags: ignoreversion recursesubdirs createallsubdirs;
|
||||
|
||||
114
src/Tools/release-mpv.net.ps1
Normal file
@@ -0,0 +1,114 @@
|
||||
|
||||
<#
|
||||
|
||||
Script that releases mpv.net on GitHub.
|
||||
|
||||
Needs 2 positional CLI arguments:
|
||||
1. Directory where the mpv.net source code is located.
|
||||
2. Directory of the output files, for instance the desktop dir.
|
||||
|
||||
Dependencies:
|
||||
7zip installation found at: 'C:\Program Files\7-Zip\7z.exe'.
|
||||
Inno Setup compiler installation found at: 'C:\Program Files (x86)\Inno Setup 6\ISCC.exe'.
|
||||
GitHub CLI https://cli.github.com
|
||||
|
||||
#>
|
||||
|
||||
# Stop when the first error occurs
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
function DeleteDir($path) {
|
||||
if (Test-Path $path) {
|
||||
Remove-Item $path -Recurse
|
||||
}
|
||||
}
|
||||
|
||||
# Throw error if the file/dir don't exist
|
||||
function Test($path) {
|
||||
if (-not (Test-Path $path)) {
|
||||
throw $path
|
||||
}
|
||||
return $path
|
||||
}
|
||||
|
||||
# Variables
|
||||
$SourceDir = Test $args[0]
|
||||
$OutputRootDir = Test $args[1]
|
||||
|
||||
Test (Join-Path $SourceDir 'MpvNet.sln')
|
||||
|
||||
$7zFile = Test 'C:\Program Files\7-Zip\7z.exe'
|
||||
$InnoSetupCompiler = Test 'C:\Program Files (x86)\Inno Setup 6\ISCC.exe'
|
||||
|
||||
$ReleaseNotes = "- [.NET Desktop Runtime 10.0](https://dotnet.microsoft.com/en-us/download/dotnet/10.0)`n- [Changelog](https://github.com/mpvnet-player/mpv.net/blob/main/docs/changelog.md)"
|
||||
$Repo = 'github.com/mpvnet-player/mpv.net'
|
||||
|
||||
# Dotnet Publish
|
||||
$PublishDir64 = Join-Path $SourceDir 'MpvNet.Windows\bin\Debug\win-x64\publish\'
|
||||
$PublishDirARM64 = Join-Path $SourceDir 'MpvNet.Windows\bin\Debug\win-arm64\publish\'
|
||||
$ProjectFile = Test (Join-Path $SourceDir 'MpvNet.Windows\MpvNet.Windows.csproj')
|
||||
dotnet publish $ProjectFile --self-contained false --configuration Debug --runtime win-x64
|
||||
dotnet publish $ProjectFile --self-contained false --configuration Debug --runtime win-arm64
|
||||
$PublishedExeFile64 = Test ($PublishDir64 + 'mpvnet.exe')
|
||||
|
||||
# Create OutputName
|
||||
$VersionInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($PublishedExeFile64)
|
||||
$IsBeta = $VersionInfo.FilePrivatePart -ne 0
|
||||
$BetaString = if ($IsBeta) { '-beta' } else { '' }
|
||||
$VersionName = $VersionInfo.FileVersion
|
||||
$OutputName64 = 'mpv.net-v' + $VersionName + $BetaString + '-portable-x64'
|
||||
$OutputNameARM64 = 'mpv.net-v' + $VersionName + $BetaString + '-portable-ARM64'
|
||||
|
||||
# Create OutputFolder
|
||||
$OutputDir64 = Join-Path $OutputRootDir ($OutputName64 + '\')
|
||||
$OutputDirARM64 = Join-Path $OutputRootDir ($OutputNameARM64 + '\')
|
||||
DeleteDir $OutputDir64
|
||||
DeleteDir $OutputDirARM64
|
||||
mkdir $OutputDir64
|
||||
mkdir $OutputDirARM64
|
||||
|
||||
# Copy Files
|
||||
Copy-Item ($PublishDir64 + '*') $OutputDir64
|
||||
Copy-Item ($PublishDirARM64 + '*') $OutputDirARM64
|
||||
$BinDirX64 = Test (Join-Path $SourceDir 'MpvNet.Windows\bin\Debug\')
|
||||
$BinDirARM64 = Test (Join-Path $SourceDir 'MpvNet.Windows\bin\Debug\win-arm64\')
|
||||
$ExtraFiles = 'mpvnet.com', 'libmpv-2.dll', 'MediaInfo.dll'
|
||||
$ExtraFiles | ForEach-Object { Copy-Item ($BinDirX64 + $_) ($OutputDir64 + $_) }
|
||||
$ExtraFiles | ForEach-Object { Copy-Item ($BinDirARM64 + $_) ($OutputDirARM64 + $_) }
|
||||
$LocaleDir = Test (Join-Path $SourceDir 'MpvNet.Windows\bin\Debug\Locale\')
|
||||
Copy-Item $LocaleDir ($OutputDir64 + 'Locale') -Recurse
|
||||
Copy-Item $LocaleDir ($OutputDirARM64 + 'Locale') -Recurse
|
||||
|
||||
# Pack
|
||||
$ZipOutputFile64 = Join-Path $OutputRootDir ($OutputName64 + '.zip')
|
||||
$ZipOutputFileARM64 = Join-Path $OutputRootDir ($OutputNameARM64 + '.zip')
|
||||
& $7zFile a -tzip -mx9 $ZipOutputFile64 -r ($OutputDir64 + '*')
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
& $7zFile a -tzip -mx9 $ZipOutputFileARM64 -r ($OutputDirARM64 + '*')
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
Test $ZipOutputFile64
|
||||
Test $ZipOutputFileARM64
|
||||
|
||||
# Inno Setup
|
||||
''; ''
|
||||
$InnoSetupScript = Test (Join-Path $SourceDir 'Setup\Inno\inno-setup.iss')
|
||||
& $InnoSetupCompiler $InnoSetupScript
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
$SetupFile = Test (Join-Path $OutputRootDir "mpv.net-v$VersionName-setup-x64.exe")
|
||||
|
||||
if ($IsBeta) {
|
||||
$NewSetupFile = Join-Path $OutputRootDir "mpv.net-v$VersionName-beta-setup-x64.exe"
|
||||
Move-Item $SetupFile $NewSetupFile
|
||||
$SetupFile = $NewSetupFile
|
||||
}
|
||||
|
||||
# Release
|
||||
$Title = 'v' + $VersionName + $BetaString
|
||||
|
||||
if ($BetaString) {
|
||||
gh release create $Title -t $Title -n $ReleaseNotes --repo $Repo --prerelease $ZipOutputFile64 $ZipOutputFileARM64 $SetupFile
|
||||
} else {
|
||||
gh release create $Title -t $Title -n $ReleaseNotes --repo $Repo $ZipOutputFile64 $ZipOutputFileARM64 $SetupFile
|
||||
}
|
||||
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
103
src/Tools/update-mpv.ps1
Normal file
@@ -0,0 +1,103 @@
|
||||
|
||||
<#
|
||||
|
||||
Updates mpv (x64) and libmpv (x64 , ARM64).
|
||||
|
||||
Files are downloaded from:
|
||||
https://github.com/shinchiro/mpv-winbuild-cmake/releases
|
||||
|
||||
Requires 7zip being installed at 'C:\Program Files\7-Zip\7z.exe'.
|
||||
|
||||
Needs 3 positional CLI arguments:
|
||||
1. Directory where mpv x64 is located. To skip pass '-'.
|
||||
2. Directory where libmpv x64 is located. To skip pass '-'.
|
||||
3. Directory where libmpv ARM64 is located. To skip pass '-'.
|
||||
#>
|
||||
|
||||
$7ZipPath = 'C:\Program Files\7-Zip\7z.exe'
|
||||
|
||||
$MpvDirX64 = $args[0]
|
||||
$LibmpvDirX64 = $args[1]
|
||||
$LibmpvDirARM64 = $args[2]
|
||||
|
||||
# Stop when the first error occurs
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# Throw exception if file or folder does not exist
|
||||
function Test($path) {
|
||||
if (-not (Test-Path $path)) {
|
||||
throw $path
|
||||
}
|
||||
return $path
|
||||
}
|
||||
|
||||
# Download file to temp dir and return file path
|
||||
function Download($apiURL, $pattern) {
|
||||
$json = Invoke-WebRequest $apiURL -MaximumRedirection 0 -ErrorAction Ignore -UseBasicParsing | ConvertFrom-Json
|
||||
$filename = ($json.assets | Where-Object { $_.name -Match $pattern }).name
|
||||
$path = Join-Path $env:TEMP $filename
|
||||
$link = ($json.assets | Where-Object { $_.name -Match $pattern }).browser_download_url
|
||||
Invoke-WebRequest -Uri $link -UserAgent "mpv-win-updater" -OutFile $path
|
||||
return Test $path
|
||||
}
|
||||
|
||||
# Unpack archive
|
||||
function Unpack($archieveFile, $outputRootDir) {
|
||||
$outputDir = Join-Path $outputRootDir $archieveFile.BaseName
|
||||
if (Test-Path $outputDir) { Remove-Item $outputDir -Recurse }
|
||||
$process = Start-Process (Test $7ZipPath) @('x', $archieveFile.FullName, "-o$outputDir") -NoNewWindow -Wait
|
||||
if ($process.ExitCode) { throw $process.ExitCode }
|
||||
return Test $outputDir
|
||||
}
|
||||
|
||||
# Update mpv x64
|
||||
|
||||
if (Test-Path (Join-Path $MpvDirX64 'mpv.exe')) {
|
||||
$apiURL = "https://api.github.com/repos/shinchiro/mpv-winbuild-cmake/releases/latest"
|
||||
$archiveFile = Get-Item (Download $apiURL "mpv-x86_64-[0-9]{8}-git-[0-9a-z]+\.7z")
|
||||
$archiveDir = Unpack $archiveFile $env:TEMP
|
||||
Remove-Item "$MpvDirX64\*" -Force -Recurse
|
||||
Copy-Item "$archiveDir\*" $MpvDirX64 -Force -Recurse
|
||||
Remove-Item $archiveFile.FullName
|
||||
Remove-Item $archiveDir -Recurse
|
||||
} else {
|
||||
"mpv x64 location not found:`n$MpvDirX64"
|
||||
}
|
||||
|
||||
# Update libmpv x64
|
||||
|
||||
if (Test-Path (Join-Path $LibmpvDirX64 'libmpv-2.dll')) {
|
||||
$apiURL = "https://api.github.com/repos/shinchiro/mpv-winbuild-cmake/releases/latest"
|
||||
$archiveFile = Get-Item (Download $apiURL "mpv-dev-x86_64-[0-9]{8}-git-[0-9a-z]+\.7z")
|
||||
$archiveDir = Unpack $archiveFile $env:TEMP
|
||||
Copy-Item $archiveDir\libmpv-2.dll $LibmpvDirX64 -Force
|
||||
Remove-Item $archiveFile.FullName
|
||||
Remove-Item $archiveDir -Recurse
|
||||
} else {
|
||||
"libmpv x64 location not found:`n$LibmpvDirX64"
|
||||
}
|
||||
|
||||
# Update libmpv ARM64
|
||||
|
||||
if (Test-Path (Join-Path $LibmpvDirARM64 'libmpv-2.dll')) {
|
||||
$apiURL = "https://api.github.com/repos/shinchiro/mpv-winbuild-cmake/releases/latest"
|
||||
$archiveFile = Get-Item (Download $apiURL "mpv-dev-aarch64-[0-9]{8}-git-[0-9a-z]+\.7z")
|
||||
$archiveDir = Unpack $archiveFile $env:TEMP
|
||||
Copy-Item $archiveDir\libmpv-2.dll $LibmpvDirARM64 -Force
|
||||
Remove-Item $archiveFile.FullName
|
||||
Remove-Item $archiveDir -Recurse
|
||||
} else {
|
||||
"libmpv ARM64 location not found:`n$LibmpvDirARM64"
|
||||
}
|
||||
|
||||
if (Test-Path (Join-Path $MpvDirX64 'mpv.exe')) {
|
||||
Get-Item (Join-Path $MpvDirX64 'mpv.exe')
|
||||
}
|
||||
|
||||
if (Test-Path (Join-Path $LibmpvDirX64 'libmpv-2.dll')) {
|
||||
Get-Item (Join-Path $LibmpvDirX64 'libmpv-2.dll')
|
||||
}
|
||||
|
||||
if (Test-Path (Join-Path $LibmpvDirARM64 'libmpv-2.dll')) {
|
||||
Get-Item (Join-Path $LibmpvDirARM64 'libmpv-2.dll')
|
||||
}
|
||||