Compare commits
128 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa1183710b | ||
|
|
f468fd9c56 | ||
|
|
22f2aa93a8 | ||
|
|
c2c0a8f190 | ||
|
|
da3e6655c6 | ||
|
|
856959a4d1 | ||
|
|
9053ecb4ee | ||
|
|
33fd7fc09b | ||
|
|
d005f19755 | ||
|
|
1081007009 | ||
|
|
e6c0a67483 | ||
|
|
265e18985d | ||
|
|
8dc204e81a | ||
|
|
b9b604bfe3 | ||
|
|
05027cd458 | ||
|
|
9bbde49a5c | ||
|
|
cfca7786f3 | ||
|
|
be57edf2c5 | ||
|
|
f48901355a | ||
|
|
ca153fecfc | ||
|
|
e3227de8b4 | ||
|
|
4a202245b5 | ||
|
|
b94f9de582 | ||
|
|
7371949730 | ||
|
|
857926696c | ||
|
|
4451a6c185 | ||
|
|
ea6a71b7c3 | ||
|
|
625dddcfbb | ||
|
|
0cd769fc0c | ||
|
|
f5e0c92824 | ||
|
|
327a097bcf | ||
|
|
68626fa536 | ||
|
|
8935101058 | ||
|
|
6947c925b9 | ||
|
|
4562131078 | ||
|
|
21188f0942 | ||
|
|
1316559ebc | ||
|
|
cd576f9211 | ||
|
|
1bac8e8937 | ||
|
|
e6d0449f8f | ||
|
|
e0e40b7918 | ||
|
|
b59f16a425 | ||
|
|
46b110d93b | ||
|
|
7e8a654ada | ||
|
|
c2c33228a0 | ||
|
|
0a28f13d51 | ||
|
|
9f3a1da931 | ||
|
|
05874ad6be | ||
|
|
078e8046bd | ||
|
|
b07901485e | ||
|
|
a37cbef8a8 | ||
|
|
8debcc171c | ||
|
|
e230f0f474 | ||
|
|
558bd67591 | ||
|
|
a7e4892acf | ||
|
|
a0ba69c1aa | ||
|
|
1e7e80577d | ||
|
|
2177308b02 | ||
|
|
a8c2409ed1 | ||
|
|
1ef9e64a41 | ||
|
|
f0546485cf | ||
|
|
032e91e4b4 | ||
|
|
1447636eb7 | ||
|
|
966f96a02b | ||
|
|
954c014708 | ||
|
|
ad30dc5ae2 | ||
|
|
3f74344b99 | ||
|
|
96d8d88d09 | ||
|
|
8626b8283f | ||
|
|
d90025e8fe | ||
|
|
a572bd8553 | ||
|
|
0f5146e58c | ||
|
|
9c6c0f3506 | ||
|
|
8c36cc8b8c | ||
|
|
44435057d7 | ||
|
|
135bdeb638 | ||
|
|
93c93b620d | ||
|
|
247aefbf07 | ||
|
|
0a8397652f | ||
|
|
ecd5b01161 | ||
|
|
1e9893977d | ||
|
|
4fd6b13e0f | ||
|
|
d21d36c196 | ||
|
|
fbffbea641 | ||
|
|
9899c2cd27 | ||
|
|
10370e9ae2 | ||
|
|
d391e24784 | ||
|
|
430fef0ac4 | ||
|
|
8430842679 | ||
|
|
9d37e67901 | ||
|
|
e98ff53058 | ||
|
|
b47d3c34f2 | ||
|
|
54dd261df0 | ||
|
|
8eb7e41d16 | ||
|
|
2068bfb6fa | ||
|
|
dfc1ac712e | ||
|
|
d96587cb7b | ||
|
|
005550af55 | ||
|
|
543e2905cc | ||
|
|
a49b9bea61 | ||
|
|
9ea9cb2757 | ||
|
|
5543381a14 | ||
|
|
cd6dcf4640 | ||
|
|
d321ab477f | ||
|
|
1cd0f87278 | ||
|
|
936274fc3b | ||
|
|
2bbaa30322 | ||
|
|
cedd54d64d | ||
|
|
38604459a6 | ||
|
|
0a48a0dc6f | ||
|
|
85a23fbae1 | ||
|
|
01da76bdc4 | ||
|
|
1f1553e159 | ||
|
|
2af84941ca | ||
|
|
a82f558acf | ||
|
|
d13f7201ba | ||
|
|
89aa0c6133 | ||
|
|
1699467e0d | ||
|
|
7a27ab0513 | ||
|
|
2a0c68e4ec | ||
|
|
91c42d4d3f | ||
|
|
49d56166d7 | ||
|
|
1ac603b904 | ||
|
|
d5b2923c68 | ||
|
|
b80b375df1 | ||
|
|
2b2b60b90f | ||
|
|
3977283ecb | ||
|
|
d27778775d |
204
Changelog.md
@@ -1,3 +1,201 @@
|
|||||||
|
|
||||||
|
### 5.4.3.0
|
||||||
|
|
||||||
|
- new: the color themes can now be customized ([manual](https://github.com/stax76/mpv.net/blob/master/Manual.md#color-theme))
|
||||||
|
- new: three new sections were added to the [manual](https://github.com/stax76/mpv.net/blob/master/Manual.md):
|
||||||
|
1. [Color Theme](https://github.com/stax76/mpv.net/blob/master/Manual.md#color-theme)
|
||||||
|
2. [Hidden and secret features](https://github.com/stax76/mpv.net/blob/master/Manual.md#hidden-and-secret-features)
|
||||||
|
3. [External Tools](https://github.com/stax76/mpv.net/blob/master/Manual.md#external-tools)
|
||||||
|
|
||||||
|
- fix: window restore from maximized and from minimized was broken
|
||||||
|
- fix: it's possible to multi select files in File Explorer and press
|
||||||
|
enter to open the files, this did however only work when the
|
||||||
|
auto load folder feature was disabled or the shift key was
|
||||||
|
pressed (blocks auto load folder). Now it should also work
|
||||||
|
without shift key and with auto load folder being enabled
|
||||||
|
|
||||||
|
- update: libmpv shinchiro 2019-10-27
|
||||||
|
- update: youtube-dl 2019-10-31
|
||||||
|
|
||||||
|
### 5.4.2.1 Beta
|
||||||
|
|
||||||
|
- pressing shift key suppresses auto-load-folder
|
||||||
|
- switch --queue added, this will not clear the playlist but append
|
||||||
|
and it will suppress auto-load-folder. To get a 'Add to mpv.net playlist'
|
||||||
|
context menu item in explorer with multi selection support use my
|
||||||
|
[Open with++](https://github.com/stax76/OpenWithPlusPlus#add-to-mpvnet-playlist) shell extension, as far as I know multi selection
|
||||||
|
can not be done using the Registry but only via shell extension
|
||||||
|
- window-size mpv property support added ([default bindings](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L137))
|
||||||
|
- the config editor keeps profiles and comments in mpv.conf intact!
|
||||||
|
- the options in the config editor are better organized
|
||||||
|
|
||||||
|
### 5.4.2
|
||||||
|
|
||||||
|
- new: the [scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting#powershell) was improved
|
||||||
|
- new: Toggle Shuffle has been added to the menu defaults
|
||||||
|
- new: for URLs the media title is shown in the title bar and in the info command
|
||||||
|
instead of displaying the URL, mpv.conf defaults were changed to use
|
||||||
|
[protocol.https] osd-playing-msg = '${media-title}'
|
||||||
|
|
||||||
|
- fix: on the very first start volume was set to 0 and mute was set to yes
|
||||||
|
- fix: there was a sound when closed from taskbar
|
||||||
|
- fix: the log feature was not working
|
||||||
|
- fix: clipboard monitoring removed because it was causing to many issues
|
||||||
|
- fix: restore resulted in collapsed window when maximized = yes was used
|
||||||
|
|
||||||
|
- update: libmpv shinchiro 2019-10-06
|
||||||
|
- update: youtube-dl 2019-10-01
|
||||||
|
|
||||||
|
### 5.4.1.1
|
||||||
|
|
||||||
|
- a issue with the taskbar-progress feature was fixed
|
||||||
|
- improved PowerShell scrip host
|
||||||
|
|
||||||
|
### 5.4.1
|
||||||
|
|
||||||
|
- fix ArgumentOutOfRangeException
|
||||||
|
|
||||||
|
### 5.4
|
||||||
|
|
||||||
|
- added taskbar-progress implementation
|
||||||
|
- added new setting to start with maximized window
|
||||||
|
- long file paths work now even if not enabled by the OS
|
||||||
|
- fixed history being written even when history file wasn't created prior
|
||||||
|
- libmpv updated to shinchiro 2019-08-31
|
||||||
|
|
||||||
|
### 5.3
|
||||||
|
|
||||||
|
- added new feature: Open > Open DVD/Blu-ray Drive/Folder...
|
||||||
|
- the default of remember-volume has been set to yes
|
||||||
|
- scale, cscale, dscale defaults have been set to spline36,
|
||||||
|
profile=gpu-hq is not used in the defaults because it starts very slow
|
||||||
|
- new menu items have been added to navigate to the first and
|
||||||
|
last playlist position, key bindings: Home, End
|
||||||
|
- new config setting recent-count added, amount of menu items
|
||||||
|
shown under 'Open > Recent'
|
||||||
|
- in the config dialog the description for keep-open was corrected
|
||||||
|
because unlike mpv, mpv.net will never terminate automatically
|
||||||
|
- there was a rare occasion where the mpv.net logo wasn't shown
|
||||||
|
- fix excessive memory usage using `osd-scale-by-window = no`
|
||||||
|
- mpv setting osd-scale-by-window added to config dialog
|
||||||
|
|
||||||
|
### 5.2.1
|
||||||
|
|
||||||
|
- fixed race condition causing various features to fail
|
||||||
|
|
||||||
|
### 5.2
|
||||||
|
|
||||||
|
- bug fix for single-instance not working with unicode filenames
|
||||||
|
- bug fix for logo not shown on start
|
||||||
|
- osd-visibility.js script was removed because the OSC uses too much memory
|
||||||
|
- youtube-dl was updated
|
||||||
|
- libmpv was updated to shinchiro 2019-08-04
|
||||||
|
- in case mpv.net was started from a terminal it sets now the mpv property input-terminal to yes,
|
||||||
|
this means mpv.net will now receive and handle input keys from the terminal
|
||||||
|
- certain command line properties didn't work (input-terminal, terminal, input-file,
|
||||||
|
config, config-dir, input-conf, load-scripts, script, scripts, player-operation-mode)
|
||||||
|
- the about dialog shows now the mpv version and build date
|
||||||
|
- the dialog that asks for a config folder has now a cancel option
|
||||||
|
|
||||||
|
### 5.1
|
||||||
|
|
||||||
|
- 'Tools > Execute mpv command' was replaced with [mpv-repl](https://github.com/rossy/mpv-repl)
|
||||||
|
- many [wiki pages](https://github.com/stax76/mpv.net/wiki) were improved
|
||||||
|
- the logo/icon had a very small cosmetic change
|
||||||
|
- the help in the context menu was improved,
|
||||||
|
for quick access consider the command palette (F1 key)
|
||||||
|
- config options specific to mpv.net are now available from the command line
|
||||||
|
- the input editor no longer has known limitations, 'alt gr' and ctrl+alt are working now
|
||||||
|
- the help in the input editor was simplified and the filter logic was improved
|
||||||
|
- fixed issue in file associations causing mpv.net not to appear in OS default apps
|
||||||
|
- 'Tools > Manage File Associations' was replaced by 'Tools > OS Setup',
|
||||||
|
it has now a feature to add and remove mpv.net to and from the Path
|
||||||
|
environment variable and the OS default apps settings can be opened (Win 10 only)
|
||||||
|
- startup folder and config folder being identical was causing a critical issue
|
||||||
|
as mpv.net was loading extensions twice and scripts four times, now identical
|
||||||
|
folders are no longer permitted
|
||||||
|
- error messages are shown when unknown scripts and extensions are found in the startup folder
|
||||||
|
because user scripts and extensions are supposed to be located in the config folder instead
|
||||||
|
- changing from maximized to fullscreen did not work
|
||||||
|
- the search field in the config editor was not always remembered
|
||||||
|
- new setting remember-volume added, saves volume and mute on exit
|
||||||
|
and restores it on start.
|
||||||
|
- it's now enforced that mpv properties on the command line and in
|
||||||
|
the mpv.conf config file are lowercase, if not a error is shown
|
||||||
|
- gpu-api vulkan was not working if media files were opened via
|
||||||
|
command line (that included Explorer)
|
||||||
|
- new setting minimum-aspect-ratio added, minimum aspect ratio for the window,
|
||||||
|
this was previously hard coded to 1.3
|
||||||
|
- new setting auto-load-folder added, for single files automatically load
|
||||||
|
the entire directory into the playlist, previously this was forced,
|
||||||
|
now it can be disabled
|
||||||
|
- new setting themed-menu added, follow theme color in context menu,
|
||||||
|
default: no. UI related settings have now a separate UI tab in the config editor
|
||||||
|
|
||||||
|
### 5.0
|
||||||
|
|
||||||
|
- [changed icon design](https://github.com/stax76/mpv.net/blob/master/img/mpvnet.png)
|
||||||
|
- libmpv was updated to shinchiro 2019-07-14
|
||||||
|
- new or improved config editor settings: screenshot-directory,
|
||||||
|
screenshot-format, screenshot-tag-colorspace, screenshot-high-bit-depth,
|
||||||
|
screenshot-jpeg-source-chroma, screenshot-template, screenshot-jpeg-quality,
|
||||||
|
screenshot-png-compression, screenshot-png-filter
|
||||||
|
- mpv.conf preview feature added to config editor, it previews the mpv.conf content
|
||||||
|
- in the entire project the term addon was replaced with the term extension,
|
||||||
|
unfortunately this will break user extensions. The reason for this drastic
|
||||||
|
change is that there exist too many different terms, addons, addins,
|
||||||
|
extensions, modules, packages etc.. mpv.net follows Google Chrome as the worlds
|
||||||
|
most popular extendable app, Chrome uses the term Extension.
|
||||||
|
- a thread synchronization bug was fixed, the shutdown thread was aborted
|
||||||
|
if it was running more than 3 seconds, this caused the rating extension
|
||||||
|
to fail if it was waiting for a drive to wake up
|
||||||
|
- a new JavaScript was included to show the playlist with a smaller font size,
|
||||||
|
the script is located at startup/scripts
|
||||||
|
- terminal support added using mpvnet.com !
|
||||||
|
- script engine performance and error handling was improved
|
||||||
|
- the [scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting) was improved
|
||||||
|
- the C# scripting host extension was converted from VB to C# because it's not
|
||||||
|
only used for hosting but I also use it now to code and debug script code
|
||||||
|
- there was a copy paste bug in the file association feature resulting in keys
|
||||||
|
from mpv being overwritten instead of using mpv.net keys. Thanks to floppyD!
|
||||||
|
- there was a exception fixed that happened opening rar files
|
||||||
|
- instead of using the OS theme color there are now default colors
|
||||||
|
for dark-color and light-color
|
||||||
|
|
||||||
|
### 4.7.7
|
||||||
|
|
||||||
|
- on Win 7 the theme color was hardcoded to DarkSlateGrey because
|
||||||
|
WPF was returning a bad color on Win 7, this was fixed by reading
|
||||||
|
the theme color from the Registry on Win 7. If the theme color
|
||||||
|
is identical to the background color it's corrected
|
||||||
|
- dark-color setting was added to overwrite the OS theme color used in dark mode,
|
||||||
|
find the setting on the General tab
|
||||||
|
- light-color setting was added to overwrite the OS theme color used in non dark mode,
|
||||||
|
find the setting on the General tab
|
||||||
|
- various changes regarding input handling, multi media keys and
|
||||||
|
mouse forward/backward were successfully tested
|
||||||
|
- it's now possible to use a custom folder as config folder,
|
||||||
|
A TaskDialog shows five options: 1. appdata mpv.net, 2. appdata mpv (shared with mpv),
|
||||||
|
3. portable_config, 4. startup, 5. custom
|
||||||
|
- slightly increased startup performance, start-threshold setting added.
|
||||||
|
Threshold in milliseconds to wait for libmpv returning the video resolution
|
||||||
|
before the window is shown, otherwise default dimensions are used as defined
|
||||||
|
by autofit and start-size. Default: 1500
|
||||||
|
- autofit-smaller setting added. Minimum window height in percent. Default: 40%
|
||||||
|
- autofit-larger setting added. Maximum window height in percent. Default: 75%
|
||||||
|
|
||||||
|
### 4.7.3
|
||||||
|
|
||||||
|
- fix cursor showing load activity on startup
|
||||||
|
- added file size and type to info command using audio files
|
||||||
|
- added image format support to the info command, to file
|
||||||
|
association management, to folder loading, to Everything
|
||||||
|
- readme/github have a updated features and architecture section
|
||||||
|
|
||||||
|
### 4.7.1
|
||||||
|
|
||||||
|
- few layout problems were fixed, autosize for instance did not work
|
||||||
|
|
||||||
### 4.7
|
### 4.7
|
||||||
|
|
||||||
- remember-height was replaced with start-size, when start-size is set
|
- remember-height was replaced with start-size, when start-size is set
|
||||||
@@ -7,10 +205,10 @@
|
|||||||
- on exit the window location can be saved with remember-position
|
- on exit the window location can be saved with remember-position
|
||||||
- in the learn window of the input editor underscores were stripped
|
- in the learn window of the input editor underscores were stripped
|
||||||
because they have a special meaning in WPF labels
|
because they have a special meaning in WPF labels
|
||||||
- keys/input not working for MBTN_LEFT_DBL, MBTN_BACK, MBTN_FORWARD
|
- fix for keys/input not working for MBTN_LEFT_DBL, MBTN_BACK, MBTN_FORWARD
|
||||||
- in the learn window of the input editor support was added for
|
- in the learn window of the input editor support was added for
|
||||||
mouse left, mouse left double, mouse mid, mouse forward, mouse back
|
mouse left, mouse left double, mouse mid, mouse forward, mouse back
|
||||||
- libmpv updated to shinchiro 2019-07-07
|
- libmpv was updated to shinchiro 2019-07-07
|
||||||
- when border is none it wasn't possible to minimize the window from
|
- when border is none it wasn't possible to minimize the window from
|
||||||
the task bar because this is the WinForms default behavier. This
|
the task bar because this is the WinForms default behavier. This
|
||||||
was fixed by calling Spy++ to the rescue and adding WS_MINIMIZEBOX
|
was fixed by calling Spy++ to the rescue and adding WS_MINIMIZEBOX
|
||||||
@@ -39,7 +237,7 @@
|
|||||||
mpv.net not appearing in the 'Open with' menu of the Windows File Explorer,
|
mpv.net not appearing in the 'Open with' menu of the Windows File Explorer,
|
||||||
thanks to 44vince44 for pointing this out!!!
|
thanks to 44vince44 for pointing this out!!!
|
||||||
- new Python and C# script examples were added to the wiki and the scripting and
|
- new Python and C# script examples were added to the wiki and the scripting and
|
||||||
add-on documentation was improved
|
extension documentation was improved
|
||||||
- invalid command line arguments were ignored, now an error message is shown
|
- invalid command line arguments were ignored, now an error message is shown
|
||||||
- a description on how to start mpv.net from Google Chrome was added to the
|
- a description on how to start mpv.net from Google Chrome was added to the
|
||||||
manual, it's useful to play videos from sites like YouTube, find the
|
manual, it's useful to play videos from sites like YouTube, find the
|
||||||
|
|||||||
31
LICENSE.txt
@@ -1,21 +1,24 @@
|
|||||||
|
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2017-2019 Frank Skare (stax76)
|
Copyright 2002-2017 Frank Skare (stax76)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person
|
||||||
a copy of this software and ssociated documentation files (the "Software"),
|
obtaining a copy of this software and ssociated documentation
|
||||||
to deal in the Software without restriction, including without limitation
|
files (the "Software"), to deal in the Software without restriction,
|
||||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
including without limitation the rights to use, copy, modify, merge,
|
||||||
and/or sell copies of the Software, and to permit persons to whom the
|
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||||
Software is furnished to do so, subject to the following conditions:
|
and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included
|
The above copyright notice and this permission notice shall be
|
||||||
in all copies or substantial portions of the Software.
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
|
||||||
|
THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|||||||
118
Manual.md
@@ -7,7 +7,6 @@
|
|||||||
* [Requirements](#requirements)
|
* [Requirements](#requirements)
|
||||||
* [Installation](#installation)
|
* [Installation](#installation)
|
||||||
+ [File Associations](#file-associations)
|
+ [File Associations](#file-associations)
|
||||||
+ [Chrome Extension](#chrome-extension)
|
|
||||||
* [Context Menu](#context-menu)
|
* [Context Menu](#context-menu)
|
||||||
+ [Open > Open Files](#open--open-files)
|
+ [Open > Open Files](#open--open-files)
|
||||||
+ [Open > Open URL](#open--open-url)
|
+ [Open > Open URL](#open--open-url)
|
||||||
@@ -89,8 +88,14 @@
|
|||||||
+ [Help > About mpv.net](#help--about-mpvnet)
|
+ [Help > About mpv.net](#help--about-mpvnet)
|
||||||
+ [Exit](#exit)
|
+ [Exit](#exit)
|
||||||
+ [Exit Watch Later](#exit-watch-later)
|
+ [Exit Watch Later](#exit-watch-later)
|
||||||
|
* [External Tools](#external-tools)
|
||||||
|
+ [Play with mpv](#play-with-mpv)
|
||||||
|
+ [External Application Button](#external-application-button)
|
||||||
|
+ [Open with++](#open-with)
|
||||||
|
+ [MediaInfo.NET](#mediainfonet)
|
||||||
* [Command Line Interface](#command-line-interface)
|
* [Command Line Interface](#command-line-interface)
|
||||||
* [Settings](#settings)
|
* [Color Theme](#color-theme)
|
||||||
|
* [Hidden and secret features](#hidden-and-secret-features)
|
||||||
|
|
||||||
## About mpv.net
|
## About mpv.net
|
||||||
|
|
||||||
@@ -104,11 +109,11 @@ mpv.net is meant to be a small single person project, it's designed to be mpv co
|
|||||||
|
|
||||||
The target audience of mpv.net are programmers, nerds and software enthusiasts that need something more advanced than typical media players.
|
The target audience of mpv.net are programmers, nerds and software enthusiasts that need something more advanced than typical media players.
|
||||||
|
|
||||||
Furthermore mpv.net is well suited for users who are interested to learn mpv, Linux, portable apps and the command line.
|
Furthermore mpv.net is well suited for people who are interested to learn mpv.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
mpv.net is based on the .NET Framework and requires Windows 7 as minimum version of the Windows operating system. As of the writing of this manual the minimum required .NET Framework version is 4.7.2.
|
mpv.net is based on the .NET Framework and requires Windows 7 as minimum version of the Windows operating system. As of the writing of this manual the minimum required .NET Framework version is 4.8.
|
||||||
|
|
||||||
For optimal results a modern graphics card is recommended.
|
For optimal results a modern graphics card is recommended.
|
||||||
|
|
||||||
@@ -124,25 +129,15 @@ x86 should though still be well supported and work but it's not as well tested t
|
|||||||
|
|
||||||
### File Associations
|
### File Associations
|
||||||
|
|
||||||
File Associations can be created using the setup or from within the apps context menu under 'Tools > Manage File Associations'.
|
File Associations can be created using the setup or with the context menu under 'Tools > OS Setup'.
|
||||||
|
|
||||||
Windows 10 prevents apps to register as the default app, to define the default video or audio player app in Windows 10 go to the Windows settings under 'Settings > Apps > Default apps' or shell execute 'ms-settings:defaultapps'.
|
Windows 10 prevents apps to register as the default app, to define the default video or audio player app in Windows 10 go to the Windows settings under 'Settings > Apps > Default apps' or shell execute 'ms-settings:defaultapps'.
|
||||||
|
|
||||||
It's also possible to change the default application using the Open With feature of the context menu in Windows File Explorer.
|
It's also possible to change the default application using the 'Open with' feature of the context menu in Windows File Explorer.
|
||||||
|
|
||||||
### Chrome Extension
|
|
||||||
|
|
||||||
In order to play videos from sites such as YouTube the Chrome Extension [Play with mpv](https://chrome.google.com/webstore/detail/play-with-mpv/hahklcmnfgffdlchjigehabfbiigleji) can be used.
|
|
||||||
|
|
||||||
Due to Chrome Extensions not being able to start a app, another app that communicates with the extension is required, this app can be downloaded [here](http://www.mediafire.com/file/6tmwdjsfknhmsxy/play-with-mpvnet-server.7z/file). The extension works only when the app is running, to have the app always running a link can be created in the auto start folder located at:
|
|
||||||
|
|
||||||
`C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup`
|
|
||||||
|
|
||||||
This will start the app on system start and have it running in the background. When the file association registration of mpv.net was executed then the app should find the location of mpv.net, alternativly the mpv.net folder can be added to the PATH environment variable.
|
|
||||||
|
|
||||||
## Context Menu
|
## Context Menu
|
||||||
|
|
||||||
The most important part of the user interface in mpv.net is the context menu, the menu can be customized as it is defined in the same file where the key bindings are defined.
|
The most important part of the user interface in mpv.net is the context menu, the menu can be customized as it's defined in the same file where the key bindings are defined.
|
||||||
|
|
||||||
### Open > Open Files
|
### Open > Open Files
|
||||||
|
|
||||||
@@ -150,9 +145,13 @@ The Open Files menu entry is one way to open files in mpv.net, it supports multi
|
|||||||
|
|
||||||
Another way to open files is the command line, it is used by the Windows File Explorer if file associations exist.
|
Another way to open files is the command line, it is used by the Windows File Explorer if file associations exist.
|
||||||
|
|
||||||
|
When mpv.net is started from a terminal such as PowerShell, mpv.net attaches to the terminal and outputs status and debug messages.
|
||||||
|
|
||||||
A third way is to drag and drop files on the main window.
|
A third way is to drag and drop files on the main window.
|
||||||
|
|
||||||
Whenever the control key is pressed when files are opened, the playlist is not cleared but the files are appended to the playlist.
|
Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist. This works in all mpv.net features that open files or URLs.
|
||||||
|
|
||||||
|
Pressing the shift key while opening a single file will suppress loading all files in the folder.
|
||||||
|
|
||||||
### Open > Open URL
|
### Open > Open URL
|
||||||
|
|
||||||
@@ -160,7 +159,9 @@ The Open URL menu entry can be used to open URLs for example from YouTube.
|
|||||||
|
|
||||||
mpv.net monitors the Windows clipboard and ask if URLs should be played in case it finds a URL in the clipboard. This feature uses a keyword whitelist that can be configured in the config editor.
|
mpv.net monitors the Windows clipboard and ask if URLs should be played in case it finds a URL in the clipboard. This feature uses a keyword whitelist that can be configured in the config editor.
|
||||||
|
|
||||||
Whenever the control key is pressed when URLs are opened, the playlist is not cleared but the URLs are appended to the playlist.
|
When mpv.net is started from a terminal such as PowerShell, mpv.net attaches to the terminal and outputs status and debug messages.
|
||||||
|
|
||||||
|
Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist. This works in all mpv.net features that open files or URLs.
|
||||||
|
|
||||||
### Open > Show media search
|
### Open > Show media search
|
||||||
|
|
||||||
@@ -734,7 +735,7 @@ Shows the command palette window which allows to find mpv.net commands, it shows
|
|||||||
|
|
||||||
### Tools > Show History
|
### Tools > Show History
|
||||||
|
|
||||||
When enabled shows a file that contains the playback history containing the time and filename.
|
Shows a text file that contains the file history. If the file don't exist it asks if the file should be created in the settings folder. Once the file exist then the history is logged. It logges the playback history containing the time and filename.
|
||||||
|
|
||||||
### Tools > Set/clear A-B loop points
|
### Tools > Set/clear A-B loop points
|
||||||
|
|
||||||
@@ -812,35 +813,78 @@ Exits mpv.net and remembers the position in the file using the following command
|
|||||||
|
|
||||||
[quit-watch-later command](https://mpv.io/manual/master/#command-interface-quit-watch-later)
|
[quit-watch-later command](https://mpv.io/manual/master/#command-interface-quit-watch-later)
|
||||||
|
|
||||||
|
## External Tools
|
||||||
|
|
||||||
|
### Play with mpv
|
||||||
|
|
||||||
|
In order to play videos from sites such as YouTube the Chrome Extension [Play with mpv](https://chrome.google.com/webstore/detail/play-with-mpv/hahklcmnfgffdlchjigehabfbiigleji) can be used.
|
||||||
|
|
||||||
|
Due to Chrome Extensions not being able to start a app, another app that communicates with the extension is required, this app can be downloaded [here](http://www.mediafire.com/file/lezj8lwqt5zf75v/play-with-mpvnet-server.7z/file). The extension works only when the app is running, to have the app always running a link can be created in the auto start folder located at:
|
||||||
|
|
||||||
|
`C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup`
|
||||||
|
|
||||||
|
This will start the app on system start and have it running in the background. When the file association registration of mpv.net was executed then the app should find the location of mpv.net, alternativly the mpv.net folder can be added to the PATH environment variable.
|
||||||
|
|
||||||
|
### External Application Button
|
||||||
|
|
||||||
|
Alternatively the Chrome extension [External Application Button](https://github.com/stax76/mpv.net/issues/106) can be used.
|
||||||
|
|
||||||
|
### Open with++
|
||||||
|
|
||||||
|
Open with++ allows to customize the File Explorer context menu for instance to add a 'Add to mpv.net playlist' menu item.
|
||||||
|
|
||||||
|
https://github.com/stax76/OpenWithPlusPlus
|
||||||
|
|
||||||
|
https://github.com/stax76/OpenWithPlusPlus#mpvnet
|
||||||
|
|
||||||
|
https://github.com/stax76/OpenWithPlusPlus#add-to-mpvnet-playlist
|
||||||
|
|
||||||
|
### MediaInfo.NET
|
||||||
|
|
||||||
|
MediaInfo.NET is a media info GUI.
|
||||||
|
|
||||||
|
https://github.com/stax76/MediaInfo.NET
|
||||||
|
|
||||||
|
To start a external application mpv has the run input command (it does not use the shell).
|
||||||
|
|
||||||
|
If the path has spaces then it must be enclosed in quotes and then double backslashes must be used for escaping or alternatively forward slashes.
|
||||||
|
|
||||||
|
`_ run D:\Software\MediaInfoNET.exe "${path}" #menu: Tools > Open file with MediaInfo.NET`
|
||||||
|
|
||||||
|
`_ run "D:\\Soft ware\\MediaInfoNET.exe" "${path}" #menu: Tools > Open file with MediaInfo.NET`
|
||||||
|
|
||||||
|
`_ run "D:/Soft ware/MediaInfoNET.exe" "${path}" #menu: Tools > Open file with MediaInfo.NET`
|
||||||
|
|
||||||
## Command Line Interface
|
## Command Line Interface
|
||||||
|
|
||||||
mpvnet implements a basic CLI to set mpv commands.
|
mpvnet implements a command line interface to set mpv commands.
|
||||||
|
|
||||||
|
Supported are all mpv properties which are documented at:
|
||||||
|
|
||||||
|
<https://mpv.io/manual/master>
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
mpvnet --mute=yes <file|URL>
|
`mpvnet --mute=yes <file|URL>`
|
||||||
|
|
||||||
## Settings
|
## Color Theme
|
||||||
|
|
||||||
mpv.net is able to share the settings with mpv and mpv.net uses the same logic to decide from where the settings are loaded. The default location is:
|
mpv.net supports custom color themes, the definition of the built-in themes can be found at:
|
||||||
|
|
||||||
```Text
|
<https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/theme.txt>
|
||||||
C:\Users\%username%\AppData\Roaming\mpv\mpv.conf
|
|
||||||
```
|
|
||||||
|
|
||||||
If a directory named portable_config next to the mpvnet.exe exists, all config will be loaded from this directory only.
|
Custom themes can be saved at:
|
||||||
|
|
||||||
```Text
|
`<conf folder>\theme.conf`
|
||||||
<startup>\portable_config\mpv.conf
|
|
||||||
```
|
|
||||||
|
|
||||||
In case there isn't any config folder mpv.net asks where to create it. If no mpv.conf file exists mpv.net generates it with the following defaults:
|
The theme.conf file may contain an unlimited amount of themes.
|
||||||
|
|
||||||
<https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt>
|
In the config editor under UI there are the settings dark-theme and light-theme to define the themes used in dark and in light mode.
|
||||||
|
|
||||||
Config files located in the same directory as mpvnet.exe are loaded with lower priority. Some config files are loaded only once, which means that e.g. of 2 input.conf files located in two config directories, only the one from the directory with higher priority will be loaded.
|
## Hidden and secret features
|
||||||
|
|
||||||
The key bindings and the context menu definitions are stored in the input.conf file,
|
Selecting multiple files in File Explorer and pressing enter will open the files in mpv.net. Explorer restricts this to maximum 15 files and the order will be random.
|
||||||
if it's missing mpv.net generates it with the following defaults:
|
|
||||||
|
|
||||||
<https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt>
|
Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist. This works in all mpv.net features that open files or URLs.
|
||||||
|
|
||||||
|
Pressing the shift key while opening a single file will suppress loading all files in the folder.
|
||||||
|
|||||||
123
README.md
@@ -1,5 +1,7 @@
|
|||||||

|

|
||||||
|
|
||||||
|
     [](https://www.paypal.me/stax76)
|
||||||
|
|
||||||
# 🎞 mpv.net
|
# 🎞 mpv.net
|
||||||
|
|
||||||
mpv.net is a modern media player for Windows that works just like [mpv](https://mpv.io).
|
mpv.net is a modern media player for Windows that works just like [mpv](https://mpv.io).
|
||||||
@@ -37,7 +39,7 @@ Table of contents
|
|||||||
- [Context Menu](#context-menu)
|
- [Context Menu](#context-menu)
|
||||||
- [Settings](#settings)
|
- [Settings](#settings)
|
||||||
- [Scripting](#scripting)
|
- [Scripting](#scripting)
|
||||||
- [Add-ons](#add-ons)
|
- [Extensions](#extensions)
|
||||||
- [Architecture](#architecture)
|
- [Architecture](#architecture)
|
||||||
- [Support](#support)
|
- [Support](#support)
|
||||||
- [Links](#links)
|
- [Links](#links)
|
||||||
@@ -46,19 +48,41 @@ Table of contents
|
|||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
|
- Very high degree of mpv compatibility, almost all mpv features are available
|
||||||
|
- Great usability due to everything in the application being searchable
|
||||||
|
- Open source built with modern tools
|
||||||
- Customizable context menu defined in the same file as the key bindings ([Screenshot](#context-menu-screenshot), [Defaults](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt))
|
- Customizable context menu defined in the same file as the key bindings ([Screenshot](#context-menu-screenshot), [Defaults](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt))
|
||||||
- Searchable config dialog ([Screenshot](#config-editor-screenshot), [Defaults](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt))
|
- Searchable config dialog ([Screenshot](#config-editor-screenshot), [Defaults](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt))
|
||||||
- Searchable input (key/mouse) binding editor ([Screenshot](#input-editor-screenshot), [Defaults](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt))
|
- Searchable input (key/mouse) binding editor ([Screenshot](#input-editor-screenshot), [Defaults](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt))
|
||||||
|
- Configuration files that are easy to read and edit
|
||||||
- Searchable command palette to quickly launch commands and look for keys ([Screenshot](#command-palette-screenshot))
|
- Searchable command palette to quickly launch commands and look for keys ([Screenshot](#command-palette-screenshot))
|
||||||
- Modern UI with dark mode ([Screenshot](#config-editor-screenshot))
|
- Modern WPF based graphical user interface with dark mode ([Screenshot](#config-editor-screenshot))
|
||||||
- Addon/extension API for .NET languages
|
- Extension API for .NET languages
|
||||||
- Scripting API for Python, C#, Lua, JavaScript and PowerShell ([Wiki](https://github.com/stax76/mpv.net/wiki/Scripting))
|
- Scripting API for Python, C#, Lua, JavaScript and PowerShell ([Wiki](https://github.com/stax76/mpv.net/wiki/Scripting))
|
||||||
- mpv's OSC, IPC and conf files
|
- Language agnostic JSON IPC to control the player with a external programs
|
||||||
|
- On Screen Controler (OSC, play control buttons)
|
||||||
- [Command Line Interface](https://mpv.io/manual/master/#options)
|
- [Command Line Interface](https://mpv.io/manual/master/#options)
|
||||||
|
- If started from a PowerShell terminal mpv.net will attach to the terminal and print status and debug output ([Screenshot](#terminal-and-repl-screenshot))
|
||||||
|
- [OSD REPL](https://github.com/rossy/mpv-repl)
|
||||||
- DXVA2 video decoding acceleration
|
- DXVA2 video decoding acceleration
|
||||||
- OpenGL based 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
|
- OpenGL based 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
|
||||||
- Search feature powered by [Everything](https://www.voidtools.com) to find and play media ([Screenshot](#media-search-screenshot))
|
- Search feature powered by [Everything](https://www.voidtools.com) to find and play media ([Screenshot](#media-search-screenshot))
|
||||||
- Extension to start mpv.net from Google Chrome ([Manual](Manual.md#chrome-extension))
|
- Extension to start mpv.net from Google Chrome ([Manual](Manual.md#chrome-extension))
|
||||||
|
- Extremely fast seek performance
|
||||||
|
- Very fast startup performance, video is usally ready to play in less then a second
|
||||||
|
- Usable as video player, audio player and image viewer with a wide range of supported formats
|
||||||
|
- All decoders are built-in, no external codecs have to be installed
|
||||||
|
- Setup and portable download options, setup is recommended but not required
|
||||||
|
- Build-in media streaming via youtube-dl
|
||||||
|
- x64 and x86 Support (64-bit and 32-bit)
|
||||||
|
- File associations can be created by the setup and from the player
|
||||||
|
- External audio and subtitle files can either be loaded manually or automatically
|
||||||
|
- Screenshot feature with many options
|
||||||
|
- File history feature to log time and filename
|
||||||
|
- A-B loop feature
|
||||||
|
- Watch later feature to save the position
|
||||||
|
- Files can be enqueued from Explorer using the shell extension [Open with++](https://github.com/stax76/OpenWithPlusPlus#add-to-mpvnet-playlist) and the --queue switch
|
||||||
|
- [Manual](#manual)
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
@@ -78,6 +102,12 @@ A searchable config editor as alternative to edit the mpv.conf file manually.
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
#### Terminal and REPL Screenshot
|
||||||
|
|
||||||
|
mpv.net attached to a PowerShell terminal showing the [OSD REPL](https://github.com/rossy/mpv-repl).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
#### Input Editor Screenshot
|
#### Input Editor Screenshot
|
||||||
|
|
||||||
A searchable key and mouse binding editor.
|
A searchable key and mouse binding editor.
|
||||||
@@ -117,44 +147,53 @@ input.conf defines mpv's key and mouse bindings and mpv.net uses comments to def
|
|||||||
|
|
||||||
### Settings
|
### Settings
|
||||||
|
|
||||||
mpv.net is able to share the settings with mpv and mpv.net uses the same logic to decide from where the settings are loaded. The default location is:
|
When mpv.net finds no config folder on startup it will ask for a location.
|
||||||
|
|
||||||
|
If a folder named portable_config next to the mpvnet.exe exists,
|
||||||
|
all config will be loaded from this folder only.
|
||||||
|
|
||||||
```Text
|
```Text
|
||||||
C:\Users\%username%\AppData\Roaming\mpv\mpv.conf
|
<startup>\portable_config\
|
||||||
```
|
```
|
||||||
|
|
||||||
If a directory named portable_config next to the mpvnet.exe exists, all config will be loaded from this directory only.
|
mpv specific settings are stored in the file mpv.conf, if no mpv.conf file exists
|
||||||
|
mpv.net generates it with the following defaults:
|
||||||
```Text
|
|
||||||
<startup>\portable_config\mpv.conf
|
|
||||||
```
|
|
||||||
|
|
||||||
In case there isn't any config folder mpv.net asks where to create it. If no mpv.conf file exists mpv.net generates it with the following defaults:
|
|
||||||
|
|
||||||
<https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt>
|
<https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt>
|
||||||
|
|
||||||
Config files located in the same directory as mpvnet.exe are loaded with lower priority. Some config files are loaded only once, which means that e.g. of 2 input.conf files located in two config directories, only the one from the directory with higher priority will be loaded.
|
mpv.net specific settings are stored in the file mpvnet.conf
|
||||||
|
|
||||||
The key bindings and the context menu definitions are stored in the input.conf file,
|
The input (key/mouse) bindings and the context menu definitions are stored in the
|
||||||
if it's missing mpv.net generates it with the following defaults:
|
input.conf file, if it's missing mpv.net generates it with the following defaults:
|
||||||
|
|
||||||
<https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt>
|
<https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt>
|
||||||
|
|
||||||
mpv.net supports almost all mpv settings and features, [limitations are listed in the wiki](https://github.com/stax76/mpv.net/wiki/Limitations).
|
mpv.net supports almost all mpv settings and features,
|
||||||
|
[limitations are listed in the wiki](https://github.com/stax76/mpv.net/wiki/Limitations).
|
||||||
|
|
||||||
|
The config folder can be opened from the context menu.
|
||||||
|
|
||||||
### Scripting
|
### Scripting
|
||||||
|
|
||||||
[Scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting)
|
[Scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting)
|
||||||
|
|
||||||
### Add-ons
|
### Extensions
|
||||||
|
|
||||||
[Add-on wiki page](https://github.com/stax76/mpv.net/wiki/Addons)
|
[Extensions wiki page](https://github.com/stax76/mpv.net/wiki/Extensions)
|
||||||
|
|
||||||
### Architecture
|
### Architecture
|
||||||
|
|
||||||
mpv.net is written in C# 7.0 and runs on the .NET framework 4.7 or higher.
|
Coding mpv.net was great fun because libmpv is such a awesome
|
||||||
|
library with a very clever design, I'm having a great experience
|
||||||
|
with libmpv.
|
||||||
|
|
||||||
The Add-on implementation is based on the [Managed Extensibility Framework](https://docs.microsoft.com/en-us/dotnet/framework/mef/).
|
The player does not contain any feature that was more work than 1-2 days or
|
||||||
|
was difficult to build, the hard parts are totally covered by libmpv.
|
||||||
|
|
||||||
|
mpv.net is written in C# 7 and runs on .NET 4.7, I've not yet decided
|
||||||
|
if I will port it to C# 8 and .NET 5 once available.
|
||||||
|
|
||||||
|
The Extension implementation is based on the [Managed Extensibility Framework](https://docs.microsoft.com/en-us/dotnet/framework/mef/).
|
||||||
|
|
||||||
There are no specific extension or scripting interfaces but instead everyting
|
There are no specific extension or scripting interfaces but instead everyting
|
||||||
is accessible for .NET compatible languages (C#, VB.NET, F#, Python, PowerShell),
|
is accessible for .NET compatible languages (C#, VB.NET, F#, Python, PowerShell),
|
||||||
@@ -162,9 +201,10 @@ this decision was made to keep the code simple and lightweight.
|
|||||||
|
|
||||||
Python scripting is implemented with IronPython which uses Python 2.7.
|
Python scripting is implemented with IronPython which uses Python 2.7.
|
||||||
|
|
||||||
The main/video window is WinForms based, all other windows are WPF based.
|
The main window is WinForms based and uses less than 750 lines of code,
|
||||||
|
all other windows are WPF based and use even less code.
|
||||||
|
|
||||||
The config editor adds it's controls dynamically and uses TOML to define it's
|
The config editor adds it's controls dynamically and uses [TOML](https://en.wikipedia.org/wiki/TOML) to define it's
|
||||||
content, there are only two simple types, StringSetting and OptionSetting.
|
content, there are only two simple types, StringSetting and OptionSetting.
|
||||||
|
|
||||||
mpv.net was started 2017 and consists of about 6000 lines of code and markup.
|
mpv.net was started 2017 and consists of about 6000 lines of code and markup.
|
||||||
@@ -189,39 +229,30 @@ Third party components:
|
|||||||
|
|
||||||
[Support thread in VideoHelp forum](https://forum.videohelp.com/threads/392514-mpv-net-a-extendable-media-player-for-windows)
|
[Support thread in VideoHelp forum](https://forum.videohelp.com/threads/392514-mpv-net-a-extendable-media-player-for-windows)
|
||||||
|
|
||||||
[Issue tracker to report bugs and request features](https://github.com/stax76/mpv.net/issues)
|
[Issue tracker](https://github.com/stax76/mpv.net/issues), feel free to use for anything mpv.net related
|
||||||
|
|
||||||
[frank.skare.de@gmail.com](mailto:frank.skare.de@gmail.com?Subject=mpv.net%20support)
|
[frank.skare.de@gmail.com](mailto:frank.skare.de@gmail.com?Subject=mpv.net%20support)
|
||||||
|
|
||||||
Please click on the star at the top of the page and like mpv.net at [alternativeto.net](https://alternativeto.net/software/mpv-net/).
|
Please click on the star at the top of the page and like mpv.net at [alternativeto.net](https://alternativeto.net/software/mpv-net/).
|
||||||
|
|
||||||
If you like you can express your appreciation for my player by sending little beer money with paypal.
|
If you want to support the development of mpv.net or express your appreciation you can do so with a donation:
|
||||||
|
|
||||||
<https://www.paypal.me/stax76>
|
<https://www.paypal.me/stax76>
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
|
|
||||||
mpv manual: <https://mpv.io/manual/master/>
|
- mpv.net wiki: <https://github.com/stax76/mpv.net/wiki>
|
||||||
|
- mpv.net default key bindings: <https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt>
|
||||||
mpv wiki: <https://github.com/mpv-player/mpv/wiki>
|
- mpv.net download: <https://github.com/stax76/mpv.net/releases>
|
||||||
|
- mpv.net bugs and requests: <https://github.com/stax76/mpv.net/issues>
|
||||||
mpv.net wiki: <https://github.com/stax76/mpv.net/wiki>
|
- mpv website: <https://mpv.io/>
|
||||||
|
- mpv manual: <https://mpv.io/manual/master/>
|
||||||
mpv apps: <https://github.com/mpv-player/mpv/wiki/Applications-using-mpv>
|
- mpv wiki: <https://github.com/mpv-player/mpv/wiki>
|
||||||
|
- mpv apps: <https://github.com/mpv-player/mpv/wiki/Applications-using-mpv>
|
||||||
mpv user scripts: <https://github.com/mpv-player/mpv/wiki/User-Scripts>
|
- mpv user scripts: <https://github.com/mpv-player/mpv/wiki/User-Scripts>
|
||||||
|
- mpv default key bindings: <https://github.com/mpv-player/mpv/blob/master/etc/input.conf>
|
||||||
mpv default key bindings: <https://github.com/mpv-player/mpv/blob/master/etc/input.conf>
|
- mpv download: <https://mpv.io/installation/>
|
||||||
|
- mpv bugs and requests: <https://mpv.io/bug-reports/>
|
||||||
mpv.net default key bindings: <https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt>
|
|
||||||
|
|
||||||
mpv download: <https://mpv.io/installation/>
|
|
||||||
|
|
||||||
mpv.net download: <https://github.com/stax76/mpv.net/releases>
|
|
||||||
|
|
||||||
mpv bugs and requests: <https://mpv.io/bug-reports/>
|
|
||||||
|
|
||||||
mpv.net bugs and requests: <https://github.com/stax76/mpv.net/issues>
|
|
||||||
|
|
||||||
### Changelog
|
### Changelog
|
||||||
|
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
'this addon implements the C# scripting feature of mpv.net,
|
|
||||||
'it is based on CS-Script: https://www.cs-script.net/
|
|
||||||
|
|
||||||
Imports System.ComponentModel.Composition
|
|
||||||
Imports System.IO
|
|
||||||
Imports System.Windows.Forms
|
|
||||||
|
|
||||||
Imports mpvnet
|
|
||||||
|
|
||||||
Imports CSScriptLibrary
|
|
||||||
|
|
||||||
<Export(GetType(IAddon))>
|
|
||||||
Public Class CSScriptAddon
|
|
||||||
Implements IAddon
|
|
||||||
|
|
||||||
Sub New()
|
|
||||||
Dim scriptFiles As New List(Of String)
|
|
||||||
|
|
||||||
If Directory.Exists(mp.ConfFolder + "scripts") Then
|
|
||||||
scriptFiles.AddRange(Directory.GetFiles(mp.ConfFolder + "scripts", "*.cs"))
|
|
||||||
End If
|
|
||||||
|
|
||||||
If Directory.Exists(Application.StartupPath + "\scripts") Then
|
|
||||||
scriptFiles.AddRange(Directory.GetFiles(Application.StartupPath + "\scripts", "*.cs"))
|
|
||||||
End If
|
|
||||||
|
|
||||||
If scriptFiles.Count = 0 Then Return
|
|
||||||
CSScriptLibrary.CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom
|
|
||||||
|
|
||||||
For Each i In scriptFiles
|
|
||||||
Try
|
|
||||||
CSScriptLibrary.CSScript.Evaluator.LoadCode(File.ReadAllText(i))
|
|
||||||
Catch ex As Exception
|
|
||||||
Msg.ShowException(ex)
|
|
||||||
End Try
|
|
||||||
Next
|
|
||||||
End Sub
|
|
||||||
End Class
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
|
||||||
<ProjectGuid>{71808A87-8B1C-4DF8-957C-D79C3B164CCA}</ProjectGuid>
|
|
||||||
<OutputType>Library</OutputType>
|
|
||||||
<RootNamespace>CSScriptAddon</RootNamespace>
|
|
||||||
<AssemblyName>CSScriptAddon</AssemblyName>
|
|
||||||
<FileAlignment>512</FileAlignment>
|
|
||||||
<MyType>Windows</MyType>
|
|
||||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
|
||||||
<TargetFrameworkProfile />
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<DefineDebug>true</DefineDebug>
|
|
||||||
<DefineTrace>true</DefineTrace>
|
|
||||||
<OutputPath>..\mpv.net\bin\Addons\CSScriptAddon\</OutputPath>
|
|
||||||
<DocumentationFile>
|
|
||||||
</DocumentationFile>
|
|
||||||
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
|
||||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<DefineDebug>false</DefineDebug>
|
|
||||||
<DefineTrace>true</DefineTrace>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<OutputPath>..\mpv.net\bin\Addons\CSScriptAddon\</OutputPath>
|
|
||||||
<DocumentationFile>
|
|
||||||
</DocumentationFile>
|
|
||||||
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
|
||||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup>
|
|
||||||
<OptionExplicit>On</OptionExplicit>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup>
|
|
||||||
<OptionCompare>Binary</OptionCompare>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup>
|
|
||||||
<OptionStrict>On</OptionStrict>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup>
|
|
||||||
<OptionInfer>On</OptionInfer>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DefineDebug>true</DefineDebug>
|
|
||||||
<DefineTrace>true</DefineTrace>
|
|
||||||
<OutputPath>..\..\mpv.net\bin\x86\Addons\CSScriptAddon\</OutputPath>
|
|
||||||
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
|
||||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
|
||||||
<DefineTrace>true</DefineTrace>
|
|
||||||
<OutputPath>..\mpv.net\bin\x86\Addons\CSScriptAddon\</OutputPath>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
|
||||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DefineDebug>true</DefineDebug>
|
|
||||||
<DefineTrace>true</DefineTrace>
|
|
||||||
<OutputPath>..\..\mpv.net\bin\x64\Addons\CSScriptAddon\</OutputPath>
|
|
||||||
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
|
||||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
|
||||||
<DefineTrace>true</DefineTrace>
|
|
||||||
<OutputPath>..\mpv.net\bin\x64\Addons\CSScriptAddon\</OutputPath>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
|
||||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="CSScriptLibrary, Version=3.27.5.0, Culture=neutral, PublicKeyToken=70fcc3d18c749033, processorArchitecture=MSIL">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>.\CSScriptLibrary.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
|
||||||
<Reference Include="System.ComponentModel.Composition" />
|
|
||||||
<Reference Include="System.Data" />
|
|
||||||
<Reference Include="System.Windows.Forms" />
|
|
||||||
<Reference Include="System.Xml" />
|
|
||||||
<Reference Include="System.Core" />
|
|
||||||
<Reference Include="System.Xml.Linq" />
|
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
|
||||||
<Reference Include="System.Net.Http" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Import Include="Microsoft.VisualBasic" />
|
|
||||||
<Import Include="System" />
|
|
||||||
<Import Include="System.Collections" />
|
|
||||||
<Import Include="System.Collections.Generic" />
|
|
||||||
<Import Include="System.Data" />
|
|
||||||
<Import Include="System.Diagnostics" />
|
|
||||||
<Import Include="System.Linq" />
|
|
||||||
<Import Include="System.Xml.Linq" />
|
|
||||||
<Import Include="System.Threading.Tasks" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="CSScriptAddon.vb" />
|
|
||||||
<Compile Include="My Project\AssemblyInfo.vb" />
|
|
||||||
<Compile Include="My Project\Application.Designer.vb">
|
|
||||||
<AutoGen>True</AutoGen>
|
|
||||||
<DependentUpon>Application.myapp</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="My Project\Resources.Designer.vb">
|
|
||||||
<AutoGen>True</AutoGen>
|
|
||||||
<DesignTime>True</DesignTime>
|
|
||||||
<DependentUpon>Resources.resx</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="My Project\Settings.Designer.vb">
|
|
||||||
<AutoGen>True</AutoGen>
|
|
||||||
<DependentUpon>Settings.settings</DependentUpon>
|
|
||||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
|
||||||
</Compile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Include="My Project\Resources.resx">
|
|
||||||
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
|
|
||||||
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
|
|
||||||
<CustomToolNamespace>My.Resources</CustomToolNamespace>
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
</EmbeddedResource>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="My Project\Application.myapp">
|
|
||||||
<Generator>MyApplicationCodeGenerator</Generator>
|
|
||||||
<LastGenOutput>Application.Designer.vb</LastGenOutput>
|
|
||||||
</None>
|
|
||||||
<None Include="My Project\Settings.settings">
|
|
||||||
<Generator>SettingsSingleFileGenerator</Generator>
|
|
||||||
<CustomToolNamespace>My</CustomToolNamespace>
|
|
||||||
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Include="CSScriptLibrary.dll" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\mpv.net\mpv.net.csproj">
|
|
||||||
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
|
|
||||||
<Name>mpv.net</Name>
|
|
||||||
<Private>False</Private>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
|
||||||
</Project>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
'------------------------------------------------------------------------------
|
|
||||||
' <auto-generated>
|
|
||||||
' This code was generated by a tool.
|
|
||||||
' Runtime Version:4.0.30319.42000
|
|
||||||
'
|
|
||||||
' Changes to this file may cause incorrect behavior and will be lost if
|
|
||||||
' the code is regenerated.
|
|
||||||
' </auto-generated>
|
|
||||||
'------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Option Strict On
|
|
||||||
Option Explicit On
|
|
||||||
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
|
||||||
<MySubMain>false</MySubMain>
|
|
||||||
<SingleInstance>false</SingleInstance>
|
|
||||||
<ShutdownMode>0</ShutdownMode>
|
|
||||||
<EnableVisualStyles>true</EnableVisualStyles>
|
|
||||||
<AuthenticationMode>0</AuthenticationMode>
|
|
||||||
<ApplicationType>1</ApplicationType>
|
|
||||||
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
|
|
||||||
</MyApplicationData>
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
Imports System
|
|
||||||
Imports System.Reflection
|
|
||||||
Imports System.Runtime.InteropServices
|
|
||||||
|
|
||||||
' General Information about an assembly is controlled through the following
|
|
||||||
' set of attributes. Change these attribute values to modify the information
|
|
||||||
' associated with an assembly.
|
|
||||||
|
|
||||||
' Review the values of the assembly attributes
|
|
||||||
|
|
||||||
<Assembly: AssemblyTitle("CSScriptAddon")>
|
|
||||||
<Assembly: AssemblyDescription("")>
|
|
||||||
<Assembly: AssemblyCompany("")>
|
|
||||||
<Assembly: AssemblyProduct("CSScriptAddon")>
|
|
||||||
<Assembly: AssemblyCopyright("Copyright © 2019")>
|
|
||||||
<Assembly: AssemblyTrademark("")>
|
|
||||||
|
|
||||||
<Assembly: ComVisible(False)>
|
|
||||||
|
|
||||||
'The following GUID is for the ID of the typelib if this project is exposed to COM
|
|
||||||
<Assembly: Guid("4a748201-3948-497d-b156-7d172a332bd6")>
|
|
||||||
|
|
||||||
' Version information for an assembly consists of the following four values:
|
|
||||||
'
|
|
||||||
' Major Version
|
|
||||||
' Minor Version
|
|
||||||
' Build Number
|
|
||||||
' Revision
|
|
||||||
'
|
|
||||||
' You can specify all the values or you can default the Build and Revision Numbers
|
|
||||||
' by using the '*' as shown below:
|
|
||||||
' <Assembly: AssemblyVersion("1.0.*")>
|
|
||||||
|
|
||||||
<Assembly: AssemblyVersion("1.0.0.0")>
|
|
||||||
<Assembly: AssemblyFileVersion("1.0.0.0")>
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
'------------------------------------------------------------------------------
|
|
||||||
' <auto-generated>
|
|
||||||
' This code was generated by a tool.
|
|
||||||
' Runtime Version:4.0.30319.42000
|
|
||||||
'
|
|
||||||
' Changes to this file may cause incorrect behavior and will be lost if
|
|
||||||
' the code is regenerated.
|
|
||||||
' </auto-generated>
|
|
||||||
'------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Option Strict On
|
|
||||||
Option Explicit On
|
|
||||||
|
|
||||||
Imports System
|
|
||||||
|
|
||||||
Namespace My.Resources
|
|
||||||
|
|
||||||
'This class was auto-generated by the StronglyTypedResourceBuilder
|
|
||||||
'class via a tool like ResGen or Visual Studio.
|
|
||||||
'To add or remove a member, edit your .ResX file then rerun ResGen
|
|
||||||
'with the /str option, or rebuild your VS project.
|
|
||||||
'''<summary>
|
|
||||||
''' A strongly-typed resource class, for looking up localized strings, etc.
|
|
||||||
'''</summary>
|
|
||||||
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _
|
|
||||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
|
||||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
|
||||||
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
|
||||||
Friend Module Resources
|
|
||||||
|
|
||||||
Private resourceMan As Global.System.Resources.ResourceManager
|
|
||||||
|
|
||||||
Private resourceCulture As Global.System.Globalization.CultureInfo
|
|
||||||
|
|
||||||
'''<summary>
|
|
||||||
''' Returns the cached ResourceManager instance used by this class.
|
|
||||||
'''</summary>
|
|
||||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
|
||||||
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
|
|
||||||
Get
|
|
||||||
If Object.ReferenceEquals(resourceMan, Nothing) Then
|
|
||||||
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("CSScriptAddon.Resources", GetType(Resources).Assembly)
|
|
||||||
resourceMan = temp
|
|
||||||
End If
|
|
||||||
Return resourceMan
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
|
|
||||||
'''<summary>
|
|
||||||
''' Overrides the current thread's CurrentUICulture property for all
|
|
||||||
''' resource lookups using this strongly typed resource class.
|
|
||||||
'''</summary>
|
|
||||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
|
||||||
Friend Property Culture() As Global.System.Globalization.CultureInfo
|
|
||||||
Get
|
|
||||||
Return resourceCulture
|
|
||||||
End Get
|
|
||||||
Set
|
|
||||||
resourceCulture = value
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
End Module
|
|
||||||
End Namespace
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<!--
|
|
||||||
Microsoft ResX Schema
|
|
||||||
|
|
||||||
Version 2.0
|
|
||||||
|
|
||||||
The primary goals of this format is to allow a simple XML format
|
|
||||||
that is mostly human readable. The generation and parsing of the
|
|
||||||
various data types are done through the TypeConverter classes
|
|
||||||
associated with the data types.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
... ado.net/XML headers & schema ...
|
|
||||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
|
||||||
<resheader name="version">2.0</resheader>
|
|
||||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
|
||||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
|
||||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
|
||||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
|
||||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
|
||||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
|
||||||
</data>
|
|
||||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
|
||||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
|
||||||
<comment>This is a comment</comment>
|
|
||||||
</data>
|
|
||||||
|
|
||||||
There are any number of "resheader" rows that contain simple
|
|
||||||
name/value pairs.
|
|
||||||
|
|
||||||
Each data row contains a name, and value. The row also contains a
|
|
||||||
type or mimetype. Type corresponds to a .NET class that support
|
|
||||||
text/value conversion through the TypeConverter architecture.
|
|
||||||
Classes that don't support this are serialized and stored with the
|
|
||||||
mimetype set.
|
|
||||||
|
|
||||||
The mimetype is used for serialized objects, and tells the
|
|
||||||
ResXResourceReader how to depersist the object. This is currently not
|
|
||||||
extensible. For a given mimetype the value must be set accordingly:
|
|
||||||
|
|
||||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
|
||||||
that the ResXResourceWriter will generate, however the reader can
|
|
||||||
read any of the formats listed below.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.binary.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
|
||||||
value : The object must be serialized into a byte array
|
|
||||||
: using a System.ComponentModel.TypeConverter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
-->
|
|
||||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
|
||||||
<xsd:element name="root" msdata:IsDataSet="true">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:choice maxOccurs="unbounded">
|
|
||||||
<xsd:element name="metadata">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="assembly">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:attribute name="alias" type="xsd:string" />
|
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="data">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="resheader">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:choice>
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:schema>
|
|
||||||
<resheader name="resmimetype">
|
|
||||||
<value>text/microsoft-resx</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="version">
|
|
||||||
<value>2.0</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="reader">
|
|
||||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="writer">
|
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
</root>
|
|
||||||
73
addons/CSScriptAddon/My Project/Settings.Designer.vb
generated
@@ -1,73 +0,0 @@
|
|||||||
'------------------------------------------------------------------------------
|
|
||||||
' <auto-generated>
|
|
||||||
' This code was generated by a tool.
|
|
||||||
' Runtime Version:4.0.30319.42000
|
|
||||||
'
|
|
||||||
' Changes to this file may cause incorrect behavior and will be lost if
|
|
||||||
' the code is regenerated.
|
|
||||||
' </auto-generated>
|
|
||||||
'------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Option Strict On
|
|
||||||
Option Explicit On
|
|
||||||
|
|
||||||
|
|
||||||
Namespace My
|
|
||||||
|
|
||||||
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
|
||||||
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0"), _
|
|
||||||
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
|
||||||
Partial Friend NotInheritable Class MySettings
|
|
||||||
Inherits Global.System.Configuration.ApplicationSettingsBase
|
|
||||||
|
|
||||||
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
|
|
||||||
|
|
||||||
#Region "My.Settings Auto-Save Functionality"
|
|
||||||
#If _MyType = "WindowsForms" Then
|
|
||||||
Private Shared addedHandler As Boolean
|
|
||||||
|
|
||||||
Private Shared addedHandlerLockObject As New Object
|
|
||||||
|
|
||||||
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
|
||||||
Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs)
|
|
||||||
If My.Application.SaveMySettingsOnExit Then
|
|
||||||
My.Settings.Save()
|
|
||||||
End If
|
|
||||||
End Sub
|
|
||||||
#End If
|
|
||||||
#End Region
|
|
||||||
|
|
||||||
Public Shared ReadOnly Property [Default]() As MySettings
|
|
||||||
Get
|
|
||||||
|
|
||||||
#If _MyType = "WindowsForms" Then
|
|
||||||
If Not addedHandler Then
|
|
||||||
SyncLock addedHandlerLockObject
|
|
||||||
If Not addedHandler Then
|
|
||||||
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
|
|
||||||
addedHandler = True
|
|
||||||
End If
|
|
||||||
End SyncLock
|
|
||||||
End If
|
|
||||||
#End If
|
|
||||||
Return defaultInstance
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
End Class
|
|
||||||
End Namespace
|
|
||||||
|
|
||||||
Namespace My
|
|
||||||
|
|
||||||
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
|
|
||||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
|
||||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
|
|
||||||
Friend Module MySettingsProperty
|
|
||||||
|
|
||||||
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
|
|
||||||
Friend ReadOnly Property Settings() As Global.CSScriptAddon.My.MySettings
|
|
||||||
Get
|
|
||||||
Return Global.CSScriptAddon.My.MySettings.Default
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
End Module
|
|
||||||
End Namespace
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
|
||||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">
|
|
||||||
<Profiles>
|
|
||||||
<Profile Name="(Default)" />
|
|
||||||
</Profiles>
|
|
||||||
<Settings />
|
|
||||||
</SettingsFile>
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
// this addon writes a rating to the filename of the current video,
|
|
||||||
// the input.conf defaults contain key bindings for this addon
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.ComponentModel.Composition;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
using mpvnet;
|
|
||||||
|
|
||||||
namespace RatingAddon
|
|
||||||
{
|
|
||||||
[Export(typeof(IAddon))]
|
|
||||||
public class RatingAddon : IAddon
|
|
||||||
{
|
|
||||||
Dictionary<string, int> Dic = new Dictionary<string, int>();
|
|
||||||
|
|
||||||
public RatingAddon()
|
|
||||||
{
|
|
||||||
mp.ClientMessage += ClientMessage; //handles keys defined in input.conf
|
|
||||||
mp.Shutdown += Shutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shutdown()
|
|
||||||
{
|
|
||||||
foreach (var i in Dic)
|
|
||||||
{
|
|
||||||
string filepath = i.Key;
|
|
||||||
int rating = i.Value;
|
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(filepath) || ! File.Exists(filepath))
|
|
||||||
return;
|
|
||||||
|
|
||||||
string basename = Path.GetFileNameWithoutExtension(filepath);
|
|
||||||
|
|
||||||
for (int x = 0; x < 6; x++)
|
|
||||||
if (basename.Contains(" (" + x.ToString() + "stars)"))
|
|
||||||
basename = basename.Replace(" (" + x.ToString() + "stars)", "");
|
|
||||||
|
|
||||||
basename += $" ({rating}stars)";
|
|
||||||
string newPath = Path.Combine(Path.GetDirectoryName(filepath), basename + Path.GetExtension(filepath));
|
|
||||||
|
|
||||||
if (filepath.ToLower() != newPath.ToLower())
|
|
||||||
File.Move(filepath, newPath);
|
|
||||||
|
|
||||||
File.SetLastWriteTime(newPath, DateTime.Now);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//handles keys defined in input.conf
|
|
||||||
void ClientMessage(string[] args)
|
|
||||||
{
|
|
||||||
if (args[0] != "rate-file" || ! int.TryParse(args[1], out int rating))
|
|
||||||
return;
|
|
||||||
Dic[mp.get_property_string("path")] = rating;
|
|
||||||
mp.commandv("show-text", $"Rating: {rating}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
using System.ComponentModel.Composition;
|
|
||||||
|
|
||||||
using mpvnet;
|
|
||||||
|
|
||||||
namespace TestAddon
|
|
||||||
{
|
|
||||||
[Export(typeof(IAddon))]
|
|
||||||
public class TestAddon : IAddon
|
|
||||||
{
|
|
||||||
// do some init work in constructor
|
|
||||||
public TestAddon()
|
|
||||||
{
|
|
||||||
// Observe changes of the fullscreen property.
|
|
||||||
// You can find a list of available mpv properties
|
|
||||||
// in mpv.net's wiki on github or use mpv --list-properties.
|
|
||||||
// You can test properties in mpv.net in the menu at:
|
|
||||||
// Tools > Execute mpv command
|
|
||||||
// where you can enter: show-text ${fullscreen}
|
|
||||||
mp.observe_property_bool("fullscreen", OnFullscreenChange);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnFullscreenChange(bool val)
|
|
||||||
{
|
|
||||||
mp.commandv("show-text", "fullscreen: " + val.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
|
|||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("RatingAddon")]
|
[assembly: AssemblyTitle("RatingExtension")]
|
||||||
[assembly: AssemblyDescription("")]
|
[assembly: AssemblyDescription("")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("")]
|
[assembly: AssemblyCompany("")]
|
||||||
[assembly: AssemblyProduct("RatingAddon")]
|
[assembly: AssemblyProduct("RatingExtension")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
[assembly: AssemblyCopyright("Copyright © 2017-2019 Frank Skare (stax76)")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
65
extensions/RatingExtension/RatingExtension.cs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
// This extension writes a rating to the filename of rated videos when mpv.net shuts down.
|
||||||
|
|
||||||
|
// The input.conf defaults contain key bindings for this extension to set ratings.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
using mpvnet;
|
||||||
|
|
||||||
|
namespace RatingExtension // the assembly name must end with 'Extension'
|
||||||
|
{
|
||||||
|
[Export(typeof(IExtension))]
|
||||||
|
public class RatingExtension : IExtension
|
||||||
|
{
|
||||||
|
// dictionory to store the filename and the rating
|
||||||
|
Dictionary<string, int> Dic = new Dictionary<string, int>();
|
||||||
|
|
||||||
|
public RatingExtension() // plugin initialization
|
||||||
|
{
|
||||||
|
mp.ClientMessage += ClientMessage; //handles keys defined in input.conf
|
||||||
|
mp.Shutdown += Shutdown; // handles MPV_EVENT_SHUTDOWN
|
||||||
|
}
|
||||||
|
|
||||||
|
// handles MPV_EVENT_SHUTDOWN
|
||||||
|
void Shutdown()
|
||||||
|
{
|
||||||
|
foreach (var i in Dic)
|
||||||
|
{
|
||||||
|
string filepath = i.Key;
|
||||||
|
int rating = i.Value;
|
||||||
|
if (String.IsNullOrEmpty(filepath) || !File.Exists(filepath))
|
||||||
|
return;
|
||||||
|
string basename = Path.GetFileNameWithoutExtension(filepath);
|
||||||
|
|
||||||
|
for (int x = 0; x < 6; x++)
|
||||||
|
if (basename.Contains(" (" + x + "stars)"))
|
||||||
|
basename = basename.Replace(" (" + x + "stars)", "");
|
||||||
|
|
||||||
|
basename += $" ({rating}stars)";
|
||||||
|
string newPath = Path.Combine(Path.GetDirectoryName(filepath), basename + Path.GetExtension(filepath));
|
||||||
|
if (filepath.ToLower() != newPath.ToLower())
|
||||||
|
File.Move(filepath, newPath);
|
||||||
|
File.SetLastWriteTime(newPath, DateTime.Now);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//handles keys defined in input.conf
|
||||||
|
void ClientMessage(string[] args)
|
||||||
|
{
|
||||||
|
if (args[0] != "rate-file") return;
|
||||||
|
|
||||||
|
if (int.TryParse(args[1], out int rating))
|
||||||
|
{
|
||||||
|
string path = mp.get_property_string("path");
|
||||||
|
if (!File.Exists(path)) return;
|
||||||
|
Dic[path] = rating;
|
||||||
|
mp.commandv("show-text", $"Rating: {rating}");
|
||||||
|
}
|
||||||
|
else if (args[1] == "about")
|
||||||
|
Msg.Show("Rating Extension", "This extension writes a rating to the filename of rated videos when mpv.net shuts down.\n\nThe input.conf defaults contain key bindings for this extension to set ratings.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,53 +4,18 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
<ProjectGuid>{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}</ProjectGuid>
|
<ProjectGuid>{55C88710-539D-4402-84C8-31694841C731}</ProjectGuid>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>TestAddon</RootNamespace>
|
<RootNamespace>RatingExtension</RootNamespace>
|
||||||
<AssemblyName>TestAddon</AssemblyName>
|
<AssemblyName>RatingExtension</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<Deterministic>true</Deterministic>
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<Optimize>false</Optimize>
|
|
||||||
<OutputPath>bin\</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<OutputPath>bin\</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
|
||||||
<OutputPath>bin\x64\Release\</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
<OutputPath>..\..\mpv.net\bin\x86\Extensions\RatingExtension\</OutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
@@ -58,7 +23,7 @@
|
|||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
<OutputPath>bin\x86\Release\</OutputPath>
|
<OutputPath>..\..\mpv.net\bin\x86\Extensions\RatingExtension\</OutputPath>
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
@@ -66,6 +31,24 @@
|
|||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>..\..\mpv.net\bin\x64\Extensions\RatingExtension\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<OutputPath>..\..\mpv.net\bin\x64\Extensions\RatingExtension\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.ComponentModel.Composition" />
|
<Reference Include="System.ComponentModel.Composition" />
|
||||||
@@ -78,7 +61,7 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="TestAddon.cs" />
|
<Compile Include="RatingExtension.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
|
|||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("TestAddon")]
|
[assembly: AssemblyTitle("RatingExtension")]
|
||||||
[assembly: AssemblyDescription("")]
|
[assembly: AssemblyDescription("")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("")]
|
[assembly: AssemblyCompany("")]
|
||||||
[assembly: AssemblyProduct("TestAddon")]
|
[assembly: AssemblyProduct("RatingExtension")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 2019")]
|
[assembly: AssemblyCopyright("Copyright © 2017-2019 Frank Skare (stax76)")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ using System.Runtime.InteropServices;
|
|||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
[assembly: Guid("06f854b0-00f9-4b53-94d9-0be65a7c55d8")]
|
[assembly: Guid("55c88710-539d-4402-84c8-31694841c731")]
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
// Version information for an assembly consists of the following four values:
|
||||||
//
|
//
|
||||||
48
extensions/ScriptingExtension/ScriptingExtension.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
// This extension implements the C# scripting feature of mpv.net which
|
||||||
|
// is based on CS-Script (https://www.cs-script.net).
|
||||||
|
|
||||||
|
// I also use this extension to code scripts in order to have full
|
||||||
|
// code completion and debugger support, once the script code is
|
||||||
|
// finished I move it from the extension to a standalone script.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
using mpvnet;
|
||||||
|
using CSScriptLibrary;
|
||||||
|
|
||||||
|
namespace ScriptingExtension // the file name of extensions must end with 'Extension'
|
||||||
|
{
|
||||||
|
[Export(typeof(IExtension))]
|
||||||
|
public class ScriptingExtension : IExtension
|
||||||
|
{
|
||||||
|
//Script Script;
|
||||||
|
|
||||||
|
public ScriptingExtension()
|
||||||
|
{
|
||||||
|
//Script = new Script();
|
||||||
|
List<string> scriptFiles = new List<string>();
|
||||||
|
|
||||||
|
if (Directory.Exists(mp.ConfigFolder + "scripts"))
|
||||||
|
scriptFiles.AddRange(Directory.GetFiles(mp.ConfigFolder + "scripts", "*.cs"));
|
||||||
|
|
||||||
|
if (Directory.Exists(Folder.Startup + "scripts"))
|
||||||
|
foreach (string path in Directory.GetFiles(Folder.Startup + "scripts", "*.cs"))
|
||||||
|
scriptFiles.AddRange(Directory.GetFiles(Folder.Startup + "scripts", "*.cs"));
|
||||||
|
|
||||||
|
if (scriptFiles.Count == 0) return;
|
||||||
|
CSScriptLibrary.CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom;
|
||||||
|
|
||||||
|
foreach (var i in scriptFiles)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
CSScriptLibrary.CSScript.Evaluator.LoadCode(File.ReadAllText(i));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Msg.ShowException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,35 +4,18 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
<ProjectGuid>{55C88710-539D-4402-84C8-31694841C731}</ProjectGuid>
|
<ProjectGuid>{94255EF2-C823-4D82-9017-0E993CC0F5A1}</ProjectGuid>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>RatingAddon</RootNamespace>
|
<RootNamespace>ScriptingExtension</RootNamespace>
|
||||||
<AssemblyName>RatingAddon</AssemblyName>
|
<AssemblyName>ScriptingExtension</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<Optimize>false</Optimize>
|
|
||||||
<OutputPath>..\mpv.net\bin\Addons\RatingAddon\</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<OutputPath>..\mpv.net\bin\Addons\RatingAddon\</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<OutputPath>..\..\mpv.net\bin\x86\Addons\RatingAddon\</OutputPath>
|
<OutputPath>..\..\mpv.net\bin\x86\Extensions\ScriptingExtension\</OutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
@@ -40,7 +23,7 @@
|
|||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
<OutputPath>..\mpv.net\bin\x86\Addons\RatingAddon\</OutputPath>
|
<OutputPath>..\..\mpv.net\bin\x86\Extensions\ScriptingExtension\</OutputPath>
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
@@ -50,7 +33,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<OutputPath>..\..\mpv.net\bin\x64\Addons\RatingAddon\</OutputPath>
|
<OutputPath>..\..\mpv.net\bin\x64\Extensions\ScriptingExtension\</OutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
@@ -58,7 +41,7 @@
|
|||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
<OutputPath>..\mpv.net\bin\x64\Addons\RatingAddon\</OutputPath>
|
<OutputPath>..\..\mpv.net\bin\x64\Extensions\ScriptingExtension\</OutputPath>
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
@@ -67,9 +50,13 @@
|
|||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="CSScriptLibrary">
|
||||||
|
<HintPath>.\CSScriptLibrary.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.ComponentModel.Composition" />
|
<Reference Include="System.ComponentModel.Composition" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
@@ -78,8 +65,9 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="RatingAddon.cs" />
|
<Compile Include="ScriptingExtension.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="script.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\mpv.net\mpv.net.csproj">
|
<ProjectReference Include="..\..\mpv.net\mpv.net.csproj">
|
||||||
31
extensions/ScriptingExtension/ScriptingExtension.sln
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.29123.88
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScriptingExtension", "ScriptingExtension.csproj", "{55C88710-539D-4402-84C8-31694841C731}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.Build.0 = Release|x64
|
||||||
|
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.Build.0 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {C8A53BF6-B00A-4215-B9D7-801ADB9C8F60}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
17
extensions/ScriptingExtension/script.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System.IO;
|
||||||
|
|
||||||
|
using mpvnet;
|
||||||
|
|
||||||
|
class Script
|
||||||
|
{
|
||||||
|
public Script()
|
||||||
|
{
|
||||||
|
mp.Shutdown += Shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Shutdown()
|
||||||
|
{
|
||||||
|
foreach (string file in Directory.GetFiles(@"C:\Users\frank\Desktop\aaa"))
|
||||||
|
File.Delete(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
img/Avatar.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
img/Main.png
|
Before Width: | Height: | Size: 5.8 MiB After Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 628 KiB |
BIN
img/Terminal.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
img/mpvnet.ico
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
img/mpvnet.pdn
BIN
img/mpvnet.png
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 8.2 KiB |
56
mpv.net.sln
@@ -5,70 +5,42 @@ VisualStudioVersion = 16.0.28729.10
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mpv.net", "mpv.net\mpv.net.csproj", "{1751F378-8EDF-4B62-BE6D-304C7C287089}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mpv.net", "mpv.net\mpv.net.csproj", "{1751F378-8EDF-4B62-BE6D-304C7C287089}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CSScriptAddon", "addons\CSScriptAddon\CSScriptAddon.vbproj", "{71808A87-8B1C-4DF8-957C-D79C3B164CCA}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatingExtension", "extensions\RatingExtension\RatingExtension.csproj", "{55C88710-539D-4402-84C8-31694841C731}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatingAddon", "addons\RatingAddon\RatingAddon.csproj", "{55C88710-539D-4402-84C8-31694841C731}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScriptingExtension", "extensions\ScriptingExtension\ScriptingExtension.csproj", "{94255EF2-C823-4D82-9017-0E993CC0F5A1}"
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestAddon", "addons\TestAddon\TestAddon.csproj", "{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}"
|
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
Debug|x86 = Debug|x86
|
Debug|x86 = Debug|x86
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
Release|x64 = Release|x64
|
Release|x64 = Release|x64
|
||||||
Release|x86 = Release|x86
|
Release|x86 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x64.ActiveCfg = Debug|x64
|
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x64.Build.0 = Debug|x64
|
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x64.Build.0 = Debug|x64
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.ActiveCfg = Debug|x86
|
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.ActiveCfg = Debug|x64
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.Build.0 = Debug|x86
|
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.Build.0 = Debug|x64
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x64.ActiveCfg = Release|x64
|
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x64.ActiveCfg = Release|x64
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x64.Build.0 = Release|x64
|
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x64.Build.0 = Release|x64
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.ActiveCfg = Release|x86
|
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.ActiveCfg = Release|x86
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.Build.0 = Release|x86
|
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.Build.0 = Release|x86
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x86.ActiveCfg = Debug|x86
|
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x86.Build.0 = Debug|x86
|
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x64.Build.0 = Release|x64
|
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x86.ActiveCfg = Release|x86
|
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x86.Build.0 = Release|x86
|
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.ActiveCfg = Debug|x64
|
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.Build.0 = Debug|x64
|
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.Build.0 = Debug|x64
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.ActiveCfg = Debug|x86
|
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.ActiveCfg = Debug|x64
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.Build.0 = Debug|x86
|
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.Build.0 = Debug|x64
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.ActiveCfg = Release|x64
|
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.ActiveCfg = Release|x64
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.Build.0 = Release|x64
|
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.Build.0 = Release|x64
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.ActiveCfg = Release|x86
|
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.ActiveCfg = Release|x86
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.Build.0 = Release|x86
|
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.Build.0 = Release|x86
|
||||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Debug|x64.Build.0 = Debug|x64
|
||||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x64.ActiveCfg = Debug|x64
|
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Debug|x86.ActiveCfg = Debug|x64
|
||||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x64.Build.0 = Debug|x64
|
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Debug|x86.Build.0 = Debug|x64
|
||||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x86.ActiveCfg = Debug|x86
|
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Release|x64.ActiveCfg = Release|x64
|
||||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x86.Build.0 = Debug|x86
|
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Release|x64.Build.0 = Release|x64
|
||||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Release|x86.ActiveCfg = Release|x86
|
||||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|Any CPU.Build.0 = Release|Any CPU
|
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Release|x86.Build.0 = Release|x86
|
||||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
<configSections>
|
<configSections>
|
||||||
</configSections>
|
</configSections>
|
||||||
<startup>
|
<startup>
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
|
||||||
</startup>
|
</startup>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
<UserControl x:Class="Controls.SearchTextBoxUserControl"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
d:DesignHeight="450" d:DesignWidth="800">
|
|
||||||
<Grid x:Name="SearchTextBoxUserControl1" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}">
|
|
||||||
<TextBlock x:Name="HintTextBlock" Margin="5,2" Text="Find a setting" Foreground="LightSteelBlue" VerticalAlignment="Center" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
|
|
||||||
<TextBox Name="SearchTextBox" Height="25" Padding="1,2,0,0" BorderThickness="2" Background="Transparent" TextChanged="SearchTextBox_TextChanged" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" CaretBrush="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
|
|
||||||
<Button x:Name="SearchClearButton" Background="Transparent" HorizontalAlignment="Right" Margin="2,0,4,0" FontSize="10" Width="17" Height="17" Visibility="Hidden" Click="SearchClearButton_Click" FontFamily="Marlett" Foreground="{Binding Path=Foreground2, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}">r</Button>
|
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
|
||||||
@@ -15,8 +15,10 @@ namespace DynamicGUI
|
|||||||
public static List<SettingBase> LoadSettings(string content)
|
public static List<SettingBase> LoadSettings(string content)
|
||||||
{
|
{
|
||||||
TomlTable table;
|
TomlTable table;
|
||||||
|
|
||||||
using (StringReader reader = new StringReader(content))
|
using (StringReader reader = new StringReader(content))
|
||||||
table = TOML.Parse(reader);
|
table = TOML.Parse(reader);
|
||||||
|
|
||||||
List<SettingBase> settingsList = new List<SettingBase>();
|
List<SettingBase> settingsList = new List<SettingBase>();
|
||||||
|
|
||||||
foreach (TomlTable setting in table["settings"])
|
foreach (TomlTable setting in table["settings"])
|
||||||
@@ -29,18 +31,20 @@ namespace DynamicGUI
|
|||||||
baseSetting = optionSetting;
|
baseSetting = optionSetting;
|
||||||
optionSetting.Default = setting["default"];
|
optionSetting.Default = setting["default"];
|
||||||
optionSetting.Value = optionSetting.Default;
|
optionSetting.Value = optionSetting.Default;
|
||||||
optionSetting.StartValue = optionSetting.Default;
|
|
||||||
|
|
||||||
foreach (TomlTable option in setting["options"])
|
foreach (TomlTable option in setting["options"])
|
||||||
{
|
{
|
||||||
var opt = new OptionSettingOption();
|
var opt = new OptionSettingOption();
|
||||||
opt.Name = option["name"];
|
opt.Name = option["name"];
|
||||||
|
|
||||||
if (option.HasKey("help"))
|
if (option.HasKey("help"))
|
||||||
opt.Help = option["help"];
|
opt.Help = option["help"];
|
||||||
|
|
||||||
if (option.HasKey("text"))
|
if (option.HasKey("text"))
|
||||||
opt.Text = option["text"];
|
opt.Text = option["text"];
|
||||||
else if (opt.Name == optionSetting.Default)
|
else if (opt.Name == optionSetting.Default)
|
||||||
opt.Text = opt.Name + " (Default)";
|
opt.Text = opt.Name + " (Default)";
|
||||||
|
|
||||||
opt.OptionSetting = optionSetting;
|
opt.OptionSetting = optionSetting;
|
||||||
optionSetting.Options.Add(opt);
|
optionSetting.Options.Add(opt);
|
||||||
}
|
}
|
||||||
@@ -53,10 +57,11 @@ namespace DynamicGUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
baseSetting.Name = setting["name"];
|
baseSetting.Name = setting["name"];
|
||||||
|
baseSetting.File = setting["file"];
|
||||||
baseSetting.Filter = setting["filter"];
|
baseSetting.Filter = setting["filter"];
|
||||||
|
|
||||||
if (setting.HasKey("help")) baseSetting.Help = setting["help"];
|
if (setting.HasKey("help")) baseSetting.Help = setting["help"];
|
||||||
if (setting.HasKey("helpurl")) baseSetting.HelpURL = setting["helpurl"];
|
if (setting.HasKey("url")) baseSetting.URL = setting["url"];
|
||||||
if (setting.HasKey("width")) baseSetting.Width = setting["width"];
|
if (setting.HasKey("width")) baseSetting.Width = setting["width"];
|
||||||
if (setting.HasKey("type")) baseSetting.Type = setting["type"];
|
if (setting.HasKey("type")) baseSetting.Type = setting["type"];
|
||||||
|
|
||||||
@@ -66,17 +71,30 @@ namespace DynamicGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ConfItem
|
||||||
|
{
|
||||||
|
public string Name { get; set; } = "";
|
||||||
|
public string Value { get; set; } = "";
|
||||||
|
public string Comment { get; set; } = "";
|
||||||
|
public string LineComment { get; set; } = "";
|
||||||
|
public string Section { get; set; } = "";
|
||||||
|
public string File { get; set; } = "";
|
||||||
|
public bool IsSectionItem { get; set; }
|
||||||
|
public SettingBase SettingBase { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class SettingBase
|
public abstract class SettingBase
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
public string File { get; set; }
|
||||||
public string Value { get; set; }
|
public string Value { get; set; }
|
||||||
public string StartValue { get; set; }
|
|
||||||
public string Help { get; set; }
|
public string Help { get; set; }
|
||||||
public string Default { get; set; }
|
public string Default { get; set; }
|
||||||
public string HelpURL { get; set; }
|
public string URL { get; set; }
|
||||||
public string Filter { get; set; }
|
public string Filter { get; set; }
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
public int Width { get; set; }
|
public int Width { get; set; }
|
||||||
|
public ConfItem ConfItem { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StringSetting : SettingBase
|
public class StringSetting : SettingBase
|
||||||
@@ -106,7 +124,10 @@ namespace DynamicGUI
|
|||||||
public bool Checked
|
public bool Checked
|
||||||
{
|
{
|
||||||
get => OptionSetting.Value == Name ;
|
get => OptionSetting.Value == Name ;
|
||||||
set { if (value) OptionSetting.Value = Name; }
|
set {
|
||||||
|
if (value)
|
||||||
|
OptionSetting.Value = Name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Visibility Visibility
|
public Visibility Visibility
|
||||||
|
|||||||
@@ -4,22 +4,58 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:DynamicGUI"
|
xmlns:local="clr-namespace:DynamicGUI"
|
||||||
|
xmlns:UI="clr-namespace:UI"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="450" d:DesignWidth="800">
|
|
||||||
|
d:DesignHeight="450"
|
||||||
|
d:DesignWidth="800">
|
||||||
|
|
||||||
<Grid Margin="20,0">
|
<Grid Margin="20,0">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<TextBox x:Name="TitleTextBox" FontSize="24" Margin="0,10" BorderThickness="0" IsReadOnly="True" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"></TextBox>
|
<TextBox x:Name="TitleTextBox"
|
||||||
|
FontSize="24"
|
||||||
|
Margin="0,10"
|
||||||
|
BorderThickness="0"
|
||||||
|
IsReadOnly="True"
|
||||||
|
Foreground="{x:Static UI:Theme.Heading}"
|
||||||
|
Background="{x:Static UI:Theme.Background}" />
|
||||||
|
|
||||||
<ItemsControl x:Name="ItemsControl">
|
<ItemsControl x:Name="ItemsControl">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<WrapPanel Orientation="Vertical">
|
<WrapPanel Orientation="Vertical">
|
||||||
<RadioButton x:Name="RadioButton" VerticalContentAlignment="Center" IsChecked="{Binding Checked}" GroupName="{Binding OptionSetting.Name}" Content="{Binding Text}" FontSize="16" FontWeight="Normal" VerticalAlignment="Top" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"></RadioButton>
|
<RadioButton x:Name="RadioButton"
|
||||||
<TextBox x:Name="ItemHelpTextBox" TextWrapping="WrapWithOverflow" Text="{Binding Help}" Visibility="{Binding Visibility}" Margin="10,0,0,0" BorderThickness="0" IsReadOnly="True" Padding="7,0,0,0" MinHeight="0" Foreground="{Binding Path=Foreground2, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"></TextBox>
|
VerticalContentAlignment="Center"
|
||||||
|
IsChecked="{Binding Checked}"
|
||||||
|
GroupName="{Binding OptionSetting.Name}"
|
||||||
|
Content="{Binding Text}"
|
||||||
|
FontSize="16"
|
||||||
|
FontWeight="Normal"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground}"/>
|
||||||
|
|
||||||
|
<TextBox x:Name="ItemHelpTextBox"
|
||||||
|
TextWrapping="WrapWithOverflow"
|
||||||
|
Text="{Binding Help}"
|
||||||
|
Visibility="{Binding Visibility}"
|
||||||
|
Margin="10,0,0,0" BorderThickness="0"
|
||||||
|
IsReadOnly="True" Padding="7,0,0,0"
|
||||||
|
MinHeight="0"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground2}"
|
||||||
|
Background="{x:Static UI:Theme.Background}"/>
|
||||||
|
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
<TextBox x:Name="HelpTextBox" TextWrapping="WrapWithOverflow" BorderThickness="0" IsReadOnly="True" Margin="0,10,0,0" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"></TextBox>
|
|
||||||
|
<TextBox x:Name="HelpTextBox"
|
||||||
|
TextWrapping="WrapWithOverflow"
|
||||||
|
BorderThickness="0"
|
||||||
|
IsReadOnly="True"
|
||||||
|
Margin="0,10,0,0"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground}"
|
||||||
|
Background="{x:Static UI:Theme.Background}"/>
|
||||||
<TextBlock x:Name="LinkTextBlock" Margin="0,10">
|
<TextBlock x:Name="LinkTextBlock" Margin="0,10">
|
||||||
<local:HyperlinkEx x:Name="Link"></local:HyperlinkEx>
|
<local:HyperlinkEx x:Name="Link"></local:HyperlinkEx>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ namespace DynamicGUI
|
|||||||
HelpTextBox.Visibility = Visibility.Collapsed;
|
HelpTextBox.Visibility = Visibility.Collapsed;
|
||||||
HelpTextBox.Text = optionSetting.Help;
|
HelpTextBox.Text = optionSetting.Help;
|
||||||
ItemsControl.ItemsSource = optionSetting.Options;
|
ItemsControl.ItemsSource = optionSetting.Options;
|
||||||
if (string.IsNullOrEmpty(optionSetting.HelpURL))
|
if (string.IsNullOrEmpty(optionSetting.URL))
|
||||||
LinkTextBlock.Visibility = Visibility.Collapsed;
|
LinkTextBlock.Visibility = Visibility.Collapsed;
|
||||||
Link.SetURL(optionSetting.HelpURL);
|
Link.SetURL(optionSetting.URL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _SearchableText;
|
private string _SearchableText;
|
||||||
|
|||||||
@@ -4,21 +4,52 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:DynamicGUI"
|
xmlns:local="clr-namespace:DynamicGUI"
|
||||||
|
xmlns:UI="clr-namespace:UI"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
d:DesignWidth="800">
|
d:DesignWidth="800">
|
||||||
|
|
||||||
<Grid Margin="20,0">
|
<Grid Margin="20,0">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<TextBox x:Name="TitleTextBox" FontSize="24" Margin="0,10" BorderThickness="0" IsReadOnly="True" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"></TextBox>
|
<TextBox x:Name="TitleTextBox"
|
||||||
|
FontSize="24"
|
||||||
|
Margin="0,10"
|
||||||
|
BorderThickness="0"
|
||||||
|
IsReadOnly="True"
|
||||||
|
Foreground="{x:Static UI:Theme.Heading}"
|
||||||
|
Background="{x:Static UI:Theme.Background}"/>
|
||||||
|
|
||||||
<Grid Margin="0,0,0,10">
|
<Grid Margin="0,0,0,10">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<TextBox x:Name="ValueTextBox" Text="{Binding Path=Text, ElementName=StringSettingControl1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="150" HorizontalAlignment="Left" Height="20" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" TextChanged="ValueTextBox_TextChanged"/>
|
<TextBox x:Name="ValueTextBox"
|
||||||
<Button x:Name="Button" Height="20" Grid.Column="1" Visibility="{Binding Path=Text, ElementName=StringSettingControl1}" Margin="5,0,0,0" Width="20" Click="Button_Click">...</Button>
|
Text="{Binding Path=Text, ElementName=StringSettingControl1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
Width="150"
|
||||||
|
Height="20"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground}"
|
||||||
|
Background="{x:Static UI:Theme.Background}"
|
||||||
|
CaretBrush="{x:Static UI:Theme.Foreground}"
|
||||||
|
TextChanged="ValueTextBox_TextChanged"/>
|
||||||
|
|
||||||
|
<Button x:Name="Button"
|
||||||
|
Height="20"
|
||||||
|
Grid.Column="1"
|
||||||
|
Visibility="{Binding Path=Text, ElementName=StringSettingControl1}"
|
||||||
|
Margin="5,0,0,0"
|
||||||
|
Width="20"
|
||||||
|
Click="Button_Click">...</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
<TextBox x:Name="HelpTextBox" TextWrapping="WrapWithOverflow" BorderThickness="0" IsReadOnly="True" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"></TextBox>
|
|
||||||
|
<TextBox x:Name="HelpTextBox"
|
||||||
|
TextWrapping="WrapWithOverflow"
|
||||||
|
BorderThickness="0"
|
||||||
|
IsReadOnly="True"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground}"
|
||||||
|
Background="{x:Static UI:Theme.Background}"/>
|
||||||
|
|
||||||
<TextBlock x:Name="LinkTextBlock" Margin="0,10">
|
<TextBlock x:Name="LinkTextBlock" Margin="0,10">
|
||||||
<local:HyperlinkEx x:Name="Link"></local:HyperlinkEx>
|
<local:HyperlinkEx x:Name="Link"></local:HyperlinkEx>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
@@ -22,8 +23,8 @@ namespace DynamicGUI
|
|||||||
ValueTextBox.Width = StringSetting.Width;
|
ValueTextBox.Width = StringSetting.Width;
|
||||||
if (StringSetting.Type != "folder" && StringSetting.Type != "color")
|
if (StringSetting.Type != "folder" && StringSetting.Type != "color")
|
||||||
Button.Visibility = Visibility.Hidden;
|
Button.Visibility = Visibility.Hidden;
|
||||||
Link.SetURL(StringSetting.HelpURL);
|
Link.SetURL(StringSetting.URL);
|
||||||
if (string.IsNullOrEmpty(stringSetting.HelpURL))
|
if (string.IsNullOrEmpty(stringSetting.URL))
|
||||||
LinkTextBlock.Visibility = Visibility.Collapsed;
|
LinkTextBlock.Visibility = Visibility.Collapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,20 +56,25 @@ namespace DynamicGUI
|
|||||||
{
|
{
|
||||||
d.Description = "Choose a folder.";
|
d.Description = "Choose a folder.";
|
||||||
d.SelectedPath = ValueTextBox.Text;
|
d.SelectedPath = ValueTextBox.Text;
|
||||||
if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
if (d.ShowDialog() == WinForms.DialogResult.OK)
|
||||||
ValueTextBox.Text = d.SelectedPath;
|
ValueTextBox.Text = d.SelectedPath;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "color":
|
case "color":
|
||||||
using (var d = new WinForms.ColorDialog())
|
using (var dialog = new WinForms.ColorDialog())
|
||||||
{
|
{
|
||||||
d.FullOpen = true;
|
dialog.FullOpen = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (!string.IsNullOrEmpty(ValueTextBox.Text))
|
||||||
|
{
|
||||||
Color col = GetColor(ValueTextBox.Text);
|
Color col = GetColor(ValueTextBox.Text);
|
||||||
d.Color = System.Drawing.Color.FromArgb(col.A, col.R, col.G, col.B);
|
dialog.Color = System.Drawing.Color.FromArgb(col.A, col.R, col.G, col.B);
|
||||||
|
}
|
||||||
} catch {}
|
} catch {}
|
||||||
if (d.ShowDialog() == WinForms.DialogResult.OK)
|
|
||||||
ValueTextBox.Text = System.Drawing.ColorTranslator.ToHtml(d.Color);
|
if (dialog.ShowDialog() == WinForms.DialogResult.OK)
|
||||||
|
ValueTextBox.Text = "#" + dialog.Color.ToArgb().ToString("X8");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.Composition;
|
|
||||||
using System.ComponentModel.Composition.Hosting;
|
|
||||||
using System.IO;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace mpvnet
|
|
||||||
{
|
|
||||||
public class Addon
|
|
||||||
{
|
|
||||||
[ImportMany]
|
|
||||||
public IEnumerable<IAddon> Addons = null;
|
|
||||||
|
|
||||||
readonly CompositionContainer CompositionContainer;
|
|
||||||
|
|
||||||
public Addon()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
AggregateCatalog catalog = new AggregateCatalog();
|
|
||||||
|
|
||||||
string dir = Application.StartupPath + "\\Addons";
|
|
||||||
|
|
||||||
if (Directory.Exists(dir))
|
|
||||||
foreach (string i in Directory.GetDirectories(dir))
|
|
||||||
catalog.Catalogs.Add(new DirectoryCatalog(i, "*Addon.dll"));
|
|
||||||
|
|
||||||
dir = mp.ConfFolder + "\\Addons";
|
|
||||||
|
|
||||||
if (Directory.Exists(dir))
|
|
||||||
foreach (string i in Directory.GetDirectories(dir))
|
|
||||||
catalog.Catalogs.Add(new DirectoryCatalog(i, "*Addon.dll"));
|
|
||||||
|
|
||||||
if (catalog.Catalogs.Count > 0)
|
|
||||||
{
|
|
||||||
CompositionContainer = new CompositionContainer(catalog);
|
|
||||||
CompositionContainer.ComposeParts(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Msg.ShowException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IAddon
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
139
mpv.net/Misc/App.cs
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using UI;
|
||||||
|
|
||||||
|
namespace mpvnet
|
||||||
|
{
|
||||||
|
public static class App
|
||||||
|
{
|
||||||
|
public static string[] VideoTypes { get; } = "264 265 asf avc avi avs flv h264 h265 hevc m2ts m2v m4v mkv mov mp4 mpeg mpg mpv mts ts vob vpy webm wmv y4m".Split(' ');
|
||||||
|
public static string[] AudioTypes { get; } = "mp3 mp2 ac3 ogg opus flac wav w64 m4a dts dtsma dtshr dtshd eac3 thd thd+ac3 mka aac mpa".Split(' ');
|
||||||
|
public static string[] ImageTypes { get; } = {"jpg", "bmp", "gif", "png"};
|
||||||
|
public static string[] SubtitleTypes { get; } = { "srt", "ass", "idx", "sup", "ttxt", "ssa", "smi" };
|
||||||
|
|
||||||
|
public static string RegPath { get; } = @"HKCU\Software\" + Application.ProductName;
|
||||||
|
public static string ConfPath { get => mp.ConfigFolder + "mpvnet.conf"; }
|
||||||
|
public static string ProcessInstance { get; set; } = "single";
|
||||||
|
public static string DarkMode { get; set; } = "always";
|
||||||
|
public static string DarkTheme { get; set; } = "dark";
|
||||||
|
public static string LightTheme { get; set; } = "light";
|
||||||
|
|
||||||
|
public static bool RememberHeight { get; set; } = true;
|
||||||
|
public static bool RememberPosition { get; set; }
|
||||||
|
public static bool Maximized { get; set; }
|
||||||
|
public static bool DebugMode { get; set; }
|
||||||
|
public static bool IsStartedFromTerminal { get; } = Environment.GetEnvironmentVariable("_started_from_console") == "yes";
|
||||||
|
public static bool RememberVolume { get; set; } = true;
|
||||||
|
public static bool AutoLoadFolder { get; set; } = true;
|
||||||
|
public static bool Queue { get; set; }
|
||||||
|
|
||||||
|
public static int StartThreshold { get; set; } = 1500;
|
||||||
|
public static int RecentCount { get; set; } = 15;
|
||||||
|
|
||||||
|
public static float MinimumAspectRatio { get; set; } = 1.3f;
|
||||||
|
|
||||||
|
public static Extension Extension { get; set; }
|
||||||
|
|
||||||
|
public static bool IsDarkMode {
|
||||||
|
get => (DarkMode == "system" && Sys.IsDarkTheme) || DarkMode == "always";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Init()
|
||||||
|
{
|
||||||
|
string dummy = mp.ConfigFolder;
|
||||||
|
var dummy2 = mp.Conf;
|
||||||
|
|
||||||
|
foreach (var i in Conf)
|
||||||
|
ProcessProperty(i.Key, i.Value);
|
||||||
|
|
||||||
|
if (App.DebugMode)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string filePath = mp.ConfigFolder + "mpvnet-debug.log";
|
||||||
|
if (File.Exists(filePath)) File.Delete(filePath);
|
||||||
|
Trace.Listeners.Add(new TextWriterTraceListener(filePath));
|
||||||
|
Trace.AutoFlush = true;
|
||||||
|
//if (App.DebugMode) Trace.WriteLine("");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Msg.ShowException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string themeContent = null;
|
||||||
|
|
||||||
|
if (File.Exists(mp.ConfigFolder + "theme.conf"))
|
||||||
|
themeContent = File.ReadAllText(mp.ConfigFolder + "theme.conf");
|
||||||
|
|
||||||
|
Theme.Init(
|
||||||
|
themeContent,
|
||||||
|
Properties.Resources.theme,
|
||||||
|
IsDarkMode ? DarkTheme : LightTheme);
|
||||||
|
|
||||||
|
mp.Shutdown += Shutdown;
|
||||||
|
mp.Initialized += Initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Initialized()
|
||||||
|
{
|
||||||
|
if (RememberVolume)
|
||||||
|
{
|
||||||
|
mp.set_property_int("volume", RegHelp.GetInt(App.RegPath, "Volume", 70));
|
||||||
|
mp.set_property_string("mute", RegHelp.GetString(App.RegPath, "Mute", "no"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Shutdown()
|
||||||
|
{
|
||||||
|
if (RememberVolume)
|
||||||
|
{
|
||||||
|
RegHelp.SetObject(App.RegPath, "Volume", mp.get_property_int("volume"));
|
||||||
|
RegHelp.SetObject(App.RegPath, "Mute", mp.get_property_string("mute"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Dictionary<string, string> _Conf;
|
||||||
|
|
||||||
|
public static Dictionary<string, string> Conf {
|
||||||
|
get {
|
||||||
|
if (_Conf == null)
|
||||||
|
{
|
||||||
|
_Conf = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
if (File.Exists(ConfPath))
|
||||||
|
foreach (string i in File.ReadAllLines(ConfPath))
|
||||||
|
if (i.Contains("=") && !i.StartsWith("#"))
|
||||||
|
_Conf[i.Substring(0, i.IndexOf("=")).Trim()] = i.Substring(i.IndexOf("=") + 1).Trim();
|
||||||
|
}
|
||||||
|
return _Conf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ProcessProperty(string name, string value)
|
||||||
|
{
|
||||||
|
switch (name)
|
||||||
|
{
|
||||||
|
case "remember-position": RememberPosition = value == "yes"; return true;
|
||||||
|
case "maximized": Maximized = value == "yes"; return true;
|
||||||
|
case "start-size": RememberHeight = value == "previous"; return true;
|
||||||
|
case "process-instance": ProcessInstance = value; return true;
|
||||||
|
case "dark-mode": DarkMode = value; return true;
|
||||||
|
case "debug-mode": DebugMode = value == "yes"; return true;
|
||||||
|
case "remember-volume": RememberVolume = value == "yes"; return true;
|
||||||
|
case "start-threshold": StartThreshold = value.Int(); return true;
|
||||||
|
case "minimum-aspect-ratio": MinimumAspectRatio = value.Float(); return true;
|
||||||
|
case "auto-load-folder": AutoLoadFolder = value == "yes"; return true;
|
||||||
|
case "recent-count": RecentCount = value.Int(); return true;
|
||||||
|
case "queue": Queue = value == "yes"; return true;
|
||||||
|
case "dark-theme": DarkTheme = value.Trim('\'', '"'); return true;
|
||||||
|
case "light-theme": LightTheme = value.Trim('\'', '"'); return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,11 +16,14 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
switch (id)
|
switch (id)
|
||||||
{
|
{
|
||||||
case "manage-file-associations": ManageFileAssociations(); break;
|
case "open-files": OpenFiles(args); break;
|
||||||
|
case "open-url": OpenURL(); break;
|
||||||
|
case "open-optical-media": Open_DVD_Or_BD_Folder(); break;
|
||||||
|
case "manage-file-associations": // deprecated 2019
|
||||||
|
case "show-setup-dialog": ShowDialog(typeof(SetupWindow)); break;
|
||||||
case "cycle-audio": CycleAudio(); break;
|
case "cycle-audio": CycleAudio(); break;
|
||||||
case "load-audio": LoadAudio(); break;
|
case "load-audio": LoadAudio(); break;
|
||||||
case "load-sub": LoadSubtitle(); break;
|
case "load-sub": LoadSubtitle(); break;
|
||||||
case "open-url": OpenURL(); break;
|
|
||||||
case "execute-mpv-command": ExecuteMpvCommand(); break;
|
case "execute-mpv-command": ExecuteMpvCommand(); break;
|
||||||
case "show-history": ShowHistory(); break;
|
case "show-history": ShowHistory(); break;
|
||||||
case "show-media-search": ShowDialog(typeof(EverythingWindow)); break;
|
case "show-media-search": ShowDialog(typeof(EverythingWindow)); break;
|
||||||
@@ -28,13 +31,18 @@ namespace mpvnet
|
|||||||
case "show-about": ShowDialog(typeof(AboutWindow)); break;
|
case "show-about": ShowDialog(typeof(AboutWindow)); break;
|
||||||
case "show-conf-editor": ShowDialog(typeof(ConfWindow)); break;
|
case "show-conf-editor": ShowDialog(typeof(ConfWindow)); break;
|
||||||
case "show-input-editor": ShowDialog(typeof(InputWindow)); break;
|
case "show-input-editor": ShowDialog(typeof(InputWindow)); break;
|
||||||
case "open-conf-folder": Process.Start(mp.ConfFolder); break;
|
case "open-conf-folder": Process.Start(mp.ConfigFolder); break;
|
||||||
case "open-files": OpenFiles(args); break;
|
|
||||||
case "shell-execute": Process.Start(args[0]); break;
|
case "shell-execute": Process.Start(args[0]); break;
|
||||||
case "show-info": ShowInfo(); break;
|
case "show-info": ShowInfo(); break;
|
||||||
|
case "playlist-last": PlaylistLast(); break;
|
||||||
case "add-files-to-playlist": OpenFiles("append"); break; // deprecated 2019
|
case "add-files-to-playlist": OpenFiles("append"); break; // deprecated 2019
|
||||||
default: Msg.ShowError($"No command '{id}' found."); break;
|
default: Msg.ShowError($"No command '{id}' found."); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MainForm.Instance.BeginInvoke(new Action(() => {
|
||||||
|
Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP
|
||||||
|
Native.SendMessage(MainForm.Instance.Handle, m.Msg, m.WParam, m.LParam);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void InvokeOnMainThread(Action action) => MainForm.Instance.Invoke(action);
|
public static void InvokeOnMainThread(Action action) => MainForm.Instance.Invoke(action);
|
||||||
@@ -66,16 +74,44 @@ namespace mpvnet
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Open_DVD_Or_BD_Folder()
|
||||||
|
{
|
||||||
|
InvokeOnMainThread(new Action(() => {
|
||||||
|
using (var d = new FolderBrowserDialog())
|
||||||
|
{
|
||||||
|
d.Description = "Select a DVD or Blu-ray folder.";
|
||||||
|
d.ShowNewFolderButton = false;
|
||||||
|
|
||||||
|
if (d.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(d.SelectedPath + "\\BDMV"))
|
||||||
|
{
|
||||||
|
mp.set_property_string("bluray-device", d.SelectedPath);
|
||||||
|
mp.Load(new[] { @"bd://" }, false, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mp.set_property_string("dvd-device", d.SelectedPath);
|
||||||
|
mp.Load(new[] { @"dvd://" }, false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PlaylistLast() => mp.set_property_int("playlist-pos", mp.get_property_int("playlist-count") - 1);
|
||||||
|
|
||||||
public static void ShowHistory()
|
public static void ShowHistory()
|
||||||
{
|
{
|
||||||
var fp = mp.ConfFolder + "history.txt";
|
if (File.Exists(mp.ConfigFolder + "history.txt"))
|
||||||
|
Process.Start(mp.ConfigFolder + "history.txt");
|
||||||
if (File.Exists(fp))
|
|
||||||
Process.Start(fp);
|
|
||||||
else
|
else
|
||||||
|
{
|
||||||
if (Msg.ShowQuestion("Create history.txt file in config folder?",
|
if (Msg.ShowQuestion("Create history.txt file in config folder?",
|
||||||
"mpv.net will write the date, time and filename of opened files to it.") == MsgResult.OK)
|
"mpv.net will write the date, time and filename of opened files to it.") == MsgResult.OK)
|
||||||
File.WriteAllText(fp, "");
|
|
||||||
|
File.WriteAllText(mp.ConfigFolder + "history.txt", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ShowInfo()
|
public static void ShowInfo()
|
||||||
@@ -85,6 +121,10 @@ namespace mpvnet
|
|||||||
string performer, title, album, genre, date, duration, text = "";
|
string performer, title, album, genre, date, duration, text = "";
|
||||||
long fileSize = 0;
|
long fileSize = 0;
|
||||||
string path = mp.get_property_string("path");
|
string path = mp.get_property_string("path");
|
||||||
|
|
||||||
|
if (path.Contains("://"))
|
||||||
|
path = mp.get_property_string("media-title");
|
||||||
|
|
||||||
int width = mp.get_property_int("video-params/w");
|
int width = mp.get_property_int("video-params/w");
|
||||||
int height = mp.get_property_int("video-params/h");
|
int height = mp.get_property_int("video-params/h");
|
||||||
|
|
||||||
@@ -92,7 +132,7 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
fileSize = new FileInfo(path).Length;
|
fileSize = new FileInfo(path).Length;
|
||||||
|
|
||||||
if (App.AudioTypes.Contains(Path.GetExtension(path).ToLower().TrimStart('.')))
|
if (App.AudioTypes.Contains(path.ShortExt()))
|
||||||
{
|
{
|
||||||
using (MediaInfo mediaInfo = new MediaInfo(path))
|
using (MediaInfo mediaInfo = new MediaInfo(path))
|
||||||
{
|
{
|
||||||
@@ -109,6 +149,22 @@ namespace mpvnet
|
|||||||
if (genre != "") text += "Genre: " + genre + "\n";
|
if (genre != "") text += "Genre: " + genre + "\n";
|
||||||
if (date != "") text += "Year: " + date + "\n";
|
if (date != "") text += "Year: " + date + "\n";
|
||||||
if (duration != "") text += "Length: " + duration + "\n";
|
if (duration != "") text += "Length: " + duration + "\n";
|
||||||
|
text += "Size: " + mediaInfo.GetInfo(MediaInfoStreamKind.General, "FileSize/String") + "\n";
|
||||||
|
text += "Type: " + path.ShortExt().ToUpper();
|
||||||
|
|
||||||
|
mp.commandv("show-text", text, "5000");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (App.ImageTypes.Contains(path.ShortExt()))
|
||||||
|
{
|
||||||
|
using (MediaInfo mediaInfo = new MediaInfo(path))
|
||||||
|
{
|
||||||
|
text =
|
||||||
|
"Width: " + mediaInfo.GetInfo(MediaInfoStreamKind.Image, "Width") + "\n" +
|
||||||
|
"Height: " + mediaInfo.GetInfo(MediaInfoStreamKind.Image, "Height") + "\n" +
|
||||||
|
"Size: " + mediaInfo.GetInfo(MediaInfoStreamKind.General, "FileSize/String") + "\n" +
|
||||||
|
"Type: " + path.ShortExt().ToUpper();
|
||||||
|
|
||||||
mp.commandv("show-text", text, "5000");
|
mp.commandv("show-text", text, "5000");
|
||||||
return;
|
return;
|
||||||
@@ -121,7 +177,7 @@ namespace mpvnet
|
|||||||
string videoFormat = mp.get_property_string("video-format").ToUpper();
|
string videoFormat = mp.get_property_string("video-format").ToUpper();
|
||||||
string audioCodec = mp.get_property_string("audio-codec-name").ToUpper();
|
string audioCodec = mp.get_property_string("audio-codec-name").ToUpper();
|
||||||
|
|
||||||
text = Path.GetFileName(path) + "\n" +
|
text = path.FileName() + "\n" +
|
||||||
FormatTime(position.TotalMinutes) + ":" +
|
FormatTime(position.TotalMinutes) + ":" +
|
||||||
FormatTime(position.Seconds) + " / " +
|
FormatTime(position.Seconds) + " / " +
|
||||||
FormatTime(duration2.TotalMinutes) + ":" +
|
FormatTime(duration2.TotalMinutes) + ":" +
|
||||||
@@ -129,7 +185,7 @@ namespace mpvnet
|
|||||||
$"{width} x {height}\n";
|
$"{width} x {height}\n";
|
||||||
|
|
||||||
if (fileSize > 0)
|
if (fileSize > 0)
|
||||||
text += Convert.ToInt32(fileSize / 1024.0 / 1024.0).ToString() + " MB\n";
|
text += Convert.ToInt32(fileSize / 1024.0 / 1024.0) + " MB\n";
|
||||||
|
|
||||||
text += $"{videoFormat}\n{audioCodec}";
|
text += $"{videoFormat}\n{audioCodec}";
|
||||||
|
|
||||||
@@ -142,13 +198,13 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ExecuteMpvCommand()
|
public static void ExecuteMpvCommand() // deprecated 2019
|
||||||
{
|
{
|
||||||
InvokeOnMainThread(new Action(() => {
|
InvokeOnMainThread(new Action(() => {
|
||||||
string command = VB.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegHelp.GetString(App.RegPath, "RecentExecutedCommand"));
|
string command = VB.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegHelp.GetString(App.RegPath, "RecentExecutedCommand"));
|
||||||
if (string.IsNullOrEmpty(command)) return;
|
if (string.IsNullOrEmpty(command)) return;
|
||||||
RegHelp.SetObject(App.RegPath, "RecentExecutedCommand", command);
|
RegHelp.SetObject(App.RegPath, "RecentExecutedCommand", command);
|
||||||
mp.command_string(command, false);
|
mp.command(command, false);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +226,8 @@ namespace mpvnet
|
|||||||
InvokeOnMainThread(new Action(() => {
|
InvokeOnMainThread(new Action(() => {
|
||||||
using (var d = new OpenFileDialog())
|
using (var d = new OpenFileDialog())
|
||||||
{
|
{
|
||||||
d.InitialDirectory = Path.GetDirectoryName(mp.get_property_string("path", false));
|
string path = mp.get_property_string("path");
|
||||||
|
if (File.Exists(path)) d.InitialDirectory = Path.GetDirectoryName(path);
|
||||||
d.Multiselect = true;
|
d.Multiselect = true;
|
||||||
if (d.ShowDialog() == DialogResult.OK)
|
if (d.ShowDialog() == DialogResult.OK)
|
||||||
foreach (string i in d.FileNames)
|
foreach (string i in d.FileNames)
|
||||||
@@ -184,7 +241,9 @@ namespace mpvnet
|
|||||||
InvokeOnMainThread(new Action(() => {
|
InvokeOnMainThread(new Action(() => {
|
||||||
using (var d = new OpenFileDialog())
|
using (var d = new OpenFileDialog())
|
||||||
{
|
{
|
||||||
d.InitialDirectory = Path.GetDirectoryName(mp.get_property_string("path", false));
|
string path = mp.get_property_string("path");
|
||||||
|
if (File.Exists(path))
|
||||||
|
d.InitialDirectory = Path.GetDirectoryName(path);
|
||||||
d.Multiselect = true;
|
d.Multiselect = true;
|
||||||
|
|
||||||
if (d.ShowDialog() == DialogResult.OK)
|
if (d.ShowDialog() == DialogResult.OK)
|
||||||
@@ -196,10 +255,10 @@ namespace mpvnet
|
|||||||
|
|
||||||
public static void CycleAudio()
|
public static void CycleAudio()
|
||||||
{
|
{
|
||||||
string filePath = mp.get_property_string("path", false);
|
string path = mp.get_property_string("path");
|
||||||
if (!File.Exists(filePath)) return;
|
if (!File.Exists(path)) return;
|
||||||
|
|
||||||
using (MediaInfo mi = new MediaInfo(filePath))
|
using (MediaInfo mi = new MediaInfo(path))
|
||||||
{
|
{
|
||||||
MediaTrack[] audTracks = mp.MediaTracks.Where(track => track.Type == "a").ToArray();
|
MediaTrack[] audTracks = mp.MediaTracks.Where(track => track.Type == "a").ToArray();
|
||||||
if (audTracks.Length < 2) return;
|
if (audTracks.Length < 2) return;
|
||||||
@@ -210,31 +269,5 @@ namespace mpvnet
|
|||||||
mp.commandv("show-text", audTracks[aid - 1].Text.Substring(3), "5000");
|
mp.commandv("show-text", audTracks[aid - 1].Text.Substring(3), "5000");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ManageFileAssociations()
|
|
||||||
{
|
|
||||||
using (var td = new TaskDialog<string>())
|
|
||||||
{
|
|
||||||
td.MainInstruction = "Choose an option.";
|
|
||||||
td.MainIcon = MsgIcon.Shield;
|
|
||||||
|
|
||||||
td.AddCommandLink("Register video file extensions", "video");
|
|
||||||
td.AddCommandLink("Register audio file extensions", "audio");
|
|
||||||
td.AddCommandLink("Unregister file extensions", "unreg");
|
|
||||||
|
|
||||||
string result = td.Show();
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(result))
|
|
||||||
{
|
|
||||||
using (var proc = new Process())
|
|
||||||
{
|
|
||||||
proc.StartInfo.FileName = System.Windows.Forms.Application.ExecutablePath;
|
|
||||||
proc.StartInfo.Arguments = "--reg-file-assoc " + result;
|
|
||||||
proc.StartInfo.Verb = "runas";
|
|
||||||
try { proc.Start(); } catch { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
59
mpv.net/Misc/Extension.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
using System.ComponentModel.Composition.Hosting;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace mpvnet
|
||||||
|
{
|
||||||
|
public class Extension
|
||||||
|
{
|
||||||
|
[ImportMany]
|
||||||
|
public IEnumerable<IExtension> Extensions = null;
|
||||||
|
|
||||||
|
readonly CompositionContainer CompositionContainer;
|
||||||
|
|
||||||
|
public Extension()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AggregateCatalog catalog = new AggregateCatalog();
|
||||||
|
string dir = Folder.Startup + "Extensions";
|
||||||
|
|
||||||
|
if (Directory.Exists(dir))
|
||||||
|
{
|
||||||
|
string[] knownExtensions = { "RatingExtension", "ScriptingExtension" };
|
||||||
|
|
||||||
|
foreach (string path in Directory.GetDirectories(dir))
|
||||||
|
{
|
||||||
|
if (knownExtensions.Contains(Path.GetFileName(path)))
|
||||||
|
catalog.Catalogs.Add(new DirectoryCatalog(path, "*Extension.dll"));
|
||||||
|
else
|
||||||
|
Msg.ShowError("Failed to load extension", path + "\n\nOnly extensions that ship with mpv.net are allowed in <startup>\\extensions\n\nUser extensions have to use <config folder>\\extensions\n\nNever copy or install a new mpv.net version over a old mpv.net version.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dir = mp.ConfigFolder + "extensions";
|
||||||
|
|
||||||
|
if (Directory.Exists(dir))
|
||||||
|
foreach (string i in Directory.GetDirectories(dir))
|
||||||
|
catalog.Catalogs.Add(new DirectoryCatalog(i, "*Extension.dll"));
|
||||||
|
|
||||||
|
if (catalog.Catalogs.Count > 0)
|
||||||
|
{
|
||||||
|
CompositionContainer = new CompositionContainer(catalog);
|
||||||
|
CompositionContainer.ComposeParts(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Msg.ShowException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IExtension
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
32
mpv.net/Misc/ExtensionMethods.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
public static class Extensions
|
||||||
|
{
|
||||||
|
public static string FileName(this string path)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(path)) return "";
|
||||||
|
int index = path.LastIndexOf('\\');
|
||||||
|
if (index > -1) return path.Substring(index + 1);
|
||||||
|
index = path.LastIndexOf('/');
|
||||||
|
if (index > -1) return path.Substring(index + 1);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ShortExt(this string path)
|
||||||
|
{
|
||||||
|
return Path.GetExtension(path).ToLower().TrimStart('.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int Int(this string value)
|
||||||
|
{
|
||||||
|
int.TryParse(value, out int result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Float(this string value)
|
||||||
|
{
|
||||||
|
float.TryParse(value.Replace(",", "."), NumberStyles.Float, CultureInfo.InvariantCulture, out float result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
11
mpv.net/Misc/Help.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
class ConsoleHelp
|
||||||
|
{
|
||||||
|
public static void WriteError(object obj)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.WriteLine(obj?.ToString());
|
||||||
|
Console.ResetColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -16,121 +16,15 @@ using Microsoft.Win32;
|
|||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
public class App
|
|
||||||
{
|
|
||||||
public static string ConfFilePath { get; } = mp.ConfFolder + "\\mpvnet.conf";
|
|
||||||
public static string RegPath { get; } = @"HKCU\Software\" + Application.ProductName;
|
|
||||||
public static string DarkMode { get; set; } = "always";
|
|
||||||
public static string ProcessInstance { get; set; } = "single";
|
|
||||||
|
|
||||||
public static string[] VideoTypes { get; } = "mkv mp4 mpg avi mov webm vob wmv flv avs 264 h264 asf webm mpeg mpv y4m avc hevc 265 h265 m2v m2ts vpy mts m4v".Split(' ');
|
|
||||||
public static string[] AudioTypes { get; } = "mp3 mp2 ac3 ogg opus flac wav w64 m4a dts dtsma dtshr dtshd eac3 thd thd+ac3 mka aac mpa".Split(' ');
|
|
||||||
public static string[] SubtitleTypes { get; } = "srt ass idx sup ttxt ssa smi".Split(' ');
|
|
||||||
public static string[] UrlWhitelist { get; set; } = { "tube", "vimeo", "ard", "zdf" };
|
|
||||||
|
|
||||||
public static bool RememberHeight { get; set; } = true;
|
|
||||||
public static bool RememberPosition { get; set; }
|
|
||||||
public static bool DebugMode { get; set; } = false;
|
|
||||||
|
|
||||||
public static bool IsDarkMode {
|
|
||||||
get => (DarkMode == "system" && Sys.IsDarkTheme) || DarkMode == "always";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Init()
|
|
||||||
{
|
|
||||||
string dummy = mp.ConfFolder;
|
|
||||||
var dummy2 = mp.Conf;
|
|
||||||
|
|
||||||
foreach (var i in Conf)
|
|
||||||
ProcessProperty(i.Key, i.Value);
|
|
||||||
|
|
||||||
if (App.DebugMode)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\mpvnet-debug.log";
|
|
||||||
if (File.Exists(filePath)) File.Delete(filePath);
|
|
||||||
Trace.Listeners.Clear();
|
|
||||||
Trace.Listeners.Add(new TextWriterTraceListener(filePath));
|
|
||||||
foreach (Screen screen in Screen.AllScreens)
|
|
||||||
Trace.WriteLine(screen);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Msg.ShowException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Exit()
|
|
||||||
{
|
|
||||||
if (Trace.Listeners.Count > 0) Trace.Listeners[0].Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
static Dictionary<string, string> _Conf;
|
|
||||||
|
|
||||||
public static Dictionary<string, string> Conf {
|
|
||||||
get {
|
|
||||||
if (_Conf == null)
|
|
||||||
{
|
|
||||||
_Conf = new Dictionary<string, string>();
|
|
||||||
|
|
||||||
if (File.Exists(ConfFilePath))
|
|
||||||
foreach (string i in File.ReadAllLines(ConfFilePath))
|
|
||||||
if (i.Contains("=") && !i.StartsWith("#"))
|
|
||||||
_Conf[i.Substring(0, i.IndexOf("=")).Trim()] = i.Substring(i.IndexOf("=") + 1).Trim();
|
|
||||||
}
|
|
||||||
return _Conf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ProcessProperty(string name, string value)
|
|
||||||
{
|
|
||||||
switch (name)
|
|
||||||
{
|
|
||||||
case "remember-position": RememberPosition = value == "yes"; break;
|
|
||||||
case "start-size": RememberHeight = value == "previous"; break;
|
|
||||||
case "process-instance": ProcessInstance = value; break;
|
|
||||||
case "dark-mode": DarkMode = value; break;
|
|
||||||
case "debug-mode": DebugMode = value == "yes"; break;
|
|
||||||
case "url-whitelist":
|
|
||||||
UrlWhitelist = value.Split(' ', ',', ';');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ProcessCommandLineEarly()
|
|
||||||
{
|
|
||||||
var args = Environment.GetCommandLineArgs().Skip(1);
|
|
||||||
|
|
||||||
foreach (string i in args)
|
|
||||||
{
|
|
||||||
if (i.StartsWith("--"))
|
|
||||||
{
|
|
||||||
if (i.Contains("="))
|
|
||||||
{
|
|
||||||
string left = i.Substring(2, i.IndexOf("=") - 2);
|
|
||||||
string right = i.Substring(left.Length + 3);
|
|
||||||
mp.ProcessProperty(left, right);
|
|
||||||
ProcessProperty(left, right);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string name = i.Substring(2);
|
|
||||||
mp.ProcessProperty(name, "yes");
|
|
||||||
ProcessProperty(name, "yes");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Sys
|
public class Sys
|
||||||
{
|
{
|
||||||
public static bool IsDarkTheme {
|
public static bool IsDarkTheme {
|
||||||
get {
|
get {
|
||||||
object value = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", 1);
|
object value = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", 1);
|
||||||
if (value is null) value = 1;
|
|
||||||
|
if (value is null)
|
||||||
|
value = 1;
|
||||||
|
|
||||||
return (int)value == 0;
|
return (int)value == 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,44 +66,52 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
Types = types;
|
Types = types;
|
||||||
|
|
||||||
RegHelp.SetObject(@"HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename, null, ExePath);
|
RegHelp.SetObject(@"HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename, null, ExePath);
|
||||||
RegHelp.SetObject($"HKCR\\Applications\\{ExeFilename}", "FriendlyAppName", "mpv.net media player");
|
RegHelp.SetObject(@"HKCR\Applications\" + ExeFilename, "FriendlyAppName", "mpv.net media player");
|
||||||
RegHelp.SetObject($"HKCR\\Applications\\{ExeFilename}\\shell\\open\\command", null, $"\"{ExePath}\" \"%1\"");
|
RegHelp.SetObject($@"HKCR\Applications\{ExeFilename}\shell\open\command", null, $"\"{ExePath}\" \"%1\"");
|
||||||
RegHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv\Capabilities", "ApplicationDescription", "mpv.net media player");
|
RegHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities", "ApplicationDescription", "mpv.net media player");
|
||||||
RegHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv\Capabilities", "ApplicationName", "mpv.net");
|
RegHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities", "ApplicationName", "mpv.net");
|
||||||
RegHelp.SetObject($"HKCR\\SystemFileAssociations\\video\\OpenWithList\\{ExeFilename}", null, "");
|
RegHelp.SetObject(@"HKCR\SystemFileAssociations\video\OpenWithList\" + ExeFilename, null, "");
|
||||||
RegHelp.SetObject($"HKCR\\SystemFileAssociations\\audio\\OpenWithList\\{ExeFilename}", null, "");
|
RegHelp.SetObject(@"HKCR\SystemFileAssociations\audio\OpenWithList\" + ExeFilename, null, "");
|
||||||
|
RegHelp.SetObject(@"HKLM\SOFTWARE\RegisteredApplications", "mpv.net", @"SOFTWARE\Clients\Media\mpv.net\Capabilities");
|
||||||
|
|
||||||
foreach (string ext in Types)
|
foreach (string ext in Types)
|
||||||
{
|
{
|
||||||
RegHelp.SetObject($"HKCR\\Applications\\{ExeFilename}\\SupportedTypes", "." + ext, "");
|
RegHelp.SetObject($@"HKCR\Applications\{ExeFilename}\SupportedTypes", "." + ext, "");
|
||||||
RegHelp.SetObject($"HKCR\\" + "." + ext, null, ExeFilenameNoExt + "." + ext);
|
RegHelp.SetObject($@"HKCR\" + "." + ext, null, ExeFilenameNoExt + "." + ext);
|
||||||
RegHelp.SetObject($"HKCR\\" + "." + ext + "\\OpenWithProgIDs", ExeFilenameNoExt + "." + ext, "");
|
RegHelp.SetObject($@"HKCR\" + "." + ext + @"\OpenWithProgIDs", ExeFilenameNoExt + "." + ext, "");
|
||||||
|
|
||||||
if (App.VideoTypes.Contains(ext))
|
if (App.VideoTypes.Contains(ext))
|
||||||
RegHelp.SetObject($"HKCR\\" + "." + ext, "PerceivedType", "video");
|
RegHelp.SetObject(@"HKCR\" + "." + ext, "PerceivedType", "video");
|
||||||
|
|
||||||
if (App.AudioTypes.Contains(ext))
|
if (App.AudioTypes.Contains(ext))
|
||||||
RegHelp.SetObject($"HKCR\\" + "." + ext, "PerceivedType", "audio");
|
RegHelp.SetObject(@"HKCR\" + "." + ext, "PerceivedType", "audio");
|
||||||
RegHelp.SetObject($"HKCR\\" + ExeFilenameNoExt + "." + ext + "\\shell\\open", null, "Play with " + Application.ProductName);
|
|
||||||
RegHelp.SetObject($"HKCR\\" + ExeFilenameNoExt + "." + ext + "\\shell\\open\\command", null, $"\"{ExePath}\" \"%1\"");
|
if (App.ImageTypes.Contains(ext))
|
||||||
|
RegHelp.SetObject(@"HKCR\" + "." + ext, "PerceivedType", "image");
|
||||||
|
|
||||||
|
RegHelp.SetObject($@"HKCR\" + ExeFilenameNoExt + "." + ext + @"\shell\open", null, "Play with " + Application.ProductName);
|
||||||
|
RegHelp.SetObject($@"HKCR\" + ExeFilenameNoExt + "." + ext + @"\shell\open\command", null, $"\"{ExePath}\" \"%1\"");
|
||||||
RegHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities\FileAssociations", "." + ext, ExeFilenameNoExt + "." + ext);
|
RegHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities\FileAssociations", "." + ext, ExeFilenameNoExt + "." + ext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Unregister()
|
public static void Unregister()
|
||||||
{
|
{
|
||||||
RegHelp.RemoveKey(@"HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename);
|
RegHelp.RemoveKey($@"HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename);
|
||||||
RegHelp.RemoveKey($"HKCR\\Applications\\{ExeFilename}");
|
RegHelp.RemoveKey($@"HKCR\Applications\" + ExeFilename);
|
||||||
RegHelp.RemoveKey(@"HKLM\SOFTWARE\Clients\Media\mpv.net");
|
RegHelp.RemoveKey($@"HKLM\SOFTWARE\Clients\Media\mpv.net");
|
||||||
RegHelp.RemoveKey($"HKCR\\SystemFileAssociations\\video\\OpenWithList\\{ExeFilename}");
|
RegHelp.RemoveKey($@"HKCR\SystemFileAssociations\video\OpenWithList\" + ExeFilename);
|
||||||
RegHelp.RemoveKey($"HKCR\\SystemFileAssociations\\audio\\OpenWithList\\{ExeFilename}");
|
RegHelp.RemoveKey($@"HKCR\SystemFileAssociations\audio\OpenWithList\" + ExeFilename);
|
||||||
|
RegHelp.RemoveValue(@"HKLM\SOFTWARE\RegisteredApplications", "mpv.net");
|
||||||
|
|
||||||
foreach (string id in Registry.ClassesRoot.GetSubKeyNames())
|
foreach (string id in Registry.ClassesRoot.GetSubKeyNames())
|
||||||
{
|
{
|
||||||
if (id.StartsWith(ExeFilenameNoExt + "."))
|
if (id.StartsWith(ExeFilenameNoExt + "."))
|
||||||
Registry.ClassesRoot.DeleteSubKeyTree(id);
|
Registry.ClassesRoot.DeleteSubKeyTree(id);
|
||||||
|
|
||||||
RegHelp.RemoveValue($"HKCR\\Software\\Classes\\" + id + "\\OpenWithProgIDs", ExeFilenameNoExt + id);
|
RegHelp.RemoveValue($@"HKCR\Software\Classes\{id}\OpenWithProgIDs", ExeFilenameNoExt + id);
|
||||||
RegHelp.RemoveValue($"HKLM\\Software\\Classes\\" + id + "\\OpenWithProgIDs", ExeFilenameNoExt + id);
|
RegHelp.RemoveValue($@"HKLM\Software\Classes\{id}\OpenWithProgIDs", ExeFilenameNoExt + id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,46 +120,43 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
public static void SetObject(string path, string name, object value)
|
public static void SetObject(string path, string name, object value)
|
||||||
{
|
{
|
||||||
using (RegistryKey rk = GetRootKey(path).CreateSubKey(path.Substring(5), RegistryKeyPermissionCheck.ReadWriteSubTree))
|
using (RegistryKey regKey = GetRootKey(path).CreateSubKey(path.Substring(5), RegistryKeyPermissionCheck.ReadWriteSubTree))
|
||||||
rk.SetValue(name, value);
|
regKey.SetValue(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetString(string path, string name)
|
public static string GetString(string path, string name, string defaultValue = "")
|
||||||
{
|
{
|
||||||
object val = GetObject(path, name);
|
object value = GetObject(path, name, defaultValue);
|
||||||
if (val == null || !(val is string)) return "";
|
return !(value is string) ? defaultValue : value.ToString();
|
||||||
return val.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int GetInt(string path, string name)
|
public static int GetInt(string path, string name, int defaultValue = 0)
|
||||||
{
|
{
|
||||||
object val = GetObject(path, name);
|
object value = GetObject(path, name, defaultValue);
|
||||||
if (val == null || !(val is int)) return 0;
|
return !(value is int) ? defaultValue : (int)value;
|
||||||
return (int)val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object GetObject(string path, string name)
|
public static object GetObject(string path, string name, object defaultValue = null)
|
||||||
{
|
{
|
||||||
using (RegistryKey rk = GetRootKey(path).OpenSubKey(path.Substring(5)))
|
using (RegistryKey regKey = GetRootKey(path).OpenSubKey(path.Substring(5)))
|
||||||
if (rk != null)
|
return regKey == null ? null : regKey.GetValue(name, defaultValue);
|
||||||
return rk.GetValue(name, "");
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RemoveKey(string path)
|
public static void RemoveKey(string path)
|
||||||
{
|
{
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
GetRootKey(path).DeleteSubKeyTree(path.Substring(5), false);
|
GetRootKey(path).DeleteSubKeyTree(path.Substring(5), false);
|
||||||
} catch { }
|
} catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RemoveValue(string path, string name)
|
public static void RemoveValue(string path, string name)
|
||||||
{
|
{
|
||||||
try {
|
try
|
||||||
using (RegistryKey rk = GetRootKey(path).OpenSubKey(path.Substring(5), true))
|
{
|
||||||
if (!(rk is null))
|
using (RegistryKey regKey = GetRootKey(path).OpenSubKey(path.Substring(5), true))
|
||||||
rk.DeleteValue(name, false);
|
if (regKey != null)
|
||||||
|
regKey.DeleteValue(name, false);
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,26 +214,38 @@ namespace mpvnet
|
|||||||
foreach (string line in content.Split('\r', '\n'))
|
foreach (string line in content.Split('\r', '\n'))
|
||||||
{
|
{
|
||||||
string val = line.Trim();
|
string val = line.Trim();
|
||||||
if (val.StartsWith("#")) continue;
|
|
||||||
if (!val.Contains(" ")) continue;
|
if (val.StartsWith("#"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!val.Contains(" "))
|
||||||
|
continue;
|
||||||
|
|
||||||
CommandItem item = new CommandItem();
|
CommandItem item = new CommandItem();
|
||||||
item.Input = val.Substring(0, val.IndexOf(" "));
|
item.Input = val.Substring(0, val.IndexOf(" "));
|
||||||
if (item.Input == "_") item.Input = "";
|
|
||||||
|
if (item.Input == "_")
|
||||||
|
item.Input = "";
|
||||||
|
|
||||||
val = val.Substring(val.IndexOf(" ") + 1);
|
val = val.Substring(val.IndexOf(" ") + 1);
|
||||||
|
|
||||||
if (val.Contains("#menu:"))
|
if (val.Contains("#menu:"))
|
||||||
{
|
{
|
||||||
item.Path = val.Substring(val.IndexOf("#menu:") + 6).Trim();
|
item.Path = val.Substring(val.IndexOf("#menu:") + 6).Trim();
|
||||||
val = val.Substring(0, val.IndexOf("#menu:"));
|
val = val.Substring(0, val.IndexOf("#menu:"));
|
||||||
|
|
||||||
if (item.Path.Contains(";"))
|
if (item.Path.Contains(";"))
|
||||||
item.Path = item.Path.Substring(item.Path.IndexOf(";") + 1).Trim();
|
item.Path = item.Path.Substring(item.Path.IndexOf(";") + 1).Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
item.Command = val.Trim();
|
item.Command = val.Trim();
|
||||||
|
|
||||||
if (item.Command == "")
|
if (item.Command == "")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (item.Command.ToLower() == "ignore")
|
if (item.Command.ToLower() == "ignore")
|
||||||
item.Command = "";
|
item.Command = "";
|
||||||
|
|
||||||
MigrateCommands(item);
|
MigrateCommands(item);
|
||||||
items.Add(item);
|
items.Add(item);
|
||||||
}
|
}
|
||||||
@@ -348,6 +259,7 @@ namespace mpvnet
|
|||||||
get {
|
get {
|
||||||
if (_Items is null)
|
if (_Items is null)
|
||||||
_Items = GetItems(File.ReadAllText(mp.InputConfPath));
|
_Items = GetItems(File.ReadAllText(mp.InputConfPath));
|
||||||
|
|
||||||
return _Items;
|
return _Items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -401,4 +313,35 @@ namespace mpvnet
|
|||||||
Math.Abs(screenPos.Y - Control.MousePosition.Y) > 10;
|
Math.Abs(screenPos.Y - Control.MousePosition.Y) > 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Folder
|
||||||
|
{
|
||||||
|
public static string Startup { get; } = Application.StartupPath + "\\";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PathHelp
|
||||||
|
{
|
||||||
|
public static string GetBaseName(string value)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(value))
|
||||||
|
return "";
|
||||||
|
|
||||||
|
int index = value.IndexOf("/");
|
||||||
|
|
||||||
|
if (index > -1)
|
||||||
|
value = value.Substring(index + 1);
|
||||||
|
|
||||||
|
index = value.IndexOf("\\");
|
||||||
|
|
||||||
|
if (index > -1)
|
||||||
|
value = value.Substring(index + 1);
|
||||||
|
|
||||||
|
index = value.LastIndexOf(".");
|
||||||
|
|
||||||
|
if (index > -1)
|
||||||
|
value = value.Substring(0, index);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
@@ -15,12 +14,22 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Application.EnableVisualStyles();
|
||||||
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
|
|
||||||
|
if (App.IsStartedFromTerminal)
|
||||||
|
Native.AttachConsole(-1 /*ATTACH_PARENT_PROCESS*/);
|
||||||
|
|
||||||
|
if (mp.ConfigFolder == "")
|
||||||
|
return;
|
||||||
|
|
||||||
string[] args = Environment.GetCommandLineArgs().Skip(1).ToArray();
|
string[] args = Environment.GetCommandLineArgs().Skip(1).ToArray();
|
||||||
|
|
||||||
if (args.Length == 2 && args[0] == "--reg-file-assoc")
|
if (args.Length == 2 && args[0] == "--reg-file-assoc")
|
||||||
{
|
{
|
||||||
if (args[1] == "audio") FileAssociation.Register(App.AudioTypes);
|
if (args[1] == "audio") FileAssociation.Register(App.AudioTypes);
|
||||||
if (args[1] == "video") FileAssociation.Register(App.VideoTypes);
|
if (args[1] == "video") FileAssociation.Register(App.VideoTypes);
|
||||||
|
if (args[1] == "image") FileAssociation.Register(App.ImageTypes);
|
||||||
if (args[1] == "unreg") FileAssociation.Unregister();
|
if (args[1] == "unreg") FileAssociation.Unregister();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -34,8 +43,14 @@ namespace mpvnet
|
|||||||
files.Add(App.ProcessInstance);
|
files.Add(App.ProcessInstance);
|
||||||
|
|
||||||
foreach (string arg in args)
|
foreach (string arg in args)
|
||||||
if (!arg.StartsWith("--") && (arg == "-" || arg.Contains("://") || File.Exists(arg)))
|
{
|
||||||
|
if (!arg.StartsWith("--") && (arg == "-" || arg.Contains("://") ||
|
||||||
|
arg.Contains(":\\") || arg.StartsWith("\\\\")))
|
||||||
|
|
||||||
files.Add(arg);
|
files.Add(arg);
|
||||||
|
else if (arg == "--queue")
|
||||||
|
files[0] = "queue";
|
||||||
|
}
|
||||||
|
|
||||||
Process[] procs = Process.GetProcessesByName("mpvnet");
|
Process[] procs = Process.GetProcessesByName("mpvnet");
|
||||||
|
|
||||||
@@ -51,18 +66,26 @@ namespace mpvnet
|
|||||||
data.cbData = data.lpData.Length * 2 + 1;
|
data.cbData = data.lpData.Length * 2 + 1;
|
||||||
Native.SendMessage(proc.MainWindowHandle, 0x004A /*WM_COPYDATA*/, IntPtr.Zero, ref data);
|
Native.SendMessage(proc.MainWindowHandle, 0x004A /*WM_COPYDATA*/, IntPtr.Zero, ref data);
|
||||||
mutex.Dispose();
|
mutex.Dispose();
|
||||||
|
|
||||||
|
if (App.IsStartedFromTerminal)
|
||||||
|
Native.FreeConsole();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread.Sleep(50);
|
Thread.Sleep(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex.Dispose();
|
mutex.Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Application.EnableVisualStyles();
|
|
||||||
Application.SetCompatibleTextRenderingDefault(false);
|
|
||||||
Application.Run(new MainForm());
|
Application.Run(new MainForm());
|
||||||
|
|
||||||
|
if (App.IsStartedFromTerminal)
|
||||||
|
Native.FreeConsole();
|
||||||
|
|
||||||
mutex.Dispose();
|
mutex.Dispose();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
96
mpv.net/Misc/Theme.cs
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace UI
|
||||||
|
{
|
||||||
|
public class Theme
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public Dictionary<string, string> Dictionary { get; } = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
public static List<Theme> DefaultThemes { get; set; }
|
||||||
|
public static List<Theme> CustomThemes { get; set; }
|
||||||
|
|
||||||
|
public static Theme Current { get; set; }
|
||||||
|
|
||||||
|
public static Brush Foreground { get; set; }
|
||||||
|
public static Brush Foreground2 { get; set; }
|
||||||
|
public static Brush Background { get; set; }
|
||||||
|
public static Brush Heading { get; set; }
|
||||||
|
|
||||||
|
public System.Drawing.Color GetWinFormsColor(string key)
|
||||||
|
{
|
||||||
|
return System.Drawing.ColorTranslator.FromHtml(Dictionary[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Brush GetBrush(string key)
|
||||||
|
{
|
||||||
|
return new SolidColorBrush((Color)ColorConverter.ConvertFromString(Dictionary[key]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Init(string customContent, string defaultContent, string activeTheme)
|
||||||
|
{
|
||||||
|
DefaultThemes = Load(defaultContent);
|
||||||
|
CustomThemes = Load(customContent);
|
||||||
|
|
||||||
|
foreach (Theme theme in CustomThemes)
|
||||||
|
{
|
||||||
|
if (theme.Name == activeTheme)
|
||||||
|
{
|
||||||
|
bool isKeyMissing = false;
|
||||||
|
|
||||||
|
foreach (string key in DefaultThemes[0].Dictionary.Keys)
|
||||||
|
{
|
||||||
|
if (!theme.Dictionary.ContainsKey(key))
|
||||||
|
{
|
||||||
|
isKeyMissing = true;
|
||||||
|
ConsoleHelp.WriteError($"Theme '{activeTheme}' misses '{key}'");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isKeyMissing)
|
||||||
|
Current = theme;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Current == null)
|
||||||
|
foreach (Theme theme in DefaultThemes)
|
||||||
|
if (theme.Name == activeTheme)
|
||||||
|
Current = theme;
|
||||||
|
|
||||||
|
if (Current == null)
|
||||||
|
Current = DefaultThemes[0];
|
||||||
|
|
||||||
|
Foreground = Current.GetBrush("foreground");
|
||||||
|
Foreground2 = Current.GetBrush("foreground2");
|
||||||
|
Background = Current.GetBrush("background");
|
||||||
|
Heading = Current.GetBrush("heading");
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<Theme> Load(string content)
|
||||||
|
{
|
||||||
|
List<Theme> list = new List<Theme>();
|
||||||
|
Theme theme = null;
|
||||||
|
|
||||||
|
foreach (string currentLine in (content ?? "").Split(new [] { '\r', '\n' }))
|
||||||
|
{
|
||||||
|
string line = currentLine.Trim();
|
||||||
|
|
||||||
|
if (line.StartsWith("[") && line.EndsWith("]"))
|
||||||
|
list.Add(theme = new Theme() { Name = line.Substring(1, line.Length - 2).Trim() });
|
||||||
|
|
||||||
|
if (line.Contains("=") && theme != null)
|
||||||
|
{
|
||||||
|
string left = line.Substring(0, line.IndexOf("=")).Trim();
|
||||||
|
theme.Dictionary[left] = line.Substring(line.IndexOf("=") + 1).Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ public class MediaInfo : IDisposable
|
|||||||
{
|
{
|
||||||
if (!Loaded)
|
if (!Loaded)
|
||||||
{
|
{
|
||||||
if (LoadLibrary("MediaInfo.dll") == IntPtr.Zero)
|
if (Native.LoadLibrary("MediaInfo.dll") == IntPtr.Zero)
|
||||||
throw new Exception("Failed to load MediaInfo.dll.");
|
throw new Exception("Failed to load MediaInfo.dll.");
|
||||||
|
|
||||||
Loaded = true;
|
Loaded = true;
|
||||||
@@ -56,21 +56,24 @@ public class MediaInfo : IDisposable
|
|||||||
|
|
||||||
~MediaInfo() { Dispose(); }
|
~MediaInfo() { Dispose(); }
|
||||||
|
|
||||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
|
||||||
static extern IntPtr LoadLibrary(string path);
|
|
||||||
|
|
||||||
[DllImport("MediaInfo.dll")]
|
[DllImport("MediaInfo.dll")]
|
||||||
static extern IntPtr MediaInfo_New();
|
static extern IntPtr MediaInfo_New();
|
||||||
|
|
||||||
[DllImport("MediaInfo.dll")]
|
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
||||||
static extern void MediaInfo_Delete(IntPtr handle);
|
static extern int MediaInfo_Open(IntPtr handle, string path);
|
||||||
|
|
||||||
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
||||||
static extern int MediaInfo_Open(IntPtr handle, string fileName);
|
static extern IntPtr MediaInfo_Option(IntPtr handle, string optionString, string value);
|
||||||
|
|
||||||
|
[DllImport("MediaInfo.dll")]
|
||||||
|
static extern IntPtr MediaInfo_Inform(IntPtr handle, int reserved);
|
||||||
|
|
||||||
[DllImport("MediaInfo.dll")]
|
[DllImport("MediaInfo.dll")]
|
||||||
static extern int MediaInfo_Close(IntPtr handle);
|
static extern int MediaInfo_Close(IntPtr handle);
|
||||||
|
|
||||||
|
[DllImport("MediaInfo.dll")]
|
||||||
|
static extern void MediaInfo_Delete(IntPtr handle);
|
||||||
|
|
||||||
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
||||||
static extern IntPtr MediaInfo_Get(IntPtr handle,
|
static extern IntPtr MediaInfo_Get(IntPtr handle,
|
||||||
MediaInfoStreamKind streamKind,
|
MediaInfoStreamKind streamKind,
|
||||||
|
|||||||
@@ -2,12 +2,16 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace mpvnet
|
|
||||||
{
|
|
||||||
public class Native
|
public class Native
|
||||||
{
|
{
|
||||||
[DllImport("kernel32.dll")]
|
[DllImport("kernel32.dll")]
|
||||||
public static extern IntPtr LoadLibrary(string dllToLoad);
|
public static extern bool AttachConsole(int dwProcessId);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
public static extern bool FreeConsole();
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
public static extern IntPtr LoadLibrary(string path);
|
||||||
|
|
||||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||||
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);
|
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);
|
||||||
@@ -18,9 +22,12 @@ namespace mpvnet
|
|||||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||||
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
|
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
|
||||||
|
|
||||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||||
public static extern IntPtr PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
|
public static extern IntPtr PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||||
|
public static extern int RegisterWindowMessage(string id);
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
public static extern bool AllowSetForegroundWindow(int dwProcessId);
|
public static extern bool AllowSetForegroundWindow(int dwProcessId);
|
||||||
|
|
||||||
@@ -30,7 +37,7 @@ namespace mpvnet
|
|||||||
[DllImport("user32.dll")]
|
[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", SetLastError = true)]
|
[DllImport("user32.dll")]
|
||||||
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
|
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
|
||||||
|
|
||||||
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||||
@@ -71,7 +78,7 @@ namespace mpvnet
|
|||||||
Bottom = bottom;
|
Bottom = bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rectangle ToRectangle() { return Rectangle.FromLTRB(Left, Top, Right, Bottom); }
|
public Rectangle ToRectangle() => Rectangle.FromLTRB(Left, Top, Right, Bottom);
|
||||||
public Size Size => new Size(Right - Left, Bottom - Top);
|
public Size Size => new Size(Right - Left, Bottom - Top);
|
||||||
public int Width => Right - Left;
|
public int Width => Right - Left;
|
||||||
public int Height => Bottom - Top;
|
public int Height => Bottom - Top;
|
||||||
@@ -82,8 +89,7 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
public IntPtr dwData;
|
public IntPtr dwData;
|
||||||
public int cbData;
|
public int cbData;
|
||||||
[MarshalAs(UnmanagedType.LPStr)]
|
[MarshalAs(UnmanagedType.LPTStr)]
|
||||||
public string lpData;
|
public string lpData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@@ -50,23 +50,23 @@ public class Msg
|
|||||||
td.Show();
|
td.Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
|
MessageBox.Show(e.GetType().Name + "\n\n" + e.Message + "\n\n" + e,
|
||||||
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ShowException(Exception e)
|
public static void ShowException(Exception exception)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (TaskDialog<string> td = new TaskDialog<string>())
|
using (TaskDialog<string> td = new TaskDialog<string>())
|
||||||
{
|
{
|
||||||
td.MainInstruction = e.GetType().Name;
|
td.MainInstruction = exception.GetType().Name;
|
||||||
td.Content = e.Message;
|
td.Content = exception.Message;
|
||||||
td.MainIcon = MsgIcon.Error;
|
td.MainIcon = MsgIcon.Error;
|
||||||
td.ExpandedInformation = e.ToString();
|
td.ExpandedInformation = exception.ToString();
|
||||||
td.Footer = "[Copy Message](copymsg)";
|
td.Footer = "[Copy Message](copymsg)";
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Msg.SupportURL))
|
if (!string.IsNullOrEmpty(Msg.SupportURL))
|
||||||
@@ -75,9 +75,9 @@ public class Msg
|
|||||||
td.Show();
|
td.Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
|
MessageBox.Show(e.GetType().Name + "\n\n" + e.Message + "\n\n" + e,
|
||||||
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,9 +144,9 @@ public class Msg
|
|||||||
return td.Show();
|
return td.Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
return (MsgResult)MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
|
return (MsgResult)MessageBox.Show(e.GetType().Name + "\n\n" + e.Message + "\n\n" + e,
|
||||||
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,6 +235,7 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
|
|||||||
|
|
||||||
if (Path.GetFileName(lpszFileName.ToString().Replace(".vshost", "")) ==
|
if (Path.GetFileName(lpszFileName.ToString().Replace(".vshost", "")) ==
|
||||||
Path.GetFileName(Assembly.GetEntryAssembly().Location))
|
Path.GetFileName(Assembly.GetEntryAssembly().Location))
|
||||||
|
|
||||||
return foregroundWindow;
|
return foregroundWindow;
|
||||||
|
|
||||||
return IntPtr.Zero;
|
return IntPtr.Zero;
|
||||||
@@ -359,7 +360,7 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
|
|||||||
public void AddCommandLink(string text, T value)
|
public void AddCommandLink(string text, T value)
|
||||||
{
|
{
|
||||||
int n = 1000 + IdValueDic.Count + 1;
|
int n = 1000 + IdValueDic.Count + 1;
|
||||||
IdValueDic[n] = value == null ? (T)(object)text : value;
|
IdValueDic[n] = value;
|
||||||
IdTextDic[n] = text;
|
IdTextDic[n] = text;
|
||||||
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
|
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
|
||||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
|
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
|
||||||
|
|||||||
53
mpv.net/Native/Taskbar.cs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
public class Taskbar
|
||||||
|
{
|
||||||
|
private ITaskbarList3 Instance = (ITaskbarList3)new TaskBarCommunication();
|
||||||
|
|
||||||
|
public IntPtr Handle { get; set; }
|
||||||
|
|
||||||
|
public Taskbar(IntPtr handle) => Handle = handle;
|
||||||
|
|
||||||
|
[ComImportAttribute]
|
||||||
|
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
[GuidAttribute("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")]
|
||||||
|
private interface ITaskbarList3
|
||||||
|
{
|
||||||
|
// ITaskbarList
|
||||||
|
[PreserveSig] void HrInit();
|
||||||
|
[PreserveSig] void AddTab(IntPtr hwnd);
|
||||||
|
[PreserveSig] void DeleteTab(IntPtr hwnd);
|
||||||
|
[PreserveSig] void ActivateTab(IntPtr hwnd);
|
||||||
|
[PreserveSig] void SetActiveAlt(IntPtr hwnd);
|
||||||
|
// ITaskbarList2
|
||||||
|
[PreserveSig] void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);
|
||||||
|
// ITaskbarList3
|
||||||
|
[PreserveSig] void SetProgressValue(IntPtr hwnd, UInt64 ullCompleted, UInt64 ullTotal);
|
||||||
|
[PreserveSig] void SetProgressState(IntPtr hwnd, TaskbarStates state);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComImportAttribute]
|
||||||
|
[ClassInterfaceAttribute(ClassInterfaceType.None)]
|
||||||
|
[GuidAttribute("56FDF344-FD6D-11d0-958A-006097C9A090")]
|
||||||
|
private class TaskBarCommunication { }
|
||||||
|
|
||||||
|
public void SetState(TaskbarStates taskbarState)
|
||||||
|
{
|
||||||
|
Instance.SetProgressState(Handle, taskbarState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue(double progressValue, double progressMax)
|
||||||
|
{
|
||||||
|
Instance.SetProgressValue(Handle, (UInt64)progressValue, (UInt64)progressMax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TaskbarStates
|
||||||
|
{
|
||||||
|
NoProgress = 0,
|
||||||
|
Indeterminate = 0x1,
|
||||||
|
Normal = 0x2,
|
||||||
|
Error = 0x4,
|
||||||
|
Paused = 0x8
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
|
|||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("Frank Skare (stax76)")]
|
[assembly: AssemblyCompany("Frank Skare (stax76)")]
|
||||||
[assembly: AssemblyProduct("mpv.net")]
|
[assembly: AssemblyProduct("mpv.net")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 2017-2019 Frank Skare (stax76)")]
|
[assembly: AssemblyCopyright("Copyright 2017-2019 Frank Skare (stax76)")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("4.7.0.0")]
|
[assembly: AssemblyVersion("5.4.3.0")]
|
||||||
[assembly: AssemblyFileVersion("4.7.0.0")]
|
[assembly: AssemblyFileVersion("5.4.3.0")]
|
||||||
|
|||||||
116
mpv.net/Properties/Resources.Designer.cs
generated
@@ -60,21 +60,37 @@ namespace mpvnet.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to [[settings]]
|
||||||
|
///name = "hwdec"
|
||||||
|
///file = "mpv"
|
||||||
|
///default = "no"
|
||||||
|
///filter = "Video"
|
||||||
|
///url = "https://mpv.io/manual/master/#options-hwdec"
|
||||||
|
///help = "Specify the hardware video decoding API that should be used if possible. Whether hardware decoding is actually done depends on the video codec. If hardware decoding is not possible, mpv will fall back on software decoding.\n\nFor more information visit:"
|
||||||
|
///options = [{ name = "no", help = "always use software decoding" },
|
||||||
|
/// { name = "auto", hel [rest of string was truncated]";.
|
||||||
|
/// </summary>
|
||||||
|
internal static string confToml {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("confToml", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to
|
/// Looks up a localized string similar to
|
||||||
/// # This file defines the input (keys and mouse) bindings of mpv and mpv.net
|
/// # This file defines the key and mouse bindings and the context menu
|
||||||
/// # and it also defines the context menu of mpv.net. mpv.net has an input
|
/// # of mpv.net. A input and config editor can be found in mpv.net's
|
||||||
/// # editor and an config editor as alternative to editing conf text files.
|
/// # context menu under 'Settings'. The defaults of this file can be found at:
|
||||||
/// # The input and config editor can be found in mpv.net's context menu at:
|
|
||||||
///
|
|
||||||
/// # Settings > Show Config Editor
|
|
||||||
/// # Settings > Show Input Editor
|
|
||||||
///
|
|
||||||
/// # The defaults of this file can be found at:
|
|
||||||
///
|
///
|
||||||
/// # https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt
|
/// # https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt
|
||||||
///
|
///
|
||||||
/// # th [rest of string was truncated]";.
|
/// # The defaults of mpv can be found at:
|
||||||
|
///
|
||||||
|
/// # https://github.com/mpv-player/mpv/blob/master/etc/input.conf
|
||||||
|
///
|
||||||
|
/// # mpv.net's defaults of mpv.conf contain: 'input-default-bindings = no'
|
||||||
|
/// # which disables mpv's [rest of string was truncated]";.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string inputConf {
|
internal static string inputConf {
|
||||||
get {
|
get {
|
||||||
@@ -83,20 +99,21 @@ namespace mpvnet.Properties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to
|
/// Looks up a localized string similar to input-default-bindings = no
|
||||||
///# manual: https://mpv.io/manual/master/
|
|
||||||
///
|
|
||||||
///# defaults: https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt
|
|
||||||
///
|
|
||||||
///input-ar-delay = 500
|
///input-ar-delay = 500
|
||||||
///input-ar-rate = 20
|
///input-ar-rate = 20
|
||||||
///volume = 50
|
|
||||||
///hwdec = yes
|
|
||||||
///keep-open = yes
|
///keep-open = yes
|
||||||
///keep-open-pause = no
|
///keep-open-pause = no
|
||||||
///osd-playing-msg = '${filename}'
|
///osd-playing-msg = '${filename}'
|
||||||
|
///script-opts = osc-scalewindowed=1.5
|
||||||
///screenshot-directory = '~~desktop/'
|
///screenshot-directory = '~~desktop/'
|
||||||
///input-default-bindings = no.
|
///cscale = spline36
|
||||||
|
///dscale = spline36
|
||||||
|
///scale = spline36
|
||||||
|
///hwdec = yes
|
||||||
|
///
|
||||||
|
///[protocol.https]
|
||||||
|
///osd-playing-msg = '${media-title}'.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string mpvConf {
|
internal static string mpvConf {
|
||||||
get {
|
get {
|
||||||
@@ -104,22 +121,6 @@ namespace mpvnet.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Looks up a localized string similar to [[settings]]
|
|
||||||
///name = "hwdec"
|
|
||||||
///default = "no"
|
|
||||||
///filter = "Video"
|
|
||||||
///helpurl = "https://mpv.io/manual/master/#options-hwdec"
|
|
||||||
///help = "Specify the hardware video decoding API that should be used if possible. Whether hardware decoding is actually done depends on the video codec. If hardware decoding is not possible, mpv will fall back on software decoding.\n\nFor more information visit:"
|
|
||||||
///options = [{ name = "no", help = "always use software decoding" },
|
|
||||||
/// { name = "auto", help = "enabl [rest of string was truncated]";.
|
|
||||||
/// </summary>
|
|
||||||
internal static string mpvConfToml {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("mpvConfToml", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -131,30 +132,37 @@ namespace mpvnet.Properties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to [[settings]]
|
/// Looks up a localized string similar to
|
||||||
///name = "dark-mode"
|
///[dark]
|
||||||
///default = "always"
|
|
||||||
///filter = "mpv.net"
|
|
||||||
///help = "Enables a dark theme."
|
|
||||||
///options = [{ name = "always" },
|
|
||||||
/// { name = "system" , help = "Available on Windows 10 or higher" },
|
|
||||||
/// { name = "never" }]
|
|
||||||
///
|
///
|
||||||
///[[settings]]
|
///heading = #1E90FF
|
||||||
///name = "url-whitelist"
|
///foreground = #FFFFFF
|
||||||
///filter = "mpv.net"
|
///foreground2 = #C0C0C0
|
||||||
///type = "string"
|
///background = #323232
|
||||||
///help = "Whitelist to monitor the clipboard for URLs to play.\n\nDefault: tube vimeo ard zdf"
|
|
||||||
///
|
///
|
||||||
///[[settings]]
|
///menu-foreground = #FFFFFF
|
||||||
///name = "process-instance"
|
///menu-background = #323232
|
||||||
///default = "single"
|
///menu-highlight = #505050
|
||||||
///filter = "mpv.net"
|
///menu-border = #FFFFFF
|
||||||
///help = "Defines [rest of string was truncated]";.
|
///menu-checked = #5A5A5A
|
||||||
|
///
|
||||||
|
///[light]
|
||||||
|
///
|
||||||
|
///heading = #0068B2
|
||||||
|
///foreground = #000000
|
||||||
|
///foreground2 = #4C4C4C
|
||||||
|
///background = #F7F7F7
|
||||||
|
///
|
||||||
|
///menu-foreground = #000000
|
||||||
|
///menu-background = #DFDFDF
|
||||||
|
///menu-highlight = #BFBFBF
|
||||||
|
///menu-border = #6A6A6A
|
||||||
|
///menu-checked = #AAAAAA
|
||||||
|
///.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string mpvNetConfToml {
|
internal static string theme {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("mpvNetConfToml", resourceCulture);
|
return ResourceManager.GetString("theme", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,19 +118,19 @@
|
|||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
|
<data name="confToml" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\ConfToml.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||||
|
</data>
|
||||||
<data name="inputConf" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="inputConf" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\inputConf.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
<value>..\Resources\inputConf.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="mpvConf" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="mpvConf" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\mpvConf.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
<value>..\Resources\mpvConf.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="mpvConfToml" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
|
||||||
<value>..\Resources\mpvConfToml.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
|
||||||
</data>
|
|
||||||
<data name="mpvnet" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="mpvnet" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\mpvnet.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Resources\mpvnet.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="mpvNetConfToml" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="theme" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\mpvNetConfToml.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
<value>..\Resources\theme.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
2
mpv.net/Properties/Settings.Designer.cs
generated
@@ -12,7 +12,7 @@ namespace mpvnet.Properties {
|
|||||||
|
|
||||||
|
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.0.0.0")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.3.0.0")]
|
||||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
[[settings]]
|
|
||||||
|
[[settings]]
|
||||||
name = "hwdec"
|
name = "hwdec"
|
||||||
|
file = "mpv"
|
||||||
default = "no"
|
default = "no"
|
||||||
filter = "Video"
|
filter = "Video"
|
||||||
helpurl = "https://mpv.io/manual/master/#options-hwdec"
|
url = "https://mpv.io/manual/master/#options-hwdec"
|
||||||
help = "Specify the hardware video decoding API that should be used if possible. Whether hardware decoding is actually done depends on the video codec. If hardware decoding is not possible, mpv will fall back on software decoding.\n\nFor more information visit:"
|
help = "Specify the hardware video decoding API that should be used if possible. Whether hardware decoding is actually done depends on the video codec. If hardware decoding is not possible, mpv will fall back on software decoding.\n\nFor more information visit:"
|
||||||
options = [{ name = "no", help = "always use software decoding" },
|
options = [{ name = "no", help = "always use software decoding" },
|
||||||
{ name = "auto", help = "enable best hw decoder (see below)" },
|
{ name = "auto", help = "enable best hw decoder (see below)" },
|
||||||
@@ -21,16 +23,18 @@ options = [{ name = "no", help = "always use software decoding" },
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "gpu-api"
|
name = "gpu-api"
|
||||||
|
file = "mpv"
|
||||||
default = "auto"
|
default = "auto"
|
||||||
filter = "Video"
|
filter = "Video"
|
||||||
help = "Controls which type of graphics APIs will be accepted."
|
help = "Controls which type of graphics APIs will be accepted. Auto uses d3d11, it should only be changed in case of problems, Vulkan is not recommended."
|
||||||
options = [{ name = "auto", help = "Use any available API" },
|
options = [{ name = "auto", help = "Use any available API" },
|
||||||
{ name = "opengl", help = "Allow only OpenGL (requires OpenGL 2.1+ or GLES 2.0+)" },
|
{ name = "opengl", help = "Allow only OpenGL (requires OpenGL 2.1+ or GLES 2.0+)" },
|
||||||
{ name = "vulkan", help = "Allow only Vulkan (requires a valid/working spirv-compiler)" },
|
{ name = "vulkan", help = "Allow only Vulkan (not recommended). " },
|
||||||
{ name = "d3d11", help = "Allow only gpu-context=d3d11" }]
|
{ name = "d3d11", help = "Allow only gpu-context=d3d11" }]
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "gpu-context"
|
name = "gpu-context"
|
||||||
|
file = "mpv"
|
||||||
default = "auto"
|
default = "auto"
|
||||||
filter = "Video"
|
filter = "Video"
|
||||||
options = [{ name = "auto", help = "auto-select" },
|
options = [{ name = "auto", help = "auto-select" },
|
||||||
@@ -42,19 +46,21 @@ options = [{ name = "auto", help = "auto-select" },
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "vo"
|
name = "vo"
|
||||||
|
file = "mpv"
|
||||||
default = "gpu"
|
default = "gpu"
|
||||||
filter = "Video"
|
filter = "Video"
|
||||||
help = "Video output drivers to be used.\n\nFor more information visit:"
|
help = "Video output drivers to be used.\n\nFor more information visit:"
|
||||||
helpurl = "https://mpv.io/manual/master/#video-output-drivers-vo"
|
url = "https://mpv.io/manual/master/#video-output-drivers-vo"
|
||||||
options = [{ name = "gpu", help = "General purpose, customizable, GPU-accelerated video output driver. It supports extended scaling methods, dithering, color management, custom shaders, HDR, and more." },
|
options = [{ name = "gpu", help = "General purpose, customizable, GPU-accelerated video output driver. It supports extended scaling methods, dithering, color management, custom shaders, HDR, and more." },
|
||||||
{ name = "direct3d", help = "Video output driver that uses the Direct3D interface" }]
|
{ name = "direct3d", help = "Video output driver that uses the Direct3D interface" }]
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "video-sync"
|
name = "video-sync"
|
||||||
|
file = "mpv"
|
||||||
default = "audio"
|
default = "audio"
|
||||||
filter = "Video"
|
filter = "Video"
|
||||||
help = "How the player synchronizes audio and video.\n\nFor more information visit:"
|
help = "How the player synchronizes audio and video.\n\nFor more information visit:"
|
||||||
helpurl = "https://mpv.io/manual/master/#options-video-sync"
|
url = "https://mpv.io/manual/master/#options-video-sync"
|
||||||
options = [{ name = "audio" },
|
options = [{ name = "audio" },
|
||||||
{ name = "display-resample" },
|
{ name = "display-resample" },
|
||||||
{ name = "display-resample-vdrop" },
|
{ name = "display-resample-vdrop" },
|
||||||
@@ -66,6 +72,7 @@ options = [{ name = "audio" },
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "scale"
|
name = "scale"
|
||||||
|
file = "mpv"
|
||||||
default = "bilinear"
|
default = "bilinear"
|
||||||
filter = "Video"
|
filter = "Video"
|
||||||
help = "The GPU renderer filter function to use when upscaling video. There are some more filters, but most are not as useful. For a complete list, pass help as value, e.g.: mpv --scale=help"
|
help = "The GPU renderer filter function to use when upscaling video. There are some more filters, but most are not as useful. For a complete list, pass help as value, e.g.: mpv --scale=help"
|
||||||
@@ -80,6 +87,7 @@ options = [{ name = "bilinear", help = "Bilinear hardware texture filter
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "cscale"
|
name = "cscale"
|
||||||
|
file = "mpv"
|
||||||
default = "bilinear"
|
default = "bilinear"
|
||||||
filter = "Video"
|
filter = "Video"
|
||||||
help = "As scale, but for interpolating chroma information. If the image is not subsampled, this option is ignored entirely."
|
help = "As scale, but for interpolating chroma information. If the image is not subsampled, this option is ignored entirely."
|
||||||
@@ -94,6 +102,7 @@ options = [{ name = "bilinear", help = "Bilinear hardware texture filter
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "dscale"
|
name = "dscale"
|
||||||
|
file = "mpv"
|
||||||
default = "bilinear"
|
default = "bilinear"
|
||||||
filter = "Video"
|
filter = "Video"
|
||||||
help = "Like scale, but apply these filters on downscaling instead. If this option is unset, the filter implied by scale will be applied."
|
help = "Like scale, but apply these filters on downscaling instead. If this option is unset, the filter implied by scale will be applied."
|
||||||
@@ -108,6 +117,7 @@ options = [{ name = "bilinear", help = "Bilinear hardware texture filter
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "dither-depth"
|
name = "dither-depth"
|
||||||
|
file = "mpv"
|
||||||
default = "no"
|
default = "no"
|
||||||
filter = "Video"
|
filter = "Video"
|
||||||
help = "Set dither target depth to N. Note that the depth of the connected video display device cannot be detected. Often, LCD panels will do dithering on their own, which conflicts with this option and leads to ugly output."
|
help = "Set dither target depth to N. Note that the depth of the connected video display device cannot be detected. Often, LCD panels will do dithering on their own, which conflicts with this option and leads to ugly output."
|
||||||
@@ -117,6 +127,7 @@ options = [{ name = "no", help = "Disable any dithering done by mpv." },
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "correct-downscaling"
|
name = "correct-downscaling"
|
||||||
|
file = "mpv"
|
||||||
default = "no"
|
default = "no"
|
||||||
filter = "Video"
|
filter = "Video"
|
||||||
help = "When using convolution based filters, extend the filter size when downscaling. Increases quality, but reduces performance while downscaling.\n\nThis will perform slightly sub-optimally for anamorphic video (but still better than without it) since it will extend the size to match only the milder of the scale factors between the axes."
|
help = "When using convolution based filters, extend the filter size when downscaling. Increases quality, but reduces performance while downscaling.\n\nThis will perform slightly sub-optimally for anamorphic video (but still better than without it) since it will extend the size to match only the milder of the scale factors between the axes."
|
||||||
@@ -125,6 +136,7 @@ options = [{ name = "yes" },
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "sigmoid-upscaling"
|
name = "sigmoid-upscaling"
|
||||||
|
file = "mpv"
|
||||||
default = "no"
|
default = "no"
|
||||||
filter = "Video"
|
filter = "Video"
|
||||||
help = "When upscaling, use a sigmoidal color transform to avoid emphasizing ringing artifacts. This also implies linear-scaling."
|
help = "When upscaling, use a sigmoidal color transform to avoid emphasizing ringing artifacts. This also implies linear-scaling."
|
||||||
@@ -133,6 +145,7 @@ options = [{ name = "yes" },
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "deband"
|
name = "deband"
|
||||||
|
file = "mpv"
|
||||||
default = "no"
|
default = "no"
|
||||||
filter = "Video"
|
filter = "Video"
|
||||||
help = "Enable the debanding algorithm. This greatly reduces the amount of visible banding, blocking and other quantization artifacts, at the expense of very slightly blurring some of the finest details. In practice, it's virtually always an improvement - the only reason to disable it would be for performance."
|
help = "Enable the debanding algorithm. This greatly reduces the amount of visible banding, blocking and other quantization artifacts, at the expense of very slightly blurring some of the finest details. In practice, it's virtually always an improvement - the only reason to disable it would be for performance."
|
||||||
@@ -141,18 +154,29 @@ options = [{ name = "yes" },
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "volume"
|
name = "volume"
|
||||||
default = "100"
|
file = "mpv"
|
||||||
filter = "Audio"
|
filter = "Audio"
|
||||||
help = "Set the startup volume. 0 means silence, 100 means no volume reduction or amplification. Negative values can be passed for compatibility, but are treated as 0. Since mpv 0.18.1, this always controls the internal mixer (aka \"softvol\"). Default: 100"
|
help = "Set the startup volume. 0 means silence, 100 means no volume reduction or amplification. Negative values can be passed for compatibility, but are treated as 0. Since mpv 0.18.1, this always controls the internal mixer (aka \"softvol\"). Default: 100"
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "remember-volume"
|
||||||
|
file = "mpvnet"
|
||||||
|
default = "yes"
|
||||||
|
filter = "Audio"
|
||||||
|
help = "Save volume and mute on exit and restore it on start. (mpv.net specific setting)"
|
||||||
|
options = [{ name = "yes" },
|
||||||
|
{ name = "no" }]
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "alang"
|
name = "alang"
|
||||||
|
file = "mpv"
|
||||||
filter = "Audio"
|
filter = "Audio"
|
||||||
type = "string"
|
type = "string"
|
||||||
help = "Specify a priority list of audio languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two-letter language codes, Matroska, MPEG-TS and NUT use ISO 639-2 three-letter language codes, while OGM uses a free-form identifier. See also aid.\n\nExamples\n\nmpv dvd://1 alang=hu,en chooses the Hungarian language track on a DVD and falls back on English if Hungarian is not available.\n\nmpv alang=jpn example.mkv plays a Matroska file with Japanese audio."
|
help = "Specify a priority list of audio languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two-letter language codes, Matroska, MPEG-TS and NUT use ISO 639-2 three-letter language codes, while OGM uses a free-form identifier. See also aid.\n\nExamples\n\nmpv dvd://1 alang=hu,en chooses the Hungarian language track on a DVD and falls back on English if Hungarian is not available.\n\nmpv alang=jpn example.mkv plays a Matroska file with Japanese audio."
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "audio-file-auto"
|
name = "audio-file-auto"
|
||||||
|
file = "mpv"
|
||||||
default = "no"
|
default = "no"
|
||||||
filter = "Audio"
|
filter = "Audio"
|
||||||
help = "Load additional audio files matching the video filename. The parameter specifies how external audio files are matched."
|
help = "Load additional audio files matching the video filename. The parameter specifies how external audio files are matched."
|
||||||
@@ -163,12 +187,14 @@ options = [{ name = "no", help = "Don't automatically load external audio fil
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "slang"
|
name = "slang"
|
||||||
|
file = "mpv"
|
||||||
filter = "Subtitle"
|
filter = "Subtitle"
|
||||||
type = "string"
|
type = "string"
|
||||||
help = "Specify a priority list of subtitle languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two letter language codes, Matroska uses ISO 639-2 three letter language codes while OGM uses a free-form identifier. See also sid."
|
help = "Specify a priority list of subtitle languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two letter language codes, Matroska uses ISO 639-2 three letter language codes while OGM uses a free-form identifier. See also sid."
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "sub-auto"
|
name = "sub-auto"
|
||||||
|
file = "mpv"
|
||||||
default = "exact"
|
default = "exact"
|
||||||
filter = "Subtitle"
|
filter = "Subtitle"
|
||||||
help = "Load additional subtitle files matching the video filename. The parameter specifies how external subtitle files are matched. exact is enabled by default."
|
help = "Load additional subtitle files matching the video filename. The parameter specifies how external subtitle files are matched. exact is enabled by default."
|
||||||
@@ -179,35 +205,41 @@ options = [{ name = "no", help = "Don't automatically load external subtitle
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "sub-font"
|
name = "sub-font"
|
||||||
|
file = "mpv"
|
||||||
filter = "Subtitle"
|
filter = "Subtitle"
|
||||||
type = "string"
|
type = "string"
|
||||||
help = "Specify font to use for subtitles that do not themselves specify a particular font. The default is sans-serif."
|
help = "Specify font to use for subtitles that do not themselves specify a particular font. The default is sans-serif."
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "sub-font-size"
|
name = "sub-font-size"
|
||||||
|
file = "mpv"
|
||||||
filter = "Subtitle"
|
filter = "Subtitle"
|
||||||
help = "Specify the sub font size. The unit is the size in scaled pixels at a window height of 720. The actual pixel size is scaled with the window height: if the window height is larger or smaller than 720, the actual size of the text increases or decreases as well. Default: 55"
|
help = "Specify the sub font size. The unit is the size in scaled pixels at a window height of 720. The actual pixel size is scaled with the window height: if the window height is larger or smaller than 720, the actual size of the text increases or decreases as well. Default: 55"
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "sub-color"
|
name = "sub-color"
|
||||||
|
file = "mpv"
|
||||||
type = "color"
|
type = "color"
|
||||||
filter = "Subtitle"
|
filter = "Subtitle"
|
||||||
help = "Specify the color used for unstyled text subtitles.\n\nThe color is specified in the form r/g/b, where each color component is specified as number in the range 0.0 to 1.0. It's also possible to specify the transparency by using r/g/b/a, where the alpha value 0 means fully transparent, and 1.0 means opaque. If the alpha component is not given, the color is 100% opaque.\n\nPassing a single number to the option sets the sub to gray, and the form gray/a lets you specify alpha additionally.\n\nExamples\n\n1.0/0.0/0.0 set sub to opaque red\n1.0/0.0/0.0/0.75 set sub to opaque red with 75% alpha\n0.5/0.75 set sub to 50% gray with 75% alpha\n\nAlternatively, the color can be specified as a RGB hex triplet in the form #RRGGBB, where each 2-digit group expresses a color value in the range 0 (00) to 255 (FF). For example, #FF0000 is red. This is similar to web colors. Alpha is given with #AARRGGBB.\n\nExamples\n\n#FF0000 set sub to opaque red\n#C0808080 set sub to 50% gray with 75% alpha"
|
help = "Specify the color used for unstyled text subtitles.\n\nThe color is specified in the form r/g/b, where each color component is specified as number in the range 0.0 to 1.0. It's also possible to specify the transparency by using r/g/b/a, where the alpha value 0 means fully transparent, and 1.0 means opaque. If the alpha component is not given, the color is 100% opaque.\n\nPassing a single number to the option sets the sub to gray, and the form gray/a lets you specify alpha additionally.\n\nExamples\n\n1.0/0.0/0.0 set sub to opaque red\n1.0/0.0/0.0/0.75 set sub to opaque red with 75% alpha\n0.5/0.75 set sub to 50% gray with 75% alpha\n\nAlternatively, the color can be specified as a RGB hex triplet in the form #RRGGBB, where each 2-digit group expresses a color value in the range 0 (00) to 255 (FF). For example, #FF0000 is red. This is similar to web colors. Alpha is given with #AARRGGBB.\n\nExamples\n\n#FF0000 set sub to opaque red\n#C0808080 set sub to 50% gray with 75% alpha"
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "sub-border-color"
|
name = "sub-border-color"
|
||||||
|
file = "mpv"
|
||||||
type = "color"
|
type = "color"
|
||||||
filter = "Subtitle"
|
filter = "Subtitle"
|
||||||
help = "See sub-color. Color used for the sub font border. Ignored when sub-back-color is specified (or more exactly: when that option is not set to completely transparent)."
|
help = "See sub-color. Color used for the sub font border. Ignored when sub-back-color is specified (or more exactly: when that option is not set to completely transparent)."
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "sub-back-color"
|
name = "sub-back-color"
|
||||||
|
file = "mpv"
|
||||||
type = "color"
|
type = "color"
|
||||||
filter = "Subtitle"
|
filter = "Subtitle"
|
||||||
help = "See sub-color. Color used for sub text background. You can use sub-shadow-offset to change its size relative to the text."
|
help = "See sub-color. Color used for sub text background. You can use sub-shadow-offset to change its size relative to the text."
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "fullscreen"
|
name = "fullscreen"
|
||||||
|
file = "mpv"
|
||||||
default = "no"
|
default = "no"
|
||||||
filter = "Screen"
|
filter = "Screen"
|
||||||
help = "Start the player in fullscreen mode."
|
help = "Start the player in fullscreen mode."
|
||||||
@@ -216,6 +248,7 @@ options = [{ name = "yes" },
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "border"
|
name = "border"
|
||||||
|
file = "mpv"
|
||||||
default = "yes"
|
default = "yes"
|
||||||
filter = "Screen"
|
filter = "Screen"
|
||||||
help = "Show window with decoration (titlebar, border)."
|
help = "Show window with decoration (titlebar, border)."
|
||||||
@@ -224,38 +257,173 @@ options = [{ name = "yes" },
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "screen"
|
name = "screen"
|
||||||
|
file = "mpv"
|
||||||
filter = "Screen"
|
filter = "Screen"
|
||||||
help = "<0-32> In multi-monitor configurations (i.e. a single desktop that spans across multiple displays), this option tells mpv which screen to display the video on."
|
help = "<0-32> In multi-monitor configurations (i.e. a single desktop that spans across multiple displays), this option tells mpv which screen to display the video on."
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "osd-playing-msg"
|
name = "osd-playing-msg"
|
||||||
|
file = "mpv"
|
||||||
width = 300
|
width = 300
|
||||||
filter = "Screen"
|
filter = "Screen"
|
||||||
type = "string"
|
type = "string"
|
||||||
help = "Show a message on OSD when playback starts. The string is expanded for properties, e.g. osd-playing-msg='file: ${filename}' will show the message file: followed by a space and the currently played filename. For more information visit:"
|
help = "Show a message on OSD when playback starts. The string is expanded for properties, e.g. osd-playing-msg='file: ${filename}' will show the message file: followed by a space and the currently played filename. For more information visit:"
|
||||||
helpurl = "https://mpv.io/manual/master/#property-expansion"
|
url = "https://mpv.io/manual/master/#property-expansion"
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "osd-font-size"
|
name = "osd-font-size"
|
||||||
default = "55"
|
file = "mpv"
|
||||||
filter = "Screen"
|
filter = "Screen"
|
||||||
help = "Specify the OSD font size. See sub-font-size for details. Default: 55"
|
help = "Specify the OSD font size. See sub-font-size for details. Default: 55"
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "screenshot-directory"
|
name = "osd-scale-by-window"
|
||||||
width = 500
|
file = "mpv"
|
||||||
type = "folder"
|
default = "yes"
|
||||||
filter = "Screen"
|
filter = "Screen"
|
||||||
help = "Store screenshots in this directory. This path is joined with the filename generated by screenshot-template. If the template filename is already absolute, the directory is ignored.\n\nIf the directory does not exist, it is created on the first screenshot. If it is not a directory, an error is generated when trying to write a screenshot.\n\nThis option is not set by default, and thus will write screenshots to the directory from which mpv was started. In pseudo-gui mode (see PSEUDO GUI MODE), this is set to the desktop."
|
help = "Whether to scale the OSD with the window size. If this is disabled, osd-font-size and other OSD options that use scaled pixels are always in actual pixels. The effect is that changing the window size won't change the OSD font size."
|
||||||
|
options = [{ name = "yes" },
|
||||||
|
{ name = "no" }]
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "autofit"
|
name = "autofit"
|
||||||
default = "50%"
|
file = "mpv"
|
||||||
filter = "Screen"
|
filter = "Screen"
|
||||||
help = "Set the initial window size in percent. Please note that this setting is only partly implemented in mpv.net, accepted are only integer values with percent sign added. Default: 50%"
|
help = "<int> Initial window height in percent. Default: 50"
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "autofit-smaller"
|
||||||
|
file = "mpv"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "<int> Minimum window height in percent. Default: 40"
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "autofit-larger"
|
||||||
|
file = "mpv"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "<int> Maximum window height in percent. Default: 75"
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "start-size"
|
||||||
|
file = "mpvnet"
|
||||||
|
default = "previous"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "Setting to remember the window height in the current session, otherwise the video's native resolution is used. (mpv.net specific setting)"
|
||||||
|
options = [{ name = "video", help = "Window size is set to native video resolution" },
|
||||||
|
{ name = "previous", help = "Window size is remembered but only from the current session" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "start-threshold"
|
||||||
|
file = "mpvnet"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "Threshold in milliseconds to wait for libmpv returning the video resolution before the window is shown, otherwise default dimensions are used as defined by autofit and start-size. Default: 1500 (mpv.net specific setting)"
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "minimum-aspect-ratio"
|
||||||
|
file = "mpvnet"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "<float> Minimum aspect ratio for the window. Default: 1.3 (mpv.net specific setting)"
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "remember-position"
|
||||||
|
file = "mpvnet"
|
||||||
|
default = "no"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "Save the window position on exit. (mpv.net specific setting)"
|
||||||
|
options = [{ name = "yes" },
|
||||||
|
{ name = "no" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "maximized"
|
||||||
|
file = "mpvnet"
|
||||||
|
default = "no"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "Start with a maximized window. (mpv.net specific setting)"
|
||||||
|
options = [{ name = "yes" },
|
||||||
|
{ name = "no" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "screenshot-directory"
|
||||||
|
file = "mpv"
|
||||||
|
width = 500
|
||||||
|
type = "folder"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "Store screenshots in this directory. This path is joined with the filename generated by screenshot-template. If the template filename is already absolute, the directory is ignored.\n\nIf the directory does not exist, it is created on the first screenshot. If it is not a directory, an error is generated when trying to write a screenshot."
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "screenshot-format"
|
||||||
|
file = "mpv"
|
||||||
|
default = "jpg"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "Set the image file type used for saving screenshots."
|
||||||
|
options = [{ name = "jpg" },
|
||||||
|
{ name = "png" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "screenshot-tag-colorspace"
|
||||||
|
file = "mpv"
|
||||||
|
default = "no"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "Tag screenshots with the appropriate colorspace. Note that not all formats are supported."
|
||||||
|
options = [{ name = "yes" },
|
||||||
|
{ name = "no" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "screenshot-high-bit-depth"
|
||||||
|
file = "mpv"
|
||||||
|
default = "yes"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "If possible, write screenshots with a bit depth similar to the source video. This is interesting in particular for PNG, as this sometimes triggers writing 16 bit PNGs with huge file sizes. This will also include an unused alpha channel in the resulting files if 16 bit is used."
|
||||||
|
options = [{ name = "yes" },
|
||||||
|
{ name = "no" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "screenshot-jpeg-source-chroma"
|
||||||
|
file = "mpv"
|
||||||
|
default = "yes"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "Write JPEG files with the same chroma subsampling as the video. If disabled, the libjpeg default is used."
|
||||||
|
options = [{ name = "yes" },
|
||||||
|
{ name = "no" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "screenshot-template"
|
||||||
|
file = "mpv"
|
||||||
|
filter = "Screen"
|
||||||
|
type = "string"
|
||||||
|
help = "Specify the filename template used to save screenshots. The template specifies the filename without file extension, and can contain format specifiers, which will be substituted when taking a screenshot. By default, the template is mpv-shot%n, which results in filenames like mpv-shot0012.png for example.\n\nFind the full documentation here:"
|
||||||
|
url = "https://mpv.io/manual/master/#options-screenshot-template"
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "screenshot-jpeg-quality"
|
||||||
|
file = "mpv"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "<0-100> Set the JPEG quality level. Higher means better quality. The default is 90."
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "screenshot-png-compression"
|
||||||
|
file = "mpv"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "<0-9> Set the PNG compression level. Higher means better compression. This will affect the file size of the written screenshot file and the time it takes to write a screenshot. Too high compression might occupy enough CPU time to interrupt playback. The default is 7."
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "screenshot-png-filter"
|
||||||
|
file = "mpv"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "<0-5> Set the filter applied prior to PNG compression. 0 is none, 1 is 'sub', 2 is 'up', 3 is 'average', 4 is 'Paeth', and 5 is 'mixed'. This affects the level of compression that can be achieved. For most images, 'mixed' achieves the best compression ratio, hence it is the default."
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "taskbar-progress"
|
||||||
|
file = "mpv"
|
||||||
|
default = "yes"
|
||||||
|
filter = "Playback"
|
||||||
|
help = "Show progress in taskbar."
|
||||||
|
options = [{ name = "yes" },
|
||||||
|
{ name = "no" }]
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "keep-open-pause"
|
name = "keep-open-pause"
|
||||||
|
file = "mpv"
|
||||||
default = "yes"
|
default = "yes"
|
||||||
filter = "Playback"
|
filter = "Playback"
|
||||||
help = "If set to no, instead of pausing when keep-open is active, just stop at end of file and continue playing forward when you seek backwards until end where it stops again."
|
help = "If set to no, instead of pausing when keep-open is active, just stop at end of file and continue playing forward when you seek backwards until end where it stops again."
|
||||||
@@ -264,38 +432,32 @@ options = [{ name = "yes" },
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "keep-open"
|
name = "keep-open"
|
||||||
|
file = "mpv"
|
||||||
default = "no"
|
default = "no"
|
||||||
filter = "Playback"
|
filter = "Playback"
|
||||||
help = "Do not terminate when playing or seeking beyond the end of the file, and there is not next file to be played (and loop is not used). Instead, pause the player. When trying to seek beyond end of the file, the player will attempt to seek to the last frame.\n\nNormally, this will act like set pause yes on EOF, unless the keep-open-pause=no option is set."
|
help = "Using no, mpv would terminate after the last file but mpv.net never terminates automatically."
|
||||||
options = [{ name = "yes", help = "Don't terminate if the current file is the last playlist entry. Equivalent to keep-open without arguments."},
|
options = [{ name = "yes", help = "If the current file ends, go to the next file, keep the last file open."},
|
||||||
{ name = "no", help = "If the current file ends, go to the next file or terminate." },
|
{ name = "no", help = "If the current file ends, go to the next file." },
|
||||||
{ name = "always", help = "Like yes, but also applies to files before the last playlist entry. This means playback will never automatically advance to the next file."}]
|
{ name = "always", help = "Playback will never automatically advance to the next file."}]
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "loop-file"
|
name = "loop-file"
|
||||||
|
file = "mpv"
|
||||||
filter = "Playback"
|
filter = "Playback"
|
||||||
help = "Loop a single file N times. inf means forever, no means normal playback.\n\nThe difference to loop-playlist is that this doesn't loop the playlist, just the file itself. If the playlist contains only a single file, the difference between the two option is that this option performs a seek on loop, instead of reloading the file. loop is an alias for this option."
|
help = "<N|inf|no> Loop a single file N times. inf means forever, no means normal playback.\n\nThe difference to loop-playlist is that this doesn't loop the playlist, just the file itself. If the playlist contains only a single file, the difference between the two option is that this option performs a seek on loop, instead of reloading the file. loop is an alias for this option."
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "save-position-on-quit"
|
name = "save-position-on-quit"
|
||||||
|
file = "mpv"
|
||||||
default = "no"
|
default = "no"
|
||||||
filter = "Playback"
|
filter = "Playback"
|
||||||
help = "Always save the current playback position on quit. When this file is played again later, the player will seek to the old playback position on start. This does not happen if playback of a file is stopped in any other way than quitting. For example, going to the next file in the playlist will not save the position, and start playback at beginning the next time the file is played.\n\nThis behavior is disabled by default, but is always available when quitting the player with Shift+Q."
|
help = "Always save the current playback position on quit. When this file is played again later, the player will seek to the old playback position on start. This does not happen if playback of a file is stopped in any other way than quitting. For example, going to the next file in the playlist will not save the position, and start playback at beginning the next time the file is played.\n\nThis behavior is disabled by default, but is always available when quitting the player with Shift+Q."
|
||||||
options = [{ name = "yes" },
|
options = [{ name = "yes" },
|
||||||
{ name = "no" }]
|
{ name = "no" }]
|
||||||
|
|
||||||
[[settings]]
|
|
||||||
name = "input-ar-delay"
|
|
||||||
filter = "Input"
|
|
||||||
help = "Delay in milliseconds before we start to autorepeat a key (0 to disable)."
|
|
||||||
|
|
||||||
[[settings]]
|
|
||||||
name = "input-ar-rate"
|
|
||||||
filter = "Input"
|
|
||||||
help = "Number of key presses to generate per second on autorepeat."
|
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "hr-seek"
|
name = "hr-seek"
|
||||||
|
file = "mpv"
|
||||||
default = "absolute"
|
default = "absolute"
|
||||||
filter = "Playback"
|
filter = "Playback"
|
||||||
help = "Select when to use precise seeks that are not limited to keyframes. Such seeks require decoding video from the previous keyframe up to the target position and so can take some time depending on decoding performance. For some video formats, precise seeks are disabled. This option selects the default choice to use for seeks; it is possible to explicitly override that default in the definition of key bindings and in input commands."
|
help = "Select when to use precise seeks that are not limited to keyframes. Such seeks require decoding video from the previous keyframe up to the target position and so can take some time depending on decoding performance. For some video formats, precise seeks are disabled. This option selects the default choice to use for seeks; it is possible to explicitly override that default in the definition of key bindings and in input commands."
|
||||||
@@ -306,6 +468,7 @@ options = [{ name = "yes", help = "Use precise seeks whenever possible." },
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "track-auto-selection"
|
name = "track-auto-selection"
|
||||||
|
file = "mpv"
|
||||||
default = "yes"
|
default = "yes"
|
||||||
filter = "Playback"
|
filter = "Playback"
|
||||||
help = "Enable the default track auto-selection. Enabling this will make the player select streams according to aid, alang, and others. If it is disabled, no tracks are selected. In addition, the player will not exit if no tracks are selected, and wait instead (this wait mode is similar to pausing, but the pause option is not set).\n\nThis is useful with lavfi-complex: you can start playback in this mode, and then set select tracks at runtime by setting the filter graph. Note that if lavfi-complex is set before playback is started, the referenced tracks are always selected."
|
help = "Enable the default track auto-selection. Enabling this will make the player select streams according to aid, alang, and others. If it is disabled, no tracks are selected. In addition, the player will not exit if no tracks are selected, and wait instead (this wait mode is similar to pausing, but the pause option is not set).\n\nThis is useful with lavfi-complex: you can start playback in this mode, and then set select tracks at runtime by setting the filter graph. Note that if lavfi-complex is set before playback is started, the referenced tracks are always selected."
|
||||||
@@ -314,5 +477,76 @@ options = [{ name = "yes" },
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "loop-playlist"
|
name = "loop-playlist"
|
||||||
|
file = "mpv"
|
||||||
filter = "Playback"
|
filter = "Playback"
|
||||||
help = "<N|inf|force|no> Loops playback N times. A value of 1 plays it one time (default), 2 two times, etc. inf means forever. no is the same as 1 and disables looping. If several files are specified on command line, the entire playlist is looped. The force mode is like inf, but does not skip playlist entries which have been marked as failing. This means the player might waste CPU time trying to loop a file that doesn't exist. But it might be useful for playing webradios under very bad network conditions."
|
help = "<N|inf|force|no> Loops playback N times. A value of 1 plays it one time (default), 2 two times, etc. inf means forever. no is the same as 1 and disables looping. If several files are specified on command line, the entire playlist is looped. The force mode is like inf, but does not skip playlist entries which have been marked as failing. This means the player might waste CPU time trying to loop a file that doesn't exist. But it might be useful for playing webradios under very bad network conditions."
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "auto-load-folder"
|
||||||
|
file = "mpvnet"
|
||||||
|
default = "yes"
|
||||||
|
filter = "Playback"
|
||||||
|
help = "For single files automatically load the entire directory into the playlist. Can be suppressed via shift key. (mpv.net specific setting)"
|
||||||
|
options = [{ name = "yes" },
|
||||||
|
{ name = "no" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "input-ar-delay"
|
||||||
|
file = "mpv"
|
||||||
|
filter = "Input"
|
||||||
|
help = "Delay in milliseconds before we start to autorepeat a key (0 to disable)."
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "input-ar-rate"
|
||||||
|
file = "mpv"
|
||||||
|
filter = "Input"
|
||||||
|
help = "Number of key presses to generate per second on autorepeat."
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "process-instance"
|
||||||
|
file = "mpvnet"
|
||||||
|
default = "single"
|
||||||
|
filter = "General"
|
||||||
|
help = "Defines if more then one mpv.net process is allowed. (mpv.net specific setting)\n\nTip: Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist. This not only works on process startup but in all mpv.net features that open files and URLs."
|
||||||
|
options = [{ name = "multi", help = "Create a new process everytime the shell starts mpv.net" },
|
||||||
|
{ name = "single", help = "Force a single process everytime the shell starts mpv.net" },
|
||||||
|
{ name = "queue", help = "Force a single process and add files to playlist" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "recent-count"
|
||||||
|
file = "mpvnet"
|
||||||
|
filter = "General"
|
||||||
|
help = "<int> Amount of recent files to be remembered. Default: 15 (mpv.net specific setting)"
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "debug-mode"
|
||||||
|
file = "mpvnet"
|
||||||
|
default = "no"
|
||||||
|
filter = "General"
|
||||||
|
help = "Enable this only when a developer asks for it. (mpv.net specific setting)"
|
||||||
|
options = [{ name = "yes" },
|
||||||
|
{ name = "no" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "dark-mode"
|
||||||
|
file = "mpvnet"
|
||||||
|
default = "always"
|
||||||
|
filter = "UI"
|
||||||
|
help = "Enables a dark theme. (mpv.net specific setting)"
|
||||||
|
options = [{ name = "always" },
|
||||||
|
{ name = "system" , help = "Available on Windows 10 or higher" },
|
||||||
|
{ name = "never" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "dark-theme"
|
||||||
|
file = "mpvnet"
|
||||||
|
filter = "UI"
|
||||||
|
url = "https://github.com/stax76/mpv.net/blob/master/Manual.md#color-theme"
|
||||||
|
help = "Color theme used in dark mode. Default: dark"
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "light-theme"
|
||||||
|
file = "mpvnet"
|
||||||
|
filter = "UI"
|
||||||
|
url = "https://github.com/stax76/mpv.net/blob/master/Manual.md#color-theme"
|
||||||
|
help = "Color theme used in light mode. Default: light"
|
||||||
@@ -1,17 +1,11 @@
|
|||||||
|
|
||||||
# This file defines the input (keys and mouse) bindings of mpv and mpv.net
|
# This file defines the key and mouse bindings and the context menu
|
||||||
# and it also defines the context menu of mpv.net. mpv.net has an input
|
# of mpv.net. A input and config editor can be found in mpv.net's
|
||||||
# editor and an config editor as alternative to editing conf text files.
|
# context menu under 'Settings'. The defaults of this file can be found at:
|
||||||
# The input and config editor can be found in mpv.net's context menu at:
|
|
||||||
|
|
||||||
# Settings > Show Config Editor
|
|
||||||
# Settings > Show Input Editor
|
|
||||||
|
|
||||||
# The defaults of this file can be found at:
|
|
||||||
|
|
||||||
# https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt
|
# https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt
|
||||||
|
|
||||||
# the defaults of mpv can be found at:
|
# The defaults of mpv can be found at:
|
||||||
|
|
||||||
# https://github.com/mpv-player/mpv/blob/master/etc/input.conf
|
# https://github.com/mpv-player/mpv/blob/master/etc/input.conf
|
||||||
|
|
||||||
@@ -28,6 +22,7 @@
|
|||||||
|
|
||||||
o script-message mpv.net open-files #menu: Open > Open Files...
|
o script-message mpv.net open-files #menu: Open > Open Files...
|
||||||
u script-message mpv.net open-url #menu: Open > Open URL or file path from clipboard
|
u script-message mpv.net open-url #menu: Open > Open URL or file path from clipboard
|
||||||
|
_ script-message mpv.net open-optical-media #menu: Open > Open DVD/Blu-ray Drive/Folder...
|
||||||
_ ignore #menu: Open > -
|
_ ignore #menu: Open > -
|
||||||
Alt+a script-message mpv.net load-audio #menu: Open > Load external audio files...
|
Alt+a script-message mpv.net load-audio #menu: Open > Load external audio files...
|
||||||
Alt+s script-message mpv.net load-sub #menu: Open > Load external subtitle files...
|
Alt+s script-message mpv.net load-sub #menu: Open > Load external subtitle files...
|
||||||
@@ -46,6 +41,9 @@
|
|||||||
F11 playlist-prev #menu: Navigate > Previous File
|
F11 playlist-prev #menu: Navigate > Previous File
|
||||||
F12 playlist-next #menu: Navigate > Next File
|
F12 playlist-next #menu: Navigate > Next File
|
||||||
_ ignore #menu: Navigate > -
|
_ ignore #menu: Navigate > -
|
||||||
|
Home set playlist-pos 0 #menu: Navigate > First File
|
||||||
|
End script-message mpv.net playlist-last #menu: Navigate > Last File
|
||||||
|
_ ignore #menu: Navigate > -
|
||||||
PGUP add chapter 1 #menu: Navigate > Next Chapter
|
PGUP add chapter 1 #menu: Navigate > Next Chapter
|
||||||
PGDWN add chapter -1 #menu: Navigate > Previous Chapter
|
PGDWN add chapter -1 #menu: Navigate > Previous Chapter
|
||||||
_ ignore #menu: Navigate > -
|
_ ignore #menu: Navigate > -
|
||||||
@@ -131,15 +129,19 @@
|
|||||||
KP3 script-message rate-file 3 #menu: Extensions > Rating > 3stars
|
KP3 script-message rate-file 3 #menu: Extensions > Rating > 3stars
|
||||||
KP4 script-message rate-file 4 #menu: Extensions > Rating > 4stars
|
KP4 script-message rate-file 4 #menu: Extensions > Rating > 4stars
|
||||||
KP5 script-message rate-file 5 #menu: Extensions > Rating > 5stars
|
KP5 script-message rate-file 5 #menu: Extensions > Rating > 5stars
|
||||||
|
_ ignore #menu: Extensions > Rating > -
|
||||||
|
_ script-message rate-file about #menu: Extensions > Rating > About
|
||||||
|
|
||||||
Ctrl+t set ontop yes #menu: View > On Top > Enable
|
Ctrl+t set ontop yes #menu: View > On Top > Enable
|
||||||
Ctrl+T set ontop no #menu: View > On Top > Disable
|
Ctrl+T set ontop no #menu: View > On Top > Disable
|
||||||
|
Alt++ no-osd set window-scale 1.2 #menu: View > Window Size > Enlarge
|
||||||
|
Alt+- no-osd set window-scale 0.8 #menu: View > Window Size > Shrink
|
||||||
b cycle border #menu: View > Toggle Border
|
b cycle border #menu: View > Toggle Border
|
||||||
i script-message mpv.net show-info #menu: View > File Info
|
i script-message mpv.net show-info #menu: View > File/Stream Info
|
||||||
t script-binding stats/display-stats #menu: View > Show Statistics
|
t script-binding stats/display-stats #menu: View > Show Statistics
|
||||||
T script-binding stats/display-stats-toggle #menu: View > Toggle Statistics
|
T script-binding stats/display-stats-toggle #menu: View > Toggle Statistics
|
||||||
Del script-binding osc/visibility #menu: View > Toggle OSC Visibility
|
Del script-binding osc/visibility #menu: View > Toggle OSC Visibility
|
||||||
F8 show-text ${playlist} 5000 #menu: View > Show Playlist
|
F8 script-binding show-playlist #menu: View > Show Playlist
|
||||||
F9 show-text ${track-list} 5000 #menu: View > Show Audio/Video/Subtitle List
|
F9 show-text ${track-list} 5000 #menu: View > Show Audio/Video/Subtitle List
|
||||||
|
|
||||||
c script-message mpv.net show-conf-editor #menu: Settings > Show Config Editor
|
c script-message mpv.net show-conf-editor #menu: Settings > Show Config Editor
|
||||||
@@ -148,17 +150,26 @@
|
|||||||
|
|
||||||
F1 script-message mpv.net show-command-palette #menu: Tools > Show All Commands
|
F1 script-message mpv.net show-command-palette #menu: Tools > Show All Commands
|
||||||
h script-message mpv.net show-history #menu: Tools > Show History
|
h script-message mpv.net show-history #menu: Tools > Show History
|
||||||
|
Ctrl+r script-message-to repl type "" #menu: Tools > Show REPL
|
||||||
l ab-loop #menu: Tools > Set/clear A-B loop points
|
l ab-loop #menu: Tools > Set/clear A-B loop points
|
||||||
L cycle-values loop-file "inf" "no" #menu: Tools > Toggle infinite file looping
|
L cycle-values loop-file "inf" "no" #menu: Tools > Toggle infinite file looping
|
||||||
|
_ cycle shuffle #menu: Tools > Toggle Shuffle
|
||||||
Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Toggle Hardware Decoding
|
Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Toggle Hardware Decoding
|
||||||
_ script-message mpv.net execute-mpv-command #menu: Tools > Execute mpv command...
|
_ script-message mpv.net show-setup-dialog #menu: Tools > OS Setup...
|
||||||
_ script-message mpv.net manage-file-associations #menu: Tools > Manage File Associations...
|
|
||||||
|
|
||||||
_ script-message mpv.net shell-execute https://mpv.io/manual/stable/ #menu: Help > Show mpv manual
|
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net/blob/master/Manual.md #menu: Help > mpv.net Manual
|
||||||
_ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/blob/master/etc/input.conf #menu: Help > Show mpv default keys
|
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net #menu: Help > mpv.net GitHub
|
||||||
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt #menu: Help > Show mpv.net default keys
|
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net/wiki #menu: Help > mpv.net Wiki
|
||||||
_ script-message mpv.net shell-execute https://mpv-net.github.io/mpv.net-web-site/ #menu: Help > Show mpv.net web site
|
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net#support #menu: Help > mpv.net Support
|
||||||
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net/blob/master/Manual.md #menu: Help > Show mpv.net manual
|
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net/releases #menu: Help > mpv.net Download
|
||||||
|
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt #menu: Help > mpv.net Default Key Bindings
|
||||||
|
_ ignore #menu: Help > -
|
||||||
|
_ script-message mpv.net shell-execute https://mpv.io/manual/stable/ #menu: Help > mpv Manual
|
||||||
|
_ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/wiki #menu: Help > mpv Wiki
|
||||||
|
_ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/wiki/User-Scripts #menu: Help > mpv User Scripts
|
||||||
|
_ script-message mpv.net shell-execute https://mpv.io/bug-reports/ #menu: Help > mpv Bugs and Requests
|
||||||
|
_ script-message mpv.net shell-execute https://mpv.io/installation/ #menu: Help > mpv Download
|
||||||
|
_ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/blob/master/etc/input.conf #menu: Help > mpv Default Key Bindings
|
||||||
_ ignore #menu: Help > -
|
_ ignore #menu: Help > -
|
||||||
_ script-message mpv.net show-about #menu: Help > About mpv.net
|
_ script-message mpv.net show-about #menu: Help > About mpv.net
|
||||||
|
|
||||||
@@ -166,12 +177,11 @@
|
|||||||
Esc quit #menu: Exit
|
Esc quit #menu: Exit
|
||||||
Q quit-watch-later #menu: Exit Watch Later
|
Q quit-watch-later #menu: Exit Watch Later
|
||||||
|
|
||||||
> playlist-next
|
|
||||||
< playlist-prev
|
|
||||||
Power quit
|
Power quit
|
||||||
Play cycle pause
|
Play cycle pause
|
||||||
Pause cycle pause
|
Pause cycle pause
|
||||||
PlayPause cycle pause
|
PlayPause cycle pause
|
||||||
|
MBTN_Mid cycle pause
|
||||||
Stop stop
|
Stop stop
|
||||||
Forward seek 60
|
Forward seek 60
|
||||||
Rewind seek -60
|
Rewind seek -60
|
||||||
@@ -182,7 +192,11 @@
|
|||||||
Wheel_Down add volume -10
|
Wheel_Down add volume -10
|
||||||
Prev playlist-prev
|
Prev playlist-prev
|
||||||
Next playlist-next
|
Next playlist-next
|
||||||
|
MBTN_Forward playlist-next
|
||||||
|
MBTN_Back playlist-prev
|
||||||
|
> playlist-next
|
||||||
|
< playlist-prev
|
||||||
Ctrl+Wheel_Up no-osd seek 7
|
Ctrl+Wheel_Up no-osd seek 7
|
||||||
Ctrl+Wheel_Down no-osd seek -7
|
Ctrl+Wheel_Down no-osd seek -7
|
||||||
MBTN_LEFT_DBL cycle fullscreen
|
MBTN_Left_DBL cycle fullscreen
|
||||||
KP_ENTER cycle fullscreen
|
KP_Enter cycle fullscreen
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
|
input-default-bindings = no
|
||||||
# manual: https://mpv.io/manual/master/
|
|
||||||
|
|
||||||
# defaults: https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt
|
|
||||||
|
|
||||||
input-ar-delay = 500
|
input-ar-delay = 500
|
||||||
input-ar-rate = 20
|
input-ar-rate = 20
|
||||||
volume = 50
|
|
||||||
hwdec = yes
|
|
||||||
keep-open = yes
|
keep-open = yes
|
||||||
keep-open-pause = no
|
keep-open-pause = no
|
||||||
osd-playing-msg = '${filename}'
|
osd-playing-msg = '${filename}'
|
||||||
screenshot-directory = '~~desktop/'
|
|
||||||
input-default-bindings = no
|
|
||||||
script-opts = osc-scalewindowed=1.5
|
script-opts = osc-scalewindowed=1.5
|
||||||
|
screenshot-directory = '~~desktop/'
|
||||||
|
cscale = spline36
|
||||||
|
dscale = spline36
|
||||||
|
scale = spline36
|
||||||
|
hwdec = yes
|
||||||
|
|
||||||
|
[protocol.https]
|
||||||
|
osd-playing-msg = '${media-title}'
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
[[settings]]
|
|
||||||
name = "dark-mode"
|
|
||||||
default = "always"
|
|
||||||
filter = "General"
|
|
||||||
help = "Enables a dark theme."
|
|
||||||
options = [{ name = "always" },
|
|
||||||
{ name = "system" , help = "Available on Windows 10 or higher" },
|
|
||||||
{ name = "never" }]
|
|
||||||
|
|
||||||
[[settings]]
|
|
||||||
name = "url-whitelist"
|
|
||||||
filter = "General"
|
|
||||||
type = "string"
|
|
||||||
help = "mpv.net specific whitelist setting to monitor the clipboard for URLs to play.\n\nDefault: tube vimeo ard zdf"
|
|
||||||
|
|
||||||
[[settings]]
|
|
||||||
name = "process-instance"
|
|
||||||
default = "single"
|
|
||||||
filter = "General"
|
|
||||||
help = "mpv.net specific setting that defines if more then one mpv.net process is allowed.\n\nTip: Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist."
|
|
||||||
options = [{ name = "multi", help = "Create a new process everytime the shell starts mpv.net" },
|
|
||||||
{ name = "single", help = "Force a single process everytime the shell starts mpv.net" },
|
|
||||||
{ name = "queue", help = "Force a single process and add files to playlist" }]
|
|
||||||
|
|
||||||
[[settings]]
|
|
||||||
name = "debug-mode"
|
|
||||||
default = "no"
|
|
||||||
filter = "General"
|
|
||||||
help = "mpv.net specific setting that writes debug info to a file located on the desktop."
|
|
||||||
options = [{ name = "yes" },
|
|
||||||
{ name = "no" }]
|
|
||||||
|
|
||||||
[[settings]]
|
|
||||||
name = "start-size"
|
|
||||||
default = "previous"
|
|
||||||
filter = "Screen"
|
|
||||||
help = "mpv.net specific setting to remember the window height in the current session, otherwise the video's native resolution is used."
|
|
||||||
options = [{ name = "video", help = "Window size is set to native video resolution" },
|
|
||||||
{ name = "previous", help = "Window size is remembered but only from the current session" }]
|
|
||||||
|
|
||||||
[[settings]]
|
|
||||||
name = "remember-position"
|
|
||||||
default = "no"
|
|
||||||
filter = "Screen"
|
|
||||||
help = "mpv.net specific setting to save the window position on exit."
|
|
||||||
options = [{ name = "yes" },
|
|
||||||
{ name = "no" }]
|
|
||||||
BIN
mpv.net/Resources/mpvnet.ico
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 8.2 KiB |
27
mpv.net/Resources/theme.txt
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
[dark]
|
||||||
|
|
||||||
|
heading = #1E90FF
|
||||||
|
foreground = #FFFFFF
|
||||||
|
foreground2 = #C0C0C0
|
||||||
|
background = #323232
|
||||||
|
|
||||||
|
menu-foreground = #FFFFFF
|
||||||
|
menu-background = #323232
|
||||||
|
menu-highlight = #505050
|
||||||
|
menu-border = #FFFFFF
|
||||||
|
menu-checked = #5A5A5A
|
||||||
|
|
||||||
|
|
||||||
|
[light]
|
||||||
|
|
||||||
|
heading = #0068B2
|
||||||
|
foreground = #000000
|
||||||
|
foreground2 = #4C4C4C
|
||||||
|
background = #F7F7F7
|
||||||
|
|
||||||
|
menu-foreground = #000000
|
||||||
|
menu-background = #DFDFDF
|
||||||
|
menu-highlight = #BFBFBF
|
||||||
|
menu-border = #6A6A6A
|
||||||
|
menu-checked = #AAAAAA
|
||||||
@@ -3,13 +3,13 @@ using System.IO;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Management.Automation.Runspaces;
|
using System.Management.Automation.Runspaces;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Management.Automation;
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
public class PowerShellScript
|
public class PowerShellScript
|
||||||
{
|
{
|
||||||
public static object Execute(string code, string[] parameters)
|
public static void Execute(string filepath, params string[] parameters)
|
||||||
{
|
{
|
||||||
using (Runspace runspace = RunspaceFactory.CreateRunspace())
|
using (Runspace runspace = RunspaceFactory.CreateRunspace())
|
||||||
{
|
{
|
||||||
@@ -23,57 +23,53 @@ namespace mpvnet
|
|||||||
"Using namespace System\n" +
|
"Using namespace System\n" +
|
||||||
"[System.Reflection.Assembly]::LoadWithPartialName(\"mpvnet\")\n");
|
"[System.Reflection.Assembly]::LoadWithPartialName(\"mpvnet\")\n");
|
||||||
|
|
||||||
pipeline.Commands.AddScript(code);
|
pipeline.Commands.AddScript(File.ReadAllText(filepath));
|
||||||
|
|
||||||
if (parameters != null)
|
if (parameters != null)
|
||||||
foreach (var i in parameters)
|
foreach (string i in parameters)
|
||||||
pipeline.Commands[1].Parameters.Add(null, i);
|
pipeline.Commands[1].Parameters.Add(null, i);
|
||||||
|
|
||||||
try
|
PowerShellOutput output = new PowerShellOutput();
|
||||||
{
|
output.ModuleName = Path.GetFileName(filepath);
|
||||||
var ret = pipeline.Invoke();
|
|
||||||
if (ret.Count > 0) return ret[0];
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (Pipeline pipeline2 = runspace.CreatePipeline())
|
|
||||||
{
|
|
||||||
pipeline2.Commands.AddScript("$PSVersionTable.PSVersion.Major * 10 +" +
|
|
||||||
"$PSVersionTable.PSVersion.Minor");
|
|
||||||
|
|
||||||
if (Convert.ToInt32(pipeline2.Invoke()[0].ToString()) < 51)
|
pipeline.Output.DataReady += output.Output_DataReady;
|
||||||
throw new Exception();
|
pipeline.Error.DataReady += output.Error_DataReady;
|
||||||
|
|
||||||
|
runspace.SessionStateProxy.SetVariable("Output", output);
|
||||||
|
|
||||||
|
try {
|
||||||
|
pipeline.Invoke();
|
||||||
}
|
}
|
||||||
|
catch (RuntimeException e) {
|
||||||
|
Msg.ShowError("PowerShell Exception", e.Message + "\n\n" +
|
||||||
|
e.ErrorRecord.ScriptStackTrace.Replace(" <ScriptBlock>, <No file>", "") +
|
||||||
|
"\n\n" + Path.GetFileName(filepath));
|
||||||
}
|
}
|
||||||
catch (Exception e2)
|
catch (Exception e) {
|
||||||
{
|
|
||||||
Msg.ShowError("PowerShell Setup Problem\n\nEnsure you have at least PowerShell 5.1 installed.", e2.ToString());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Msg.ShowException(e);
|
Msg.ShowException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pipeline.Output.DataReady -= output.Output_DataReady;
|
||||||
|
pipeline.Error.DataReady -= output.Error_DataReady;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Init(string filePath)
|
public static void Init(string filepath)
|
||||||
{
|
{
|
||||||
foreach (var eventInfo in typeof(mp).GetEvents())
|
foreach (var eventInfo in typeof(mp).GetEvents())
|
||||||
{
|
{
|
||||||
if (eventInfo.Name.ToLower() ==
|
if (eventInfo.Name.ToLower() ==
|
||||||
Path.GetFileNameWithoutExtension(filePath).ToLower().Replace("-", ""))
|
Path.GetFileNameWithoutExtension(filepath).ToLower().Replace("-", ""))
|
||||||
{
|
{
|
||||||
PowerShellEventObject eventObject = new PowerShellEventObject();
|
PowerShellEventObject eventObject = new PowerShellEventObject();
|
||||||
MethodInfo mi;
|
MethodInfo mi;
|
||||||
eventObject.FilePath = filePath;
|
eventObject.Filepath = filepath;
|
||||||
|
|
||||||
if (eventInfo.EventHandlerType == typeof(Action))
|
if (eventInfo.EventHandlerType == typeof(Action))
|
||||||
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.Invoke));
|
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.Invoke));
|
||||||
else if (eventInfo.EventHandlerType == typeof(Action<EndFileEventMode>))
|
else if (eventInfo.EventHandlerType == typeof(Action<EndFileEventMode>))
|
||||||
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeEndFileEventMode));
|
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeEndFile));
|
||||||
else if (eventInfo.EventHandlerType == typeof(Action<string[]>))
|
else if (eventInfo.EventHandlerType == typeof(Action<string[]>))
|
||||||
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeStrings));
|
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeStrings));
|
||||||
else
|
else
|
||||||
@@ -86,7 +82,37 @@ namespace mpvnet
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Task.Run(() => PowerShellScript.Execute(File.ReadAllText(filePath), null));
|
Execute(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
class PowerShellOutput
|
||||||
|
{
|
||||||
|
public string ModuleName { get; set; }
|
||||||
|
|
||||||
|
public bool WriteStandard { get; set; } = true;
|
||||||
|
public bool WriteError { get; set; } = true;
|
||||||
|
|
||||||
|
public void Output_DataReady(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!WriteStandard)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var output = sender as PipelineReader<PSObject>;
|
||||||
|
|
||||||
|
while (output.Count > 0)
|
||||||
|
Console.WriteLine("[" + ModuleName + "] " + output.Read().ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Error_DataReady(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!WriteError)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var output = sender as PipelineReader<Object>;
|
||||||
|
|
||||||
|
while (output.Count > 0)
|
||||||
|
ConsoleHelp.WriteError("[" + ModuleName + "] " + output.Read().ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,18 +120,10 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
public EventInfo EventInfo { get; set; }
|
public EventInfo EventInfo { get; set; }
|
||||||
public Delegate Delegate { get; set; }
|
public Delegate Delegate { get; set; }
|
||||||
public string FilePath { get; set; }
|
public string Filepath { get; set; }
|
||||||
|
|
||||||
public void Invoke() => Task.Run(() => { PowerShellScript.Execute(File.ReadAllText(FilePath), null); });
|
public void Invoke() => PowerShellScript.Execute(Filepath);
|
||||||
|
public void InvokeEndFile(EndFileEventMode arg) => PowerShellScript.Execute(Filepath, arg.ToString());
|
||||||
public void InvokeEndFileEventMode(EndFileEventMode arg)
|
public void InvokeStrings(string[] args) => PowerShellScript.Execute(Filepath, args);
|
||||||
{
|
|
||||||
Task.Run(() => PowerShellScript.Execute(File.ReadAllText(FilePath), new [] { arg.ToString() }));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InvokeStrings(string[] args)
|
|
||||||
{
|
|
||||||
Task.Run(() => PowerShellScript.Execute(File.ReadAllText(FilePath), args));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
using Microsoft.Scripting;
|
using Microsoft.Scripting;
|
||||||
@@ -15,7 +16,7 @@ namespace mpvnet
|
|||||||
ScriptEngine engine;
|
ScriptEngine engine;
|
||||||
ScriptScope scope;
|
ScriptScope scope;
|
||||||
|
|
||||||
public PythonScript(string code)
|
public PythonScript(string scriptPath)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -26,14 +27,14 @@ namespace mpvnet
|
|||||||
engine.Execute("clr.AddReference(\"mpvnet\")", scope);
|
engine.Execute("clr.AddReference(\"mpvnet\")", scope);
|
||||||
engine.Execute("import mpvnet", scope);
|
engine.Execute("import mpvnet", scope);
|
||||||
engine.Execute("from mpvnet import *", scope);
|
engine.Execute("from mpvnet import *", scope);
|
||||||
engine.Execute(code, scope);
|
engine.Execute(File.ReadAllText(scriptPath), scope);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
if (ex is SyntaxErrorException e)
|
if (ex is SyntaxErrorException e)
|
||||||
Msg.ShowError($"{e.Line}, {e.Column}: " + ex.Message);
|
Msg.ShowError(e.GetType().Name,$"{e.Line}, {e.Column}: " + e.Message + "\n\n" + Path.GetFileName(scriptPath));
|
||||||
else
|
else
|
||||||
Msg.ShowException(ex);
|
Msg.ShowError(ex.GetType().Name, ex.Message + "\n\n" + Path.GetFileName(scriptPath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,14 +3,25 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:UI="clr-namespace:UI"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="About mpv.net" Height="230" Width="420" FontSize="16" ShowInTaskbar="False"
|
|
||||||
WindowStartupLocation="CenterOwner" ResizeMode="NoResize">
|
Title="About mpv.net"
|
||||||
|
Height="230"
|
||||||
|
Width="400"
|
||||||
|
FontSize="16"
|
||||||
|
ShowInTaskbar="False"
|
||||||
|
WindowStartupLocation="CenterOwner"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground}"
|
||||||
|
Background="{x:Static UI:Theme.Background}">
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
<TextBlock FontSize="48" HorizontalAlignment="Center" Margin="0,0,0,10">mpv.net</TextBlock>
|
<TextBlock FontSize="48" HorizontalAlignment="Center" Margin="0,0,0,10">mpv.net</TextBlock>
|
||||||
<TextBlock HorizontalAlignment="Center">Copyright (c) 2017-2019 Frank Skare (stax76)</TextBlock>
|
<TextBlock HorizontalAlignment="Center">Copyright (c) 2017-2019 Frank Skare (stax76)</TextBlock>
|
||||||
<TextBlock Name="Version" HorizontalAlignment="Center" />
|
<TextBlock Name="Version" HorizontalAlignment="Center" />
|
||||||
|
<TextBlock Name="mpvVersion" HorizontalAlignment="Center" />
|
||||||
<TextBlock HorizontalAlignment="Center" Margin="0,0,0,20">MIT License</TextBlock>
|
<TextBlock HorizontalAlignment="Center" Margin="0,0,0,20">MIT License</TextBlock>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Windows;
|
using System.IO;
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
@@ -8,8 +9,8 @@ namespace mpvnet
|
|||||||
public AboutWindow()
|
public AboutWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Version.Text = $"Version {System.Windows.Forms.Application.ProductVersion}";
|
Version.Text = $"mpv.net Version {System.Windows.Forms.Application.ProductVersion} ({File.GetLastWriteTime(System.Windows.Forms.Application.ExecutablePath).ToShortDateString()})";
|
||||||
Foreground = WPF.WPF.ThemeBrush;
|
mpvVersion.Text = $"{mp.get_property_string("mpv-version")} ({File.GetLastWriteTime(Folder.Startup + "mpv-1.dll").ToShortDateString()})";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnPreviewKeyDown(KeyEventArgs e) => Close();
|
protected override void OnPreviewKeyDown(KeyEventArgs e) => Close();
|
||||||
|
|||||||
@@ -3,21 +3,41 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:UI="clr-namespace:UI"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Command Palette" Height="295" Width="400" ResizeMode="NoResize"
|
|
||||||
WindowStartupLocation="CenterOwner" Loaded="Window_Loaded" FontSize="13">
|
Title="Command Palette"
|
||||||
|
Height="295"
|
||||||
|
Width="400"
|
||||||
|
FontSize="13"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterOwner"
|
||||||
|
Loaded="Window_Loaded">
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition></RowDefinition>
|
<RowDefinition></RowDefinition>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<TextBox Name="FilterTextBox" PreviewKeyDown="FilterTextBox_PreviewKeyDown" TextChanged="FilterTextBox_TextChanged"></TextBox>
|
|
||||||
<ListView Name="ListView" Grid.Row="1" MouseUp="ListView_MouseUp">
|
<TextBox Name="FilterTextBox"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground}"
|
||||||
|
Background="{x:Static UI:Theme.Background}"
|
||||||
|
PreviewKeyDown="FilterTextBox_PreviewKeyDown"
|
||||||
|
TextChanged="FilterTextBox_TextChanged"/>
|
||||||
|
|
||||||
|
<ListView Name="ListView"
|
||||||
|
Grid.Row="1"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground}"
|
||||||
|
Background="{x:Static UI:Theme.Background}"
|
||||||
|
MouseUp="ListView_MouseUp">
|
||||||
|
|
||||||
<ListView.ItemContainerStyle>
|
<ListView.ItemContainerStyle>
|
||||||
<Style TargetType="ListBoxItem">
|
<Style TargetType="ListBoxItem">
|
||||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
|
||||||
</Style>
|
</Style>
|
||||||
</ListView.ItemContainerStyle>
|
</ListView.ItemContainerStyle>
|
||||||
|
|
||||||
<ListView.ItemTemplate>
|
<ListView.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Grid>
|
<Grid>
|
||||||
@@ -25,8 +45,12 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<TextBlock Text="{Binding Path}"></TextBlock>
|
<TextBlock Text="{Binding Path}"></TextBlock>
|
||||||
<TextBlock Grid.Column="1" Text="{Binding Input}" HorizontalAlignment="Right"></TextBlock>
|
|
||||||
|
<TextBlock Grid.Column="1"
|
||||||
|
Text="{Binding Input}"
|
||||||
|
HorizontalAlignment="Right"></TextBlock>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListView.ItemTemplate>
|
</ListView.ItemTemplate>
|
||||||
|
|||||||
@@ -23,14 +23,6 @@ namespace mpvnet
|
|||||||
var yourCostumFilter = new Predicate<object>(item => Filter((CommandItem)item));
|
var yourCostumFilter = new Predicate<object>(item => Filter((CommandItem)item));
|
||||||
CollectionView.Filter = yourCostumFilter;
|
CollectionView.Filter = yourCostumFilter;
|
||||||
ListView.ItemsSource = CollectionView;
|
ListView.ItemsSource = CollectionView;
|
||||||
|
|
||||||
if (App.IsDarkMode)
|
|
||||||
{
|
|
||||||
ListView.Foreground = Brushes.White;
|
|
||||||
ListView.Background = Brushes.Black;
|
|
||||||
FilterTextBox.Foreground = Brushes.White;
|
|
||||||
FilterTextBox.Background = Brushes.Black;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Filter(CommandItem item)
|
bool Filter(CommandItem item)
|
||||||
@@ -104,7 +96,7 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
CommandItem item = ListView.SelectedItem as CommandItem;
|
CommandItem item = ListView.SelectedItem as CommandItem;
|
||||||
Close();
|
Close();
|
||||||
mp.command_string(item.Command);
|
mp.command(item.Command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,34 +3,63 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:WPF="clr-namespace:WPF"
|
xmlns:UI="clr-namespace:UI"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Height="500" Width="700" Loaded="ConfWindow1_Loaded" ShowInTaskbar="False"
|
|
||||||
WindowStartupLocation="CenterScreen" Title="Config Editor">
|
Title="Config Editor"
|
||||||
|
Height="530"
|
||||||
|
Width="700"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground}"
|
||||||
|
Background="{x:Static UI:Theme.Background}"
|
||||||
|
ShowInTaskbar="False"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Loaded="ConfWindow1_Loaded">
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="100" />
|
<ColumnDefinition Width="100" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Controls:SearchTextBoxUserControl HintText="Find a setting" x:Name="SearchControl" Width="250" Margin="0,20,0,0" Grid.ColumnSpan="2"/>
|
|
||||||
<ScrollViewer x:Name="MainScrollViewer" VerticalScrollBarVisibility="Auto" Grid.Row="1" Grid.Column="2" Margin="0,0,0,10">
|
<Controls:SearchTextBoxUserControl HintText="Find a setting"
|
||||||
|
x:Name="SearchControl"
|
||||||
|
Width="250"
|
||||||
|
Margin="0,20,0,0"
|
||||||
|
Grid.ColumnSpan="2"/>
|
||||||
|
|
||||||
|
<ScrollViewer x:Name="MainScrollViewer"
|
||||||
|
VerticalScrollBarVisibility="Auto"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="2"
|
||||||
|
Margin="0,0,0,10">
|
||||||
|
|
||||||
<StackPanel x:Name="MainStackPanel"></StackPanel>
|
<StackPanel x:Name="MainStackPanel"></StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|
||||||
<StackPanel Margin="20,0,0,0" Grid.Row="1">
|
<StackPanel Margin="20,0,0,0" Grid.Row="1">
|
||||||
<ListBox x:Name="FilterListBox" ItemsSource="{Binding FilterStrings}" BorderThickness="0" SelectionChanged="ListBox_SelectionChanged" Foreground="{x:Static WPF:WPF.ThemeBrush}" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}">
|
<ListBox x:Name="FilterListBox"
|
||||||
|
ItemsSource="{Binding FilterStrings}"
|
||||||
|
BorderThickness="0"
|
||||||
|
SelectionChanged="FilterListBox_SelectionChanged"
|
||||||
|
Foreground="{x:Static UI:Theme.Heading}"
|
||||||
|
Background="{x:Static UI:Theme.Background}">
|
||||||
|
|
||||||
<ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<TextBlock Text="{Binding}" FontSize="16" />
|
<TextBlock Text="{Binding}" FontSize="16" />
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListBox.ItemTemplate>
|
</ListBox.ItemTemplate>
|
||||||
</ListBox>
|
</ListBox>
|
||||||
<TextBlock x:Name="OpenSettingsTextBlock" Margin="0,30,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static WPF:WPF.ThemeBrush}" MouseUp="OpenSettingsTextBlock_MouseUp">Open config folder</TextBlock>
|
|
||||||
<TextBlock x:Name="ShowManualTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static WPF:WPF.ThemeBrush}" MouseUp="ShowManualTextBlock_MouseUp">Show mpv manual</TextBlock>
|
<TextBlock x:Name="OpenSettingsTextBlock" Margin="0,30,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static UI:Theme.Heading}" MouseUp="OpenSettingsTextBlock_MouseUp">Open config folder</TextBlock>
|
||||||
<TextBlock x:Name="SupportTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static WPF:WPF.ThemeBrush}" MouseUp="SupportTextBlock_MouseUp">Show support forum</TextBlock>
|
<TextBlock x:Name="PreviewTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static UI:Theme.Heading}" MouseUp="PreviewTextBlock_MouseUp">Preview mpv.conf</TextBlock>
|
||||||
|
<TextBlock x:Name="ShowManualTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static UI:Theme.Heading}" MouseUp="ShowManualTextBlock_MouseUp">Show mpv manual</TextBlock>
|
||||||
|
<TextBlock x:Name="SupportTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static UI:Theme.Heading}" MouseUp="SupportTextBlock_MouseUp">Show support forum</TextBlock>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
using DynamicGUI;
|
using DynamicGUI;
|
||||||
|
|
||||||
@@ -15,51 +16,37 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
public partial class ConfWindow : Window
|
public partial class ConfWindow : Window
|
||||||
{
|
{
|
||||||
private List<SettingBase> SettingsDefinitions = Settings.LoadSettings(Properties.Resources.mpvConfToml);
|
List<SettingBase> SettingsDefinitions = Settings.LoadSettings(Properties.Resources.confToml);
|
||||||
private List<SettingBase> NetSettingsDefinitions = Settings.LoadSettings(Properties.Resources.mpvNetConfToml);
|
List<ConfItem> ConfItems = new List<ConfItem>();
|
||||||
private Dictionary<string, Dictionary<string, string>> Comments = new Dictionary<string, Dictionary<string, string>>();
|
|
||||||
|
|
||||||
public ObservableCollection<string> FilterStrings { get; } = new ObservableCollection<string>();
|
public ObservableCollection<string> FilterStrings { get; } = new ObservableCollection<string>();
|
||||||
|
string InitialContent;
|
||||||
|
|
||||||
public ConfWindow()
|
public ConfWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
DataContext = this;
|
DataContext = this;
|
||||||
SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged;
|
SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged;
|
||||||
LoadSettings(SettingsDefinitions, Conf);
|
LoadConf(mp.ConfPath);
|
||||||
LoadSettings(NetSettingsDefinitions, NetConf);
|
LoadConf(App.ConfPath);
|
||||||
SearchControl.Text = RegHelp.GetString(App.RegPath, "config editor search");
|
LoadSettings();
|
||||||
|
InitialContent = GetCompareString();
|
||||||
|
SearchControl.Text = RegHelp.GetString(App.RegPath, "ConfigEditorSearch");
|
||||||
|
}
|
||||||
|
|
||||||
if (App.IsDarkMode)
|
private void LoadSettings()
|
||||||
{
|
{
|
||||||
Foreground = Brushes.White;
|
foreach (SettingBase setting in SettingsDefinitions)
|
||||||
Foreground2 = Brushes.Silver;
|
|
||||||
Background = Brushes.Black;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Brush Foreground2 {
|
|
||||||
get { return (Brush)GetValue(Foreground2Property); }
|
|
||||||
set { SetValue(Foreground2Property, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static readonly DependencyProperty Foreground2Property =
|
|
||||||
DependencyProperty.Register("Foreground2", typeof(Brush), typeof(ConfWindow), new PropertyMetadata(Brushes.DarkSlateGray));
|
|
||||||
|
|
||||||
private void LoadSettings(List<SettingBase> settingsDefinitions,
|
|
||||||
Dictionary<string, string> confSettings)
|
|
||||||
{
|
|
||||||
foreach (SettingBase setting in settingsDefinitions)
|
|
||||||
{
|
{
|
||||||
if (!FilterStrings.Contains(setting.Filter))
|
if (!FilterStrings.Contains(setting.Filter))
|
||||||
FilterStrings.Add(setting.Filter);
|
FilterStrings.Add(setting.Filter);
|
||||||
|
|
||||||
foreach (var pair in confSettings)
|
foreach (ConfItem confItem in ConfItems)
|
||||||
{
|
{
|
||||||
if (setting.Name == pair.Key)
|
if (setting.Name == confItem.Name && confItem.Section == "" && !confItem.IsSectionItem)
|
||||||
{
|
{
|
||||||
setting.Value = pair.Value.Trim('\'', '"');
|
setting.Value = confItem.Value.Trim('\'', '"');
|
||||||
setting.StartValue = pair.Value.Trim('\'', '"');
|
setting.ConfItem = confItem;
|
||||||
|
confItem.SettingBase = setting;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,125 +55,196 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
case StringSetting s:
|
case StringSetting s:
|
||||||
var sc = new StringSettingControl(s);
|
var sc = new StringSettingControl(s);
|
||||||
sc.TitleTextBox.Foreground = WPF.WPF.ThemeBrush;
|
|
||||||
MainStackPanel.Children.Add(sc);
|
MainStackPanel.Children.Add(sc);
|
||||||
break;
|
break;
|
||||||
case OptionSetting s:
|
case OptionSetting s:
|
||||||
var oc = new OptionSettingControl(s);
|
var oc = new OptionSettingControl(s);
|
||||||
oc.TitleTextBox.Foreground = WPF.WPF.ThemeBrush;
|
|
||||||
MainStackPanel.Children.Add(oc);
|
MainStackPanel.Children.Add(oc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string, string> _Conf;
|
|
||||||
|
|
||||||
public Dictionary<string, string> Conf {
|
|
||||||
get {
|
|
||||||
if (_Conf == null) _Conf = LoadConf(mp.ConfPath);
|
|
||||||
return _Conf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dictionary<string, string> _NetConf;
|
|
||||||
|
|
||||||
public Dictionary<string, string> NetConf {
|
|
||||||
get {
|
|
||||||
if (_NetConf == null) _NetConf = LoadConf(App.ConfFilePath);
|
|
||||||
return _NetConf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dictionary<string, string> LoadConf(string filePath)
|
|
||||||
{
|
|
||||||
Dictionary<string, string> conf = new Dictionary<string, string>();
|
|
||||||
Comments[filePath] = new Dictionary<string, string>();
|
|
||||||
|
|
||||||
if (File.Exists(filePath))
|
|
||||||
{
|
|
||||||
foreach (string i in File.ReadAllLines(filePath))
|
|
||||||
{
|
|
||||||
if (i.Contains("="))
|
|
||||||
{
|
|
||||||
int pos = i.IndexOf("=");
|
|
||||||
string left = i.Substring(0, pos).Replace(" ", "").ToLower();
|
|
||||||
string right = i.Substring(pos + 1).Trim();
|
|
||||||
|
|
||||||
if (left.StartsWith("#"))
|
|
||||||
{
|
|
||||||
Comments[filePath][left.TrimStart('#')] = right;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (left == "fs") left = "fullscreen";
|
|
||||||
if (left == "loop") left = "loop-file";
|
|
||||||
conf[left] = right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return conf;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnClosed(EventArgs e)
|
protected override void OnClosed(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnClosed(e);
|
base.OnClosed(e);
|
||||||
WriteToDisk();
|
RegHelp.SetObject(App.RegPath, "ConfigEditorSearch", SearchControl.Text);
|
||||||
RegHelp.SetObject(App.RegPath, "config editor search", SearchControl.Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriteToDisk()
|
if (InitialContent == GetCompareString())
|
||||||
{
|
|
||||||
bool isDirty = false;
|
|
||||||
|
|
||||||
foreach (SettingBase i in SettingsDefinitions)
|
|
||||||
if (i.StartValue != i.Value)
|
|
||||||
isDirty = true;
|
|
||||||
|
|
||||||
foreach (SettingBase i in NetSettingsDefinitions)
|
|
||||||
if (i.StartValue != i.Value)
|
|
||||||
isDirty = true;
|
|
||||||
|
|
||||||
if (!isDirty)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WriteToDisk(mp.ConfPath, Conf, SettingsDefinitions);
|
File.WriteAllText(mp.ConfPath, GetContent("mpv"));
|
||||||
WriteToDisk(App.ConfFilePath, NetConf, NetSettingsDefinitions);
|
File.WriteAllText(App.ConfPath, GetContent("mpvnet"));
|
||||||
|
|
||||||
Msg.Show("Changes will be available on next mpv.net startup.");
|
Msg.Show("Changes will be available on next mpv.net startup.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteToDisk(string filePath,
|
string GetCompareString()
|
||||||
Dictionary<string, string> confSettings,
|
|
||||||
List<SettingBase> settings)
|
|
||||||
{
|
{
|
||||||
string content = "";
|
return string.Join("", SettingsDefinitions.Select(item => item.Name + item.Value).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var i in Comments[filePath])
|
void LoadConf(string file)
|
||||||
content += $"#{i.Key} = {i.Value}\r\n";
|
|
||||||
|
|
||||||
foreach (SettingBase setting in settings)
|
|
||||||
{
|
{
|
||||||
|
if (!File.Exists(file))
|
||||||
|
return;
|
||||||
|
|
||||||
|
string comment = "";
|
||||||
|
string section = "";
|
||||||
|
bool isSectionItem = false;
|
||||||
|
|
||||||
|
foreach (string currentLine in File.ReadAllLines(file))
|
||||||
|
{
|
||||||
|
string line = currentLine.Trim();
|
||||||
|
|
||||||
|
if (line == "")
|
||||||
|
{
|
||||||
|
comment += "\r\n";
|
||||||
|
}
|
||||||
|
else if (line.StartsWith("#"))
|
||||||
|
{
|
||||||
|
comment += line.Trim() + "\r\n";
|
||||||
|
}
|
||||||
|
else if (line.StartsWith("[") && line.Contains("]"))
|
||||||
|
{
|
||||||
|
if (!isSectionItem && comment != "" && comment != "\r\n")
|
||||||
|
ConfItems.Add(new ConfItem() {
|
||||||
|
Comment = comment, File = Path.GetFileNameWithoutExtension(file)});
|
||||||
|
|
||||||
|
section = line.Substring(0, line.IndexOf("]") + 1);
|
||||||
|
comment = "";
|
||||||
|
isSectionItem = true;
|
||||||
|
}
|
||||||
|
else if (line.Contains("="))
|
||||||
|
{
|
||||||
|
ConfItem item = new ConfItem();
|
||||||
|
item.File = Path.GetFileNameWithoutExtension(file);
|
||||||
|
item.IsSectionItem = isSectionItem;
|
||||||
|
item.Comment = comment;
|
||||||
|
comment = "";
|
||||||
|
item.Section = section;
|
||||||
|
section = "";
|
||||||
|
|
||||||
|
if (line.Contains("#") && !line.Contains("'") && !line.Contains("\""))
|
||||||
|
{
|
||||||
|
item.LineComment = line.Substring(line.IndexOf("#")).Trim();
|
||||||
|
line = line.Substring(0, line.IndexOf("#")).Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
int pos = line.IndexOf("=");
|
||||||
|
string left = line.Substring(0, pos).Trim().ToLower();
|
||||||
|
string right = line.Substring(pos + 1).Trim();
|
||||||
|
|
||||||
|
if (left == "fs")
|
||||||
|
left = "fullscreen";
|
||||||
|
|
||||||
|
if (left == "loop")
|
||||||
|
left = "loop-file";
|
||||||
|
|
||||||
|
item.Name = left;
|
||||||
|
item.Value = right;
|
||||||
|
ConfItems.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string GetContent(string filename)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
List<string> namesWritten = new List<string>();
|
||||||
|
|
||||||
|
foreach (ConfItem item in ConfItems)
|
||||||
|
{
|
||||||
|
if (filename != item.File || item.Section != "" || item.IsSectionItem)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (item.Comment != "")
|
||||||
|
sb.Append(item.Comment);
|
||||||
|
|
||||||
|
if (item.SettingBase == null)
|
||||||
|
{
|
||||||
|
if (item.Name != "")
|
||||||
|
{
|
||||||
|
sb.Append(item.Name + " = " + item.Value);
|
||||||
|
|
||||||
|
if (item.LineComment != "")
|
||||||
|
sb.Append(" " + item.LineComment);
|
||||||
|
|
||||||
|
sb.AppendLine();
|
||||||
|
namesWritten.Add(item.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((item.SettingBase.Value ?? "") != item.SettingBase.Default)
|
||||||
|
{
|
||||||
|
string value = "";
|
||||||
|
|
||||||
|
if (item.SettingBase.Type == "string" ||
|
||||||
|
item.SettingBase.Type == "folder" ||
|
||||||
|
item.SettingBase.Type == "color")
|
||||||
|
|
||||||
|
value = "'" + item.SettingBase.Value + "'";
|
||||||
|
else
|
||||||
|
value = item.SettingBase.Value;
|
||||||
|
|
||||||
|
sb.Append(item.Name + " = " + value);
|
||||||
|
|
||||||
|
if (item.LineComment != "")
|
||||||
|
sb.Append(" " + item.LineComment);
|
||||||
|
|
||||||
|
sb.AppendLine();
|
||||||
|
namesWritten.Add(item.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sb.ToString().Contains("# Editor"))
|
||||||
|
sb.AppendLine("# Editor");
|
||||||
|
|
||||||
|
foreach (SettingBase setting in SettingsDefinitions)
|
||||||
|
{
|
||||||
|
if (filename != setting.File || namesWritten.Contains(setting.Name))
|
||||||
|
continue;
|
||||||
|
|
||||||
if ((setting.Value ?? "") != setting.Default)
|
if ((setting.Value ?? "") != setting.Default)
|
||||||
|
{
|
||||||
|
string value = "";
|
||||||
|
|
||||||
if (setting.Type == "string" ||
|
if (setting.Type == "string" ||
|
||||||
setting.Type == "folder" ||
|
setting.Type == "folder" ||
|
||||||
setting.Type == "color")
|
setting.Type == "color")
|
||||||
|
|
||||||
confSettings[setting.Name] = "'" + setting.Value + "'";
|
value = "'" + setting.Value + "'";
|
||||||
else
|
else
|
||||||
confSettings[setting.Name] = setting.Value;
|
value = setting.Value;
|
||||||
|
|
||||||
if (confSettings.ContainsKey(setting.Name) &&
|
sb.AppendLine(setting.Name + " = " + value);
|
||||||
(setting.Value ?? "") == setting.Default ||
|
}
|
||||||
(setting.Value ?? "") == "")
|
|
||||||
|
|
||||||
confSettings.Remove(setting.Name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var i in confSettings)
|
foreach (ConfItem item in ConfItems)
|
||||||
content = content + $"{i.Key} = {i.Value}\r\n";
|
{
|
||||||
|
if (filename != item.File || (item.Section == "" && !item.IsSectionItem))
|
||||||
|
continue;
|
||||||
|
|
||||||
File.WriteAllText(filePath, content);
|
if (item.Section != "")
|
||||||
|
{
|
||||||
|
if (!sb.ToString().EndsWith("\r\n\r\n"))
|
||||||
|
sb.AppendLine();
|
||||||
|
|
||||||
|
sb.AppendLine(item.Section);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.Comment != "")
|
||||||
|
sb.Append(item.Comment);
|
||||||
|
|
||||||
|
sb.Append(item.Name + " = " + item.Value);
|
||||||
|
|
||||||
|
if (item.LineComment != "")
|
||||||
|
sb.Append(" " + item.LineComment);
|
||||||
|
|
||||||
|
sb.AppendLine();
|
||||||
|
namesWritten.Add(item.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "\r\n" + sb.ToString().Trim() + "\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
@@ -221,14 +279,14 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
SearchControl.SearchTextBox.SelectAll();
|
SearchControl.SearchTextBox.SelectAll();
|
||||||
Keyboard.Focus(SearchControl.SearchTextBox);
|
Keyboard.Focus(SearchControl.SearchTextBox);
|
||||||
|
|
||||||
foreach (var i in MainStackPanel.Children.OfType<StringSettingControl>())
|
foreach (var i in MainStackPanel.Children.OfType<StringSettingControl>())
|
||||||
i.Update();
|
i.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void FilterListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.AddedItems.Count > 0)
|
if (e.AddedItems.Count > 0) SearchControl.Text = e.AddedItems[0] + ":";
|
||||||
SearchControl.Text = e.AddedItems[0].ToString() + ":";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenSettingsTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
private void OpenSettingsTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||||
@@ -236,6 +294,11 @@ namespace mpvnet
|
|||||||
Process.Start(Path.GetDirectoryName(mp.ConfPath));
|
Process.Start(Path.GetDirectoryName(mp.ConfPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PreviewTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
Msg.Show("mpv.conf Preview", GetContent("mpv"));
|
||||||
|
}
|
||||||
|
|
||||||
private void ShowManualTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
private void ShowManualTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
Process.Start("https://mpv.io/manual/master/");
|
Process.Start("https://mpv.io/manual/master/");
|
||||||
@@ -249,6 +312,7 @@ namespace mpvnet
|
|||||||
protected override void OnKeyDown(KeyEventArgs e)
|
protected override void OnKeyDown(KeyEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnKeyDown(e);
|
base.OnKeyDown(e);
|
||||||
|
|
||||||
if (e.Key == Key.Escape)
|
if (e.Key == Key.Escape)
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,21 +3,42 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:UI="clr-namespace:UI"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Media File Search" Height="300" Width="600" ResizeMode="NoResize"
|
|
||||||
WindowStartupLocation="CenterOwner" Loaded="Window_Loaded" FontSize="13">
|
Title="Media File Search"
|
||||||
|
FontSize="13"
|
||||||
|
Height="300"
|
||||||
|
Width="600"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterOwner"
|
||||||
|
Loaded="Window_Loaded">
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition></RowDefinition>
|
<RowDefinition></RowDefinition>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<TextBox Name="FilterTextBox" PreviewKeyDown="FilterTextBox_PreviewKeyDown" TextChanged="FilterTextBox_TextChanged"></TextBox>
|
|
||||||
<ListView Name="ListView" Grid.Row="1" MouseUp="ListView_MouseUp" PreviewKeyDown="ListView_PreviewKeyDown">
|
<TextBox Name="FilterTextBox"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground}"
|
||||||
|
Background="{x:Static UI:Theme.Background}"
|
||||||
|
PreviewKeyDown="FilterTextBox_PreviewKeyDown"
|
||||||
|
TextChanged="FilterTextBox_TextChanged"/>
|
||||||
|
|
||||||
|
<ListView Name="ListView"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground}"
|
||||||
|
Background="{x:Static UI:Theme.Background}"
|
||||||
|
Grid.Row="1"
|
||||||
|
MouseUp="ListView_MouseUp"
|
||||||
|
PreviewKeyDown="ListView_PreviewKeyDown">
|
||||||
|
|
||||||
<ListView.ItemContainerStyle>
|
<ListView.ItemContainerStyle>
|
||||||
<Style TargetType="ListBoxItem">
|
<Style TargetType="ListBoxItem">
|
||||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
|
||||||
</Style>
|
</Style>
|
||||||
</ListView.ItemContainerStyle>
|
</ListView.ItemContainerStyle>
|
||||||
|
|
||||||
</ListView>
|
</ListView>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -9,7 +9,6 @@ using System.Windows;
|
|||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
using System.Windows.Media;
|
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
@@ -18,19 +17,10 @@ namespace mpvnet
|
|||||||
public EverythingWindow()
|
public EverythingWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
if (App.IsDarkMode)
|
|
||||||
{
|
|
||||||
ListView.Foreground = Brushes.White;
|
|
||||||
ListView.Background = Brushes.Black;
|
|
||||||
FilterTextBox.Foreground = Brushes.White;
|
|
||||||
FilterTextBox.Background = Brushes.Black;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int EVERYTHING_REQUEST_FILE_NAME = 0x00000001;
|
const int EVERYTHING_REQUEST_FILE_NAME = 0x00000001;
|
||||||
const int EVERYTHING_REQUEST_PATH = 0x00000002;
|
const int EVERYTHING_REQUEST_PATH = 0x00000002;
|
||||||
const int EVERYTHING_SORT_SIZE_DESCENDING = 6;
|
|
||||||
|
|
||||||
[DllImport("Everything.dll", CharSet = CharSet.Unicode)]
|
[DllImport("Everything.dll", CharSet = CharSet.Unicode)]
|
||||||
public static extern int Everything_SetSearch(string lpSearchString);
|
public static extern int Everything_SetSearch(string lpSearchString);
|
||||||
@@ -70,6 +60,7 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
if (msg == 0x200 /*WM_MOUSEMOVE*/ && Mouse.LeftButton != MouseButtonState.Pressed)
|
if (msg == 0x200 /*WM_MOUSEMOVE*/ && Mouse.LeftButton != MouseButtonState.Pressed)
|
||||||
handled = true;
|
handled = true;
|
||||||
|
|
||||||
return IntPtr.Zero;
|
return IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,14 +93,18 @@ namespace mpvnet
|
|||||||
|
|
||||||
private void ListView_PreviewKeyDown(object sender, KeyEventArgs e)
|
private void ListView_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Key == Key.Escape) Close();
|
if (e.Key == Key.Escape)
|
||||||
if (e.Key == Key.Enter) Execute();
|
Close();
|
||||||
|
|
||||||
|
if (e.Key == Key.Enter)
|
||||||
|
Execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Execute()
|
void Execute()
|
||||||
{
|
{
|
||||||
if (ListView.SelectedItem != null)
|
if (ListView.SelectedItem != null)
|
||||||
mp.Load(new[] { ListView.SelectedItem as string }, true, Keyboard.Modifiers == ModifierKeys.Control);
|
mp.Load(new[] { ListView.SelectedItem as string }, true, Keyboard.Modifiers == ModifierKeys.Control);
|
||||||
|
|
||||||
Keyboard.Focus(FilterTextBox);
|
Keyboard.Focus(FilterTextBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,16 +130,21 @@ namespace mpvnet
|
|||||||
StringBuilder buf = new StringBuilder(bufsize);
|
StringBuilder buf = new StringBuilder(bufsize);
|
||||||
Everything_SetSearch(searchtext);
|
Everything_SetSearch(searchtext);
|
||||||
Everything_SetRequestFlags(EVERYTHING_REQUEST_FILE_NAME | EVERYTHING_REQUEST_PATH);
|
Everything_SetRequestFlags(EVERYTHING_REQUEST_FILE_NAME | EVERYTHING_REQUEST_PATH);
|
||||||
Everything_SetSort(EVERYTHING_SORT_SIZE_DESCENDING);
|
|
||||||
Everything_Query(true);
|
Everything_Query(true);
|
||||||
|
|
||||||
for (i = 0; i < Everything_GetNumResults(); i++)
|
for (i = 0; i < Everything_GetNumResults(); i++)
|
||||||
{
|
{
|
||||||
Everything_GetResultFullPathName(i, buf, bufsize);
|
Everything_GetResultFullPathName(i, buf, bufsize);
|
||||||
string ext = Path.GetExtension(buf.ToString()).TrimStart('.').ToLower();
|
string ext = buf.ToString().ShortExt();
|
||||||
if (App.AudioTypes.Contains(ext) || App.VideoTypes.Contains(ext))
|
|
||||||
|
if (App.AudioTypes.Contains(ext) || App.VideoTypes.Contains(ext) ||
|
||||||
|
App.ImageTypes.Contains(ext))
|
||||||
|
|
||||||
items.Add(buf.ToString());
|
items.Add(buf.ToString());
|
||||||
|
|
||||||
if (items.Count > 100) break;
|
if (items.Count > 100) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Application.Current.Dispatcher.Invoke(() => {
|
Application.Current.Dispatcher.Invoke(() => {
|
||||||
ListView.ItemsSource = items;
|
ListView.ItemsSource = items;
|
||||||
SelectFirst();
|
SelectFirst();
|
||||||
|
|||||||
@@ -3,9 +3,19 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:UI="clr-namespace:UI"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Input Editor" Height="500" Width="750" FontSize="13"
|
|
||||||
Loaded="Window_Loaded" Closed="Window_Closed" ShowInTaskbar="False">
|
Title="Input Editor"
|
||||||
|
Height="500"
|
||||||
|
Width="750"
|
||||||
|
FontSize="13"
|
||||||
|
ShowInTaskbar="False"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground}"
|
||||||
|
Background="{x:Static UI:Theme.Background}"
|
||||||
|
Loaded="Window_Loaded"
|
||||||
|
Closed="Window_Closed">
|
||||||
|
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
<Style x:Key="DataGrid_Font_Centering" TargetType="{x:Type DataGridCell}">
|
<Style x:Key="DataGrid_Font_Centering" TargetType="{x:Type DataGridCell}">
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
@@ -19,15 +29,29 @@
|
|||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
</Window.Resources>
|
</Window.Resources>
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Controls:SearchTextBoxUserControl HintText="Type ? to get help." x:Name="SearchControl" Width="300" Margin="0,20,0,20" Grid.ColumnSpan="2" />
|
|
||||||
<DataGrid Grid.Row="1" x:Name="DataGrid" CommandManager.PreviewCanExecute="DataGrid_PreviewCanExecute" AutoGenerateColumns="False" CellStyle="{StaticResource DataGrid_Font_Centering}">
|
<Controls:SearchTextBoxUserControl
|
||||||
|
HintText="Type ? to get help."
|
||||||
|
x:Name="SearchControl"
|
||||||
|
Width="300"
|
||||||
|
Margin="0,20,0,20"
|
||||||
|
Grid.ColumnSpan="2" />
|
||||||
|
|
||||||
|
<DataGrid x:Name="DataGrid"
|
||||||
|
Grid.Row="1"
|
||||||
|
CommandManager.PreviewCanExecute="DataGrid_PreviewCanExecute"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
CellStyle="{StaticResource DataGrid_Font_Centering}" >
|
||||||
|
|
||||||
<DataGrid.Columns>
|
<DataGrid.Columns>
|
||||||
<DataGridTextColumn Header="Menu" Binding="{Binding Path}"/>
|
<DataGridTextColumn Header="Menu" Binding="{Binding Path}"/>
|
||||||
|
|
||||||
<DataGridTemplateColumn Header="Input">
|
<DataGridTemplateColumn Header="Input">
|
||||||
<DataGridTemplateColumn.CellTemplate>
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
@@ -37,7 +61,9 @@
|
|||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
</DataGridTemplateColumn>
|
</DataGridTemplateColumn>
|
||||||
|
|
||||||
<DataGridTextColumn Header="Command" Binding="{Binding Command}" MaxWidth="330" />
|
<DataGridTextColumn Header="Command" Binding="{Binding Command}" MaxWidth="330" />
|
||||||
|
|
||||||
</DataGrid.Columns>
|
</DataGrid.Columns>
|
||||||
</DataGrid>
|
</DataGrid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -6,7 +7,6 @@ using System.Windows;
|
|||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
@@ -26,38 +26,28 @@ namespace mpvnet
|
|||||||
var yourCostumFilter = new Predicate<object>(item => Filter((CommandItem)item));
|
var yourCostumFilter = new Predicate<object>(item => Filter((CommandItem)item));
|
||||||
CollectionView.Filter = yourCostumFilter;
|
CollectionView.Filter = yourCostumFilter;
|
||||||
DataGrid.ItemsSource = CollectionView;
|
DataGrid.ItemsSource = CollectionView;
|
||||||
|
|
||||||
if (App.IsDarkMode)
|
|
||||||
{
|
|
||||||
Foreground = Brushes.White;
|
|
||||||
Foreground2 = Brushes.Silver;
|
|
||||||
Background = Brushes.Black;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public Brush Foreground2 {
|
|
||||||
get { return (Brush)GetValue(Foreground2Property); }
|
|
||||||
set { SetValue(Foreground2Property, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static readonly DependencyProperty Foreground2Property =
|
|
||||||
DependencyProperty.Register("Foreground2", typeof(Brush), typeof(InputWindow), new PropertyMetadata(Brushes.DarkSlateGray));
|
|
||||||
|
|
||||||
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
{
|
{
|
||||||
CollectionView.Refresh();
|
CollectionView.Refresh();
|
||||||
|
|
||||||
if (SearchControl.SearchTextBox.Text == "?")
|
if (SearchControl.SearchTextBox.Text == "?")
|
||||||
Msg.Show("Filtering works by searching in the Input, Menu and Command but it's possible to reduce the filter scope to either of Input, Menu or Command by prefixing as follows:\n\ni <input search>\ni: <input search>\n\nm <menu search>\nm: <menu search>\n\nc <command search>\nc: <command search>\n\nIf only one character is entered the search will be performed only in the input.", "Filtering");
|
{
|
||||||
|
SearchControl.SearchTextBox.Text = "";
|
||||||
|
Msg.Show("Filtering", "Reduce the filter scope with:\n\ni input\n\nm menu\n\nc command\n\nIf only one character is entered input search is performed.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Filter(CommandItem item)
|
bool Filter(CommandItem item)
|
||||||
{
|
{
|
||||||
if (item.Command == "") return false;
|
if (item.Command == "") return false;
|
||||||
string searchText = SearchControl.SearchTextBox.Text.ToLower();
|
string searchText = SearchControl.SearchTextBox.Text.ToLower();
|
||||||
if (searchText == "") return true;
|
if (searchText == "" || searchText == "?") return true;
|
||||||
|
|
||||||
if (searchText.StartsWith("i ") || searchText.StartsWith("i:") || searchText.Length == 1)
|
if (searchText.Length == 1)
|
||||||
|
return item.Input.ToLower().Replace("ctrl+", "").Replace("shift+", "").Replace("alt+", "") == searchText.ToLower();
|
||||||
|
else if (searchText.StartsWith("i ") || searchText.StartsWith("i:") || searchText.Length == 1)
|
||||||
{
|
{
|
||||||
if (searchText.Length > 1)
|
if (searchText.Length > 1)
|
||||||
searchText = searchText.Substring(2).Trim();
|
searchText = searchText.Substring(2).Trim();
|
||||||
|
|||||||
@@ -3,21 +3,47 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:UI="clr-namespace:UI"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Learn Input" Height="200" Width="400" WindowStartupLocation="CenterOwner"
|
|
||||||
ResizeMode="NoResize" Loaded="Window_Loaded" Background="Black" MouseWheel="Window_MouseWheel" MouseUp="Window_MouseUp" MouseDoubleClick="Window_MouseDoubleClick">
|
Title="Learn Input"
|
||||||
|
Height="200"
|
||||||
|
Width="400"
|
||||||
|
WindowStartupLocation="CenterOwner"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
Loaded="Window_Loaded"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground}"
|
||||||
|
Background="{x:Static UI:Theme.Background}"
|
||||||
|
MouseWheel="Window_MouseWheel"
|
||||||
|
MouseUp="Window_MouseUp"
|
||||||
|
MouseDoubleClick="Window_MouseDoubleClick"
|
||||||
|
TextInput="Window_TextInput">
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
<RowDefinition Height="40" />
|
<RowDefinition Height="40" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<TextBlock x:Name="MenuTextBlock" Grid.ColumnSpan="2" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="16"></TextBlock>
|
|
||||||
<TextBlock x:Name="KeyTextBlock" Grid.Row="1" Grid.ColumnSpan="2" Foreground="White" VerticalAlignment="Top" HorizontalAlignment="Center" FontSize="16"></TextBlock>
|
<TextBlock x:Name="MenuTextBlock"
|
||||||
|
Grid.ColumnSpan="2"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
FontSize="16"></TextBlock>
|
||||||
|
|
||||||
|
<TextBlock x:Name="KeyTextBlock"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.ColumnSpan="2"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
FontSize="16" />
|
||||||
|
|
||||||
<Button x:Name="ConfirmButton" Grid.Row="2" Click="ConfirmButton_Click">Confirm</Button>
|
<Button x:Name="ConfirmButton" Grid.Row="2" Click="ConfirmButton_Click">Confirm</Button>
|
||||||
<Button x:Name="ClearButton" Grid.Row="2" Click="ClearButton_Click" Grid.Column="1">Clear</Button>
|
<Button x:Name="ClearButton" Grid.Row="2" Click="ClearButton_Click" Grid.Column="1">Clear</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -1,23 +1,25 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
using WF = System.Windows.Forms;
|
|
||||||
|
using WinForms = System.Windows.Forms;
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
public partial class LearnWindow : Window
|
public partial class LearnWindow : Window
|
||||||
{
|
{
|
||||||
public CommandItem InputItem { get; set; }
|
public CommandItem InputItem { get; set; }
|
||||||
public string NewKey { get; set; } = "";
|
string NewKey = "";
|
||||||
|
string KeyChar = "";
|
||||||
|
|
||||||
public LearnWindow() => InitializeComponent();
|
public LearnWindow() => InitializeComponent();
|
||||||
|
|
||||||
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||||
{
|
{
|
||||||
WF.Message m = new WF.Message();
|
WinForms.Message m = new WinForms.Message();
|
||||||
m.HWnd = hwnd;
|
m.HWnd = hwnd;
|
||||||
m.Msg = msg;
|
m.Msg = msg;
|
||||||
m.WParam = wParam;
|
m.WParam = wParam;
|
||||||
@@ -26,10 +28,10 @@ namespace mpvnet
|
|||||||
return m.Result;
|
return m.Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnKeyUp(WF.KeyEventArgs e)
|
void OnKeyUp(WinForms.KeyEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.KeyCode == WF.Keys.ControlKey || e.KeyCode == WF.Keys.ShiftKey ||
|
if (e.KeyCode == WinForms.Keys.ControlKey || e.KeyCode == WinForms.Keys.ShiftKey ||
|
||||||
e.KeyCode == WF.Keys.Menu || e.KeyCode == WF.Keys.None)
|
e.KeyCode == WinForms.Keys.Menu || e.KeyCode == WinForms.Keys.None)
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -44,192 +46,203 @@ namespace mpvnet
|
|||||||
} catch {}
|
} catch {}
|
||||||
|
|
||||||
for (int i = 0; i < 13; i++)
|
for (int i = 0; i < 13; i++)
|
||||||
if ("D" + i.ToString() == text)
|
if ("D" + i == text)
|
||||||
text = text.Substring(1);
|
text = text.Substring(1);
|
||||||
|
|
||||||
switch (e.KeyCode)
|
switch (e.KeyCode)
|
||||||
{
|
{
|
||||||
case WF.Keys.NumPad0:
|
case WinForms.Keys.NumPad0:
|
||||||
case WF.Keys.NumPad1:
|
case WinForms.Keys.NumPad1:
|
||||||
case WF.Keys.NumPad2:
|
case WinForms.Keys.NumPad2:
|
||||||
case WF.Keys.NumPad3:
|
case WinForms.Keys.NumPad3:
|
||||||
case WF.Keys.NumPad4:
|
case WinForms.Keys.NumPad4:
|
||||||
case WF.Keys.NumPad5:
|
case WinForms.Keys.NumPad5:
|
||||||
case WF.Keys.NumPad6:
|
case WinForms.Keys.NumPad6:
|
||||||
case WF.Keys.NumPad7:
|
case WinForms.Keys.NumPad7:
|
||||||
case WF.Keys.NumPad8:
|
case WinForms.Keys.NumPad8:
|
||||||
case WF.Keys.NumPad9:
|
case WinForms.Keys.NumPad9:
|
||||||
text = "KP" + e.KeyCode.ToString()[6].ToString(); break;
|
text = "KP" + e.KeyCode.ToString()[6]; break;
|
||||||
case WF.Keys.Space:
|
case WinForms.Keys.Space:
|
||||||
text = "Space"; break;
|
text = "Space"; break;
|
||||||
case WF.Keys.Enter:
|
case WinForms.Keys.Enter:
|
||||||
text = "Enter"; break;
|
text = "Enter"; break;
|
||||||
case WF.Keys.Tab:
|
case WinForms.Keys.Tab:
|
||||||
text = "Tab"; break;
|
text = "TAB"; break;
|
||||||
case WF.Keys.Back:
|
case WinForms.Keys.Back:
|
||||||
text = "BS"; break;
|
text = "BS"; break;
|
||||||
case WF.Keys.Delete:
|
case WinForms.Keys.Delete:
|
||||||
text = "Del"; break;
|
text = "DEL"; break;
|
||||||
case WF.Keys.Insert:
|
case WinForms.Keys.Insert:
|
||||||
text = "Ins"; break;
|
text = "INS"; break;
|
||||||
case WF.Keys.Home:
|
case WinForms.Keys.Home:
|
||||||
text = "Home"; break;
|
text = "Home"; break;
|
||||||
case WF.Keys.End:
|
case WinForms.Keys.End:
|
||||||
text = "End"; break;
|
text = "END"; break;
|
||||||
case WF.Keys.PageUp:
|
case WinForms.Keys.PageUp:
|
||||||
text = "PGUP"; break;
|
text = "PGUP"; break;
|
||||||
case WF.Keys.PageDown:
|
case WinForms.Keys.PageDown:
|
||||||
text = "PGDWN"; break;
|
text = "PGDWN"; break;
|
||||||
case WF.Keys.Escape:
|
case WinForms.Keys.Escape:
|
||||||
text = "Esc"; break;
|
text = "ESC"; break;
|
||||||
case WF.Keys.PrintScreen:
|
case WinForms.Keys.PrintScreen:
|
||||||
text = "Print"; break;
|
text = "Print"; break;
|
||||||
case WF.Keys.Play:
|
case WinForms.Keys.Play:
|
||||||
text = "Play"; break;
|
text = "Play"; break;
|
||||||
case WF.Keys.Pause:
|
case WinForms.Keys.Pause:
|
||||||
text = "Pause"; break;
|
text = "Pause"; break;
|
||||||
case WF.Keys.MediaPlayPause:
|
case WinForms.Keys.MediaPlayPause:
|
||||||
text = "PlayPause"; break;
|
text = "PlayPause"; break;
|
||||||
case WF.Keys.MediaStop:
|
case WinForms.Keys.MediaStop:
|
||||||
text = "Stop"; break;
|
text = "Stop"; break;
|
||||||
case WF.Keys.MediaNextTrack:
|
case WinForms.Keys.MediaNextTrack:
|
||||||
text = "Next"; break;
|
text = "Next"; break;
|
||||||
case WF.Keys.MediaPreviousTrack:
|
case WinForms.Keys.MediaPreviousTrack:
|
||||||
text = "Prev"; break;
|
text = "Prev"; break;
|
||||||
case WF.Keys.VolumeUp:
|
case WinForms.Keys.VolumeUp:
|
||||||
text = "Volume_Up"; break;
|
text = "Volume_Up"; break;
|
||||||
case WF.Keys.VolumeDown:
|
case WinForms.Keys.VolumeDown:
|
||||||
text = "Volume_Down"; break;
|
text = "Volume_Down"; break;
|
||||||
case WF.Keys.VolumeMute:
|
case WinForms.Keys.VolumeMute:
|
||||||
text = "Mute"; break;
|
text = "Mute"; break;
|
||||||
case WF.Keys.BrowserHome:
|
case WinForms.Keys.BrowserHome:
|
||||||
text = "Homepage"; break;
|
text = "Homepage"; break;
|
||||||
case WF.Keys.LaunchMail:
|
case WinForms.Keys.LaunchMail:
|
||||||
text = "Mail"; break;
|
text = "Mail"; break;
|
||||||
case WF.Keys.BrowserFavorites:
|
case WinForms.Keys.BrowserFavorites:
|
||||||
text = "Favorites"; break;
|
text = "Favorites"; break;
|
||||||
case WF.Keys.BrowserSearch:
|
case WinForms.Keys.BrowserSearch:
|
||||||
text = "Search"; break;
|
text = "Search"; break;
|
||||||
case WF.Keys.Sleep:
|
case WinForms.Keys.Sleep:
|
||||||
text = "Sleep"; break;
|
text = "Sleep"; break;
|
||||||
case WF.Keys.Cancel:
|
case WinForms.Keys.Cancel:
|
||||||
text = "Cancel"; break;
|
text = "Cancel"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shiftWasHandled = false;
|
bool wasModified = false;
|
||||||
|
|
||||||
bool isAlt = GetKeyState(18) < (short)0;
|
bool isAlt = GetKeyState(18) < (short)0;
|
||||||
bool isShift = GetKeyState(16) < (short)0;
|
bool isShift = GetKeyState(16) < (short)0;
|
||||||
bool isCtrl = GetKeyState(17) < (short)0;
|
bool isCtrl = GetKeyState(17) < (short)0;
|
||||||
|
|
||||||
if (text.Length == 1 && isShift && text[0] != GetModifiedKey(text[0]))
|
if (text.Length == 1 && KeyChar != text)
|
||||||
{
|
{
|
||||||
text = GetModifiedKey(text[0]).ToString();
|
text = KeyChar;
|
||||||
shiftWasHandled = true;
|
wasModified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text == "#") text = "Sharp";
|
if (text == "#") text = "SHARP";
|
||||||
|
|
||||||
if (isAlt) text = "Alt+" + text;
|
if (isAlt && !wasModified)
|
||||||
if (isShift && !shiftWasHandled) text = "Shift+" + text;
|
text = "ALT+" + text;
|
||||||
if (isCtrl) text = "Ctrl+" + text;
|
|
||||||
|
if (isShift && !wasModified)
|
||||||
|
text = "SHIFT+" + text;
|
||||||
|
|
||||||
|
if (isCtrl && !wasModified)
|
||||||
|
text = "CTRL+" + text;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(text))
|
if (!string.IsNullOrEmpty(text))
|
||||||
SetKey(text);
|
SetKey(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DateTime LastKeyUp;
|
||||||
|
|
||||||
void SetKey(string key)
|
void SetKey(string key)
|
||||||
{
|
{
|
||||||
NewKey = key;
|
NewKey = key;
|
||||||
MenuTextBlock.Text = InputItem.Path;
|
MenuTextBlock.Text = InputItem.Path;
|
||||||
KeyTextBlock.Text = key;
|
KeyTextBlock.Text = key;
|
||||||
|
LastKeyUp = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
static extern uint MapVirtualKey(uint uCode, uint uMapType);
|
static extern uint MapVirtualKey(uint uCode, uint uMapType);
|
||||||
|
|
||||||
public static WF.Keys ModifierKeys {
|
public static WinForms.Keys ModifierKeys {
|
||||||
get {
|
get {
|
||||||
WF.Keys keys = WF.Keys.None;
|
WinForms.Keys keys = WinForms.Keys.None;
|
||||||
|
|
||||||
if (GetKeyState(17) < (short)0)
|
if (GetKeyState(17) < (short)0)
|
||||||
keys |= WF.Keys.Control;
|
keys |= WinForms.Keys.Control;
|
||||||
|
|
||||||
if (GetKeyState(16) < (short)0)
|
if (GetKeyState(16) < (short)0)
|
||||||
keys |= WF.Keys.Shift;
|
keys |= WinForms.Keys.Shift;
|
||||||
|
|
||||||
if (GetKeyState(18) < (short)0)
|
if (GetKeyState(18) < (short)0)
|
||||||
keys |= WF.Keys.Alt;
|
keys |= WinForms.Keys.Alt;
|
||||||
|
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static char GetModifiedKey(char c)
|
void ProcessKeyEventArgs(ref WinForms.Message m)
|
||||||
{
|
|
||||||
short vkKeyScanResult = VkKeyScan(c);
|
|
||||||
|
|
||||||
if (vkKeyScanResult == -1)
|
|
||||||
return c;
|
|
||||||
|
|
||||||
uint code = (uint)vkKeyScanResult & 0xff;
|
|
||||||
byte[] b = new byte[256];
|
|
||||||
b[0x10] = 0x80;
|
|
||||||
uint r;
|
|
||||||
|
|
||||||
if (1 != ToAscii(code, code, b, out r, 0))
|
|
||||||
return c;
|
|
||||||
|
|
||||||
return (char)r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProcessKeyEventArgs(ref WF.Message m)
|
|
||||||
{
|
{
|
||||||
int WM_KEYUP = 0x0101, WM_SYSKEYUP = 0x0105, WM_APPCOMMAND = 0x0319;
|
int WM_KEYUP = 0x0101, WM_SYSKEYUP = 0x0105, WM_APPCOMMAND = 0x0319;
|
||||||
|
|
||||||
if (m.Msg == WM_KEYUP || m.Msg == WM_SYSKEYUP)
|
if (m.Msg == WM_KEYUP || m.Msg == WM_SYSKEYUP)
|
||||||
OnKeyUp(new WF.KeyEventArgs((WF.Keys)(unchecked((int)(long)m.WParam)) | ModifierKeys));
|
OnKeyUp(new WinForms.KeyEventArgs((WinForms.Keys)(unchecked((int)(long)m.WParam)) | ModifierKeys));
|
||||||
else if (m.Msg == WM_APPCOMMAND)
|
else if (m.Msg == WM_APPCOMMAND)
|
||||||
{
|
{
|
||||||
switch ((AppCommand)(m.LParam.ToInt32() >> 16))
|
var value = (AppCommand)(m.LParam.ToInt64() >> 16 & ~0xf000);
|
||||||
|
|
||||||
|
switch (value)
|
||||||
{
|
{
|
||||||
case AppCommand.MEDIA_CHANNEL_DOWN:
|
case AppCommand.APPCOMMAND_MEDIA_CHANNEL_DOWN:
|
||||||
SetKey("Channel_Down");
|
SetKey("CHANNEL_DOWN");
|
||||||
break;
|
break;
|
||||||
case AppCommand.MEDIA_CHANNEL_UP:
|
case AppCommand.APPCOMMAND_MEDIA_CHANNEL_UP:
|
||||||
SetKey("Channel_Up");
|
SetKey("CHANNEL_UP");
|
||||||
break;
|
break;
|
||||||
case AppCommand.MEDIA_FAST_FORWARD:
|
case AppCommand.APPCOMMAND_MEDIA_FAST_FORWARD:
|
||||||
SetKey("Forward");
|
SetKey("FORWARD");
|
||||||
break;
|
break;
|
||||||
case AppCommand.MEDIA_REWIND:
|
case AppCommand.APPCOMMAND_MEDIA_REWIND:
|
||||||
SetKey("Rewind");
|
SetKey("REWIND");
|
||||||
break;
|
break;
|
||||||
case AppCommand.MEDIA_PAUSE:
|
case AppCommand.APPCOMMAND_MEDIA_PAUSE:
|
||||||
SetKey("Pause");
|
SetKey("PAUSE");
|
||||||
break;
|
break;
|
||||||
case AppCommand.MEDIA_PLAY:
|
case AppCommand.APPCOMMAND_MEDIA_PLAY:
|
||||||
SetKey("Play");
|
SetKey("PLAY");
|
||||||
break;
|
break;
|
||||||
case AppCommand.MEDIA_PLAY_PAUSE:
|
case AppCommand.APPCOMMAND_MEDIA_PLAY_PAUSE:
|
||||||
SetKey("PlayPause");
|
SetKey("PLAYPAUSE");
|
||||||
break;
|
break;
|
||||||
case AppCommand.MEDIA_NEXTTRACK:
|
case AppCommand.APPCOMMAND_MEDIA_NEXTTRACK:
|
||||||
SetKey("Next");
|
SetKey("NEXT");
|
||||||
break;
|
break;
|
||||||
case AppCommand.MEDIA_PREVIOUSTRACK:
|
case AppCommand.APPCOMMAND_MEDIA_PREVIOUSTRACK:
|
||||||
SetKey("Prev");
|
SetKey("PREV");
|
||||||
break;
|
break;
|
||||||
case AppCommand.MEDIA_RECORD:
|
case AppCommand.APPCOMMAND_MEDIA_RECORD:
|
||||||
SetKey("Record");
|
SetKey("RECORD");
|
||||||
break;
|
break;
|
||||||
case AppCommand.MEDIA_STOP:
|
case AppCommand.APPCOMMAND_MEDIA_STOP:
|
||||||
SetKey("Stop");
|
SetKey("STOP");
|
||||||
break;
|
break;
|
||||||
case AppCommand.VolumeUp:
|
case AppCommand.APPCOMMAND_VOLUME_UP:
|
||||||
SetKey("Volume_Up");
|
SetKey("VOLUME_UP");
|
||||||
break;
|
break;
|
||||||
case AppCommand.VolumeDown:
|
case AppCommand.APPCOMMAND_VOLUME_DOWN:
|
||||||
SetKey("Volume_Down");
|
SetKey("VOLUME_DOWN");
|
||||||
break;
|
break;
|
||||||
case AppCommand.VolumeMute:
|
case AppCommand.APPCOMMAND_VOLUME_MUTE:
|
||||||
SetKey("Mute");
|
SetKey("MUTE");
|
||||||
|
break;
|
||||||
|
case AppCommand.APPCOMMAND_BROWSER_HOME:
|
||||||
|
SetKey("HOMEPAGE");
|
||||||
|
break;
|
||||||
|
case AppCommand.APPCOMMAND_LAUNCH_MAIL:
|
||||||
|
SetKey("MAIL");
|
||||||
|
break;
|
||||||
|
case AppCommand.APPCOMMAND_BROWSER_FAVORITES:
|
||||||
|
SetKey("FAVORITES");
|
||||||
|
break;
|
||||||
|
case AppCommand.APPCOMMAND_BROWSER_SEARCH:
|
||||||
|
SetKey("SEARCH");
|
||||||
|
break;
|
||||||
|
case AppCommand.APPCOMMAND_PRINT:
|
||||||
|
SetKey("PRINT");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,20 +250,58 @@ namespace mpvnet
|
|||||||
|
|
||||||
internal enum AppCommand
|
internal enum AppCommand
|
||||||
{
|
{
|
||||||
MEDIA_CHANNEL_DOWN = 52,
|
APPCOMMAND_BASS_BOOST = 20,
|
||||||
MEDIA_CHANNEL_UP = 51,
|
APPCOMMAND_BASS_DOWN = 19,
|
||||||
MEDIA_FAST_FORWARD = 49,
|
APPCOMMAND_BASS_UP = 21,
|
||||||
MEDIA_NEXTTRACK = 11,
|
APPCOMMAND_BROWSER_BACKWARD = 1,
|
||||||
MEDIA_PAUSE = 47,
|
APPCOMMAND_BROWSER_FAVORITES = 6,
|
||||||
MEDIA_PLAY = 46,
|
APPCOMMAND_BROWSER_FORWARD = 2,
|
||||||
MEDIA_PLAY_PAUSE = 14,
|
APPCOMMAND_BROWSER_HOME = 7,
|
||||||
MEDIA_PREVIOUSTRACK = 12,
|
APPCOMMAND_BROWSER_REFRESH = 3,
|
||||||
MEDIA_RECORD = 48,
|
APPCOMMAND_BROWSER_SEARCH = 5,
|
||||||
MEDIA_REWIND = 50,
|
APPCOMMAND_BROWSER_STOP = 4,
|
||||||
MEDIA_STOP = 13,
|
APPCOMMAND_CLOSE = 31,
|
||||||
VolumeMute = 8,
|
APPCOMMAND_COPY = 36,
|
||||||
VolumeDown = 9,
|
APPCOMMAND_CORRECTION_LIST = 45,
|
||||||
VolumeUp = 10
|
APPCOMMAND_CUT = 37,
|
||||||
|
APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE = 43,
|
||||||
|
APPCOMMAND_FIND = 28,
|
||||||
|
APPCOMMAND_FORWARD_MAIL = 40,
|
||||||
|
APPCOMMAND_HELP = 27,
|
||||||
|
APPCOMMAND_LAUNCH_APP1 = 17,
|
||||||
|
APPCOMMAND_LAUNCH_APP2 = 18,
|
||||||
|
APPCOMMAND_LAUNCH_MAIL = 15,
|
||||||
|
APPCOMMAND_LAUNCH_MEDIA_SELECT = 16,
|
||||||
|
APPCOMMAND_MEDIA_CHANNEL_DOWN = 52,
|
||||||
|
APPCOMMAND_MEDIA_CHANNEL_UP = 51,
|
||||||
|
APPCOMMAND_MEDIA_FAST_FORWARD = 49,
|
||||||
|
APPCOMMAND_MEDIA_NEXTTRACK = 11,
|
||||||
|
APPCOMMAND_MEDIA_PAUSE = 47,
|
||||||
|
APPCOMMAND_MEDIA_PLAY = 46,
|
||||||
|
APPCOMMAND_MEDIA_PLAY_PAUSE = 14,
|
||||||
|
APPCOMMAND_MEDIA_PREVIOUSTRACK = 12,
|
||||||
|
APPCOMMAND_MEDIA_RECORD = 48,
|
||||||
|
APPCOMMAND_MEDIA_REWIND = 50,
|
||||||
|
APPCOMMAND_MEDIA_STOP = 13,
|
||||||
|
APPCOMMAND_MIC_ON_OFF_TOGGLE = 44,
|
||||||
|
APPCOMMAND_MICROPHONE_VOLUME_DOWN = 25,
|
||||||
|
APPCOMMAND_MICROPHONE_VOLUME_MUTE = 24,
|
||||||
|
APPCOMMAND_MICROPHONE_VOLUME_UP = 26,
|
||||||
|
APPCOMMAND_NEW = 29,
|
||||||
|
APPCOMMAND_OPEN = 30,
|
||||||
|
APPCOMMAND_PASTE = 38,
|
||||||
|
APPCOMMAND_PRINT = 33,
|
||||||
|
APPCOMMAND_REDO = 35,
|
||||||
|
APPCOMMAND_REPLY_TO_MAIL = 39,
|
||||||
|
APPCOMMAND_SAVE = 32,
|
||||||
|
APPCOMMAND_SEND_MAIL = 41,
|
||||||
|
APPCOMMAND_SPELL_CHECK = 42,
|
||||||
|
APPCOMMAND_TREBLE_DOWN = 22,
|
||||||
|
APPCOMMAND_TREBLE_UP = 23,
|
||||||
|
APPCOMMAND_UNDO = 34,
|
||||||
|
APPCOMMAND_VOLUME_DOWN = 9,
|
||||||
|
APPCOMMAND_VOLUME_MUTE = 8,
|
||||||
|
APPCOMMAND_VOLUME_UP = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||||
@@ -325,5 +376,10 @@ namespace mpvnet
|
|||||||
BlockMBTN_LEFT = true;
|
BlockMBTN_LEFT = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Window_TextInput(object sender, TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
KeyChar = e.Text;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,23 @@
|
|||||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:WPF="clr-namespace:WPF">
|
xmlns:UI="clr-namespace:UI">
|
||||||
|
|
||||||
<Style TargetType="TextBox">
|
<Style TargetType="TextBox">
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate TargetType="{x:Type TextBox}">
|
<ControlTemplate TargetType="{x:Type TextBox}">
|
||||||
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
|
<Border x:Name="border"
|
||||||
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
|
SnapsToDevicePixels="True">
|
||||||
|
|
||||||
|
<ScrollViewer x:Name="PART_ContentHost"
|
||||||
|
Focusable="false"
|
||||||
|
HorizontalScrollBarVisibility="Hidden"
|
||||||
|
VerticalScrollBarVisibility="Hidden"/>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<ControlTemplate.Triggers>
|
<ControlTemplate.Triggers>
|
||||||
<Trigger Property="IsEnabled" Value="false">
|
<Trigger Property="IsEnabled" Value="false">
|
||||||
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
|
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
|
||||||
@@ -17,7 +26,7 @@
|
|||||||
<Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
|
<Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
<Trigger Property="IsFocused" Value="true">
|
<Trigger Property="IsFocused" Value="true">
|
||||||
<Setter Property="BorderBrush" TargetName="border" Value="{x:Static WPF:WPF.ThemeBrush}"/>
|
<Setter Property="BorderBrush" TargetName="border" Value="{x:Static UI:Theme.Heading}"/>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
</ControlTemplate.Triggers>
|
</ControlTemplate.Triggers>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
@@ -34,13 +43,14 @@
|
|||||||
<ColumnDefinition x:Name="LeftCol" Width="18" />
|
<ColumnDefinition x:Name="LeftCol" Width="18" />
|
||||||
<ColumnDefinition x:Name="RightCol" Width="*" />
|
<ColumnDefinition x:Name="RightCol" Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Grid x:Name="PART_CHECKBOX">
|
<Grid x:Name="PART_CHECKBOX">
|
||||||
<Ellipse
|
<Ellipse
|
||||||
x:Name="normal"
|
x:Name="normal"
|
||||||
Width="18"
|
Width="18"
|
||||||
Height="18"
|
Height="18"
|
||||||
Fill="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
|
Fill="{x:Static UI:Theme.Background}"
|
||||||
Stroke="{x:Static WPF:WPF.ThemeBrush}"
|
Stroke="{x:Static UI:Theme.Heading}"
|
||||||
StrokeThickness="2" />
|
StrokeThickness="2" />
|
||||||
<Ellipse
|
<Ellipse
|
||||||
x:Name="Checked1"
|
x:Name="Checked1"
|
||||||
@@ -56,6 +66,7 @@
|
|||||||
Opacity="0"
|
Opacity="0"
|
||||||
StrokeThickness="{TemplateBinding BorderThickness}" />
|
StrokeThickness="{TemplateBinding BorderThickness}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<ContentPresenter
|
<ContentPresenter
|
||||||
x:Name="contentPresenter"
|
x:Name="contentPresenter"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
@@ -67,6 +78,7 @@
|
|||||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||||
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
|
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
|
||||||
RecognizesAccessKey="True" />
|
RecognizesAccessKey="True" />
|
||||||
|
|
||||||
<VisualStateManager.VisualStateGroups>
|
<VisualStateManager.VisualStateGroups>
|
||||||
<VisualStateGroup x:Name="CommonStates">
|
<VisualStateGroup x:Name="CommonStates">
|
||||||
<VisualState x:Name="Normal" />
|
<VisualState x:Name="Normal" />
|
||||||
|
|||||||
68
mpv.net/WPF/SearchTextBoxUserControl.xaml
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<UserControl x:Class="Controls.SearchTextBoxUserControl"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:UI="clr-namespace:UI"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450"
|
||||||
|
d:DesignWidth="800">
|
||||||
|
|
||||||
|
<Grid Name="SearchTextBoxUserControl1"
|
||||||
|
Background="{x:Static UI:Theme.Background}">
|
||||||
|
|
||||||
|
<TextBlock Name="HintTextBlock"
|
||||||
|
Margin="5,2"
|
||||||
|
Text="Find a setting"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground2}"
|
||||||
|
Background="{x:Static UI:Theme.Background}" />
|
||||||
|
|
||||||
|
<TextBox Name="SearchTextBox"
|
||||||
|
Height="25"
|
||||||
|
Padding="1,2,0,0"
|
||||||
|
BorderThickness="2"
|
||||||
|
Background="Transparent"
|
||||||
|
TextChanged="SearchTextBox_TextChanged"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground}"
|
||||||
|
CaretBrush="{x:Static UI:Theme.Foreground}" />
|
||||||
|
|
||||||
|
<Button Name="SearchClearButton"
|
||||||
|
Background="Transparent"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
FontFamily="Marlett"
|
||||||
|
FontSize="10"
|
||||||
|
Width="17"
|
||||||
|
Height="17"
|
||||||
|
Margin="2,0,4,0"
|
||||||
|
Visibility="Hidden"
|
||||||
|
Click="SearchClearButton_Click" >r
|
||||||
|
|
||||||
|
<Button.Style>
|
||||||
|
<Style TargetType="Button">
|
||||||
|
<Setter Property="Background" Value="{x:Static UI:Theme.Background}"/>
|
||||||
|
<Setter Property="Foreground" Value="{x:Static UI:Theme.Foreground2}"/>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="Button">
|
||||||
|
<Border BorderThickness="1"
|
||||||
|
BorderBrush="{TemplateBinding Foreground}"
|
||||||
|
SnapsToDevicePixels="True">
|
||||||
|
|
||||||
|
<ContentPresenter HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center" />
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter Property="Foreground" Value="{x:Static UI:Theme.Heading}"/>
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</Button.Style>
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
33
mpv.net/WPF/SetupWindow.xaml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<Window x:Class="mpvnet.SetupWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:UI="clr-namespace:UI"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
|
||||||
|
Title="mpv.net OS Setup"
|
||||||
|
FontSize="13"
|
||||||
|
Foreground="{x:Static UI:Theme.Foreground}"
|
||||||
|
Background="{x:Static UI:Theme.Background}"
|
||||||
|
SizeToContent="WidthAndHeight"
|
||||||
|
WindowStartupLocation="CenterOwner" >
|
||||||
|
|
||||||
|
<Window.Resources>
|
||||||
|
<Style TargetType="Button">
|
||||||
|
<Setter Property="Padding" Value="10"></Setter>
|
||||||
|
<Setter Property="Margin" Value="5"></Setter>
|
||||||
|
</Style>
|
||||||
|
</Window.Resources>
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<StackPanel Margin="10">
|
||||||
|
<Button Name="RegisterVideo" Click="RegisterVideo_Click">Register video file extensions (requires elevated privileges)</Button>
|
||||||
|
<Button Name="RegisterAudio" Click="RegisterAudio_Click">Register audio file extensions (requires elevated privileges)</Button>
|
||||||
|
<Button Name="RegisterImage" Click="RegisterImage_Click">Register image file extensions (requires elevated privileges)</Button>
|
||||||
|
<Button Name="UnregisterFileAssociations" Click="UnregisterFileAssociations_Click">Unregister file extensions (requires elevated privileges)</Button>
|
||||||
|
<Button Name="AddToPathEnvVar" Click="AddToPathEnvVar_Click">Add mpv.net to Path environment variable</Button>
|
||||||
|
<Button Name="RemoveFromPathEnvVar" Click="RemoveFromPathEnvVar_Click">Remove mpv.net from Path environment variable</Button>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
64
mpv.net/WPF/SetupWindow.xaml.cs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
using WinForms = System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace mpvnet
|
||||||
|
{
|
||||||
|
public partial class SetupWindow : Window
|
||||||
|
{
|
||||||
|
public SetupWindow() => InitializeComponent();
|
||||||
|
|
||||||
|
void RegisterFileAssociations(string value)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var proc = new Process())
|
||||||
|
{
|
||||||
|
proc.StartInfo.FileName = WinForms.Application.ExecutablePath;
|
||||||
|
proc.StartInfo.Arguments = "--reg-file-assoc " + value;
|
||||||
|
proc.StartInfo.Verb = "runas";
|
||||||
|
proc.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
Process.Start("ms-settings:defaultapps");
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterVideo_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("video");
|
||||||
|
private void RegisterAudio_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("audio");
|
||||||
|
private void RegisterImage_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("image");
|
||||||
|
|
||||||
|
private void UnregisterFileAssociations_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("unreg");
|
||||||
|
|
||||||
|
private void AddToPathEnvVar_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
string var = WinForms.Application.StartupPath + ";";
|
||||||
|
string path = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.User);
|
||||||
|
|
||||||
|
if (path.Contains(var))
|
||||||
|
Msg.ShowWarning("Path was already containing mpv.net.");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Environment.SetEnvironmentVariable("Path", var + path, EnvironmentVariableTarget.User);
|
||||||
|
Msg.Show("mpv.net was successfully added to Path.", (var + path).Replace(";","\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveFromPathEnvVar_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
string var = WinForms.Application.StartupPath + ";";
|
||||||
|
string path = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.User);
|
||||||
|
|
||||||
|
if (path.Contains(var))
|
||||||
|
{
|
||||||
|
Environment.SetEnvironmentVariable("Path", path.Replace(var, ""), EnvironmentVariableTarget.User);
|
||||||
|
Msg.Show("mpv.net was successfully removed from Path.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Msg.ShowWarning("Path was not containing mpv.net.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,34 +1,20 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
|
||||||
|
|
||||||
namespace WPF
|
namespace WPF
|
||||||
{
|
{
|
||||||
public class WPF
|
public class WPF
|
||||||
{
|
{
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
|
||||||
EnsureApplicationResources();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void EnsureApplicationResources()
|
|
||||||
{
|
{
|
||||||
if (Application.Current == null)
|
if (Application.Current == null)
|
||||||
{
|
{
|
||||||
new Application();
|
new Application();
|
||||||
|
|
||||||
Application.Current.Resources.MergedDictionaries.Add(
|
Application.Current.Resources.MergedDictionaries.Add(
|
||||||
Application.LoadComponent(new Uri("mpvnet;component/WPF/Resources.xaml",
|
Application.LoadComponent(new Uri("mpvnet;component/WPF/Resources.xaml",
|
||||||
UriKind.Relative)) as ResourceDictionary);
|
UriKind.Relative)) as ResourceDictionary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Brush ThemeBrush {
|
|
||||||
get {
|
|
||||||
if (Environment.OSVersion.Version.Major < 10)
|
|
||||||
return new SolidColorBrush(Colors.DarkSlateGray);
|
|
||||||
else
|
|
||||||
return SystemParameters.WindowGlassBrush;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
21
mpv.net/WinForms/MainForm.Designer.cs
generated
@@ -30,14 +30,19 @@
|
|||||||
{
|
{
|
||||||
this.components = new System.ComponentModel.Container();
|
this.components = new System.ComponentModel.Container();
|
||||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||||
this.Timer = new System.Windows.Forms.Timer(this.components);
|
this.CursorTimer = new System.Windows.Forms.Timer(this.components);
|
||||||
|
this.ProgressTimer = new System.Windows.Forms.Timer(this.components);
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// Timer
|
// CursorTimer
|
||||||
//
|
//
|
||||||
this.Timer.Enabled = true;
|
this.CursorTimer.Enabled = true;
|
||||||
this.Timer.Interval = 1000;
|
this.CursorTimer.Interval = 1000;
|
||||||
this.Timer.Tick += new System.EventHandler(this.Timer_Tick);
|
this.CursorTimer.Tick += new System.EventHandler(this.CursorTimer_Tick);
|
||||||
|
//
|
||||||
|
// ProgressTimer
|
||||||
|
//
|
||||||
|
this.ProgressTimer.Tick += new System.EventHandler(this.ProgressTimer_Tick);
|
||||||
//
|
//
|
||||||
// MainForm
|
// MainForm
|
||||||
//
|
//
|
||||||
@@ -45,19 +50,19 @@
|
|||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(288F, 288F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(288F, 288F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
|
||||||
this.BackColor = System.Drawing.Color.Black;
|
this.BackColor = System.Drawing.Color.Black;
|
||||||
this.ClientSize = new System.Drawing.Size(1777, 1109);
|
this.ClientSize = new System.Drawing.Size(348, 0);
|
||||||
this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||||
this.Name = "MainForm";
|
this.Name = "MainForm";
|
||||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||||
this.Text = "mpv.net";
|
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private System.Windows.Forms.Timer Timer;
|
private System.Windows.Forms.Timer CursorTimer;
|
||||||
|
private System.Windows.Forms.Timer ProgressTimer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using UI;
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
@@ -16,12 +18,12 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
public static MainForm Instance { get; set; }
|
public static MainForm Instance { get; set; }
|
||||||
public static IntPtr Hwnd { get; set; }
|
public static IntPtr Hwnd { get; set; }
|
||||||
|
|
||||||
public new ContextMenuStripEx ContextMenu { get; set; }
|
public new ContextMenuStripEx ContextMenu { get; set; }
|
||||||
|
|
||||||
Point LastCursorPosChanged;
|
Point LastCursorPosChanged;
|
||||||
int LastCursorChangedTickCount;
|
int LastCursorChangedTickCount;
|
||||||
bool IgnoreDpiChanged = true;
|
int TaskbarButtonCreatedMessage;
|
||||||
|
bool WasShown;
|
||||||
|
Taskbar Taskbar;
|
||||||
List<string> RecentFiles;
|
List<string> RecentFiles;
|
||||||
|
|
||||||
public MainForm()
|
public MainForm()
|
||||||
@@ -30,15 +32,6 @@ namespace mpvnet
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
|
||||||
Application.ThreadException += Application_ThreadException;
|
|
||||||
Msg.SupportURL = "https://github.com/stax76/mpv.net#support";
|
|
||||||
Instance = this;
|
|
||||||
WPF.WPF.Init();
|
|
||||||
System.Windows.Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;
|
|
||||||
Hwnd = Handle;
|
|
||||||
Text += " " + Application.ProductVersion;
|
|
||||||
|
|
||||||
object recent = RegHelp.GetObject(App.RegPath, "Recent");
|
object recent = RegHelp.GetObject(App.RegPath, "Recent");
|
||||||
|
|
||||||
if (recent is string[] r)
|
if (recent is string[] r)
|
||||||
@@ -46,13 +39,51 @@ namespace mpvnet
|
|||||||
else
|
else
|
||||||
RecentFiles = new List<string>();
|
RecentFiles = new List<string>();
|
||||||
|
|
||||||
App.ProcessCommandLineEarly();
|
Instance = this;
|
||||||
|
Hwnd = Handle;
|
||||||
|
mp.Init();
|
||||||
|
|
||||||
|
mp.Shutdown += Shutdown;
|
||||||
|
mp.VideoSizeChanged += VideoSizeChanged;
|
||||||
|
mp.FileLoaded += FileLoaded;
|
||||||
|
mp.Idle += Idle;
|
||||||
|
mp.Seek += () => UpdateProgressBar();
|
||||||
|
|
||||||
|
mp.observe_property_bool("pause", PropChangePause);
|
||||||
|
mp.observe_property_bool("fullscreen", PropChangeFullscreen);
|
||||||
|
mp.observe_property_bool("ontop", PropChangeOnTop);
|
||||||
|
mp.observe_property_bool("border", PropChangeBorder);
|
||||||
|
mp.observe_property_string("sid", PropChangeSid);
|
||||||
|
mp.observe_property_string("aid", PropChangeAid);
|
||||||
|
mp.observe_property_string("vid", PropChangeVid);
|
||||||
|
mp.observe_property_int("edition", PropChangeEdition);
|
||||||
|
mp.observe_property_double("window-scale", PropChangeWindowScale);
|
||||||
|
|
||||||
|
if (mp.GPUAPI != "vulkan")
|
||||||
|
mp.ProcessCommandLine(false);
|
||||||
|
|
||||||
|
AppDomain.CurrentDomain.UnhandledException += (sender, e) => Msg.ShowError(e.ExceptionObject.ToString());
|
||||||
|
Application.ThreadException += (sender, e) => Msg.ShowException(e.Exception);
|
||||||
|
Msg.SupportURL = "https://github.com/stax76/mpv.net#support";
|
||||||
|
Text = "mpv.net " + Application.ProductVersion;
|
||||||
|
TaskbarButtonCreatedMessage = Native.RegisterWindowMessage("TaskbarButtonCreated");
|
||||||
|
|
||||||
|
ContextMenu = new ContextMenuStripEx(components);
|
||||||
|
ContextMenu.Opened += ContextMenu_Opened;
|
||||||
|
ContextMenu.Opening += ContextMenu_Opening;
|
||||||
|
|
||||||
|
if (mp.Screen == -1)
|
||||||
|
mp.Screen = Array.IndexOf(Screen.AllScreens, Screen.PrimaryScreen);
|
||||||
|
|
||||||
if (mp.Screen == -1) mp.Screen = Array.IndexOf(Screen.AllScreens, Screen.PrimaryScreen);
|
|
||||||
int targetIndex = mp.Screen;
|
int targetIndex = mp.Screen;
|
||||||
Screen[] screens = Screen.AllScreens;
|
Screen[] screens = Screen.AllScreens;
|
||||||
if (targetIndex < 0) targetIndex = 0;
|
|
||||||
if (targetIndex > screens.Length - 1) targetIndex = screens.Length - 1;
|
if (targetIndex < 0)
|
||||||
|
targetIndex = 0;
|
||||||
|
|
||||||
|
if (targetIndex > screens.Length - 1)
|
||||||
|
targetIndex = screens.Length - 1;
|
||||||
|
|
||||||
Screen screen = screens[Array.IndexOf(screens, screens[targetIndex])];
|
Screen screen = screens[Array.IndexOf(screens, screens[targetIndex])];
|
||||||
Rectangle target = screen.Bounds;
|
Rectangle target = screen.Bounds;
|
||||||
Left = target.X + (target.Width - Width) / 2;
|
Left = target.X + (target.Width - Width) / 2;
|
||||||
@@ -67,19 +98,11 @@ namespace mpvnet
|
|||||||
Top = posY - Height / 2;
|
Top = posY - Height / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp.Shutdown += Shutdown;
|
if (App.Maximized)
|
||||||
mp.VideoSizeChanged += VideoSizeChanged;
|
{
|
||||||
mp.FileLoaded += FileLoaded;
|
SetFormPosAndSize(1, true);
|
||||||
mp.Idle += Idle;
|
WindowState = FormWindowState.Maximized;
|
||||||
Task.Run(() => mp.Init());
|
}
|
||||||
mp.VideoSizeAutoResetEvent.WaitOne(1000);
|
|
||||||
mp.observe_property_bool("fullscreen", PropChangeFullscreen);
|
|
||||||
mp.observe_property_bool("ontop", PropChangeOnTop);
|
|
||||||
mp.observe_property_bool("border", PropChangeBorder);
|
|
||||||
mp.observe_property_string("sid", PropChangeSid);
|
|
||||||
mp.observe_property_string("aid", PropChangeAid);
|
|
||||||
mp.observe_property_string("vid", PropChangeVid);
|
|
||||||
mp.observe_property_int("edition", PropChangeEdition);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -89,19 +112,22 @@ namespace mpvnet
|
|||||||
|
|
||||||
public MenuItem FindMenuItem(string text) => FindMenuItem(text, ContextMenu.Items);
|
public MenuItem FindMenuItem(string text) => FindMenuItem(text, ContextMenu.Items);
|
||||||
|
|
||||||
void Idle() => BeginInvoke(new Action(() => Text = "mpv.net " + Application.ProductVersion));
|
void Shutdown() => BeginInvoke(new Action(() => Close()));
|
||||||
|
|
||||||
|
void Idle()
|
||||||
|
{
|
||||||
|
BeginInvoke(new Action(() => Text = "mpv.net " + Application.ProductVersion));
|
||||||
|
}
|
||||||
|
|
||||||
void CM_Popup(object sender, EventArgs e) => CursorHelp.Show();
|
void CM_Popup(object sender, EventArgs e) => CursorHelp.Show();
|
||||||
|
|
||||||
void VideoSizeChanged() => BeginInvoke(new Action(() => SetFormPosAndSize()));
|
void VideoSizeChanged() => BeginInvoke(new Action(() => SetFormPosAndSize()));
|
||||||
|
|
||||||
void Shutdown() => BeginInvoke(new Action(() => Close()));
|
|
||||||
|
|
||||||
void PropChangeFullscreen(bool value) => BeginInvoke(new Action(() => CycleFullscreen(value)));
|
void PropChangeFullscreen(bool value) => BeginInvoke(new Action(() => CycleFullscreen(value)));
|
||||||
|
|
||||||
void ContextMenu_Opened(object sender, EventArgs e) => CursorHelp.Show();
|
void ContextMenu_Opened(object sender, EventArgs e) => CursorHelp.Show();
|
||||||
|
|
||||||
bool IsFullscreen => WindowState == FormWindowState.Maximized;
|
bool IsFullscreen => WindowState == FormWindowState.Maximized && FormBorderStyle == FormBorderStyle.None;
|
||||||
|
|
||||||
bool IsMouseInOSC() => PointToClient(Control.MousePosition).Y > ClientSize.Height * 0.9;
|
bool IsMouseInOSC() => PointToClient(Control.MousePosition).Y > ClientSize.Height * 0.9;
|
||||||
|
|
||||||
@@ -123,7 +149,7 @@ namespace mpvnet
|
|||||||
foreach (MediaTrack track in vidTracks)
|
foreach (MediaTrack track in vidTracks)
|
||||||
{
|
{
|
||||||
MenuItem mi = new MenuItem(track.Text);
|
MenuItem mi = new MenuItem(track.Text);
|
||||||
mi.Action = () => { mp.commandv("set", "vid", track.ID.ToString()); };
|
mi.Action = () => mp.commandv("set", "vid", track.ID.ToString());
|
||||||
mi.Checked = mp.Vid == track.ID.ToString();
|
mi.Checked = mp.Vid == track.ID.ToString();
|
||||||
trackMenuItem.DropDownItems.Add(mi);
|
trackMenuItem.DropDownItems.Add(mi);
|
||||||
}
|
}
|
||||||
@@ -134,7 +160,7 @@ namespace mpvnet
|
|||||||
foreach (MediaTrack track in audTracks)
|
foreach (MediaTrack track in audTracks)
|
||||||
{
|
{
|
||||||
MenuItem mi = new MenuItem(track.Text);
|
MenuItem mi = new MenuItem(track.Text);
|
||||||
mi.Action = () => { mp.commandv("set", "aid", track.ID.ToString()); };
|
mi.Action = () => mp.commandv("set", "aid", track.ID.ToString());
|
||||||
mi.Checked = mp.Aid == track.ID.ToString();
|
mi.Checked = mp.Aid == track.ID.ToString();
|
||||||
trackMenuItem.DropDownItems.Add(mi);
|
trackMenuItem.DropDownItems.Add(mi);
|
||||||
}
|
}
|
||||||
@@ -145,7 +171,7 @@ namespace mpvnet
|
|||||||
foreach (MediaTrack track in subTracks)
|
foreach (MediaTrack track in subTracks)
|
||||||
{
|
{
|
||||||
MenuItem mi = new MenuItem(track.Text);
|
MenuItem mi = new MenuItem(track.Text);
|
||||||
mi.Action = () => { mp.commandv("set", "sid", track.ID.ToString()); };
|
mi.Action = () => mp.commandv("set", "sid", track.ID.ToString());
|
||||||
mi.Checked = mp.Sid == track.ID.ToString();
|
mi.Checked = mp.Sid == track.ID.ToString();
|
||||||
trackMenuItem.DropDownItems.Add(mi);
|
trackMenuItem.DropDownItems.Add(mi);
|
||||||
}
|
}
|
||||||
@@ -153,7 +179,7 @@ namespace mpvnet
|
|||||||
if (subTracks.Length > 0)
|
if (subTracks.Length > 0)
|
||||||
{
|
{
|
||||||
MenuItem mi = new MenuItem("S: No subtitles");
|
MenuItem mi = new MenuItem("S: No subtitles");
|
||||||
mi.Action = () => { mp.commandv("set", "sid", "no"); };
|
mi.Action = () => mp.commandv("set", "sid", "no");
|
||||||
mi.Checked = mp.Sid == "no";
|
mi.Checked = mp.Sid == "no";
|
||||||
trackMenuItem.DropDownItems.Add(mi);
|
trackMenuItem.DropDownItems.Add(mi);
|
||||||
}
|
}
|
||||||
@@ -164,7 +190,7 @@ namespace mpvnet
|
|||||||
foreach (MediaTrack track in ediTracks)
|
foreach (MediaTrack track in ediTracks)
|
||||||
{
|
{
|
||||||
MenuItem mi = new MenuItem(track.Text);
|
MenuItem mi = new MenuItem(track.Text);
|
||||||
mi.Action = () => { mp.commandv("set", "edition", track.ID.ToString()); };
|
mi.Action = () => mp.commandv("set", "edition", track.ID.ToString());
|
||||||
mi.Checked = mp.Edition == track.ID;
|
mi.Checked = mp.Edition == track.ID;
|
||||||
trackMenuItem.DropDownItems.Add(mi);
|
trackMenuItem.DropDownItems.Add(mi);
|
||||||
}
|
}
|
||||||
@@ -183,7 +209,7 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
MenuItem mi = new MenuItem(i.Key);
|
MenuItem mi = new MenuItem(i.Key);
|
||||||
mi.ShortcutKeyDisplayString = TimeSpan.FromSeconds(i.Value).ToString().Substring(0, 8) + " ";
|
mi.ShortcutKeyDisplayString = TimeSpan.FromSeconds(i.Value).ToString().Substring(0, 8) + " ";
|
||||||
mi.Action = () => { mp.commandv("seek", i.Value.ToString(CultureInfo.InvariantCulture), "absolute"); };
|
mi.Action = () => mp.commandv("seek", i.Value.ToString(CultureInfo.InvariantCulture), "absolute");
|
||||||
chaptersMenuItem.DropDownItems.Add(mi);
|
chaptersMenuItem.DropDownItems.Add(mi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,8 +220,10 @@ namespace mpvnet
|
|||||||
if (recent != null)
|
if (recent != null)
|
||||||
{
|
{
|
||||||
recent.DropDownItems.Clear();
|
recent.DropDownItems.Clear();
|
||||||
|
|
||||||
foreach (string path in RecentFiles)
|
foreach (string path in RecentFiles)
|
||||||
MenuItem.Add(recent.DropDownItems, path, () => mp.Load(new[] { path }, true, Control.ModifierKeys.HasFlag(Keys.Control)));
|
MenuItem.Add(recent.DropDownItems, path, () => mp.Load(new[] { path }, true, Control.ModifierKeys.HasFlag(Keys.Control)));
|
||||||
|
|
||||||
recent.DropDownItems.Add(new ToolStripSeparator());
|
recent.DropDownItems.Add(new ToolStripSeparator());
|
||||||
MenuItem mi = new MenuItem("Clear List");
|
MenuItem mi = new MenuItem("Clear List");
|
||||||
mi.Action = () => RecentFiles.Clear();
|
mi.Action = () => RecentFiles.Clear();
|
||||||
@@ -211,6 +239,7 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
if (mi.Text.StartsWith(text) && mi.Text.Trim() == text)
|
if (mi.Text.StartsWith(text) && mi.Text.Trim() == text)
|
||||||
return mi;
|
return mi;
|
||||||
|
|
||||||
if (mi.DropDownItems.Count > 0)
|
if (mi.DropDownItems.Count > 0)
|
||||||
{
|
{
|
||||||
MenuItem val = FindMenuItem(text, mi.DropDownItems);
|
MenuItem val = FindMenuItem(text, mi.DropDownItems);
|
||||||
@@ -221,33 +250,71 @@ namespace mpvnet
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFormPosAndSize()
|
bool WasInitialSizeSet;
|
||||||
|
|
||||||
|
void SetFormPosAndSize(double scale = 1, bool force = false)
|
||||||
{
|
{
|
||||||
|
if (!force)
|
||||||
|
{
|
||||||
|
if (WindowState == FormWindowState.Maximized)
|
||||||
|
return;
|
||||||
|
|
||||||
if (mp.Fullscreen)
|
if (mp.Fullscreen)
|
||||||
{
|
{
|
||||||
CycleFullscreen(true);
|
CycleFullscreen(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Size size = mp.VideoSize;
|
|
||||||
Screen screen = Screen.FromControl(this);
|
|
||||||
int fixedHeight = Convert.ToInt32(screen.Bounds.Height * mp.Autofit);
|
|
||||||
|
|
||||||
if (size.Height == 0 || size.Width == 0 || size.Width / (float)size.Height < 1.3)
|
|
||||||
{
|
|
||||||
size.Height = fixedHeight;
|
|
||||||
size.Width = (int)(fixedHeight * 1.7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Screen screen = Screen.FromControl(this);
|
||||||
|
int autoFitHeight = Convert.ToInt32(screen.WorkingArea.Height * mp.Autofit);
|
||||||
|
|
||||||
|
if (mp.VideoSize.Height == 0 || mp.VideoSize.Width == 0 ||
|
||||||
|
mp.VideoSize.Width / (float)mp.VideoSize.Height < App.MinimumAspectRatio)
|
||||||
|
|
||||||
|
mp.VideoSize = new Size((int)(autoFitHeight * (16 / 9.0)), autoFitHeight);
|
||||||
|
|
||||||
|
Size size = mp.VideoSize;
|
||||||
int height = size.Height;
|
int height = size.Height;
|
||||||
|
|
||||||
if (App.RememberHeight)
|
if (App.RememberHeight)
|
||||||
|
{
|
||||||
|
if (WasInitialSizeSet)
|
||||||
height = ClientSize.Height;
|
height = ClientSize.Height;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
height = autoFitHeight;
|
||||||
|
WasInitialSizeSet = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (height > screen.Bounds.Height * 0.9)
|
height = Convert.ToInt32(height * scale);
|
||||||
height = fixedHeight;
|
|
||||||
|
|
||||||
int width = Convert.ToInt32(height * size.Width / (double)size.Height);
|
int width = Convert.ToInt32(height * size.Width / (double)size.Height);
|
||||||
|
|
||||||
|
if (height > screen.WorkingArea.Height * 0.9)
|
||||||
|
{
|
||||||
|
height = Convert.ToInt32(screen.WorkingArea.Height * 0.9);
|
||||||
|
width = Convert.ToInt32(height * size.Width / (double)size.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width > screen.WorkingArea.Width * 0.9)
|
||||||
|
{
|
||||||
|
width = Convert.ToInt32(screen.WorkingArea.Width * 0.9);
|
||||||
|
height = Convert.ToInt32(width * size.Height / (double)size.Width);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height < screen.WorkingArea.Height * mp.AutofitSmaller)
|
||||||
|
{
|
||||||
|
height = Convert.ToInt32(screen.WorkingArea.Height * mp.AutofitSmaller);
|
||||||
|
width = Convert.ToInt32(height * size.Width / (double)size.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height > screen.WorkingArea.Height * mp.AutofitLarger)
|
||||||
|
{
|
||||||
|
height = Convert.ToInt32(screen.WorkingArea.Height * mp.AutofitLarger);
|
||||||
|
width = Convert.ToInt32(height * size.Width / (double)size.Height);
|
||||||
|
}
|
||||||
|
|
||||||
Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
|
Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
|
||||||
var rect = new Native.RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height));
|
var rect = new Native.RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height));
|
||||||
NativeHelp.AddWindowBorders(Handle, ref rect);
|
NativeHelp.AddWindowBorders(Handle, ref rect);
|
||||||
@@ -260,10 +327,17 @@ namespace mpvnet
|
|||||||
int minTop = screens.Select(val => val.WorkingArea.Y).Min();
|
int minTop = screens.Select(val => val.WorkingArea.Y).Min();
|
||||||
int maxBottom = screens.Select(val => val.WorkingArea.Bottom).Max();
|
int maxBottom = screens.Select(val => val.WorkingArea.Bottom).Max();
|
||||||
|
|
||||||
if (left < minLeft) left = minLeft;
|
if (left < minLeft)
|
||||||
if (left + rect.Width > maxRight) left = maxRight - rect.Width;
|
left = minLeft;
|
||||||
if (top < minTop) top = minTop;
|
|
||||||
if (top + rect.Height > maxBottom) top = maxBottom - rect.Height;
|
if (left + rect.Width > maxRight)
|
||||||
|
left = maxRight - rect.Width;
|
||||||
|
|
||||||
|
if (top < minTop)
|
||||||
|
top = minTop;
|
||||||
|
|
||||||
|
if (top + rect.Height > maxBottom)
|
||||||
|
top = maxBottom - rect.Height;
|
||||||
|
|
||||||
Native.SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */, left, top, rect.Width, rect.Height, 4 /* SWP_NOZORDER */);
|
Native.SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */, left, top, rect.Width, rect.Height, 4 /* SWP_NOZORDER */);
|
||||||
}
|
}
|
||||||
@@ -274,15 +348,18 @@ namespace mpvnet
|
|||||||
|
|
||||||
if (enabled)
|
if (enabled)
|
||||||
{
|
{
|
||||||
if (WindowState != FormWindowState.Maximized)
|
if (WindowState != FormWindowState.Maximized || FormBorderStyle != FormBorderStyle.None)
|
||||||
{
|
{
|
||||||
|
if (WindowState == FormWindowState.Maximized)
|
||||||
|
WindowState = FormWindowState.Minimized;
|
||||||
|
|
||||||
FormBorderStyle = FormBorderStyle.None;
|
FormBorderStyle = FormBorderStyle.None;
|
||||||
WindowState = FormWindowState.Maximized;
|
WindowState = FormWindowState.Maximized;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (WindowState == FormWindowState.Maximized)
|
if (WindowState == FormWindowState.Maximized && FormBorderStyle == FormBorderStyle.None)
|
||||||
{
|
{
|
||||||
WindowState = FormWindowState.Normal;
|
WindowState = FormWindowState.Normal;
|
||||||
|
|
||||||
@@ -304,50 +381,61 @@ namespace mpvnet
|
|||||||
if (!content.Contains("#menu:"))
|
if (!content.Contains("#menu:"))
|
||||||
{
|
{
|
||||||
var defaultItems = CommandItem.GetItems(Properties.Resources.inputConf);
|
var defaultItems = CommandItem.GetItems(Properties.Resources.inputConf);
|
||||||
|
|
||||||
foreach (CommandItem item in items)
|
foreach (CommandItem item in items)
|
||||||
foreach (CommandItem defaultItem in defaultItems)
|
foreach (CommandItem defaultItem in defaultItems)
|
||||||
if (item.Command == defaultItem.Command)
|
if (item.Command == defaultItem.Command)
|
||||||
defaultItem.Input = item.Input;
|
defaultItem.Input = item.Input;
|
||||||
|
|
||||||
items = defaultItems;
|
items = defaultItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (CommandItem item in items)
|
foreach (CommandItem item in items)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(item.Path)) continue;
|
if (string.IsNullOrEmpty(item.Path))
|
||||||
|
continue;
|
||||||
|
|
||||||
string path = item.Path.Replace("&", "&&");
|
string path = item.Path.Replace("&", "&&");
|
||||||
|
|
||||||
MenuItem menuItem = ContextMenu.Add(path, () => {
|
MenuItem menuItem = ContextMenu.Add(path, () => {
|
||||||
try {
|
try {
|
||||||
mp.command_string(item.Command);
|
mp.command(item.Command);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Msg.ShowException(ex);
|
Msg.ShowException(ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (menuItem != null) menuItem.ShortcutKeyDisplayString = item.Input + " ";
|
|
||||||
|
if (menuItem != null)
|
||||||
|
menuItem.ShortcutKeyDisplayString = item.Input + " ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FileLoaded()
|
private void FileLoaded()
|
||||||
{
|
{
|
||||||
string path = mp.get_property_string("path");
|
string path = mp.get_property_string("path");
|
||||||
|
|
||||||
BeginInvoke(new Action(() => {
|
BeginInvoke(new Action(() => {
|
||||||
if (File.Exists(path) || path.Contains("://"))
|
if (path.Contains("://"))
|
||||||
Text = Path.GetFileName(path) + " - mpv.net " + Application.ProductVersion;
|
Text = mp.get_property_string("media-title") + " - mpv.net " + Application.ProductVersion;
|
||||||
|
else if (path.Contains(":\\") || path.StartsWith("\\\\"))
|
||||||
|
Text = path.FileName() + " - mpv.net " + Application.ProductVersion;
|
||||||
else
|
else
|
||||||
Text = "mpv.net " + Application.ProductVersion;
|
Text = "mpv.net " + Application.ProductVersion;
|
||||||
|
|
||||||
|
int interval = (int)(mp.Duration.TotalMilliseconds / 100);
|
||||||
|
if (interval < 100) interval = 100;
|
||||||
|
if (interval > 1000) interval = 1000;
|
||||||
|
ProgressTimer.Interval = interval;
|
||||||
|
UpdateProgressBar();
|
||||||
}));
|
}));
|
||||||
if (RecentFiles.Contains(path)) RecentFiles.Remove(path);
|
|
||||||
|
if (RecentFiles.Contains(path))
|
||||||
|
RecentFiles.Remove(path);
|
||||||
|
|
||||||
RecentFiles.Insert(0, path);
|
RecentFiles.Insert(0, path);
|
||||||
if (RecentFiles.Count > 15) RecentFiles.RemoveAt(15);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
|
while (RecentFiles.Count > App.RecentCount)
|
||||||
{
|
RecentFiles.RemoveAt(App.RecentCount);
|
||||||
Msg.ShowException(e.Exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
|
||||||
{
|
|
||||||
Msg.ShowError(e.ExceptionObject.ToString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override CreateParams CreateParams {
|
protected override CreateParams CreateParams {
|
||||||
@@ -360,7 +448,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
protected override void WndProc(ref Message m)
|
protected override void WndProc(ref Message m)
|
||||||
{
|
{
|
||||||
//System.Diagnostics.Debug.WriteLine(m);
|
//Debug.WriteLine(m);
|
||||||
|
|
||||||
switch (m.Msg)
|
switch (m.Msg)
|
||||||
{
|
{
|
||||||
@@ -368,38 +456,36 @@ namespace mpvnet
|
|||||||
case 0x0202: // WM_LBUTTONUP
|
case 0x0202: // WM_LBUTTONUP
|
||||||
case 0x0207: // WM_MBUTTONDOWN
|
case 0x0207: // WM_MBUTTONDOWN
|
||||||
case 0x0208: // WM_MBUTTONUP
|
case 0x0208: // WM_MBUTTONUP
|
||||||
|
case 0x020b: // WM_XBUTTONDOWN
|
||||||
|
case 0x020c: // WM_XBUTTONUP
|
||||||
case 0x020A: // WM_MOUSEWHEEL
|
case 0x020A: // WM_MOUSEWHEEL
|
||||||
case 0x020C: // WM_XBUTTONUP
|
|
||||||
case 0x020B: // WM_XBUTTONDOWN
|
|
||||||
case 0x0100: // WM_KEYDOWN
|
case 0x0100: // WM_KEYDOWN
|
||||||
case 0x0101: // WM_KEYUP
|
case 0x0101: // WM_KEYUP
|
||||||
case 0x0104: // WM_SYSKEYDOWN
|
case 0x0104: // WM_SYSKEYDOWN
|
||||||
case 0x0105: // WM_SYSKEYUP
|
case 0x0105: // WM_SYSKEYUP
|
||||||
|
case 0x319: // WM_APPCOMMAND
|
||||||
if (mp.WindowHandle != IntPtr.Zero)
|
if (mp.WindowHandle != IntPtr.Zero)
|
||||||
Native.SendMessage(mp.WindowHandle, m.Msg, m.WParam, m.LParam);
|
Native.SendMessage(mp.WindowHandle, m.Msg, m.WParam, m.LParam);
|
||||||
break;
|
break;
|
||||||
case 0x0200: // WM_MOUSEMOVE
|
case 0x0200: // WM_MOUSEMOVE
|
||||||
{
|
{
|
||||||
Point pos = PointToClient(Cursor.Position);
|
Point pos = PointToClient(Cursor.Position);
|
||||||
mp.command_string($"mouse {pos.X} {pos.Y}");
|
mp.command($"mouse {pos.X} {pos.Y}");
|
||||||
if (CursorHelp.IsPosDifferent(LastCursorPosChanged)) CursorHelp.Show();
|
if (CursorHelp.IsPosDifferent(LastCursorPosChanged)) CursorHelp.Show();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x2a3: // WM_MOUSELEAVE
|
case 0x2a3: // WM_MOUSELEAVE
|
||||||
mp.command_string("mouse 1 1"); // osc won't always auto hide
|
mp.command("mouse 1 1"); // osc won't always auto hide
|
||||||
break;
|
|
||||||
case 0x319: // WM_APPCOMMAND
|
|
||||||
if (mp.WindowHandle != IntPtr.Zero)
|
|
||||||
Native.PostMessage(mp.WindowHandle, m.Msg, m.WParam, m.LParam);
|
|
||||||
break;
|
break;
|
||||||
case 0x203: // Native.WM.LBUTTONDBLCLK
|
case 0x203: // Native.WM.LBUTTONDBLCLK
|
||||||
{
|
{
|
||||||
Point pos = PointToClient(Cursor.Position);
|
Point pos = PointToClient(Cursor.Position);
|
||||||
mp.command_string($"mouse {pos.X} {pos.Y} 0 double");
|
mp.command($"mouse {pos.X} {pos.Y} 0 double");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x02E0: // WM_DPICHANGED
|
case 0x02E0: // WM_DPICHANGED
|
||||||
if (IgnoreDpiChanged) break;
|
if (!WasShown)
|
||||||
|
break;
|
||||||
var r2 = Marshal.PtrToStructure<Native.RECT>(m.LParam);
|
var r2 = Marshal.PtrToStructure<Native.RECT>(m.LParam);
|
||||||
Native.SetWindowPos(Handle, IntPtr.Zero, r2.Left, r2.Top, r2.Width, r2.Height, 0);
|
Native.SetWindowPos(Handle, IntPtr.Zero, r2.Left, r2.Top, r2.Width, r2.Height, 0);
|
||||||
break;
|
break;
|
||||||
@@ -408,13 +494,21 @@ namespace mpvnet
|
|||||||
var r = rc;
|
var r = rc;
|
||||||
NativeHelp.SubtractWindowBorders(Handle, ref r);
|
NativeHelp.SubtractWindowBorders(Handle, ref r);
|
||||||
int c_w = r.Right - r.Left, c_h = r.Bottom - r.Top;
|
int c_w = r.Right - r.Left, c_h = r.Bottom - r.Top;
|
||||||
float aspect = mp.VideoSize.Width / (float)mp.VideoSize.Height;
|
Size s = mp.VideoSize;
|
||||||
|
|
||||||
|
if (s == Size.Empty)
|
||||||
|
s = new Size(16, 9);
|
||||||
|
|
||||||
|
float aspect = s.Width / (float)s.Height;
|
||||||
int d_w = Convert.ToInt32(c_h * aspect - c_w);
|
int d_w = Convert.ToInt32(c_h * aspect - c_w);
|
||||||
int d_h = Convert.ToInt32(c_w / aspect - c_h);
|
int d_h = Convert.ToInt32(c_w / aspect - c_h);
|
||||||
int[] d_corners = { d_w, d_h, -d_w, -d_h };
|
int[] d_corners = { d_w, d_h, -d_w, -d_h };
|
||||||
int[] corners = { rc.Left, rc.Top, rc.Right, rc.Bottom };
|
int[] corners = { rc.Left, rc.Top, rc.Right, rc.Bottom };
|
||||||
int corner = NativeHelp.GetResizeBorder(m.WParam.ToInt32());
|
int corner = NativeHelp.GetResizeBorder(m.WParam.ToInt32());
|
||||||
if (corner >= 0) corners[corner] -= d_corners[corner];
|
|
||||||
|
if (corner >= 0)
|
||||||
|
corners[corner] -= d_corners[corner];
|
||||||
|
|
||||||
Marshal.StructureToPtr<Native.RECT>(new Native.RECT(corners[0], corners[1], corners[2], corners[3]), m.LParam, false);
|
Marshal.StructureToPtr<Native.RECT>(new Native.RECT(corners[0], corners[1], corners[2], corners[3]), m.LParam, false);
|
||||||
m.Result = new IntPtr(1);
|
m.Result = new IntPtr(1);
|
||||||
return;
|
return;
|
||||||
@@ -439,26 +533,16 @@ namespace mpvnet
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m.Msg == TaskbarButtonCreatedMessage && mp.TaskbarProgress)
|
||||||
|
{
|
||||||
|
Taskbar = new Taskbar(Handle);
|
||||||
|
ProgressTimer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
base.WndProc(ref m);
|
base.WndProc(ref m);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDragEnter(DragEventArgs e)
|
void CursorTimer_Tick(object sender, EventArgs e)
|
||||||
{
|
|
||||||
base.OnDragEnter(e);
|
|
||||||
if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent(DataFormats.Text))
|
|
||||||
e.Effect = DragDropEffects.Copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnDragDrop(DragEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnDragDrop(e);
|
|
||||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
|
||||||
mp.Load(e.Data.GetData(DataFormats.FileDrop) as String[], true, Control.ModifierKeys.HasFlag(Keys.Control));
|
|
||||||
if (e.Data.GetDataPresent(DataFormats.Text))
|
|
||||||
mp.Load(new[] { e.Data.GetData(DataFormats.Text).ToString() }, true, Control.ModifierKeys.HasFlag(Keys.Control));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer_Tick(object sender, EventArgs e)
|
|
||||||
{
|
{
|
||||||
if (CursorHelp.IsPosDifferent(LastCursorPosChanged))
|
if (CursorHelp.IsPosDifferent(LastCursorPosChanged))
|
||||||
{
|
{
|
||||||
@@ -472,6 +556,14 @@ namespace mpvnet
|
|||||||
CursorHelp.Hide();
|
CursorHelp.Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ProgressTimer_Tick(object sender, EventArgs e) => UpdateProgressBar();
|
||||||
|
|
||||||
|
void UpdateProgressBar()
|
||||||
|
{
|
||||||
|
if (mp.TaskbarProgress && Taskbar != null)
|
||||||
|
Taskbar.SetValue(mp.get_property_number("time-pos"), mp.Duration.TotalSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
void PropChangeOnTop(bool value) => BeginInvoke(new Action(() => TopMost = value));
|
void PropChangeOnTop(bool value) => BeginInvoke(new Action(() => TopMost = value));
|
||||||
|
|
||||||
void PropChangeAid(string value) => mp.Aid = value;
|
void PropChangeAid(string value) => mp.Aid = value;
|
||||||
@@ -482,6 +574,15 @@ namespace mpvnet
|
|||||||
|
|
||||||
void PropChangeEdition(int value) => mp.Edition = value;
|
void PropChangeEdition(int value) => mp.Edition = value;
|
||||||
|
|
||||||
|
void PropChangeWindowScale(double value)
|
||||||
|
{
|
||||||
|
if (value != 1)
|
||||||
|
{
|
||||||
|
BeginInvoke(new Action(() => SetFormPosAndSize(value)));
|
||||||
|
mp.command("no-osd set window-scale 1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PropChangeBorder(bool enabled) {
|
void PropChangeBorder(bool enabled) {
|
||||||
mp.Border = enabled;
|
mp.Border = enabled;
|
||||||
|
|
||||||
@@ -490,37 +591,63 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
if (mp.Border && FormBorderStyle == FormBorderStyle.None)
|
if (mp.Border && FormBorderStyle == FormBorderStyle.None)
|
||||||
FormBorderStyle = FormBorderStyle.Sizable;
|
FormBorderStyle = FormBorderStyle.Sizable;
|
||||||
|
|
||||||
if (!mp.Border && FormBorderStyle == FormBorderStyle.Sizable)
|
if (!mp.Border && FormBorderStyle == FormBorderStyle.Sizable)
|
||||||
FormBorderStyle = FormBorderStyle.None;
|
FormBorderStyle = FormBorderStyle.None;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PropChangePause(bool enabled)
|
||||||
|
{
|
||||||
|
if (Taskbar != null && mp.TaskbarProgress)
|
||||||
|
{
|
||||||
|
if (enabled)
|
||||||
|
Taskbar.SetState(TaskbarStates.Paused);
|
||||||
|
else
|
||||||
|
Taskbar.SetState(TaskbarStates.Normal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnLoad(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnLoad(e);
|
||||||
|
|
||||||
|
if (mp.GPUAPI != "vulkan")
|
||||||
|
mp.VideoSizeAutoResetEvent.WaitOne(App.StartThreshold);
|
||||||
|
|
||||||
|
SetFormPosAndSize();
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnShown(EventArgs e)
|
protected override void OnShown(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnShown(e);
|
base.OnShown(e);
|
||||||
if (App.IsDarkMode) ToolStripRendererEx.ColorTheme = Color.Black;
|
|
||||||
ContextMenu = new ContextMenuStripEx(components);
|
if (mp.GPUAPI == "vulkan")
|
||||||
ContextMenu.Opened += ContextMenu_Opened;
|
mp.ProcessCommandLine(false);
|
||||||
ContextMenu.Opening += ContextMenu_Opening;
|
|
||||||
|
ToolStripRendererEx.ForegroundColor = Theme.Current.GetWinFormsColor("menu-foreground");
|
||||||
|
ToolStripRendererEx.BackgroundColor = Theme.Current.GetWinFormsColor("menu-background");
|
||||||
|
ToolStripRendererEx.SelectionColor = Theme.Current.GetWinFormsColor("menu-highlight");
|
||||||
|
ToolStripRendererEx.BorderColor = Theme.Current.GetWinFormsColor("menu-border");
|
||||||
|
ToolStripRendererEx.CheckedColor = Theme.Current.GetWinFormsColor("menu-checked");
|
||||||
|
|
||||||
BuildMenu();
|
BuildMenu();
|
||||||
ContextMenuStrip = ContextMenu;
|
ContextMenuStrip = ContextMenu;
|
||||||
IgnoreDpiChanged = false;
|
WPF.WPF.Init();
|
||||||
CheckClipboardForURL();
|
System.Windows.Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;
|
||||||
}
|
Cursor.Position = new Point(Cursor.Position.X + 1, Cursor.Position.Y);
|
||||||
|
WasShown = true;
|
||||||
protected override void OnActivated(EventArgs e)
|
mp.LoadScripts();
|
||||||
{
|
Task.Run(() => App.Extension = new Extension());
|
||||||
base.OnActivated(e);
|
|
||||||
CheckClipboardForURL();
|
|
||||||
Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP
|
|
||||||
Native.SendMessage(Handle, m.Msg, m.WParam, m.LParam);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnResize(EventArgs e)
|
protected override void OnResize(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnResize(e);
|
base.OnResize(e);
|
||||||
if (mp.IsLogoVisible) mp.ShowLogo();
|
|
||||||
|
if (mp.IsLogoVisible)
|
||||||
|
mp.ShowLogo();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnFormClosing(FormClosingEventArgs e)
|
protected override void OnFormClosing(FormClosingEventArgs e)
|
||||||
@@ -534,9 +661,12 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
|
|
||||||
RegHelp.SetObject(App.RegPath, "Recent", RecentFiles.ToArray());
|
RegHelp.SetObject(App.RegPath, "Recent", RecentFiles.ToArray());
|
||||||
App.Exit();
|
|
||||||
|
if (mp.IsQuitNeeded)
|
||||||
mp.commandv("quit");
|
mp.commandv("quit");
|
||||||
mp.ShutdownAutoResetEvent.WaitOne(3000);
|
|
||||||
|
if (!mp.ShutdownAutoResetEvent.WaitOne(10000))
|
||||||
|
Msg.ShowError("Shutdown thread failed to complete within 10 seconds.");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnMouseDown(MouseEventArgs e)
|
protected override void OnMouseDown(MouseEventArgs e)
|
||||||
@@ -556,28 +686,35 @@ namespace mpvnet
|
|||||||
mp.commandv("quit");
|
mp.commandv("quit");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnDragEnter(DragEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnDragEnter(e);
|
||||||
|
|
||||||
|
if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent(DataFormats.Text))
|
||||||
|
e.Effect = DragDropEffects.Copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDragDrop(DragEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnDragDrop(e);
|
||||||
|
|
||||||
|
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||||
|
mp.Load(e.Data.GetData(DataFormats.FileDrop) as String[], true, Control.ModifierKeys.HasFlag(Keys.Control));
|
||||||
|
|
||||||
|
if (e.Data.GetDataPresent(DataFormats.Text))
|
||||||
|
mp.Load(new[] { e.Data.GetData(DataFormats.Text).ToString() }, true, Control.ModifierKeys.HasFlag(Keys.Control));
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnLostFocus(EventArgs e)
|
protected override void OnLostFocus(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnLostFocus(e);
|
base.OnLostFocus(e);
|
||||||
CursorHelp.Show();
|
CursorHelp.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckClipboardForURL()
|
protected override void OnKeyDown(KeyEventArgs e)
|
||||||
{
|
{
|
||||||
string clipboard = Clipboard.GetText();
|
e.SuppressKeyPress = true; // prevent beep using alt key
|
||||||
|
base.OnKeyDown(e);
|
||||||
foreach (string url in App.UrlWhitelist)
|
|
||||||
{
|
|
||||||
if (clipboard.Contains("://") && ! clipboard.Contains("\n") &&
|
|
||||||
! clipboard.Contains(" ") && clipboard.Contains(url.ToLower()) &&
|
|
||||||
RegHelp.GetString(App.RegPath, "LastURL") != clipboard && Visible)
|
|
||||||
{
|
|
||||||
RegHelp.SetObject(App.RegPath, "LastURL", clipboard);
|
|
||||||
|
|
||||||
if (Msg.ShowQuestion("Play URL?", clipboard) == MsgResult.OK)
|
|
||||||
mp.Load(new[] { clipboard }, true, Control.ModifierKeys.HasFlag(Keys.Control));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,28 +117,31 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<metadata name="Timer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="CursorTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>30, 12</value>
|
<value>30, 12</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
<metadata name="ProgressTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>321, 12</value>
|
||||||
|
</metadata>
|
||||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
AAABAAUAEBAAAAEAIABoBAAAVgAAABgYAAABACAAiAkAAL4EAAAgIAAAAQAgAKgQAABGDgAAMDAAAAEA
|
AAABAAUAEBAAAAEAIABoBAAAVgAAABgYAAABACAAiAkAAL4EAAAgIAAAAQAgAKgQAABGDgAAMDAAAAEA
|
||||||
IACoJQAA7h4AAAAAAAABACAAzhwAAJZEAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAADDDgAAww4AAAAA
|
IACoJQAA7h4AAAAAAAABACAA3x8AAJZEAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAADDDgAAww4AAAAA
|
||||||
AAAAAAAAAAAAAAAAAAD/lAAA/5QABf+UAEH/lACe/5QA3P+UAPX/lAD1/5QA3P+UAJ7/lABB/5QABf+U
|
AAAAAAAAAAAAAAAAAAD/lAAA/5QABf+UAEH/lACe/5QA3P+UAPX/lAD1/5QA3P+UAJ7/lABB/5QABf+U
|
||||||
AAAAAAAAAAAAAP+UAAD/lAAA/5QAFP+UAIn/lADr/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA6/+U
|
AAAAAAAAAAAAAP+UAAD/lAAA/5QAFP+UAIn/lADr/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA6/+U
|
||||||
AIr/lAAU/5QAAP+UAAD/lAAA/5QAFP+UAKj/lAD+/5QA//+TAP//lgb//5oR//+aEf//lgf//5MA//+U
|
AIr/lAAU/5QAAP+UAAD/lAAA/5QAFP+UAKj/lAD+/5QA//+TAP//lgb//5oR//+aEf//lgf//5MA//+U
|
||||||
AP//lAD+/5QAqf+UABT/lAAA/5QABP+UAIn/lAD+/5QA//+WBv//qDb//7po///Be///wXz//7tq//+p
|
AP//lAD+/5QAqf+UABT/lAAA/5QABP+UAIn/lAD+/5QA//+WBv//pzX//7ln///Be///wXz//7tq//+p
|
||||||
Ov//lwj//5QA//+UAP7/lACK/5QABP+UAEH/lADp/5QA//+WBv//sVD//8aK///KlP//x4z//8eN///I
|
Ov//lwj//5QA//+UAP7/lACK/5QABP+UAEH/lADp/5QA//+WBv//sVD//8mP///Tpv//yZH//8eM///I
|
||||||
jv//x4v//7NW//+XCP//lAD//5QA6f+UAEH/lACe/5QA//+TAP//qDf//8aK///Ijv//5Mj//926///J
|
jv//x4v//7NW//+XCP//lAD//5QA6f+UAEH/lACe/5QA//+TAP//qDf//8aI///Sov//9+///+vX///T
|
||||||
kP//xov//8eM///Hi///qj7//5QA//+UAP//lACe/5QA2/+UAP//lgb//7pp///Ijv//yI3//+zZ///+
|
pP//x4z//8eM///Hi///qj7//5QA//+UAP//lACe/5QA2/+UAP//lgb//7pp///Hjf//06T///Hh///h
|
||||||
/v//7Nn//9Ki///HjP//yI7//71v//+XCf//lAD//5QA2/+UAPT/lAD//5oR///BfP//x43//8eN///s
|
wv//8eL//+TH///NmP//x43//7xv//+XCf//lAD//5QA2/+UAPT/lAD//5oR///BfP//x4z//9Ok///u
|
||||||
2P/////////////58///373//8iP///CgP//nBb//5MA//+UAPT/lAD0/5QA//+aEf//wXv//8eN///H
|
3P//yZD//8+c///q1f//8+f//9Gh///Cf///nBb//5MA//+UAPT/lAD0/5QA//+aEf//wXv//8eM///T
|
||||||
jf//7Nj/////////////9u3//9u1///Ijv//wn///5wW//+TAP//lAD0/5QA2/+UAP//lgb//7ln///I
|
pP//7tz//8mR///Up///7tz//+rU///Nmf//wn///5wW//+TAP//lAD0/5QA2/+UAP//lgb//7ln///H
|
||||||
jv//x43//+zY///9/P//6dL//8+c///Gi///yI7//7xt//+XCP//lAD//5QA2/+UAJ3/lAD//5MA//+m
|
jf//06T///Hj///lyv//8eL//9y3///Jj///x43//7xt//+XCP//lAD//5QA2/+UAJ3/lAD//5MA//+m
|
||||||
M///xoj//8iO///iw///27T//8iO///Gi///x43//8aK//+pOf//lAD//5QA//+UAJ3/lABB/5QA6f+U
|
M///xYf//9Gi///37///6dH//8+d///Gi///x4z//8aK//+pOf//lAD//5QA//+UAJ3/lABB/5QA6f+U
|
||||||
AP//lQT//69J///GiP//ypL//8eN///Hjf//yI7//8aJ//+xT///lgb//5QA//+UAOn/lABB/5QABP+U
|
AP//lQT//69J///IjP//06T//8mQ///HjP//yI7//8aJ//+xT///lgb//5QA//+UAOn/lABB/5QABP+U
|
||||||
AIn/lAD+/5QA//+VBP//pS///7dh//+/dv//v3f//7hj//+mMv//lgX//5QA//+UAP7/lACJ/5QABP+U
|
AIn/lAD+/5QA//+VBP//pS7//7dg//+/dv//v3f//7hj//+mMv//lgX//5QA//+UAP7/lACJ/5QABP+U
|
||||||
AAD/lAAU/5QAqP+UAP7/lAD//5MA//+VBP//mQ3//5kN//+VBP//kwD//5QA//+UAP7/lACo/5QAFP+U
|
AAD/lAAU/5QAqP+UAP7/lAD//5MA//+VBP//mQ3//5kN//+VBP//kwD//5QA//+UAP7/lACo/5QAFP+U
|
||||||
AAD/lAAA/5QAAP+UABT/lACJ/5QA6/+UAP//lAD//5QA//+UAP//lAD//5QA//+UAOv/lACJ/5QAFP+U
|
AAD/lAAA/5QAAP+UABT/lACJ/5QA6/+UAP//lAD//5QA//+UAP//lAD//5QA//+UAOv/lACJ/5QAFP+U
|
||||||
AAD/lAAAAAAAAAAAAAD/lAAA/5QABf+UAEH/lACe/5QA3P+UAPX/lAD1/5QA3P+UAJ7/lABB/5QABf+U
|
AAD/lAAAAAAAAAAAAAD/lAAA/5QABf+UAEH/lACe/5QA3P+UAPX/lAD1/5QA3P+UAJ7/lABB/5QABf+U
|
||||||
@@ -154,26 +157,26 @@
|
|||||||
Of//r0r//69L//+qPP//nx///5YG//+TAP//lAD//5QA//+UAP//lADv/5QAWP+UAAD/lAAA/5QAAP+U
|
Of//r0r//69L//+qPP//nx///5YG//+TAP//lAD//5QA//+UAP//lADv/5QAWP+UAAD/lAAA/5QAAP+U
|
||||||
ACn/lADZ/5QA//+UAP//lAD//5QA//+eG///tVz//8OC///HjP//yI7//8iO///Hjf//xIT//7dh//+g
|
ACn/lADZ/5QA//+UAP//lAD//5QA//+eG///tVz//8OC///HjP//yI7//8iO///Hjf//xIT//7dh//+g
|
||||||
IP//lAH//5QA//+UAP//lAD//5QA2f+UACn/lAAA/5QAA/+UAJP/lAD//5QA//+UAP//lAD//6Mq///A
|
IP//lAH//5QA//+UAP//lAD//5QA2f+UACn/lAAA/5QAA/+UAJP/lAD//5QA//+UAP//lAD//6Mq///A
|
||||||
ef//yI7//8eM///Hi///x4z//8eM///HjP//x43//8iO///Cfv//pjL//5QA//+UAP//lAD//5QA//+U
|
ef//yI///8qS///HjP//x4v//8eM///HjP//x43//8iO///Cfv//pjL//5QA//+UAP//lAD//5QA//+U
|
||||||
AJP/lAAD/5QAMf+UAOL/lAD//5QA//+TAP//nhz//8B6///Ijv//x4z//9Wp///Qn///xov//8eM///H
|
AJP/lAAD/5QAMf+UAOL/lAD//5QA//+TAP//nhz//8B6///Hjf//0J7///Dg///ixP//zJf//8aK///H
|
||||||
jP//x4z//8eM///Ijv//wn///6Ek//+TAP//lAD//5QA//+UAOL/lAAx/5QAfP+UAP3/lAD//5QA//+V
|
jP//x4z//8eM///Ijv//wn///6Ek//+TAP//lAD//5QA//+UAOL/lAAx/5QAfP+UAP3/lAD//5QA//+V
|
||||||
BP//tlz//8iO///HjP//xov//+XK///48P//3br//8mR///Gi///x4z//8eM///HjP//yI7//7lm//+X
|
BP//tlz//8iO///Giv//1Kj///36///+/P//9Oj//9qz///JkP//xov//8eM///HjP//yI7//7lm//+X
|
||||||
CP//lAD//5QA//+UAP3/lAB8/5QAvf+UAP//lAD//5MA//+fHv//xIP//8eN///HjP//xov//+XK////
|
CP//lAD//5QA//+UAP3/lAB8/5QAvf+UAP//lAD//5MA//+fHv//xIP//8eN///Giv//1Kj///v3///i
|
||||||
/////vz//+3a///So///x4v//8eL///HjP//x4z//8WH//+iJ///kwD//5QA//+UAP//lAC8/5QA4v+U
|
xP//7tz///z5///t2f//06T//8eM///Hi///x4z//8WH//+iJ///kwD//5QA//+UAP//lAC8/5QA4v+U
|
||||||
AP//lAD//5MA//+qO///x43//8eM///HjP//xov//+XJ///////////////////58///4cL//8uU///H
|
AP//lAD//5MA//+qO///x43//8eM///Giv//1aj///v3///Vqf//yY///9y3///27P//+vT//+TH///N
|
||||||
i///x4z//8iO//+uR///kwD//5QA//+UAP//lADi/5QA8v+UAP//lAD//5MA//+vS///yI7//8eM///H
|
mP//x4z//8iO//+uR///kwD//5QA//+UAP//lADi/5QA8v+UAP//lAD//5MA//+vS///yI7//8eM///G
|
||||||
jP//xov//+XJ/////////////////////////v7///Hi///Rof//x4v//8iO//+zVv//lAD//5QA//+U
|
iv//1aj///v3///Wq///xor//8aK///NmP//6dL////////w3///ypP//8iO//+zVv//lAD//5QA//+U
|
||||||
AP//lADy/5QA8v+UAP//lAD//5MA//+vSf//yI7//8eM///HjP//xov//+TI////////////////////
|
AP//lADy/5QA8v+UAP//lAD//5MA//+vSf//yI7//8eM///Giv//1aj///v3///Wq///xon//8eN///W
|
||||||
/////fv//+rU///Om///x4v//8iO//+zVf//lAD//5QA//+UAP//lADy/5QA4v+UAP//lAD//5MA//+p
|
q///8uX///r2///hwf//yI///8iO//+zVf//lAD//5QA//+UAP//lADy/5QA4v+UAP//lAD//5MA//+p
|
||||||
OP//x4z//8eM///HjP//xov//+TH///////////////////16///27T//8iP///Hi///x4z//8iO//+t
|
OP//x4z//8eM///Giv//1aj///v3///Vqf//zJb//+bL///79///8eP//9Wp///HjP//x4z//8iO//+t
|
||||||
RP//kwD//5QA//+UAP//lADi/5QAvP+UAP//lAD//5MA//+eG///w4H//8eN///HjP//xov//+TH////
|
RP//kwD//5QA//+UAP//lADi/5QAvP+UAP//lAD//5MA//+eG///w4H//8eN///Giv//1Kj///v3///m
|
||||||
/////Pn//+jQ///Om///xov//8eM///HjP//x4z//8WG//+hJP//kwD//5QA//+UAP//lAC8/5QAe/+U
|
y///8+f///r1///ixP//y5T//8aK///HjP//x4z//8WG//+hJP//kwD//5QA//+UAP//lAC8/5QAe/+U
|
||||||
AP3/lAD//5QA//+VA///s1f//8iO///HjP//xov//+PG///16v//2bH//8iO///Gi///x4z//8eM///H
|
AP3/lAD//5QA//+VA///s1f//8iO///Giv//1Kf///36///+/f//79///9Om///HjP//x4v//8eM///H
|
||||||
jP//yI7//7dh//+WBv//lAD//5QA//+UAP3/lAB7/5QAMf+UAOL/lAD//5QA//+UAP//nBf//750///I
|
jP//yI7//7dh//+WBv//lAD//5QA//+UAP3/lAB7/5QAMf+UAOL/lAD//5QA//+UAP//nBf//750///H
|
||||||
jv//x4z//9Ki///Omv//xor//8eM///HjP//x4z//8eM///Ijv//wXr//58e//+TAP//lAD//5QA//+U
|
jf//z5z//+7d///gv///ypP//8aL///HjP//x4z//8eM///Ijv//wXr//58e//+TAP//lAD//5QA//+U
|
||||||
AOL/lAAx/5QAA/+UAJL/lAD//5QA//+UAP//lAD//6Ah//++cv//yI7//8eM///Hi///x4z//8eM///H
|
AOL/lAAx/5QAA/+UAJL/lAD//5QA//+UAP//lAD//6Ah//++cv//yI7//8mR///HjP//x4v//8eM///H
|
||||||
jP//x43//8iO///AeP//oyn//5QA//+UAP//lAD//5QA//+UAJL/lAAD/5QAAP+UACj/lADY/5QA//+U
|
jP//x43//8iO///AeP//oyn//5QA//+UAP//lAD//5QA//+UAJL/lAAD/5QAAP+UACj/lADY/5QA//+U
|
||||||
AP//lAD//5QA//+bFP//sVD//8F8///Giv//x43//8eN///Hi///wn7//7NW//+dGP//lAD//5QA//+U
|
AP//lAD//5QA//+bFP//sVD//8F7///Giv//x43//8eN///Hi///wn7//7NW//+dGP//lAD//5QA//+U
|
||||||
AP//lAD//5QA2f+UACn/lAAA/5QAAP+UAAD/lABX/5QA7/+UAP//lAD//5QA//+UAP//lAL//5sU//+l
|
AP//lAD//5QA2f+UACn/lAAA/5QAAP+UAAD/lABX/5QA7/+UAP//lAD//5QA//+UAP//lAL//5sU//+l
|
||||||
Lv//qz7//6s///+mMf//nBb//5UD//+TAP//lAD//5QA//+UAP//lADv/5QAWP+UAAD/lAAAAAAAAP+U
|
Lv//qz7//6s///+mMf//nBb//5UD//+TAP//lAD//5QA//+UAP//lADv/5QAWP+UAAD/lAAAAAAAAP+U
|
||||||
AAD/lAAD/5QAav+UAO//lAD//5QA//+UAP//lAD//5QA//+TAP//kwD//5MA//+TAP//lAD//5QA//+U
|
AAD/lAAD/5QAav+UAO//lAD//5QA//+UAP//lAD//5QA//+TAP//kwD//5MA//+TAP//lAD//5QA//+U
|
||||||
@@ -202,39 +205,39 @@
|
|||||||
AP//lAD//5QA//+UAP//lACz/5QAEv+UAAAAAAAA/5QAAP+UAAD/lAB4/5QA/f+UAP//lAD//5QA//+U
|
AP//lAD//5QA//+UAP//lACz/5QAEv+UAAAAAAAA/5QAAP+UAAD/lAB4/5QA/f+UAP//lAD//5QA//+U
|
||||||
AP//lAD//5cI//+rPv//wHr//8eN///Ijv//x43//8eN///Hjf//x43//8iO///Hjf//wn7//65H//+Y
|
AP//lAD//5cI//+rPv//wHr//8eN///Ijv//x43//8eN///Hjf//x43//8iO///Hjf//wn7//65H//+Y
|
||||||
DP//kwD//5QA//+UAP//lAD//5QA//+UAP3/lAB5/5QAAP+UAAD/lAAA/5QALP+UAOD/lAD//5QA//+U
|
DP//kwD//5QA//+UAP//lAD//5QA//+UAP3/lAB5/5QAAP+UAAD/lAAA/5QALP+UAOD/lAD//5QA//+U
|
||||||
AP//lAD//5QA//+ZDv//tVr//8eL///Hjf//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///H
|
AP//lAD//5QA//+ZDv//tVr//8eL///Hjf//xov//8aL///HjP//x4z//8eM///HjP//x4z//8eM///H
|
||||||
jf//x4z//7hk//+bFf//kwD//5QA//+UAP//lAD//5QA//+UAOD/lAAs/5QAAP+UAAD/lACH/5QA//+U
|
jf//x4z//7hk//+bFf//kwD//5QA//+UAP//lAD//5QA//+UAOD/lAAs/5QAAP+UAAD/lACH/5QA//+U
|
||||||
AP//lAD//5QA//+UAP//lwj//7Va///Hjf//x4z//8eM///Lk///yZD//8aL///HjP//x4z//8eM///H
|
AP//lAD//5QA//+UAP//lwj//7Va///Hjf//x4z//8uU///gv///2K///8mP///Gi///x4z//8eM///H
|
||||||
jP//x4z//8eM///HjP//yI7//7lm//+ZDv//lAD//5QA//+UAP//lAD//5QA//+UAIf/lAAA/5QAHv+U
|
jP//x4z//8eM///HjP//yI7//7lm//+ZDv//lAD//5QA//+UAP//lAD//5QA//+UAIf/lAAA/5QAHv+U
|
||||||
ANP/lAD//5QA//+UAP//lAD//5QA//+rQP//x4v//8eM///HjP//xor//9y2///r1f//0J///8aL///H
|
ANP/lAD//5QA//+UAP//lAD//5QA//+rQP//x4v//8eM///Giv//1qr///37///9+v//69b//9Kj///H
|
||||||
jP//x4z//8eM///HjP//x4z//8eM///HjP//x43//7BO//+VAv//lAD//5QA//+UAP//lAD//5QA0/+U
|
jP//x4v//8eM///HjP//x4z//8eM///HjP//x43//7BO//+VAv//lAD//5QA//+UAP//lAD//5QA0/+U
|
||||||
AB7/lABa/5QA9/+UAP//lAD//5QA//+UAP//nBb//8B6///Hjf//x4z//8eM///Giv//3rr////////3
|
AB7/lABa/5QA9/+UAP//lAD//5QA//+UAP//nBb//8B6///Hjf//x4z//8aK///Xrf///v3///79////
|
||||||
7///3rv//8qS///Gi///x4z//8eM///HjP//x4z//8eM///Hjf//w4L//6Ah//+TAP//lAD//5QA//+U
|
/v//+fP//+PF///Nl///xor//8eM///HjP//x4z//8eM///Hjf//w4L//6Ah//+TAP//lAD//5QA//+U
|
||||||
AP//lAD3/5QAWv+UAJr/lAD//5QA//+UAP//lAD//5MA//+sQf//x43//8eM///HjP//x4z//8aK///e
|
AP//lAD3/5QAWv+UAJr/lAD//5QA//+UAP//lAD//5MA//+sQf//x43//8eM///HjP//xor//9et////
|
||||||
uv/////////////+/P//7tz//9Ol///HjP//x4v//8eM///HjP//x4z//8eM///Ijv//slH//5QA//+U
|
/v//7tz//+PF///69P////////To///atP//yZD//8aL///HjP//x4z//8eM///Ijv//slH//5QA//+U
|
||||||
AP//lAD//5QA//+UAP//lACa/5QAyP+UAP//lAD//5QA//+UAP//lgX//7lm///Ijv//x4z//8eM///H
|
AP//lAD//5QA//+UAP//lACa/5QAyP+UAP//lAD//5QA//+UAP//lgX//7lm///Ijv//x4z//8eM///G
|
||||||
jP//xor//926////////////////////////+fT//+LD///Llf//xor//8eM///HjP//x4z//8iO//+9
|
iv//163////////p0v//x4v//9Kj///s1////fv///38///s2f//06X//8eM///Hi///x4z//8iO//+9
|
||||||
cv//mAv//5QA//+UAP//lAD//5QA//+UAMj/lADj/5QA//+UAP//lAD//5QA//+aEP//wHn//8eN///H
|
cv//mAv//5QA//+UAP//lAD//5QA//+UAMj/lADj/5QA//+UAP//lAD//5QA//+aEP//wHn//8eN///H
|
||||||
jP//x4z//8eM///Giv//3bn//////////////////////////////v7///Hj///Wq///yI3//8eM///H
|
jP//x4z//8aK///Xrf///////+nS///HjP//xov//8mP///asv//8+b////+///69P//5Mj//8yX///H
|
||||||
jP//x43//8OB//+dGv//kwD//5QA//+UAP//lAD//5QA4/+UAO//lAD//5QA//+UAP//kwD//5wW///C
|
jP//x43//8OB//+dGv//kwD//5QA//+UAP//lAD//5QA4/+UAO//lAD//5QA//+UAP//kwD//5wW///C
|
||||||
f///x43//8eM///HjP//x4z//8aK///duf////////////////////////////////////////z4///k
|
f///x43//8eM///HjP//xor//9et////////6dL//8eM///HjP//x4z//8aK///Llf//587///7+////
|
||||||
x///yZD//8eM///HjP//xYb//6Ah//+TAP//lAD//5QA//+UAP//lADv/5QA7/+UAP//lAD//5QA//+U
|
////5cr//8eL///HjP//xYb//6Ah//+TAP//lAD//5QA//+UAP//lADv/5QA7/+UAP//lAD//5QA//+U
|
||||||
AP//nBX//8J////Hjf//x4z//8eM///HjP//xor//924////////////////////////////////////
|
AP//nBX//8J////Hjf//x4z//8eM///Giv//163////////p0v//x4z//8eM///Gi///yI7//9iw///0
|
||||||
////9u3//9u2///Ijv//x4z//8eM///Fhv//oCH//5MA//+UAP//lAD//5QA//+UAO//lADj/5QA//+U
|
5/////////bs///WrP//x4v//8eM///Fhv//oCH//5MA//+UAP//lAD//5QA//+UAO//lADj/5QA//+U
|
||||||
AP//lAD//5QA//+ZDv//v3f//8eN///HjP//x4z//8eM///Giv//3Lf/////////////////////////
|
AP//lAD//5QA//+ZDv//v3f//8eN///HjP//x4z//8aK///Xrf///////+nS///Hi///xov//86b///o
|
||||||
/////Pr//+nR///PnP//xov//8eM///HjP//x43//8OA//+dGP//kwD//5QA//+UAP//lAD//5QA4/+U
|
0P///Pr///37///q1P//z53//8eL///HjP//x43//8OA//+dGP//kwD//5QA//+UAP//lAD//5QA4/+U
|
||||||
AMj/lAD//5QA//+UAP//lAD//5UE//+4Yv//yI7//8eM///HjP//x4z//8aK///ct///////////////
|
AMj/lAD//5QA//+UAP//lAD//5UE//+4Yv//yI7//8eM///HjP//xor//9et////////6dH//8iP///b
|
||||||
//////////Xq///asv//yI7//8aL///HjP//x4z//8eM///Ijv//vG///5cJ//+UAP//lAD//5QA//+U
|
tf//9ev////////27P//27X//8mP///Gi///x4z//8eM///Ijv//vG///5cJ//+UAP//lAD//5QA//+U
|
||||||
AP//lADI/5QAmv+UAP//lAD//5QA//+UAP//kwD//6o8///HjP//x4z//8eM///HjP//xor//9y3////
|
AP//lADI/5QAmv+UAP//lAD//5QA//+UAP//kwD//6o8///HjP//x4z//8eM///Giv//163///7+///w
|
||||||
//////////z5///nzv//zpr//8aL///HjP//x4z//8eM///HjP//x4z//8iO//+vS///lAD//5QA//+U
|
4P//6tP///37///9+v//6NH//8+c///Gi///x4z//8eM///HjP//x4z//8iO//+vS///lAD//5QA//+U
|
||||||
AP//lAD//5QA//+UAJr/lABa/5QA9/+UAP//lAD//5QA//+UAP//mhH//791///Ijv//x4z//8eM///G
|
AP//lAD//5QA//+UAJr/lABa/5QA9/+UAP//lAD//5QA//+UAP//mhH//791///Ijv//x4z//8aK///X
|
||||||
iv//27b////+///z5///2K///8iO///Hi///x4z//8eM///HjP//x4z//8eM///Hjf//wn7//54b//+T
|
rf///v3////+////////9On//9mx///Ijv//xov//8eM///HjP//x4z//8eM///Hjf//wn7//54b//+T
|
||||||
AP//lAD//5QA//+UAP//lAD3/5QAWv+UAB7/lADT/5QA//+UAP//lAD//5QA//+UAP//qDf//8aI///H
|
AP//lAD//5QA//+UAP//lAD3/5QAWv+UAB7/lADT/5QA//+UAP//lAD//5QA//+UAP//qDf//8aI///H
|
||||||
jf//x4z//8aK///Yr///5cr//82Y///Giv//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eL//+t
|
jf//xor//9Wp///9+////Pj//+bM///Nmf//xov//8eM///HjP//x4z//8eM///HjP//x4z//8eL//+t
|
||||||
Rf//lAH//5QA//+UAP//lAD//5QA//+UANP/lAAe/5QAAP+UAIb/lAD//5QA//+UAP//lAD//5QA//+V
|
Rf//lAH//5QA//+UAP//lAD//5QA//+UANP/lAAe/5QAAP+UAIb/lAD//5QA//+UAP//lAD//5QA//+V
|
||||||
Bf//sU///8eM///Hjf//x4z//8mQ///Ijf//x4v//8eM///HjP//x4z//8eM///HjP//x4z//8eM///H
|
Bf//sU///8eM///HjP//ypL//967///XrP//yI3//8eL///HjP//x4z//8eM///HjP//x4z//8eM///H
|
||||||
jf//tVv//5cJ//+UAP//lAD//5QA//+UAP//lAD//5QAhv+UAAD/lAAA/5QAK/+UAOD/lAD//5QA//+U
|
jf//tVv//5cJ//+UAP//lAD//5QA//+UAP//lAD//5QAhv+UAAD/lAAA/5QAK/+UAOD/lAD//5QA//+U
|
||||||
AP//lAD//5QA//+XCf//sEz//8WH///Ijv//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///I
|
AP//lAD//5QA//+XCf//sEz//8WH///Hjf//xov//8aL///HjP//x4z//8eM///HjP//x4z//8eM///I
|
||||||
jv//xor//7RX//+ZDf//lAD//5QA//+UAP//lAD//5QA//+UAOD/lAAr/5QAAP+UAAD/lAAA/5QAd/+U
|
jv//xor//7RX//+ZDf//lAD//5QA//+UAP//lAD//5QA//+UAOD/lAAr/5QAAP+UAAD/lAAA/5QAd/+U
|
||||||
APz/lAD//5QA//+UAP//lAD//5QA//+VBP//pjD//7xv///Giv//yI7//8iO///Ijf//yI3//8iO///I
|
APz/lAD//5QA//+UAP//lAD//5QA//+VBP//pjD//7xv///Giv//yI7//8iO///Ijf//yI3//8iO///I
|
||||||
jv//x4v//750//+pOf//lgf//5QA//+UAP//lAD//5QA//+UAP//lAD9/5QAeP+UAAD/lAAAAAAAAP+U
|
jv//x4v//750//+pOf//lgf//5QA//+UAP//lAD//5QA//+UAP//lAD9/5QAeP+UAAD/lAAAAAAAAP+U
|
||||||
@@ -298,74 +301,74 @@
|
|||||||
YP//x4z//8eN///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///H
|
YP//x4z//8eN///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///H
|
||||||
jP//x4z//8eN///Hjf//vG3//58g//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
jP//x4z//8eN///Hjf//vG3//58g//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||||
ANL/lAAf/5QAAAAAAAD/lAAA/5QAAP+UAHb/lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+T
|
ANL/lAAf/5QAAAAAAAD/lAAA/5QAAP+UAHb/lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+T
|
||||||
AP//mxX//7tr///Ijv//x4z//8eM///HjP//x4z//8eL///HjP//x4z//8eM///HjP//x4z//8eM///H
|
AP//mxX//7tr///Ijv//x4z//8eM///Hi///yI7//8iO///Gi///x4z//8eM///HjP//x4z//8eM///H
|
||||||
jP//x4z//8eM///HjP//x4z//8eM///HjP//yI7//8B4//+gIv//kwD//5QA//+UAP//lAD//5QA//+U
|
jP//x4z//8eM///HjP//x4z//8eM///HjP//yI7//8B4//+gIv//kwD//5QA//+UAP//lAD//5QA//+U
|
||||||
AP//lAD//5QA//+UAP//lAB2/5QAAP+UAAD/lAAA/5QAGv+UANH/lAD//5QA//+UAP//lAD//5QA//+U
|
AP//lAD//5QA//+UAP//lAB2/5QAAP+UAAD/lAAA/5QAGv+UANH/lAD//5QA//+UAP//lAD//5QA//+U
|
||||||
AP//lAD//5QA//+YCv//t2D//8iO///HjP//x4z//8eM///HjP//ypL//82Z///Gi///x4z//8eM///H
|
AP//lAD//5QA//+YCv//t2D//8iO///HjP//x4z//8eL///NmP//6tT//+3a///YsP//yI///8aL///H
|
||||||
jP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8iO//+9cP//mxX//5QA//+U
|
jP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8iO//+9cP//mxX//5QA//+U
|
||||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lADR/5QAGv+UAAD/lAAA/5QAWf+UAPv/lAD//5QA//+U
|
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lADR/5QAGv+UAAD/lAAA/5QAWf+UAPv/lAD//5QA//+U
|
||||||
AP//lAD//5QA//+UAP//lAD//5QB//+uSP//x4z//8eM///HjP//x4z//8eM///Gi///0aD///Hj///c
|
AP//lAD//5QA//+UAP//lAD//5QB//+uSP//x4z//8eM///HjP//x4z//8aK///btP////7////////8
|
||||||
uP//yZD//8aL///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///I
|
+v//69X//9Ki///HjP//x4v//8eM///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///I
|
||||||
jv//tVz//5YG//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD7/5QAWf+UAAD/lAAF/5QApf+U
|
jv//tVz//5YG//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD7/5QAWf+UAAD/lAAF/5QApf+U
|
||||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//6Ag///DgP//x43//8eM///HjP//x4z//8eM///G
|
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//6Ag///DgP//x43//8eM///HjP//x4z//8aK///d
|
||||||
i///0aD///v2///9/P//7Nf//9Gh///Hi///x4v//8eM///HjP//x4z//8eM///HjP//x4z//8eM///H
|
uf////////////////////////ny///ixP//zJf//8aL///HjP//x4z//8eM///HjP//x4z//8eM///H
|
||||||
jP//x4z//8eM///HjP//xoj//6cz//+TAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QApf+U
|
jP//x4z//8eM///HjP//xoj//6cz//+TAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QApf+U
|
||||||
AAX/lAAj/5QA2/+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lQP//7RZ///Ijv//x4z//8eM///H
|
AAX/lAAj/5QA2/+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lQP//7RZ///Ijv//x4z//8eM///H
|
||||||
jP//x4z//8eM///Gi///0aD///v2//////////////jx///gv///ypP//8aL///HjP//x4z//8eM///H
|
jP//x4z//8aK///duf/////////////9/P////7//////////v//8+f//9qz///JkP//xov//8eM///H
|
||||||
jP//x4z//8eM///HjP//x4z//8eM///HjP//yI7//7xt//+YC///lAD//5QA//+UAP//lAD//5QA//+U
|
jP//x4z//8eM///HjP//x4z//8eM///HjP//yI7//7xt//+YC///lAD//5QA//+UAP//lAD//5QA//+U
|
||||||
AP//lAD//5QA2/+UACP/lABU/5QA9v+UAP//lAD//5QA//+UAP//lAD//5QA//+TAP//nhv//8OA///H
|
AP//lAD//5QA2/+UACP/lABU/5QA9v+UAP//lAD//5QA//+UAP//lAD//5QA//+TAP//nhv//8OA///H
|
||||||
jf//x4z//8eM///HjP//x4z//8eM///Gi///0aD///v2///////////////////+/f//797//9Sn///H
|
jf//x4z//8eM///HjP//x4z//8aK///duf/////////////nz///587///v4//////////////37///s
|
||||||
jP//x4v//8eM///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8aJ//+lMP//kwD//5QA//+U
|
2P//06T//8eM///Hi///x4z//8eM///HjP//x4z//8eM///HjP//x4z//8aJ//+lMP//kwD//5QA//+U
|
||||||
AP//lAD//5QA//+UAP//lAD//5QA9v+UAFT/lACI/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+T
|
AP//lAD//5QA//+UAP//lAD//5QA9v+UAFT/lACI/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+T
|
||||||
AP//rEH//8eN///HjP//x4z//8eM///HjP//x4z//8eM///Gi///0aD///v2////////////////////
|
AP//rEH//8eN///HjP//x4z//8eM///HjP//x4z//8aK///duf/////////////fvv//x4z//9ar///w
|
||||||
//////////r1///jxv//zJf//8aK///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8iO//+0
|
4P///v3/////////////+fT//+TH///NmP//xov//8eM///HjP//x4z//8eM///HjP//x4z//8iO//+0
|
||||||
V///lAH//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAIj/lACv/5QA//+UAP//lAD//5QA//+U
|
V///lAH//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAIj/lACv/5QA//+UAP//lAD//5QA//+U
|
||||||
AP//lAD//5QA//+VA///t2D//8iO///HjP//x4z//8eM///HjP//x4z//8eM///Gi///0J////r1////
|
AP//lAD//5QA//+VA///t2D//8iO///HjP//x4z//8eM///HjP//x4z//8aK///duf/////////////g
|
||||||
/////////////////////////////////v//8uX//9iu///Ijv//xov//8eM///HjP//x4z//8eM///H
|
v///xor//8aK///Kk///3rv///bt///////////////+///06f//27b//8mR///Gi///x4z//8eM///H
|
||||||
jP//x4z//8iO//++c///mAz//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAK//lADP/5QA//+U
|
jP//x4z//8iO//++c///mAz//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAK//lADP/5QA//+U
|
||||||
AP//lAD//5QA//+UAP//lAD//5QA//+YDP//vnT//8iN///HjP//x4z//8eM///HjP//x4z//8eM///G
|
AP//lAD//5QA//+UAP//lAD//5QA//+YDP//vnT//8iN///HjP//x4z//8eM///HjP//x4z//8aK///d
|
||||||
i///0J7///r1//////////////////////////////////////////////z4///nzv//zpv//8aL///H
|
uf/////////////gv///xor//8eM///Hi///xov//8+c///mzf//+/f//////////////fv//+3a///U
|
||||||
jP//x4z//8eM///HjP//x4z//8eN///Dgv//nhv//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
pv//x43//8eM///HjP//x4z//8eN///Dgv//nhv//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||||
AM//lADf/5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+cF///wn///8eN///HjP//x4z//8eM///H
|
AM//lADf/5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+cF///wn///8eN///HjP//x4z//8eM///H
|
||||||
jP//x4z//8eM///Gi///0J7///r1////////////////////////////////////////////////////
|
jP//x4z//8aK///duf/////////////gv///xor//8eM///HjP//x4z//8aL///Hjf//1an//+7d///9
|
||||||
////9ev//9u1///JkP//x4z//8eM///HjP//x4z//8eM///Gif//oyn//5MA//+UAP//lAD//5QA//+U
|
/P/////////////69f//4MD//8iO///HjP//x4z//8eM///Gif//oyn//5MA//+UAP//lAD//5QA//+U
|
||||||
AP//lAD//5QA//+UAN//lADp/5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+dGf//w4H//8eN///H
|
AP//lAD//5QA//+UAN//lADp/5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+dGf//w4H//8eN///H
|
||||||
jP//x4z//8eM///HjP//x4z//8eM///Gi///0J7///r1////////////////////////////////////
|
jP//x4z//8eM///HjP//x4z//8aK///duf/////////////gv///xor//8eM///HjP//x4z//8eM///H
|
||||||
//////////////////////////38///p0f//y5T//8eM///HjP//x4z//8eM///Gif//pCv//5MA//+U
|
jP//xor//8mR///my////v7/////////////9u3//8yX///Hi///x4z//8eM///Gif//pCv//5MA//+U
|
||||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAOn/lADp/5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+d
|
AP//lAD//5QA//+UAP//lAD//5QA//+UAOn/lADp/5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+d
|
||||||
Gf//w4H//8eN///HjP//x4z//8eM///HjP//x4z//8eM///Gi///0J7///r1////////////////////
|
Gf//w4H//8eN///HjP//x4z//8eM///HjP//x4z//8aK///duf/////////////gv///xor//8eM///H
|
||||||
//////////////////////////////////////////bs///ct///yY///8eM///HjP//x4z//8eM///G
|
jP//x4z//8eM///Gi///ypH//967///37v/////////////8+v//48b//8iP///HjP//x4z//8eM///G
|
||||||
if//pCz//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAOn/lADf/5QA//+UAP//lAD//5QA//+U
|
if//pCz//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAOn/lADf/5QA//+UAP//lAD//5QA//+U
|
||||||
AP//lAD//5QA//+bFP//wX3//8eN///HjP//x4z//8eM///HjP//x4z//8eM///Gi///z53///n0////
|
AP//lAD//5QA//+bFP//wX3//8eN///HjP//x4z//8eM///HjP//x4z//8aK///duf/////////////g
|
||||||
///////////////////////////////////////////////8+v//6dH//8+c///Gi///x4z//8eM///H
|
v///xor//8eM///HjP//x4v//8eL///So///7dr///78//////////////bt///atP//yI7//8eM///H
|
||||||
jP//x4z//8eM///FiP//oif//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAN//lADP/5QA//+U
|
jP//x4z//8eM///FiP//oif//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAN//lADP/5QA//+U
|
||||||
AP//lAD//5QA//+UAP//lAD//5QA//+YCv//vXH//8iO///HjP//x4z//8eM///HjP//x4z//8eM///G
|
AP//lAD//5QA//+UAP//lAD//5QA//+YCv//vXH//8iO///HjP//x4z//8eM///HjP//x4z//8aK///d
|
||||||
i///z5z///nz//////////////////////////////////////////////Tp///asv//yI7//8aL///H
|
uf/////////////gv///xor//8eM///Gi///ypP//+C////58v/////////////9+///6tT//8+d///G
|
||||||
jP//x4z//8eM///HjP//x4z//8eN///DgP//nRj//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
i///x4z//8eM///HjP//x4z//8eN///DgP//nRj//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||||
AM//lACv/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+VAv//tVv//8iO///HjP//x4z//8eM///H
|
AM//lACv/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+VAv//tVv//8iO///HjP//x4z//8eM///H
|
||||||
jP//x4z//8eM///Gi///z5z///nz///////////////////////////////////8+f//587//86a///G
|
jP//x4z//8aK///duf/////////////gv///xon//8eM///Upv//797///79//////////////Xr///b
|
||||||
i///x4z//8eM///HjP//x4z//8eM///HjP//x4z//8iO//+8bv//lwn//5QA//+UAP//lAD//5QA//+U
|
tf//yY///8aL///HjP//x4z//8eM///HjP//x4z//8iO//+8bv//lwn//5QA//+UAP//lAD//5QA//+U
|
||||||
AP//lAD//5QA//+UAK//lACI/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+TAP//qTr//8eM///H
|
AP//lAD//5QA//+UAK//lACI/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+TAP//qTr//8eM///H
|
||||||
jP//x4z//8eM///HjP//x4z//8eM///Gi///z5z///nz//////////////////////////7///Pn///Y
|
jP//x4z//8eM///HjP//x4z//8aK///duf/////////////fvv//ypP//+LE///69P/////////////8
|
||||||
r///yI7//8eL///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8iO//+xUP//lAD//5QA//+U
|
+f//6ND//8+c///Gi///x4z//8eM///HjP//x4z//8eM///HjP//x4z//8iO//+xUP//lAD//5QA//+U
|
||||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAIj/lABU/5QA9v+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
AP//lAD//5QA//+UAP//lAD//5QA//+UAIj/lABU/5QA9v+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||||
AP//mxX//8F7///Hjf//x4z//8eM///HjP//x4z//8eM///Hi///z5z///nz///////////////////7
|
AP//mxX//8F7///Hjf//x4z//8eM///HjP//x4z//8aK///duf/////////////s2P//8OD///7+////
|
||||||
9///5cr//82Y///Gi///x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8WG//+i
|
//////////To///Zsf//yI7//8aL///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8WG//+i
|
||||||
Jv//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA9v+UAFT/lAAj/5QA2v+UAP//lAD//5QA//+U
|
Jv//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA9v+UAFT/lAAj/5QA2v+UAP//lAD//5QA//+U
|
||||||
AP//lAD//5QA//+UAP//lAH//7BO///Ijf//x4z//8eM///HjP//x4z//8eM///Hi///zpv///jy////
|
AP//lAD//5QA//+UAP//lAH//7BO///Ijf//x4z//8eM///HjP//x4z//8aK///duf//////////////
|
||||||
//////7///Lk///WrP//x43//8eL///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///H
|
/v/////////////7+P//5sz//82Z///Gi///x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///H
|
||||||
jP//yI7//7hj//+WB///lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA2v+UACP/lAAF/5QApf+U
|
jP//yI7//7hj//+WB///lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA2v+UACP/lAAF/5QApf+U
|
||||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5wX///Aef//yI3//8eM///HjP//x4z//8eM///H
|
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5wX///Aef//yI3//8eM///HjP//x4z//8aK///d
|
||||||
i///zpv///ny///79v//48f//8yW///Giv//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///H
|
uf////////////////////7///Ll///Xrf//yI3//8eL///HjP//x4z//8eM///HjP//x4z//8eM///H
|
||||||
jP//x4z//8eM///Hjf//xIT//6Io//+TAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QApP+U
|
jP//x4z//8eM///Hjf//xIT//6Io//+TAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QApP+U
|
||||||
AAX/lAAA/5QAWf+UAPv/lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+pOv//xon//8eN///H
|
AAX/lAAA/5QAWf+UAPv/lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+pOv//xon//8eN///H
|
||||||
jP//x4z//8eM///Hi///zpr//+rU///Vqf//x4z//8eL///HjP//x4z//8eM///HjP//x4z//8eM///H
|
jP//x4z//8aK///Zsv///v3////////79v//5Mj//8yX///Giv//x4z//8eM///HjP//x4z//8eM///H
|
||||||
jP//x4z//8eM///HjP//x4z//8eM///HjP//sE7//5UD//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
jP//x4z//8eM///HjP//x4z//8eM///HjP//sE7//5UD//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||||
AP//lAD7/5QAWf+UAAD/lAAA/5QAGv+UANH/lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+W
|
AP//lAD7/5QAWf+UAAD/lAAA/5QAGv+UANH/lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+W
|
||||||
Bf//sU///8eM///HjP//x4z//8eM///HjP//yI7//8mR///Gi///x4z//8eM///HjP//x4z//8eM///H
|
Bf//sU///8eM///HjP//x4z//8eL///LlP//5cv//+zX///Vqv//x4z//8eL///HjP//x4z//8eM///H
|
||||||
jP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8iO//+3Yf//mAz//5QA//+UAP//lAD//5QA//+U
|
jP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8iO//+3Yf//mAz//5QA//+UAP//lAD//5QA//+U
|
||||||
AP//lAD//5QA//+UAP//lADR/5QAGv+UAAD/lAAA/5QAAP+UAHb/lAD//5QA//+UAP//lAD//5QA//+U
|
AP//lAD//5QA//+UAP//lADR/5QAGv+UAAD/lAAA/5QAAP+UAHb/lAD//5QA//+UAP//lAD//5QA//+U
|
||||||
AP//lAD//5QA//+UAP//mAv//7Va///Hi///x43//8eM///HjP//x4z//8eM///HjP//x4z//8eM///H
|
AP//lAD//5QA//+UAP//mAv//7Va///Hi///x43//8eM///HjP//x4z//8iN///Gi///x4z//8eM///H
|
||||||
jP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x43//7pp//+bFf//kwD//5QA//+U
|
jP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x43//7pp//+bFf//kwD//5QA//+U
|
||||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP7/lAB2/5QAAP+UAAAAAAAA/5QAAP+UAB//lADR/5QA//+U
|
AP//lAD//5QA//+UAP//lAD//5QA//+UAP7/lAB2/5QAAP+UAAAAAAAA/5QAAP+UAB//lADR/5QA//+U
|
||||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5cJ//+wTP//xYb//8iO///HjP//x4z//8eM///H
|
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5cJ//+wTP//xYb//8iO///HjP//x4z//8eM///H
|
||||||
@@ -416,129 +419,142 @@
|
|||||||
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
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -3,7 +3,6 @@ using System.Linq;
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Drawing.Text;
|
using System.Drawing.Text;
|
||||||
using Microsoft.Win32;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
|
||||||
@@ -131,62 +130,29 @@ public class MenuItem : ToolStripMenuItem
|
|||||||
|
|
||||||
public class ToolStripRendererEx : ToolStripSystemRenderer
|
public class ToolStripRendererEx : ToolStripSystemRenderer
|
||||||
{
|
{
|
||||||
public static Color ColorForeground { get; set; } = Color.Black;
|
public static Color ForegroundColor { get; set; }
|
||||||
public static Color ColorTheme { get; set; } = Color.Empty;
|
public static Color BackgroundColor { get; set; }
|
||||||
public static Color ColorChecked { get; set; }
|
public static Color SelectionColor { get; set; }
|
||||||
public static Color ColorBorder { get; set; }
|
public static Color CheckedColor { get; set; }
|
||||||
public static Color ColorTop { get; set; }
|
public static Color BorderColor { get; set; }
|
||||||
public static Color ColorSelection { get; set; }
|
|
||||||
public static Color ColorBackground { get; set; }
|
|
||||||
|
|
||||||
public static Color ColorToolStrip1 { get; set; }
|
|
||||||
public static Color ColorToolStrip2 { get; set; }
|
|
||||||
public static Color ColorToolStrip3 { get; set; }
|
|
||||||
public static Color ColorToolStrip4 { get; set; }
|
|
||||||
|
|
||||||
int TextOffset;
|
int TextOffset;
|
||||||
|
|
||||||
public ToolStripRendererEx()
|
public static void SetDefaultColors()
|
||||||
{
|
{
|
||||||
var argb = Convert.ToInt32(Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM", "ColorizationColor", 0));
|
ForegroundColor = Color.FromArgb(unchecked((int)0xFF000000));
|
||||||
|
BackgroundColor = Color.FromArgb(unchecked((int)0xFFDFDFDF));
|
||||||
if (argb == 0)
|
SelectionColor = Color.FromArgb(unchecked((int)0xFFBFBFBF));
|
||||||
argb = Color.LightBlue.ToArgb();
|
CheckedColor = Color.FromArgb(unchecked((int)0xFFAAAAAA));
|
||||||
if (ColorTheme == Color.Empty)
|
BorderColor = Color.FromArgb(unchecked((int)0xFF6A6A6A));
|
||||||
InitColors(Color.FromArgb(argb));
|
|
||||||
else
|
|
||||||
InitColors(ColorTheme);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void InitColors(Color c)
|
|
||||||
{
|
|
||||||
ColorBorder = HSLColor.Convert(c).ToColorSetLuminosity(100);
|
|
||||||
ColorChecked = HSLColor.Convert(c).ToColorSetLuminosity(160);
|
|
||||||
ColorSelection = HSLColor.Convert(c).ToColorSetLuminosity(180);
|
|
||||||
ColorBackground = HSLColor.Convert(c).ToColorSetLuminosity(210);
|
|
||||||
ColorTop = HSLColor.Convert(c).ToColorSetLuminosity(240);
|
|
||||||
|
|
||||||
if (ColorTheme == Color.Black)
|
|
||||||
{
|
|
||||||
ColorBorder = Color.White;
|
|
||||||
ColorBackground = Color.FromArgb(50, 50, 50);
|
|
||||||
ColorSelection = Color.FromArgb(80, 80, 80);
|
|
||||||
ColorForeground = Color.White;
|
|
||||||
ColorChecked = Color.FromArgb(90, 90, 90);
|
|
||||||
}
|
|
||||||
|
|
||||||
ColorToolStrip1 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 1)));
|
|
||||||
ColorToolStrip2 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 0.7f)));
|
|
||||||
ColorToolStrip3 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 0.1f)));
|
|
||||||
ColorToolStrip4 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 0.4f)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
|
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
|
||||||
{
|
{
|
||||||
Rectangle r = e.AffectedBounds;
|
Rectangle r = e.AffectedBounds;
|
||||||
r.Inflate(-1, -1);
|
r.Inflate(-1, -1);
|
||||||
ControlPaint.DrawBorder(e.Graphics, r, ColorBackground, ButtonBorderStyle.Solid);
|
ControlPaint.DrawBorder(e.Graphics, r, BackgroundColor, ButtonBorderStyle.Solid);
|
||||||
ControlPaint.DrawBorder(e.Graphics, e.AffectedBounds, ColorBorder, ButtonBorderStyle.Solid);
|
ControlPaint.DrawBorder(e.Graphics, e.AffectedBounds, BorderColor, ButtonBorderStyle.Solid);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
|
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
|
||||||
@@ -203,37 +169,26 @@ public class ToolStripRendererEx : ToolStripSystemRenderer
|
|||||||
else
|
else
|
||||||
TextOffset = Convert.ToInt32(e.Item.Height * 0.2);
|
TextOffset = Convert.ToInt32(e.Item.Height * 0.2);
|
||||||
|
|
||||||
e.TextColor = ColorForeground;
|
e.TextColor = ForegroundColor;
|
||||||
e.TextRectangle = new Rectangle(TextOffset, Convert.ToInt32((e.Item.Height - rect.Height) / 2.0), rect.Width, rect.Height);
|
e.TextRectangle = new Rectangle(TextOffset, Convert.ToInt32((e.Item.Height - rect.Height) / 2.0), rect.Width, rect.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
base.OnRenderItemText(e);
|
base.OnRenderItemText(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
|
|
||||||
{
|
|
||||||
if (!(e.ToolStrip is ToolStripDropDownMenu) && !(e.ToolStrip.LayoutStyle == ToolStripLayoutStyle.VerticalStackWithOverflow))
|
|
||||||
{
|
|
||||||
Rectangle r = new Rectangle(-1, -1, e.AffectedBounds.Width, e.AffectedBounds.Height);
|
|
||||||
|
|
||||||
using (SolidBrush b = new SolidBrush(ColorToolStrip2))
|
|
||||||
e.Graphics.FillRectangle(b, r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
|
protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
|
||||||
{
|
{
|
||||||
Rectangle rect = new Rectangle(Point.Empty, e.Item.Size);
|
Rectangle rect = new Rectangle(Point.Empty, e.Item.Size);
|
||||||
|
|
||||||
if (!(e.Item.Owner is MenuStrip))
|
if (!(e.Item.Owner is MenuStrip))
|
||||||
e.Graphics.Clear(ColorBackground);
|
e.Graphics.Clear(BackgroundColor);
|
||||||
|
|
||||||
if (e.Item.Selected && e.Item.Enabled)
|
if (e.Item.Selected && e.Item.Enabled)
|
||||||
{
|
{
|
||||||
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||||
rect = new Rectangle(rect.X + 2, rect.Y, rect.Width - 4, rect.Height - 1);
|
rect = new Rectangle(rect.X + 2, rect.Y, rect.Width - 4, rect.Height - 1);
|
||||||
rect.Inflate(-1, -1);
|
rect.Inflate(-1, -1);
|
||||||
using (SolidBrush b = new SolidBrush(ColorSelection))
|
using (SolidBrush b = new SolidBrush(SelectionColor))
|
||||||
e.Graphics.FillRectangle(b, rect);
|
e.Graphics.FillRectangle(b, rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,7 +204,7 @@ public class ToolStripRendererEx : ToolStripSystemRenderer
|
|||||||
float y3 = e.Item.Height * 0.75f;
|
float y3 = e.Item.Height * 0.75f;
|
||||||
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
|
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
|
||||||
using (Brush b = new SolidBrush(ColorForeground))
|
using (Brush b = new SolidBrush(ForegroundColor))
|
||||||
{
|
{
|
||||||
using (Pen p = new Pen(b, Control.DefaultFont.Height / 20f))
|
using (Pen p = new Pen(b, Control.DefaultFont.Height / 20f))
|
||||||
{
|
{
|
||||||
@@ -275,7 +230,7 @@ public class ToolStripRendererEx : ToolStripSystemRenderer
|
|||||||
rect = new Rectangle(rect.X + 2, rect.Y, rect.Height - 1, rect.Height - 1);
|
rect = new Rectangle(rect.X + 2, rect.Y, rect.Height - 1, rect.Height - 1);
|
||||||
rect.Inflate(-1, -1);
|
rect.Inflate(-1, -1);
|
||||||
|
|
||||||
using (Brush brush = new SolidBrush(ColorChecked))
|
using (Brush brush = new SolidBrush(CheckedColor))
|
||||||
e.Graphics.FillRectangle(brush, rect);
|
e.Graphics.FillRectangle(brush, rect);
|
||||||
|
|
||||||
float ellipseWidth = rect.Height / 3f;
|
float ellipseWidth = rect.Height / 3f;
|
||||||
@@ -285,17 +240,17 @@ public class ToolStripRendererEx : ToolStripSystemRenderer
|
|||||||
ellipseWidth,
|
ellipseWidth,
|
||||||
ellipseWidth);
|
ellipseWidth);
|
||||||
|
|
||||||
using (Brush brush = new SolidBrush(ColorForeground))
|
using (Brush brush = new SolidBrush(ForegroundColor))
|
||||||
e.Graphics.FillEllipse(brush, rectF);
|
e.Graphics.FillEllipse(brush, rectF);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e)
|
protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e)
|
||||||
{
|
{
|
||||||
e.Graphics.Clear(ColorBackground);
|
e.Graphics.Clear(BackgroundColor);
|
||||||
int top = e.Item.Height / 2;
|
int top = e.Item.Height / 2;
|
||||||
top -= 1;
|
top -= 1;
|
||||||
int offset = Convert.ToInt32(e.Item.Font.Height * 0.7);
|
int offset = Convert.ToInt32(e.Item.Font.Height * 0.7);
|
||||||
using (Pen p = new Pen(ColorBorder))
|
using (Pen p = new Pen(BorderColor))
|
||||||
e.Graphics.DrawLine(p,
|
e.Graphics.DrawLine(p,
|
||||||
new Point(offset, top),
|
new Point(offset, top),
|
||||||
new Point(e.Item.Width - offset, top));
|
new Point(e.Item.Width - offset, top));
|
||||||
|
|||||||
@@ -9,34 +9,11 @@
|
|||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>mpvnet</RootNamespace>
|
<RootNamespace>mpvnet</RootNamespace>
|
||||||
<AssemblyName>mpvnet</AssemblyName>
|
<AssemblyName>mpvnet</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<Optimize>false</Optimize>
|
|
||||||
<OutputPath>bin\</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
|
||||||
<GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
|
|
||||||
<LangVersion>7.3</LangVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<OutputPath>bin\</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup />
|
<PropertyGroup />
|
||||||
<PropertyGroup />
|
<PropertyGroup />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
@@ -137,8 +114,14 @@
|
|||||||
<Reference Include="WindowsBase" />
|
<Reference Include="WindowsBase" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Misc\Addon.cs" />
|
<Compile Include="Misc\App.cs" />
|
||||||
<Page Include="Controls\SearchTextBoxUserControl.xaml">
|
<Compile Include="Misc\Extension.cs" />
|
||||||
|
<Content Include="Resources\theme.txt" />
|
||||||
|
<Page Include="WPF\SearchTextBoxUserControl.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="WPF\SetupWindow.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
@@ -158,7 +141,9 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Compile Include="Controls\SearchTextBoxUserControl.xaml.cs">
|
<Compile Include="Misc\Help.cs" />
|
||||||
|
<Compile Include="Misc\Theme.cs" />
|
||||||
|
<Compile Include="WPF\SearchTextBoxUserControl.xaml.cs">
|
||||||
<DependentUpon>SearchTextBoxUserControl.xaml</DependentUpon>
|
<DependentUpon>SearchTextBoxUserControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="DynamicGUI\DynamicGUI.cs" />
|
<Compile Include="DynamicGUI\DynamicGUI.cs" />
|
||||||
@@ -169,7 +154,9 @@
|
|||||||
<DependentUpon>StringSettingControl.xaml</DependentUpon>
|
<DependentUpon>StringSettingControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="DynamicGUI\Tommy.cs" />
|
<Compile Include="DynamicGUI\Tommy.cs" />
|
||||||
|
<Compile Include="Misc\ExtensionMethods.cs" />
|
||||||
<Compile Include="Native\MediaInfo.cs" />
|
<Compile Include="Native\MediaInfo.cs" />
|
||||||
|
<Compile Include="Native\Taskbar.cs" />
|
||||||
<Compile Include="WinForms\Menu.cs">
|
<Compile Include="WinForms\Menu.cs">
|
||||||
<SubType>Component</SubType>
|
<SubType>Component</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -195,6 +182,9 @@
|
|||||||
<Compile Include="Misc\Program.cs" />
|
<Compile Include="Misc\Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Native\TaskDialog.cs" />
|
<Compile Include="Native\TaskDialog.cs" />
|
||||||
|
<Compile Include="WPF\SetupWindow.xaml.cs">
|
||||||
|
<DependentUpon>SetupWindow.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="WPF\EverythingWindow.xaml.cs">
|
<Compile Include="WPF\EverythingWindow.xaml.cs">
|
||||||
<DependentUpon>EverythingWindow.xaml</DependentUpon>
|
<DependentUpon>EverythingWindow.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -252,9 +242,9 @@
|
|||||||
</Content>
|
</Content>
|
||||||
<Content Include="mpvnet.ico" />
|
<Content Include="mpvnet.ico" />
|
||||||
<Content Include="Resources\mpvConf.txt" />
|
<Content Include="Resources\mpvConf.txt" />
|
||||||
<Content Include="Resources\mpvConfToml.txt" />
|
<Content Include="Resources\confToml.txt" />
|
||||||
|
<None Include="Resources\mpvnet.ico" />
|
||||||
<None Include="Resources\mpvnet.png" />
|
<None Include="Resources\mpvnet.png" />
|
||||||
<Content Include="Resources\mpvNetConfToml.txt" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="App.config" />
|
<None Include="App.config" />
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
@@ -12,8 +13,10 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
using WinForms = System.Windows.Forms;
|
||||||
|
|
||||||
using static mpvnet.libmpv;
|
using static mpvnet.libmpv;
|
||||||
using static mpvnet.Native;
|
using static Native;
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
@@ -51,109 +54,164 @@ namespace mpvnet
|
|||||||
public static event Action QueueOverflow; // MPV_EVENT_QUEUE_OVERFLOW
|
public static event Action QueueOverflow; // MPV_EVENT_QUEUE_OVERFLOW
|
||||||
public static event Action Hook; // MPV_EVENT_HOOK
|
public static event Action Hook; // MPV_EVENT_HOOK
|
||||||
|
|
||||||
public static IntPtr Handle { get; set; }
|
public static event Action Initialized;
|
||||||
public static IntPtr WindowHandle { get; set; }
|
|
||||||
public static Addon Addon { get; set; }
|
|
||||||
public static bool IsLogoVisible { set; get; }
|
|
||||||
public static List<KeyValuePair<string, Action<bool>>> BoolPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<bool>>>();
|
public static List<KeyValuePair<string, Action<bool>>> BoolPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<bool>>>();
|
||||||
public static List<KeyValuePair<string, Action<int>>> IntPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<int>>>();
|
public static List<KeyValuePair<string, Action<int>>> IntPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<int>>>();
|
||||||
|
public static List<KeyValuePair<string, Action<double>>> DoublePropChangeActions { get; set; } = new List<KeyValuePair<string, Action<double>>>();
|
||||||
public static List<KeyValuePair<string, Action<string>>> StringPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<string>>>();
|
public static List<KeyValuePair<string, Action<string>>> StringPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<string>>>();
|
||||||
public static Size VideoSize { get; set; }
|
|
||||||
public static List<PythonScript> PythonScripts { get; set; } = new List<PythonScript>();
|
|
||||||
public static AutoResetEvent ShutdownAutoResetEvent { get; set; } = new AutoResetEvent(false);
|
|
||||||
public static AutoResetEvent VideoSizeAutoResetEvent { get; set; } = new AutoResetEvent(false);
|
|
||||||
public static List<MediaTrack> MediaTracks { get; set; } = new List<MediaTrack>();
|
public static List<MediaTrack> MediaTracks { get; set; } = new List<MediaTrack>();
|
||||||
public static List<KeyValuePair<string, double>> Chapters { get; set; } = new List<KeyValuePair<string, double>>();
|
public static List<KeyValuePair<string, double>> Chapters { get; set; } = new List<KeyValuePair<string, double>>();
|
||||||
|
public static IntPtr Handle { get; set; }
|
||||||
|
public static IntPtr WindowHandle { get; set; }
|
||||||
|
public static List<PythonScript> PythonScripts { get; set; } = new List<PythonScript>();
|
||||||
|
public static Size VideoSize { get; set; }
|
||||||
|
public static TimeSpan Duration;
|
||||||
|
public static AutoResetEvent ShutdownAutoResetEvent { get; set; } = new AutoResetEvent(false);
|
||||||
|
public static AutoResetEvent VideoSizeAutoResetEvent { get; set; } = new AutoResetEvent(false);
|
||||||
|
|
||||||
public static string InputConfPath { get; } = ConfFolder + "\\input.conf";
|
public static string InputConfPath { get => ConfigFolder + "input.conf"; }
|
||||||
public static string ConfPath { get; } = ConfFolder + "\\mpv.conf";
|
public static string ConfPath { get => ConfigFolder + "mpv.conf"; }
|
||||||
public static string Sid { get; set; } = "";
|
public static string Sid { get; set; } = "";
|
||||||
public static string Aid { get; set; } = "";
|
public static string Aid { get; set; } = "";
|
||||||
public static string Vid { get; set; } = "";
|
public static string Vid { get; set; } = "";
|
||||||
|
public static string GPUAPI { get; set; } = "auto";
|
||||||
|
|
||||||
|
public static bool IsLogoVisible { set; get; }
|
||||||
|
public static bool IsQuitNeeded { set; get; } = true;
|
||||||
public static bool Fullscreen { get; set; }
|
public static bool Fullscreen { get; set; }
|
||||||
public static bool Border { get; set; } = true;
|
public static bool Border { get; set; } = true;
|
||||||
|
public static bool TaskbarProgress { get; set; } = true;
|
||||||
|
|
||||||
public static int Screen { get; set; } = -1;
|
public static int Screen { get; set; } = -1;
|
||||||
public static int Edition { get; set; }
|
public static int Edition { get; set; }
|
||||||
|
|
||||||
public static float Autofit { get; set; } = 0.5f;
|
public static float Autofit { get; set; } = 0.5f;
|
||||||
|
public static float AutofitSmaller { get; set; } = 0.4f;
|
||||||
|
public static float AutofitLarger { get; set; } = 0.75f;
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
LoadLibrary("mpv-1.dll");
|
LoadLibrary("mpv-1.dll");
|
||||||
Handle = mpv_create();
|
Handle = mpv_create();
|
||||||
set_property_string("osc", "yes");
|
Task.Run(() => EventLoop());
|
||||||
set_property_string("config", "yes");
|
|
||||||
|
if (App.IsStartedFromTerminal)
|
||||||
|
{
|
||||||
|
set_property_string("terminal", "yes");
|
||||||
|
set_property_string("input-terminal", "yes");
|
||||||
|
set_property_string("msg-level", "osd/libass=fatal");
|
||||||
|
}
|
||||||
|
|
||||||
set_property_string("wid", MainForm.Hwnd.ToString());
|
set_property_string("wid", MainForm.Hwnd.ToString());
|
||||||
set_property_string("force-window", "yes");
|
set_property_string("osc", "yes");
|
||||||
set_property_string("input-media-keys", "yes");
|
set_property_string("input-media-keys", "yes");
|
||||||
|
set_property_string("force-window", "yes");
|
||||||
|
set_property_string("config-dir", ConfigFolder);
|
||||||
|
set_property_string("config", "yes");
|
||||||
|
|
||||||
|
ProcessCommandLine(true);
|
||||||
mpv_initialize(Handle);
|
mpv_initialize(Handle);
|
||||||
ShowLogo();
|
Initialized?.Invoke();
|
||||||
ProcessCommandLine();
|
LoadMpvScripts();
|
||||||
Task.Run(() => { LoadScripts(); });
|
|
||||||
Task.Run(() => { Addon = new Addon(); });
|
|
||||||
Task.Run(() => { EventLoop(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ProcessProperty(string name, string value)
|
public static void ProcessProperty(string name, string value)
|
||||||
{
|
{
|
||||||
|
if (name.Any(char.IsUpper))
|
||||||
|
Msg.ShowError("Uppercase char detected: " + name,
|
||||||
|
"mpv properties using the command line and the mpv.conf config file are required to be lowercase.");
|
||||||
|
|
||||||
switch (name)
|
switch (name)
|
||||||
{
|
{
|
||||||
case "autofit":
|
case "autofit":
|
||||||
if (value.Length == 3 && value.EndsWith("%"))
|
if (int.TryParse(value.Trim('%'), out int result))
|
||||||
if (int.TryParse(value.Substring(0, 2), out int result))
|
|
||||||
Autofit = result / 100f;
|
Autofit = result / 100f;
|
||||||
break;
|
break;
|
||||||
|
case "autofit-smaller":
|
||||||
|
if (int.TryParse(value.Trim('%'), out int result2))
|
||||||
|
AutofitSmaller = result2 / 100f;
|
||||||
|
break;
|
||||||
|
case "autofit-larger":
|
||||||
|
if (int.TryParse(value.Trim('%'), out int result3))
|
||||||
|
AutofitLarger = result3 / 100f;
|
||||||
|
break;
|
||||||
case "fs":
|
case "fs":
|
||||||
case "fullscreen": Fullscreen = value == "yes"; break;
|
case "fullscreen": Fullscreen = value == "yes"; break;
|
||||||
case "border": Border = value == "yes"; break;
|
case "border": Border = value == "yes"; break;
|
||||||
|
case "taskbar-progress": TaskbarProgress = value == "yes"; break;
|
||||||
case "screen": Screen = Convert.ToInt32(value); break;
|
case "screen": Screen = Convert.ToInt32(value); break;
|
||||||
|
case "gpu-api": GPUAPI = value; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static string _ConfFolder;
|
static string _ConfigFolder;
|
||||||
|
|
||||||
public static string ConfFolder {
|
public static string ConfigFolder {
|
||||||
get {
|
get {
|
||||||
if (_ConfFolder == null)
|
if (_ConfigFolder == null)
|
||||||
{
|
{
|
||||||
string portableFolder = Application.StartupPath + "\\portable_config\\";
|
string portableFolder = Folder.Startup + "portable_config\\";
|
||||||
string appdataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\";
|
_ConfigFolder = portableFolder;
|
||||||
string startupFolder = Application.StartupPath + "\\";
|
|
||||||
|
|
||||||
if (!Directory.Exists(appdataFolder) && !Directory.Exists(portableFolder) &&
|
if (!Directory.Exists(_ConfigFolder))
|
||||||
Sys.IsDirectoryWritable(Application.StartupPath) &&
|
_ConfigFolder = RegHelp.GetString(App.RegPath, "ConfigFolder");
|
||||||
!File.Exists(startupFolder + "mpv.conf"))
|
|
||||||
|
if (!Directory.Exists(_ConfigFolder))
|
||||||
{
|
{
|
||||||
|
string appdataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv.net\\";
|
||||||
|
string appdataFolderMpv = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\";
|
||||||
|
|
||||||
using (TaskDialog<string> td = new TaskDialog<string>())
|
using (TaskDialog<string> td = new TaskDialog<string>())
|
||||||
{
|
{
|
||||||
td.MainInstruction = "Choose a settings folder.";
|
td.MainInstruction = "Choose a settings folder.";
|
||||||
td.Content = "[MPV documentation about files on Windows.](https://mpv.io/manual/master/#files-on-windows)";
|
td.AddCommandLink(@"AppData\Roaming\mpv.net", appdataFolder, appdataFolder);
|
||||||
td.AddCommandLink("appdata", appdataFolder, appdataFolder);
|
td.AddCommandLink(@"AppData\Roaming\mpv", appdataFolderMpv, appdataFolderMpv);
|
||||||
td.AddCommandLink("portable", portableFolder, portableFolder);
|
td.AddCommandLink("<startup>\\portable_config", portableFolder, portableFolder);
|
||||||
td.AddCommandLink("startup", startupFolder, startupFolder);
|
td.AddCommandLink("Choose custom folder", "custom");
|
||||||
td.AllowCancel = false;
|
_ConfigFolder = td.Show();
|
||||||
_ConfFolder = td.Show();
|
}
|
||||||
|
|
||||||
|
if (_ConfigFolder == null)
|
||||||
|
{
|
||||||
|
_ConfigFolder = "";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_ConfigFolder == "custom")
|
||||||
|
{
|
||||||
|
using (var d = new WinForms.FolderBrowserDialog())
|
||||||
|
{
|
||||||
|
d.Description = "Choose a folder.";
|
||||||
|
|
||||||
|
if (d.ShowDialog() == WinForms.DialogResult.OK)
|
||||||
|
_ConfigFolder = d.SelectedPath + "\\";
|
||||||
|
else
|
||||||
|
_ConfigFolder = appdataFolder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Directory.Exists(portableFolder))
|
|
||||||
_ConfFolder = portableFolder;
|
|
||||||
else if (Directory.Exists(appdataFolder))
|
|
||||||
_ConfFolder = appdataFolder;
|
|
||||||
else if (File.Exists(Application.StartupPath + "\\mpv.conf"))
|
|
||||||
_ConfFolder = Application.StartupPath + "\\";
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(_ConfFolder)) _ConfFolder = appdataFolder;
|
|
||||||
if (!Directory.Exists(_ConfFolder)) Directory.CreateDirectory(_ConfFolder);
|
|
||||||
|
|
||||||
if (!File.Exists(_ConfFolder + "\\input.conf"))
|
|
||||||
File.WriteAllText(_ConfFolder + "\\input.conf", Properties.Resources.inputConf);
|
|
||||||
|
|
||||||
if (!File.Exists(_ConfFolder + "\\mpv.conf"))
|
|
||||||
File.WriteAllText(_ConfFolder + "\\mpv.conf", Properties.Resources.mpvConf);
|
|
||||||
}
|
}
|
||||||
return _ConfFolder;
|
|
||||||
|
if (Folder.Startup == _ConfigFolder)
|
||||||
|
{
|
||||||
|
Msg.ShowError("Startup folder and config folder cannot be identical, using portable_config instead.");
|
||||||
|
_ConfigFolder = portableFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(_ConfigFolder))
|
||||||
|
Directory.CreateDirectory(_ConfigFolder);
|
||||||
|
|
||||||
|
if (!_ConfigFolder.Contains("portable_config"))
|
||||||
|
RegHelp.SetObject(App.RegPath, "ConfigFolder", _ConfigFolder);
|
||||||
|
|
||||||
|
if (!File.Exists(_ConfigFolder + "input.conf"))
|
||||||
|
File.WriteAllText(_ConfigFolder + "input.conf", Properties.Resources.inputConf);
|
||||||
|
|
||||||
|
if (!File.Exists(_ConfigFolder + "mpv.conf"))
|
||||||
|
File.WriteAllText(_ConfigFolder + "mpv.conf", Properties.Resources.mpvConf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _ConfigFolder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,38 +225,54 @@ namespace mpvnet
|
|||||||
|
|
||||||
if (File.Exists(ConfPath))
|
if (File.Exists(ConfPath))
|
||||||
foreach (var i in File.ReadAllLines(ConfPath))
|
foreach (var i in File.ReadAllLines(ConfPath))
|
||||||
if (i.Contains("=") && ! i.StartsWith("#"))
|
if (i.Contains("=") && !i.TrimStart().StartsWith("#"))
|
||||||
_Conf[i.Substring(0, i.IndexOf("=")).Trim()] = i.Substring(i.IndexOf("=") + 1).Trim();
|
_Conf[i.Substring(0, i.IndexOf("=")).Trim()] = i.Substring(i.IndexOf("=") + 1).Trim();
|
||||||
|
|
||||||
foreach (var i in Conf)
|
foreach (var i in _Conf)
|
||||||
ProcessProperty(i.Key, i.Value);
|
ProcessProperty(i.Key, i.Value);
|
||||||
}
|
}
|
||||||
return _Conf;
|
return _Conf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void LoadMpvScripts()
|
||||||
|
{
|
||||||
|
if (Directory.Exists(Folder.Startup + "Scripts"))
|
||||||
|
{
|
||||||
|
string[] startupScripts = Directory.GetFiles(Folder.Startup + "Scripts");
|
||||||
|
|
||||||
|
foreach (string path in startupScripts)
|
||||||
|
if ((path.EndsWith(".lua") || path.EndsWith(".js")) && KnownScripts.Contains(Path.GetFileName(path)))
|
||||||
|
commandv("load-script", $"{path}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string[] KnownScripts { get; } = { "osc-visibility.js", "show-playlist.js", "seek-show-position.py", "repl.lua" };
|
||||||
|
|
||||||
public static void LoadScripts()
|
public static void LoadScripts()
|
||||||
{
|
{
|
||||||
string[] startupScripts = Directory.GetFiles(Application.StartupPath + "\\Scripts");
|
if (Directory.Exists(Folder.Startup + "Scripts"))
|
||||||
|
{
|
||||||
|
foreach (string scriptPath in Directory.GetFiles(Folder.Startup + "Scripts"))
|
||||||
|
{
|
||||||
|
if (KnownScripts.Contains(Path.GetFileName(scriptPath)))
|
||||||
|
{
|
||||||
|
if (scriptPath.EndsWith(".py"))
|
||||||
|
Task.Run(() => PythonScripts.Add(new PythonScript(scriptPath)));
|
||||||
|
else if (scriptPath.EndsWith(".ps1"))
|
||||||
|
Task.Run(() => PowerShellScript.Init(scriptPath));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Msg.ShowError("Failed to load script", scriptPath + "\n\nOnly scripts that ship with mpv.net are allowed in <startup>\\scripts\n\nUser scripts have to use <config folder>\\scripts\n\nNever copy or install a new mpv.net version over a old mpv.net version.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (string scriptPath in startupScripts)
|
if (Directory.Exists(ConfigFolder + "scripts"))
|
||||||
if (scriptPath.EndsWith(".lua") || scriptPath.EndsWith(".js"))
|
foreach (string scriptPath in Directory.GetFiles(ConfigFolder + "scripts"))
|
||||||
commandv("load-script", $"{scriptPath}");
|
if (scriptPath.EndsWith(".py"))
|
||||||
|
Task.Run(() => PythonScripts.Add(new PythonScript(scriptPath)));
|
||||||
foreach (string scriptPath in startupScripts)
|
else if (scriptPath.EndsWith(".ps1"))
|
||||||
if (Path.GetExtension(scriptPath) == ".py")
|
Task.Run(() => PowerShellScript.Init(scriptPath));
|
||||||
PythonScripts.Add(new PythonScript(File.ReadAllText(scriptPath)));
|
|
||||||
|
|
||||||
foreach (string scriptPath in startupScripts)
|
|
||||||
if (Path.GetExtension(scriptPath) == ".ps1")
|
|
||||||
PowerShellScript.Init(scriptPath);
|
|
||||||
|
|
||||||
if (Directory.Exists(ConfFolder + "Scripts"))
|
|
||||||
foreach (string scriptPath in Directory.GetFiles(ConfFolder + "Scripts"))
|
|
||||||
if (Path.GetExtension(scriptPath) == ".py")
|
|
||||||
PythonScripts.Add(new PythonScript(File.ReadAllText(scriptPath)));
|
|
||||||
else if (Path.GetExtension(scriptPath) == ".ps1")
|
|
||||||
PowerShellScript.Init(scriptPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void EventLoop()
|
public static void EventLoop()
|
||||||
@@ -211,13 +285,14 @@ namespace mpvnet
|
|||||||
if (WindowHandle == IntPtr.Zero)
|
if (WindowHandle == IntPtr.Zero)
|
||||||
WindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null);
|
WindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null);
|
||||||
|
|
||||||
//System.Diagnostics.Debug.WriteLine(evt.event_id.ToString());
|
// Debug.WriteLine(evt.event_id.ToString());
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch (evt.event_id)
|
switch (evt.event_id)
|
||||||
{
|
{
|
||||||
case mpv_event_id.MPV_EVENT_SHUTDOWN:
|
case mpv_event_id.MPV_EVENT_SHUTDOWN:
|
||||||
|
IsQuitNeeded = false;
|
||||||
Shutdown?.Invoke();
|
Shutdown?.Invoke();
|
||||||
WriteHistory(null);
|
WriteHistory(null);
|
||||||
ShutdownAutoResetEvent.Set();
|
ShutdownAutoResetEvent.Set();
|
||||||
@@ -244,8 +319,22 @@ namespace mpvnet
|
|||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_FILE_LOADED:
|
case mpv_event_id.MPV_EVENT_FILE_LOADED:
|
||||||
HideLogo();
|
HideLogo();
|
||||||
|
Duration = TimeSpan.FromSeconds(get_property_number("duration"));
|
||||||
|
Size vidSize = new Size(get_property_int("width"), get_property_int("height"));
|
||||||
|
if (vidSize.Width == 0 || vidSize.Height == 0)
|
||||||
|
vidSize = new Size(1, 1);
|
||||||
|
if (VideoSize != vidSize)
|
||||||
|
{
|
||||||
|
VideoSize = vidSize;
|
||||||
|
VideoSizeChanged?.Invoke();
|
||||||
|
}
|
||||||
|
VideoSizeAutoResetEvent.Set();
|
||||||
|
Task.Run(new Action(() => ReadMetaData()));
|
||||||
|
string path = mp.get_property_string("path");
|
||||||
|
if (path.Contains("://"))
|
||||||
|
path = mp.get_property_string("media-title");
|
||||||
|
WriteHistory(path);
|
||||||
FileLoaded?.Invoke();
|
FileLoaded?.Invoke();
|
||||||
WriteHistory(get_property_string("path"));
|
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_TRACKS_CHANGED:
|
case mpv_event_id.MPV_EVENT_TRACKS_CHANGED:
|
||||||
TracksChanged?.Invoke();
|
TracksChanged?.Invoke();
|
||||||
@@ -255,7 +344,7 @@ namespace mpvnet
|
|||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_IDLE:
|
case mpv_event_id.MPV_EVENT_IDLE:
|
||||||
Idle?.Invoke();
|
Idle?.Invoke();
|
||||||
if (get_property_int("playlist-count") == 0) ShowLogo();
|
ShowLogo();
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_PAUSE:
|
case mpv_event_id.MPV_EVENT_PAUSE:
|
||||||
Pause?.Invoke();
|
Pause?.Invoke();
|
||||||
@@ -293,33 +382,36 @@ namespace mpvnet
|
|||||||
var propData = (mpv_event_property)Marshal.PtrToStructure(evt.data, typeof(mpv_event_property));
|
var propData = (mpv_event_property)Marshal.PtrToStructure(evt.data, typeof(mpv_event_property));
|
||||||
|
|
||||||
if (propData.format == mpv_format.MPV_FORMAT_FLAG)
|
if (propData.format == mpv_format.MPV_FORMAT_FLAG)
|
||||||
|
{
|
||||||
|
lock (BoolPropChangeActions)
|
||||||
foreach (var i in BoolPropChangeActions)
|
foreach (var i in BoolPropChangeActions)
|
||||||
if (i.Key== propData.name)
|
if (i.Key== propData.name)
|
||||||
i.Value.Invoke(Marshal.PtrToStructure<int>(propData.data) == 1);
|
i.Value.Invoke(Marshal.PtrToStructure<int>(propData.data) == 1);
|
||||||
|
}
|
||||||
if (propData.format == mpv_format.MPV_FORMAT_STRING)
|
else if (propData.format == mpv_format.MPV_FORMAT_STRING)
|
||||||
|
{
|
||||||
|
lock (StringPropChangeActions)
|
||||||
foreach (var i in StringPropChangeActions)
|
foreach (var i in StringPropChangeActions)
|
||||||
if (i.Key == propData.name)
|
if (i.Key == propData.name)
|
||||||
i.Value.Invoke(StringFromNativeUtf8(Marshal.PtrToStructure<IntPtr>(propData.data)));
|
i.Value.Invoke(StringFromNativeUtf8(Marshal.PtrToStructure<IntPtr>(propData.data)));
|
||||||
|
}
|
||||||
if (propData.format == mpv_format.MPV_FORMAT_INT64)
|
else if(propData.format == mpv_format.MPV_FORMAT_INT64)
|
||||||
|
{
|
||||||
|
lock (IntPropChangeActions)
|
||||||
foreach (var i in IntPropChangeActions)
|
foreach (var i in IntPropChangeActions)
|
||||||
if (i.Key == propData.name)
|
if (i.Key == propData.name)
|
||||||
i.Value.Invoke(Marshal.PtrToStructure<int>(propData.data));
|
i.Value.Invoke(Marshal.PtrToStructure<int>(propData.data));
|
||||||
|
}
|
||||||
|
else if (propData.format == mpv_format.MPV_FORMAT_DOUBLE)
|
||||||
|
{
|
||||||
|
lock (DoublePropChangeActions)
|
||||||
|
foreach (var i in DoublePropChangeActions)
|
||||||
|
if (i.Key == propData.name)
|
||||||
|
i.Value.Invoke(Marshal.PtrToStructure<double>(propData.data));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_PLAYBACK_RESTART:
|
case mpv_event_id.MPV_EVENT_PLAYBACK_RESTART:
|
||||||
PlaybackRestart?.Invoke();
|
PlaybackRestart?.Invoke();
|
||||||
Size vidSize = new Size(get_property_int("dwidth"), get_property_int("dheight"));
|
|
||||||
|
|
||||||
if (VideoSize != vidSize && vidSize != Size.Empty)
|
|
||||||
{
|
|
||||||
VideoSize = vidSize;
|
|
||||||
VideoSizeChanged?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
VideoSizeAutoResetEvent.Set();
|
|
||||||
|
|
||||||
Task.Run(new Action(() => ReadMetaData()));
|
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_CHAPTER_CHANGE:
|
case mpv_event_id.MPV_EVENT_CHAPTER_CHANGE:
|
||||||
ChapterChange?.Invoke();
|
ChapterChange?.Invoke();
|
||||||
@@ -341,12 +433,9 @@ namespace mpvnet
|
|||||||
|
|
||||||
static void HideLogo()
|
static void HideLogo()
|
||||||
{
|
{
|
||||||
if (IsLogoVisible)
|
command("overlay-remove 0");
|
||||||
{
|
|
||||||
commandv("overlay-remove", "0");
|
|
||||||
IsLogoVisible = false;
|
IsLogoVisible = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static List<PythonEventObject> PythonEventObjects = new List<PythonEventObject>();
|
static List<PythonEventObject> PythonEventObjects = new List<PythonEventObject>();
|
||||||
|
|
||||||
@@ -397,20 +486,18 @@ namespace mpvnet
|
|||||||
Marshal.FreeHGlobal(mainPtr);
|
Marshal.FreeHGlobal(mainPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void command_string(string command, bool throwException = false)
|
public static void command(string command, bool throwException = false)
|
||||||
{
|
{
|
||||||
if (Handle == IntPtr.Zero) return;
|
if (Handle == IntPtr.Zero) return;
|
||||||
int err = mpv_command_string(Handle, command);
|
int err = mpv_command_string(Handle, command);
|
||||||
if (err < 0 && throwException)
|
if (err < 0 && throwException) throw new Exception($"{(mpv_error)err}\n\n" + command);
|
||||||
throw new Exception($"{(mpv_error)err}\r\n\r\n" + command);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void set_property_string(string name, string value, bool throwOnException = false)
|
public static void set_property_string(string name, string value, bool throwOnException = false)
|
||||||
{
|
{
|
||||||
byte[] bytes = GetUtf8Bytes(value);
|
byte[] bytes = GetUtf8Bytes(value);
|
||||||
int err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, ref bytes);
|
int err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, ref bytes);
|
||||||
if (err < 0 && throwOnException)
|
if (err < 0 && throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string get_property_string(string name, bool throwOnException = false)
|
public static string get_property_string(string name, bool throwOnException = false)
|
||||||
@@ -418,7 +505,13 @@ namespace mpvnet
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, out IntPtr lpBuffer);
|
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, out IntPtr lpBuffer);
|
||||||
if (err < 0 && throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
|
||||||
|
if (err < 0)
|
||||||
|
{
|
||||||
|
if (throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
string ret = StringFromNativeUtf8(lpBuffer);
|
string ret = StringFromNativeUtf8(lpBuffer);
|
||||||
mpv_free(lpBuffer);
|
mpv_free(lpBuffer);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -434,9 +527,12 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, out IntPtr lpBuffer);
|
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, out IntPtr lpBuffer);
|
||||||
|
|
||||||
if (err < 0 && throwOnException)
|
if (err < 0)
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
{
|
||||||
else
|
if (throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return lpBuffer.ToInt32();
|
return lpBuffer.ToInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,29 +541,20 @@ namespace mpvnet
|
|||||||
double val = 0;
|
double val = 0;
|
||||||
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_DOUBLE, ref val);
|
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_DOUBLE, ref val);
|
||||||
|
|
||||||
if (err < 0 && throwOnException)
|
if (err < 0)
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
{
|
||||||
else
|
if (throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
||||||
return val;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool get_property_bool(string name, bool throwOnException = false)
|
return val;
|
||||||
{
|
|
||||||
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_FLAG, out IntPtr lpBuffer);
|
|
||||||
|
|
||||||
if (err < 0 && throwOnException)
|
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
|
||||||
else
|
|
||||||
return lpBuffer.ToInt32() == 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void set_property_int(string name, int value, bool throwOnException = false)
|
public static void set_property_int(string name, int value, bool throwOnException = false)
|
||||||
{
|
{
|
||||||
Int64 val = value;
|
Int64 val = value;
|
||||||
int err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, ref val);
|
int err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, ref val);
|
||||||
|
if (err < 0 && throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
||||||
if (err < 0 && throwOnException)
|
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void observe_property_int(string name, Action<int> action)
|
public static void observe_property_int(string name, Action<int> action)
|
||||||
@@ -477,9 +564,21 @@ namespace mpvnet
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
throw new Exception($"{name}: {(mpv_error)err}");
|
||||||
else
|
else
|
||||||
|
lock (IntPropChangeActions)
|
||||||
IntPropChangeActions.Add(new KeyValuePair<string, Action<int>>(name, action));
|
IntPropChangeActions.Add(new KeyValuePair<string, Action<int>>(name, action));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void observe_property_double(string name, Action<double> action)
|
||||||
|
{
|
||||||
|
int err = mpv_observe_property(Handle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_DOUBLE);
|
||||||
|
|
||||||
|
if (err < 0)
|
||||||
|
throw new Exception($"{name}: {(mpv_error)err}");
|
||||||
|
else
|
||||||
|
lock (DoublePropChangeActions)
|
||||||
|
DoublePropChangeActions.Add(new KeyValuePair<string, Action<double>>(name, action));
|
||||||
|
}
|
||||||
|
|
||||||
public static void observe_property_bool(string name, Action<bool> action)
|
public static void observe_property_bool(string name, Action<bool> action)
|
||||||
{
|
{
|
||||||
int err = mpv_observe_property(Handle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_FLAG);
|
int err = mpv_observe_property(Handle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_FLAG);
|
||||||
@@ -487,6 +586,7 @@ namespace mpvnet
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
throw new Exception($"{name}: {(mpv_error)err}");
|
||||||
else
|
else
|
||||||
|
lock (BoolPropChangeActions)
|
||||||
BoolPropChangeActions.Add(new KeyValuePair<string, Action<bool>>(name, action));
|
BoolPropChangeActions.Add(new KeyValuePair<string, Action<bool>>(name, action));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,41 +597,48 @@ namespace mpvnet
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
throw new Exception($"{name}: {(mpv_error)err}");
|
||||||
else
|
else
|
||||||
|
lock (StringPropChangeActions)
|
||||||
StringPropChangeActions.Add(new KeyValuePair<string, Action<string>>(name, action));
|
StringPropChangeActions.Add(new KeyValuePair<string, Action<string>>(name, action));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void ProcessCommandLine()
|
public static void ProcessCommandLine(bool preInit)
|
||||||
{
|
{
|
||||||
var args = Environment.GetCommandLineArgs().Skip(1);
|
var args = Environment.GetCommandLineArgs().Skip(1);
|
||||||
List<string> files = new List<string>();
|
|
||||||
|
//Msg.Show(string.Join("\n", args));
|
||||||
|
|
||||||
|
string[] preInitProperties = { "input-terminal", "terminal", "input-file", "config", "config-dir", "input-conf", "load-scripts", "scripts", "player-operation-mode" };
|
||||||
|
|
||||||
foreach (string i in args)
|
foreach (string i in args)
|
||||||
{
|
{
|
||||||
if (!i.StartsWith("--") && (i == "-" || i.Contains("://") || File.Exists(i)))
|
string arg = i;
|
||||||
{
|
|
||||||
files.Add(i);
|
|
||||||
if (i.Contains("://")) RegHelp.SetObject(App.RegPath, "LastURL", i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Load(files.ToArray(), App.ProcessInstance != "queue", Control.ModifierKeys.HasFlag(Keys.Control));
|
if (arg.StartsWith("--"))
|
||||||
|
|
||||||
if (files.Count == 0) VideoSizeAutoResetEvent.Set();
|
|
||||||
|
|
||||||
foreach (string i in args)
|
|
||||||
{
|
|
||||||
if (i.StartsWith("--"))
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (i.Contains("="))
|
if (!arg.Contains("=")) arg += "=yes";
|
||||||
|
|
||||||
|
string left = arg.Substring(2, arg.IndexOf("=") - 2);
|
||||||
|
string right = arg.Substring(left.Length + 3);
|
||||||
|
|
||||||
|
if (left == "script") left = "scripts";
|
||||||
|
|
||||||
|
if (preInit && preInitProperties.Contains(left))
|
||||||
{
|
{
|
||||||
string left = i.Substring(2, i.IndexOf("=") - 2);
|
mp.ProcessProperty(left, right);
|
||||||
string right = i.Substring(left.Length + 3);
|
if (!App.ProcessProperty(left, right))
|
||||||
set_property_string(left, right, true);
|
set_property_string(left, right, true);
|
||||||
}
|
}
|
||||||
else
|
else if (!preInit && !preInitProperties.Contains(left))
|
||||||
set_property_string(i.Substring(2), "yes", true);
|
{
|
||||||
|
if (!PrintCommandLineArgument(arg))
|
||||||
|
{
|
||||||
|
mp.ProcessProperty(left, right);
|
||||||
|
if (!App.ProcessProperty(left, right))
|
||||||
|
set_property_string(left, right, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -539,22 +646,60 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!preInit)
|
||||||
|
{
|
||||||
|
List<string> files = new List<string>();
|
||||||
|
|
||||||
|
foreach (string i in args)
|
||||||
|
{
|
||||||
|
if (!i.StartsWith("--") && (i == "-" || i.Contains("://") ||
|
||||||
|
i.Contains(":\\") || i.StartsWith("\\\\") || File.Exists(i)))
|
||||||
|
{
|
||||||
|
files.Add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Load(files.ToArray(), !App.Queue, Control.ModifierKeys.HasFlag(Keys.Control) || App.Queue);
|
||||||
|
|
||||||
|
if (files.Count == 0 || files[0].Contains("://"))
|
||||||
|
{
|
||||||
|
VideoSizeChanged?.Invoke();
|
||||||
|
VideoSizeAutoResetEvent.Set();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool PrintCommandLineArgument(string argument)
|
||||||
|
{
|
||||||
|
switch (argument)
|
||||||
|
{
|
||||||
|
case "--list-properties=yes":
|
||||||
|
var list = get_property_string("property-list").Split(',').ToList();
|
||||||
|
list.Sort();
|
||||||
|
Console.WriteLine(string.Join("\r\n", list.ToArray()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DateTime LastLoad;
|
public static DateTime LastLoad;
|
||||||
|
|
||||||
public static void Load(string[] files, bool loadFolder, bool append)
|
public static void Load(string[] files, bool loadFolder, bool append)
|
||||||
{
|
{
|
||||||
if (files is null || files.Length == 0) return;
|
if (files is null || files.Length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
HideLogo();
|
HideLogo();
|
||||||
|
|
||||||
if ((DateTime.Now - LastLoad).TotalMilliseconds < 500)
|
if ((DateTime.Now - LastLoad).TotalMilliseconds < 1000)
|
||||||
append = true;
|
append = true;
|
||||||
|
|
||||||
LastLoad = DateTime.Now;
|
LastLoad = DateTime.Now;
|
||||||
|
|
||||||
for (int i = 0; i < files.Length; i++)
|
for (int i = 0; i < files.Length; i++)
|
||||||
if (App.SubtitleTypes.Contains(Path.GetExtension(files[i]).TrimStart('.').ToLower()))
|
if (App.SubtitleTypes.Contains(files[i].ShortExt()))
|
||||||
commandv("sub-add", files[i]);
|
commandv("sub-add", files[i]);
|
||||||
else
|
else
|
||||||
if (i == 0 && !append)
|
if (i == 0 && !append)
|
||||||
@@ -564,27 +709,41 @@ namespace mpvnet
|
|||||||
|
|
||||||
if (string.IsNullOrEmpty(get_property_string("path")))
|
if (string.IsNullOrEmpty(get_property_string("path")))
|
||||||
set_property_int("playlist-pos", 0);
|
set_property_int("playlist-pos", 0);
|
||||||
if (loadFolder && !append) Task.Run(() => LoadFolder()); // user reported race condition
|
|
||||||
|
if (loadFolder && !append)
|
||||||
|
Task.Run(() => LoadFolder());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LoadFolder()
|
public static void LoadFolder()
|
||||||
{
|
{
|
||||||
Thread.Sleep(200); // user reported race condition
|
if (!App.AutoLoadFolder || Control.ModifierKeys.HasFlag(Keys.Shift))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Thread.Sleep(1000);
|
||||||
string path = get_property_string("path");
|
string path = get_property_string("path");
|
||||||
if (!File.Exists(path) || get_property_int("playlist-count") != 1) return;
|
|
||||||
|
if (!File.Exists(path) || get_property_int("playlist-count") != 1)
|
||||||
|
return;
|
||||||
|
|
||||||
List<string> files = Directory.GetFiles(Path.GetDirectoryName(path)).ToList();
|
List<string> files = Directory.GetFiles(Path.GetDirectoryName(path)).ToList();
|
||||||
files = files.Where((file) =>
|
|
||||||
App.VideoTypes.Contains(Path.GetExtension(file).TrimStart('.').ToLower()) ||
|
files = files.Where(file =>
|
||||||
App.AudioTypes.Contains(Path.GetExtension(file).TrimStart('.').ToLower())).ToList();
|
App.VideoTypes.Contains(file.ShortExt()) ||
|
||||||
|
App.AudioTypes.Contains(file.ShortExt()) ||
|
||||||
|
App.ImageTypes.Contains(file.ShortExt())).ToList();
|
||||||
|
|
||||||
files.Sort(new StringLogicalComparer());
|
files.Sort(new StringLogicalComparer());
|
||||||
int index = files.IndexOf(path);
|
int index = files.IndexOf(path);
|
||||||
files.Remove(path);
|
files.Remove(path);
|
||||||
|
|
||||||
foreach (string i in files)
|
foreach (string i in files)
|
||||||
commandv("loadfile", i, "append");
|
commandv("loadfile", i, "append");
|
||||||
if (index > 0) commandv("playlist-move", "0", (index + 1).ToString());
|
|
||||||
|
if (index > 0)
|
||||||
|
commandv("playlist-move", "0", (index + 1).ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
static IntPtr AllocateUtf8IntPtrArrayWithSentinel(string[] arr, out IntPtr[] byteArrayPointers)
|
public static IntPtr AllocateUtf8IntPtrArrayWithSentinel(string[] arr, out IntPtr[] byteArrayPointers)
|
||||||
{
|
{
|
||||||
int numberOfStrings = arr.Length + 1; // add extra element for extra null pointer last (sentinel)
|
int numberOfStrings = arr.Length + 1; // add extra element for extra null pointer last (sentinel)
|
||||||
byteArrayPointers = new IntPtr[numberOfStrings];
|
byteArrayPointers = new IntPtr[numberOfStrings];
|
||||||
@@ -602,7 +761,7 @@ namespace mpvnet
|
|||||||
return rootPointer;
|
return rootPointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static string[] NativeUtf8StrArray2ManagedStrArray(IntPtr unmanagedStringArray, int StringCount)
|
public static string[] NativeUtf8StrArray2ManagedStrArray(IntPtr unmanagedStringArray, int StringCount)
|
||||||
{
|
{
|
||||||
IntPtr[] intPtrArray = new IntPtr[StringCount];
|
IntPtr[] intPtrArray = new IntPtr[StringCount];
|
||||||
string[] stringArray = new string[StringCount];
|
string[] stringArray = new string[StringCount];
|
||||||
@@ -614,7 +773,7 @@ namespace mpvnet
|
|||||||
return stringArray;
|
return stringArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
static string StringFromNativeUtf8(IntPtr nativeUtf8)
|
public static string StringFromNativeUtf8(IntPtr nativeUtf8)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
while (Marshal.ReadByte(nativeUtf8, len) != 0) ++len;
|
while (Marshal.ReadByte(nativeUtf8, len) != 0) ++len;
|
||||||
@@ -623,25 +782,23 @@ namespace mpvnet
|
|||||||
return Encoding.UTF8.GetString(buffer);
|
return Encoding.UTF8.GetString(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte[] GetUtf8Bytes(string s) => Encoding.UTF8.GetBytes(s + "\0");
|
public static byte[] GetUtf8Bytes(string s) => Encoding.UTF8.GetBytes(s + "\0");
|
||||||
|
|
||||||
static string LastHistoryPath;
|
static string LastHistoryPath;
|
||||||
static DateTime LastHistoryStartDateTime;
|
static DateTime LastHistoryStartDateTime;
|
||||||
|
|
||||||
static void WriteHistory(string filePath)
|
static void WriteHistory(string path)
|
||||||
{
|
{
|
||||||
|
if (!File.Exists(ConfigFolder + "history.txt"))
|
||||||
|
return;
|
||||||
|
|
||||||
int totalMinutes = Convert.ToInt32((DateTime.Now - LastHistoryStartDateTime).TotalMinutes);
|
int totalMinutes = Convert.ToInt32((DateTime.Now - LastHistoryStartDateTime).TotalMinutes);
|
||||||
|
|
||||||
if (File.Exists(LastHistoryPath) && totalMinutes > 1)
|
if (PathHelp.GetBaseName(LastHistoryPath) != "" && totalMinutes > 1)
|
||||||
{
|
File.AppendAllText(ConfigFolder + "history.txt", DateTime.Now.ToString().Substring(0, 16) +
|
||||||
string historyFilepath = ConfFolder + "history.txt";
|
" " + totalMinutes.ToString().PadLeft(3) + " " + PathHelp.GetBaseName(LastHistoryPath) + "\r\n");
|
||||||
|
|
||||||
File.AppendAllText(historyFilepath, DateTime.Now.ToString().Substring(0, 16) +
|
LastHistoryPath = path;
|
||||||
" " + totalMinutes.ToString().PadLeft(3) + " " +
|
|
||||||
Path.GetFileNameWithoutExtension(LastHistoryPath) + "\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
LastHistoryPath = filePath;
|
|
||||||
LastHistoryStartDateTime = DateTime.Now;
|
LastHistoryStartDateTime = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,8 +806,8 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
if (MainForm.Instance is null) return;
|
if (MainForm.Instance is null) return;
|
||||||
Rectangle cr = MainForm.Instance.ClientRectangle;
|
Rectangle cr = MainForm.Instance.ClientRectangle;
|
||||||
if (cr.Width == 0 || cr.Height == 0) return;
|
|
||||||
int len = cr.Height / 5;
|
int len = cr.Height / 5;
|
||||||
|
if (len == 0) return;
|
||||||
|
|
||||||
using (Bitmap b = new Bitmap(len, len))
|
using (Bitmap b = new Bitmap(len, len))
|
||||||
{
|
{
|
||||||
@@ -675,8 +832,11 @@ namespace mpvnet
|
|||||||
lock (MediaTracks)
|
lock (MediaTracks)
|
||||||
{
|
{
|
||||||
MediaTracks.Clear();
|
MediaTracks.Clear();
|
||||||
|
string path = get_property_string("path");
|
||||||
|
|
||||||
using (MediaInfo mi = new MediaInfo(get_property_string("path")))
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
using (MediaInfo mi = new MediaInfo(path))
|
||||||
{
|
{
|
||||||
int count = mi.GetCount(MediaInfoStreamKind.Video);
|
int count = mi.GetCount(MediaInfoStreamKind.Video);
|
||||||
|
|
||||||
@@ -752,6 +912,7 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lock (Chapters)
|
lock (Chapters)
|
||||||
{
|
{
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 25 KiB |
@@ -39,6 +39,7 @@ Source: "{#MyAppSourceDir}\*"; DestDir: "{app}"; Flags: ignoreversion recursesub
|
|||||||
[Run]
|
[Run]
|
||||||
Filename: "{app}\{#MyAppExeName}"; Description: "Associate video file extensions?"; Flags: postinstall unchecked runascurrentuser runhidden nowait; Parameters: "--reg-file-assoc video"
|
Filename: "{app}\{#MyAppExeName}"; Description: "Associate video file extensions?"; Flags: postinstall unchecked runascurrentuser runhidden nowait; Parameters: "--reg-file-assoc video"
|
||||||
Filename: "{app}\{#MyAppExeName}"; Description: "Associate audio file extensions?"; Flags: postinstall unchecked runascurrentuser runhidden nowait; Parameters: "--reg-file-assoc audio"
|
Filename: "{app}\{#MyAppExeName}"; Description: "Associate audio file extensions?"; Flags: postinstall unchecked runascurrentuser runhidden nowait; Parameters: "--reg-file-assoc audio"
|
||||||
|
Filename: "{app}\{#MyAppExeName}"; Description: "Associate image file extensions?"; Flags: postinstall unchecked runascurrentuser runhidden nowait; Parameters: "--reg-file-assoc image"
|
||||||
|
|
||||||
[UninstallRun]
|
[UninstallRun]
|
||||||
Filename: "{app}\{#MyAppExeName}"; Flags: runascurrentuser runhidden; Parameters: "--reg-file-assoc unreg"
|
Filename: "{app}\{#MyAppExeName}"; Flags: runascurrentuser runhidden; Parameters: "--reg-file-assoc unreg"
|
||||||
48
setup.ps1
@@ -1,48 +0,0 @@
|
|||||||
# exit the script if the exit code is greater than 0
|
|
||||||
function CheckExitCode {
|
|
||||||
if ($LastExitCode -gt 0) {
|
|
||||||
Write-Host "`nExit code $LastExitCode was returned.`n" -ForegroundColor Red
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# exit the script if the file don't exist
|
|
||||||
function CheckFileExist($path) {
|
|
||||||
if (![IO.File]::Exists($path)) {
|
|
||||||
Write-Host "`nFile is missing:`n`n$path`n" -ForegroundColor Red
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$msbuild = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe"
|
|
||||||
$innoSetup = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe"
|
|
||||||
$sevenZip = "C:\Program Files\7-Zip\7z.exe"
|
|
||||||
|
|
||||||
# exit the script if one of the executables don't exist
|
|
||||||
CheckFileExist($msbuild); CheckFileExist($innoSetup); CheckFileExist($sevenZip);
|
|
||||||
|
|
||||||
# build the projects using msbuild
|
|
||||||
& $msbuild mpv.net.sln /p:Configuration=Debug /p:Platform=x64; CheckExitCode
|
|
||||||
& $msbuild mpv.net.sln /p:Configuration=Debug /p:Platform=x86; CheckExitCode
|
|
||||||
|
|
||||||
# build the setups using inno setup
|
|
||||||
& $innoSetup /Darch="x64" setup.iss; CheckExitCode
|
|
||||||
& $innoSetup /Darch="x86" setup.iss; CheckExitCode
|
|
||||||
|
|
||||||
# create the x64 portable archives using 7zip
|
|
||||||
$scriptDir = Split-Path -Path $PSCommandPath -Parent
|
|
||||||
$desktopDir = [Environment]::GetFolderPath("Desktop")
|
|
||||||
$exePath = $scriptDir + "\mpv.net\bin\x64\mpvnet.exe"
|
|
||||||
$version = [Diagnostics.FileVersionInfo]::GetVersionInfo($exePath).FileVersion
|
|
||||||
$targetDir = $desktopDir + "\mpv.net-portable-x64-" + $version
|
|
||||||
Copy-Item $scriptDir\mpv.net\bin\x64 $targetDir -Recurse -Exclude System.Management.Automation.xml -Force
|
|
||||||
& $sevenZip a -t7z -mx9 "$targetDir.7z" -r "$targetDir\*"; CheckExitCode
|
|
||||||
& $sevenZip a -tzip -mx9 "$targetDir.zip" -r "$targetDir\*"; CheckExitCode
|
|
||||||
|
|
||||||
# create the x86 portable archives using 7zip
|
|
||||||
$exePath = $scriptDir + "\mpv.net\bin\x86\mpvnet.exe"
|
|
||||||
$version = [Diagnostics.FileVersionInfo]::GetVersionInfo($exePath).FileVersion
|
|
||||||
$targetDir = $desktopDir + "\mpv.net-portable-x86-" + $version
|
|
||||||
Copy-Item $scriptDir\mpv.net\bin\x86 $targetDir -Recurse -Exclude System.Management.Automation.xml -Force
|
|
||||||
& $sevenZip a -t7z -mx9 "$targetDir.7z" -r "$targetDir\*"; CheckExitCode
|
|
||||||
& $sevenZip a -tzip -mx9 "$targetDir.zip" -r "$targetDir\*"; CheckExitCode
|
|
||||||