Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5c9df31e4 | ||
|
|
c0a8e895f7 | ||
|
|
064ae44ecf | ||
|
|
005ba6e5ea | ||
|
|
9f6aba6cbd | ||
|
|
87e3d9ca3e | ||
|
|
29a0eae3d5 | ||
|
|
01b2492cde | ||
|
|
d2b1ca0c69 | ||
|
|
91b429e6b0 | ||
|
|
fa05e95892 | ||
|
|
701a58a4bf | ||
|
|
387c3f7896 | ||
|
|
eeb0189577 | ||
|
|
de4c2d6d70 | ||
|
|
63ee598ebd | ||
|
|
1bf8e568c5 | ||
|
|
f8f58dba5e | ||
|
|
ebb8ad351a | ||
|
|
0202c34c6f | ||
|
|
c3f2b22ff5 | ||
|
|
c1a03c3e4b | ||
|
|
e041908f04 | ||
|
|
270559c3f7 | ||
|
|
0dfd19eb45 | ||
|
|
9cdba6d2f2 | ||
|
|
50bf09ff8d | ||
|
|
c54fa708f8 | ||
|
|
7698e873ca | ||
|
|
89b8de2c40 | ||
|
|
259d2d882a | ||
|
|
b7fbef5a88 | ||
|
|
0ca9ac93f1 | ||
|
|
f7b3900a0a | ||
|
|
c98036dc42 | ||
|
|
a9e7ae4b97 | ||
|
|
30fb744114 | ||
|
|
d465516a6a | ||
|
|
0b951875e6 | ||
|
|
5ed65733a0 | ||
|
|
caac45a871 | ||
|
|
f4f69816a7 | ||
|
|
1dddf129df | ||
|
|
ca9690c3b3 | ||
|
|
3b0b098bda | ||
|
|
c72080e92c | ||
|
|
237a3cf132 | ||
|
|
562f149fff | ||
|
|
dc85372c36 | ||
|
|
2595465ec7 | ||
|
|
1db733ae13 | ||
|
|
ba3bc48297 | ||
|
|
5e16c47100 | ||
|
|
a13c6648a3 | ||
|
|
5dc244d6f6 | ||
|
|
da9bc4199b | ||
|
|
1868957388 | ||
|
|
0139a1ef70 | ||
|
|
0989b7ef95 | ||
|
|
16924e5a3b | ||
|
|
502e1a9651 | ||
|
|
36a7bbcfab | ||
|
|
8fda90e09a | ||
|
|
269457dbde | ||
|
|
c93647841e | ||
|
|
0f78ea38ac | ||
|
|
7eb60f3e4c | ||
|
|
2636da446e | ||
|
|
c7fab24044 | ||
|
|
2ce1f3d9c1 | ||
|
|
d2f9108c22 | ||
|
|
3a2b9ee542 | ||
|
|
5c93bc00f7 | ||
|
|
19c09da4e1 | ||
|
|
95c9c115b2 | ||
|
|
2512c02bff | ||
|
|
351fae8344 | ||
|
|
30b562a1e1 | ||
|
|
8a9a017875 | ||
|
|
fa0b0f496f | ||
|
|
83b5d9b65c | ||
|
|
b199d33f7a | ||
|
|
a7b6f79ee1 | ||
|
|
fc3c5ee3a7 | ||
|
|
ed71cb704f | ||
|
|
a9474b1c22 | ||
|
|
be3b31f7e6 | ||
|
|
b2884e2037 | ||
|
|
3910776b54 | ||
|
|
b37272db8b | ||
|
|
08a23430c7 | ||
|
|
ba41b8026f | ||
|
|
4aeb00afb5 | ||
|
|
6e6015b185 | ||
|
|
68240ac49d | ||
|
|
bafc481117 | ||
|
|
9198d610ad | ||
|
|
ad4199aff0 | ||
|
|
3164e2322c |
71
Changelog.md
Normal file
@@ -0,0 +1,71 @@
|
||||
### 4.3.1
|
||||
|
||||
- there was a old bug setting the screen property
|
||||
|
||||
### 4.3
|
||||
|
||||
- there was new bug in file association feature
|
||||
|
||||
### 4.2
|
||||
|
||||
- the help and layout in the config editor was improved
|
||||
- clipboard monitoring for URLs can be disabled in the settings
|
||||
- the context menu has a new feature: Open > Add files to playlist,
|
||||
it appends files to the playlist [(Default binding)](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L33)
|
||||
- a setting was added to force using a single mpv.net process instance
|
||||
|
||||
### 4.1
|
||||
|
||||
- drag & drop support for subtitles was added
|
||||
- libmpv was updated
|
||||
- command line support for stdin and URLs was added
|
||||
- there was a crash happening when the player is
|
||||
minimized in the taskbar
|
||||
|
||||
### 4.0
|
||||
|
||||
- on the start screen the mpv.NET icon is shown instead of the mpv icon,
|
||||
feedback and contributions regarding the icon are welcome! The paint.net
|
||||
pdn and png source is located [here](https://github.com/stax76/mpv.net/tree/master/img)
|
||||
- everytime only one file is opened the complete folder is loaded in the playlist
|
||||
- the info command (i key) shows the audio format
|
||||
- new options osd-font-size, sub-font, sub-font-size
|
||||
- new color options with dedicated GUI support: sub-color, sub-border-color, sub-back-color
|
||||
- the config editor no longer shows the command line switches
|
||||
- the github start page was greatly improved
|
||||
- the setup.ps1 PowerShell script was greatly improved in regard of error handling and readability
|
||||
- a [manual to mpv.net](Manual.md) was created
|
||||
|
||||
### 3.7
|
||||
|
||||
- new icon design, probably better then before but still too simple
|
||||
- the radio buttons in the config editor have now a Windows 10 like design,
|
||||
they are larger and use the Windows theme color
|
||||
|
||||
### 3.6.1
|
||||
|
||||
- there was a bug causing an exception if both the input editor and config editor
|
||||
is opened, as soon as one is opened, the other can't be opened
|
||||
|
||||
### 3.6
|
||||
|
||||
- playing files from rar archives caused an exception
|
||||
- there was a bug that caused underscores beeing removed from input like MBTN_LEFT_DBL
|
||||
- the search clear button in the input editor had a render issue in dark mode
|
||||
- new search feature added to search and play media files, requires
|
||||
[Everything](https://www.voidtools.com) to be installed. [Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L29)
|
||||
|
||||
### 3.5
|
||||
|
||||
- when the main windows gets activated and the clipboard content starts with http
|
||||
mpv.net will ask to play the URL, previously this was restricted to YouTube URLs
|
||||
- Python script errors show line and column whenever it is supported by IronPython
|
||||
- if conf files exist in the startup directory mpv.net will use the startup
|
||||
directory as config directory instead of creating default conf files in appdata
|
||||
- renamed commands are handled now by migration code instead of being broken
|
||||
|
||||
### 3.4
|
||||
|
||||
- new feature added to manage file associations from within the app. It can be found in the menu at: Tools > Manage... [Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L149)
|
||||
- new zip download option added
|
||||
- new x86 download option added
|
||||
831
Manual.md
Normal file
@@ -0,0 +1,831 @@
|
||||
# mpv.net manual
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [About mpv.net](#about-mpvnet)
|
||||
+ [Target Audience](#target-audience)
|
||||
* [Requirements](#requirements)
|
||||
* [Installation](#installation)
|
||||
+ [File Associations](#file-associations)
|
||||
* [Context Menu](#context-menu)
|
||||
+ [Open > Open Files](#open--open-files)
|
||||
+ [Open > Open URL](#open--open-url)
|
||||
+ [Open > Show media search](#open--show-media-search)
|
||||
+ [Open > Load external audio files](#open--load-external-audio-files)
|
||||
+ [Open > Load external subtitle files](#open--load-external-subtitle-files)
|
||||
+ [Play/Pause](#play-pause)
|
||||
+ [Stop](#stop)
|
||||
+ [Toggle Fullscreen](#toggle-fullscreen)
|
||||
+ [Navigate > Previous File](#navigate--previous-file)
|
||||
+ [Navigate > Next File](#navigate--next-file)
|
||||
+ [Navigate > Next Chapter](#navigate--next-chapter)
|
||||
+ [Navigate > Previous Chapter](#navigate--previous-chapter)
|
||||
+ [Navigate > Jump Next Frame](#navigate--jump-next-frame)
|
||||
+ [Navigate > Jump Previous Frame](#navigate--jump-previous-frame)
|
||||
+ [Navigate > Jump](#navigate--jump)
|
||||
+ [Pan & Scan > Increase Size](#pan--scan--increase-size)
|
||||
+ [Pan & Scan > Decrease Size](#pan--scan--decrease-size)
|
||||
+ [Pan & Scan > Move Left](#pan--scan--move-left)
|
||||
+ [Pan & Scan > Move Right](#pan--scan--move-right)
|
||||
+ [Pan & Scan > Move Up](#pan--scan--move-up)
|
||||
+ [Pan & Scan > Move Down](#pan--scan--move-down)
|
||||
+ [Pan & Scan > Decrease Height](#pan--scan--decrease-height)
|
||||
+ [Pan & Scan > Increase Height](#pan--scan--increase-height)
|
||||
+ [Pan & Scan > Reset](#pan--scan--reset)
|
||||
+ [Video > Decrease Contrast](#video--decrease-contrast)
|
||||
+ [Video > Increase Contrast](#video--increase-contrast)
|
||||
+ [Video > Decrease Brightness](#video--decrease-brightness)
|
||||
+ [Video > Increase Brightness](#video--increase-brightness)
|
||||
+ [Video > Decrease Gamma](#video--decrease-gamma)
|
||||
+ [Video > Increase Gamma](#video--increase-gamma)
|
||||
+ [Video > Decrease Saturation](#video--decrease-saturation)
|
||||
+ [Video > Increase Saturation](#video--increase-saturation)
|
||||
+ [Video > Take Screenshot](#video--take-screenshot)
|
||||
+ [Video > Toggle Deinterlace](#video--toggle-deinterlace)
|
||||
+ [Video > Cycle Aspect Ratio](#video--cycle-aspect-ratio)
|
||||
+ [Audio > Cycle/Next](#audio--cycle-next)
|
||||
+ [Audio > Delay +0.1](#audio--delay--01)
|
||||
+ [Audio > Delay -0.1](#audio--delay--01)
|
||||
+ [Subtitle > Cycle/Next](#subtitle--cycle-next)
|
||||
+ [Subtitle > Toggle Visibility](#subtitle--toggle-visibility)
|
||||
+ [Subtitle > Delay -0.1](#subtitle--delay--01)
|
||||
+ [Subtitle > Delay 0.1](#subtitle--delay-01)
|
||||
+ [Subtitle > Move Up](#subtitle--move-up)
|
||||
+ [Subtitle > Move Down](#subtitle--move-down)
|
||||
+ [Subtitle > Decrease Subtitle Font Size](#subtitle--decrease-subtitle-font-size)
|
||||
+ [Subtitle > Increase Subtitle Font Size](#subtitle--increase-subtitle-font-size)
|
||||
+ [Volume > Up](#volume--up)
|
||||
+ [Volume > Down](#volume--down)
|
||||
+ [Volume > Mute](#volume--mute)
|
||||
+ [Speed > -10%](#speed---10-)
|
||||
+ [Speed > 10%](#speed--10-)
|
||||
+ [Speed > Half](#speed--half)
|
||||
+ [Speed > Double](#speed--double)
|
||||
+ [Speed > Reset](#speed--reset)
|
||||
+ [Extensions > Rating > 0stars](#extensions--rating--0stars)
|
||||
+ [View > On Top > Enable](#view--on-top--enable)
|
||||
+ [View > On Top > Disable](#view--on-top--disable)
|
||||
+ [View > File Info](#view--file-info)
|
||||
+ [View > Show Statistics](#view--show-statistics)
|
||||
+ [View > Toggle Statistics](#view--toggle-statistics)
|
||||
+ [View > Toggle OSC Visibility](#view--toggle-osc-visibility)
|
||||
+ [View > Show Playlist](#view--show-playlist)
|
||||
+ [View > Show Audio/Video/Subtitle List](#view--show-audio-video-subtitle-list)
|
||||
+ [Settings > Show Config Editor](#settings--show-config-editor)
|
||||
+ [Settings > Show Input Editor](#settings--show-input-editor)
|
||||
+ [Settings > Open Config Folder](#settings--open-config-folder)
|
||||
+ [Tools > Command Palette](#tools--command-palette)
|
||||
+ [Tools > Show History](#tools--show-history)
|
||||
+ [Tools > Set/clear A-B loop points](#tools--set-clear-a-b-loop-points)
|
||||
+ [Tools > Toggle infinite file looping](#tools--toggle-infinite-file-looping)
|
||||
+ [Tools > Cycle Hardware Decoding](#tools--cycle-hardware-decoding)
|
||||
+ [Tools > Execute mpv command](#tools--execute-mpv-command)
|
||||
+ [Tools > Manage File Associations](#tools--manage-file-associations)
|
||||
+ [Help > Show mpv manual](#help--show-mpv-manual)
|
||||
+ [Help > Show mpv default keys](#help--show-mpv-default-keys)
|
||||
+ [Help > Show mpv.net default keys](#help--show-mpvnet-default-keys)
|
||||
+ [Help > Show mpv.net manual](#help--show-mpvnet-manual)
|
||||
+ [Help > About mpv.net](#help--about-mpvnet)
|
||||
+ [Exit](#exit)
|
||||
+ [Exit Watch Later](#exit-watch-later)
|
||||
* [Command Line Interface](#command-line-interface)
|
||||
* [Settings](#settings)
|
||||
|
||||
## About mpv.net
|
||||
|
||||
mpv.net is a media player for Windows. Similar like VLC mpv.net is not based on DirectShow like MPC, mpv.net is based on libmpv which in return is based on ffmpeg.
|
||||
|
||||
libmpv provides the majority of the features of the mpv media player, a fork of mplayer. mpv focuses on the usage of the command line interface, mpv.net retains the ability to be used from the command line and adds a simple and easy to use GUI on top of it.
|
||||
|
||||
mpv.net is meant to be a small single person project, it's designed to be mpv compatible, can use the same settings as mpv and offers almost all mpv features because they are all contained in libmpv, this means the official [mpv manual](https://mpv.io/manual/master/) fully applies to mpv.net.
|
||||
|
||||
### Target Audience
|
||||
|
||||
The target audience of mpv.net are Windows programmers and users that need something more advanced than common media players.
|
||||
|
||||
Furthermore mpv.net is well suited for Windows users who are interested to learn about the Linux operating system and portable apps, even though mpv.net self is not portable.
|
||||
|
||||
## 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.
|
||||
|
||||
For optimal results a modern graphics card is recommended.
|
||||
|
||||
## Installation
|
||||
|
||||
mpv.net is available as setup and as portable download in the 7zip and zip archive format, to unpack the portable download 7zip can be used, it is available at www.7-zip.org.
|
||||
|
||||
If you are new to mpv.net the portable download is recommended, for regular mpv.net users the setup is typically more easy to use.
|
||||
|
||||
The x64 editions require more memory and have the advantage of decoders being typically first and better optimized for x64.
|
||||
|
||||
x86 should though still be well supported and work.
|
||||
|
||||
### File Associations
|
||||
|
||||
File Associations can be created using the setup or from within the apps context menu under 'Tools > Manage File Associations'.
|
||||
|
||||
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.
|
||||
|
||||
## 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.
|
||||
|
||||
### Open > Open Files
|
||||
|
||||
The Open Files menu entry is one way to open files in mpv.net, it supports multi selection.
|
||||
|
||||
Another way to open files is the command line, it is used by the Windows File Explorer if file associations exist.
|
||||
|
||||
A third way is to drag and drop files on the main window.
|
||||
|
||||
### Open > Open URL
|
||||
|
||||
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.
|
||||
|
||||
### Open > Show media search
|
||||
|
||||
mpv.net supports system wide media searches using the Everything indexing service installed by the popular file search tool Everything (www.voidtools.com).
|
||||
|
||||
### Open > Load external audio files
|
||||
|
||||
Allows to load an external audio file. It's also possible to auto detect external audio files based on the file name, the option for this can be found in the settings under 'Settings > Show Config Editor > Audio > audio-file-auto'.
|
||||
|
||||
### Open > Load external subtitle files
|
||||
|
||||
Allows to load an external subtitle file. It's also possible to auto detect external subtitle files based on the file name, the option for this can be found in the settings under 'Settings > Show Config Editor > Subtitles > sub-auto'.
|
||||
|
||||
### Play/Pause
|
||||
|
||||
Play/Pause using the command:
|
||||
|
||||
`cycle pause`
|
||||
|
||||
[cycle command](https://mpv.io/manual/master/#command-interface-cycle-%3Cproperty%3E-[up|down])
|
||||
|
||||
[pause property](https://mpv.io/manual/master/#options-pause)
|
||||
|
||||
### Stop
|
||||
|
||||
Stops the player and unloads the playlist using the command:
|
||||
|
||||
`stop`
|
||||
|
||||
[stop command](https://mpv.io/manual/master/#command-interface-stop)
|
||||
|
||||
### Toggle Fullscreen
|
||||
|
||||
Toggles fullscreen using the command:
|
||||
|
||||
`cycle fullscreen`
|
||||
|
||||
[cycle command](https://mpv.io/manual/master/#command-interface-cycle-%3Cproperty%3E-[up|down])
|
||||
|
||||
[fullscreen property](https://mpv.io/manual/master/#options-fs)
|
||||
|
||||
### Navigate > Previous File
|
||||
|
||||
Navigates to the previous file in the playlist using the command:
|
||||
|
||||
`playlist-prev`
|
||||
|
||||
[playlist-prev command](https://mpv.io/manual/master/#command-interface-playlist-prev)
|
||||
|
||||
### Navigate > Next File
|
||||
|
||||
Navigates to the next file in the playlist using the command:
|
||||
|
||||
`playlist-next`
|
||||
|
||||
[playlist-next command](https://mpv.io/manual/master/#command-interface-playlist-next)
|
||||
|
||||
### Navigate > Next Chapter
|
||||
|
||||
Navigates to the next chapter using the command:
|
||||
|
||||
`add chapter 1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[chapter property](https://mpv.io/manual/master/#command-interface-chapter)
|
||||
|
||||
### Navigate > Previous Chapter
|
||||
|
||||
Navigates to the previous chapter using the command:
|
||||
|
||||
`add chapter -1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[chapter property](https://mpv.io/manual/master/#command-interface-chapter)
|
||||
|
||||
### Navigate > Jump Next Frame
|
||||
|
||||
Jumps to the next frame using the command:
|
||||
|
||||
`frame-step`
|
||||
|
||||
[frame-step command](https://mpv.io/manual/master/#command-interface-frame-step)
|
||||
|
||||
### Navigate > Jump Previous Frame
|
||||
|
||||
Jumps to the previous frame using the command:
|
||||
|
||||
`frame-back-step`
|
||||
|
||||
[frame-back-step command](https://mpv.io/manual/master/#command-interface-frame-back-step)
|
||||
|
||||
### Navigate > Jump
|
||||
|
||||
Seeking using the command:
|
||||
|
||||
`no-osd seek sec`
|
||||
|
||||
sec is the relative amount of seconds to jump, the no-osd prefix
|
||||
is used because mpv.net includes a script that shows the position
|
||||
when a seek operation is performed, the script uses a more simple
|
||||
time format.
|
||||
|
||||
[no-osd command prefix](https://mpv.io/manual/master/#command-interface-no-osd)
|
||||
|
||||
[seek command](https://mpv.io/manual/master/#command-interface-[relative|absolute|absolute-percent|relative-percent|exact|keyframes])
|
||||
|
||||
### Pan & Scan > Increase Size
|
||||
|
||||
Adds video zoom using the command:
|
||||
|
||||
`add video-zoom 0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[video-zoom property](https://mpv.io/manual/master/#options-video-zoom)
|
||||
|
||||
### Pan & Scan > Decrease Size
|
||||
|
||||
Adds negative video zoom using the command:
|
||||
|
||||
`add video-zoom -0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[video-zoom property](https://mpv.io/manual/master/#options-video-zoom)
|
||||
|
||||
### Pan & Scan > Move Left
|
||||
|
||||
`add video-pan-x -0.01`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[video-pan-x, video-pan-y property](https://mpv.io/manual/master/#options-video-pan-y)
|
||||
|
||||
### Pan & Scan > Move Right
|
||||
|
||||
`add video-pan-x 0.01`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[video-pan-x, video-pan-y property](https://mpv.io/manual/master/#options-video-pan-y)
|
||||
|
||||
### Pan & Scan > Move Up
|
||||
|
||||
`add video-pan-y -0.01`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[video-pan-x, video-pan-y property](https://mpv.io/manual/master/#options-video-pan-y)
|
||||
|
||||
### Pan & Scan > Move Down
|
||||
|
||||
`add video-pan-y 0.01`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[video-pan-x, video-pan-y property](https://mpv.io/manual/master/#options-video-pan-y)
|
||||
|
||||
### Pan & Scan > Decrease Height
|
||||
|
||||
`add panscan -0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[panscan property](https://mpv.io/manual/master/#options-panscan)
|
||||
|
||||
### Pan & Scan > Increase Height
|
||||
|
||||
`add panscan 0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[panscan property](https://mpv.io/manual/master/#options-panscan)
|
||||
|
||||
### Pan & Scan > Reset
|
||||
|
||||
Resets Pan & Scan, multiple commands in the same line are separated with semicolon.
|
||||
|
||||
`set video-zoom 0; set video-pan-x 0; set video-pan-y 0`
|
||||
|
||||
[video-zoom property](https://mpv.io/manual/master/#options-video-zoom)
|
||||
|
||||
[video-pan-x, video-pan-y property](https://mpv.io/manual/master/#options-video-pan-y)
|
||||
|
||||
### Video > Decrease Contrast
|
||||
|
||||
Decreases contrast with the following command:
|
||||
|
||||
`add contrast -1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[contrast property](https://mpv.io/manual/master/#options-contrast)
|
||||
|
||||
### Video > Increase Contrast
|
||||
|
||||
Increases contrast with the following command:
|
||||
|
||||
`add contrast 1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[contrast property](https://mpv.io/manual/master/#options-contrast)
|
||||
|
||||
### Video > Decrease Brightness
|
||||
|
||||
Decreases brightness using the following command:
|
||||
|
||||
`add brightness -1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[brightness property](https://mpv.io/manual/master/#options-brightness)
|
||||
|
||||
### Video > Increase Brightness
|
||||
|
||||
Increases brightness using the following command:
|
||||
|
||||
`add brightness 1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[brightness property](https://mpv.io/manual/master/#options-brightness)
|
||||
|
||||
### Video > Decrease Gamma
|
||||
|
||||
Decreases gamma using the following command:
|
||||
|
||||
`add gamma -1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[gamma property](https://mpv.io/manual/master/#options-gamma)
|
||||
|
||||
### Video > Increase Gamma
|
||||
|
||||
Increases gamma using the following command:
|
||||
|
||||
`add gamma 1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[gamma property](https://mpv.io/manual/master/#options-gamma)
|
||||
|
||||
### Video > Decrease Saturation
|
||||
|
||||
Decreases saturation using the following command:
|
||||
|
||||
`add saturation -1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[saturation property](https://mpv.io/manual/master/#options-saturation)
|
||||
|
||||
### Video > Increase Saturation
|
||||
|
||||
Increases saturation using the following command:
|
||||
|
||||
`add saturation 1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[saturation property](https://mpv.io/manual/master/#options-saturation)
|
||||
|
||||
### Video > Take Screenshot
|
||||
|
||||
`async screenshot`
|
||||
|
||||
[async command prefix](https://mpv.io/manual/master/#command-interface-async)
|
||||
|
||||
[screenshot command](https://mpv.io/manual/master/#command-interface-[subtitles|video|window|single|each-frame])
|
||||
|
||||
### Video > Toggle Deinterlace
|
||||
|
||||
Cycles the deinterlace property using the following command:
|
||||
|
||||
`cycle deinterlace`
|
||||
|
||||
[cycle command](https://mpv.io/manual/master/#command-interface-cycle-%3Cproperty%3E-[up|down])
|
||||
|
||||
[deinterlace property](https://mpv.io/manual/master/#options-deinterlace)
|
||||
|
||||
### Video > Cycle Aspect Ratio
|
||||
|
||||
Cycles the aspect ratio using the following command:
|
||||
|
||||
`cycle-values video-aspect "16:9" "4:3" "2.35:1" "-1"`
|
||||
|
||||
[cycle-values command](https://mpv.io/manual/master/#command-interface-cycle-values)
|
||||
|
||||
[video-aspect property](https://mpv.io/manual/master/#options-video-aspect)
|
||||
|
||||
### Audio > Cycle/Next
|
||||
|
||||
This uses a mpv.net command that shows better info then the mpv preset
|
||||
and also has the advantage of not showing no audio.
|
||||
|
||||
### Audio > Delay +0.1
|
||||
|
||||
Adds a audio delay using the following command:
|
||||
|
||||
`add audio-delay 0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[audio-delay property](https://mpv.io/manual/master/#options-audio-delay)
|
||||
|
||||
### Audio > Delay -0.1
|
||||
|
||||
Adds a negative audio delay using the following command:
|
||||
|
||||
`add audio-delay -0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[audio-delay property](https://mpv.io/manual/master/#options-audio-delay)
|
||||
|
||||
### Subtitle > Cycle/Next
|
||||
|
||||
Shows the next subtitle track using the following command:
|
||||
|
||||
`cycle sub`
|
||||
|
||||
[cycle command](https://mpv.io/manual/master/#command-interface-cycle-%3Cproperty%3E-[up|down])
|
||||
|
||||
[sub/sid property](https://mpv.io/manual/master/#options-sid)
|
||||
|
||||
### Subtitle > Toggle Visibility
|
||||
|
||||
Cycles the subtitle visibility using the following command:
|
||||
|
||||
`cycle sub-visibility`
|
||||
|
||||
[cycle command](https://mpv.io/manual/master/#command-interface-cycle-%3Cproperty%3E-[up|down])
|
||||
|
||||
[sub-visibility property](https://mpv.io/manual/master/#options-no-sub-visibility)
|
||||
|
||||
### Subtitle > Delay -0.1
|
||||
|
||||
Adds a negative subtitle delay using the following command:
|
||||
|
||||
`add sub-delay -0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[sub-delay property](https://mpv.io/manual/master/#options-sub-delay)
|
||||
|
||||
### Subtitle > Delay 0.1
|
||||
|
||||
Adds a positive subtitle delay using the following command:
|
||||
|
||||
`add sub-delay 0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[sub-delay property](https://mpv.io/manual/master/#options-sub-delay)
|
||||
|
||||
### Subtitle > Move Up
|
||||
|
||||
Moves the subtitle up using the following command:
|
||||
|
||||
`add sub-pos -1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[sub-pos property](https://mpv.io/manual/master/#options-sub-pos)
|
||||
|
||||
### Subtitle > Move Down
|
||||
|
||||
Moves the subtitle down using the following command:
|
||||
|
||||
`add sub-pos 1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[sub-pos property](https://mpv.io/manual/master/#options-sub-pos)
|
||||
|
||||
### Subtitle > Decrease Subtitle Font Size
|
||||
|
||||
Decreases the subtitle font size using the following command:
|
||||
|
||||
`add sub-scale -0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[sub-scale property](https://mpv.io/manual/master/#options-sub-scale)
|
||||
|
||||
### Subtitle > Increase Subtitle Font Size
|
||||
|
||||
Increases the subtitle font size using the following command:
|
||||
|
||||
`add sub-scale 0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[sub-scale property](https://mpv.io/manual/master/#options-sub-scale)
|
||||
|
||||
### Volume > Up
|
||||
|
||||
Increases the volume using the following command:
|
||||
|
||||
`add volume 10`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[volume property](https://mpv.io/manual/master/#options-volume)
|
||||
|
||||
### Volume > Down
|
||||
|
||||
Decreases the volume using the following command:
|
||||
|
||||
`add volume -10`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[volume property](https://mpv.io/manual/master/#options-volume)
|
||||
|
||||
### Volume > Mute
|
||||
|
||||
Cycles the mute property using the following command:
|
||||
|
||||
`cycle mute`
|
||||
|
||||
[cycle command](https://mpv.io/manual/master/#command-interface-cycle-%3Cproperty%3E-[up|down])
|
||||
|
||||
[mute property](https://mpv.io/manual/master/#options-mute)
|
||||
|
||||
### Speed > -10%
|
||||
|
||||
Decreases the speed by 10% using the following command:
|
||||
|
||||
`multiply speed 1/1.1`
|
||||
|
||||
[multiply command](https://mpv.io/manual/master/#command-interface-multiply-%3Cproperty%3E-%3Cfactor%3E)
|
||||
|
||||
[speed property](https://mpv.io/manual/master/#options-speed)
|
||||
|
||||
### Speed > 10%
|
||||
|
||||
Increases the speed by 10% using the following command:
|
||||
|
||||
`multiply speed 1.1`
|
||||
|
||||
[multiply command](https://mpv.io/manual/master/#command-interface-multiply-%3Cproperty%3E-%3Cfactor%3E)
|
||||
|
||||
[speed property](https://mpv.io/manual/master/#options-speed)
|
||||
|
||||
### Speed > Half
|
||||
|
||||
Halfs the speed using the following command:
|
||||
|
||||
`multiply speed 0.5`
|
||||
|
||||
[multiply command](https://mpv.io/manual/master/#command-interface-multiply-%3Cproperty%3E-%3Cfactor%3E)
|
||||
|
||||
[speed property](https://mpv.io/manual/master/#options-speed)
|
||||
|
||||
### Speed > Double
|
||||
|
||||
Doubles the speed using the following command:
|
||||
|
||||
`multiply speed 2`
|
||||
|
||||
[multiply command](https://mpv.io/manual/master/#command-interface-multiply-%3Cproperty%3E-%3Cfactor%3E)
|
||||
|
||||
[speed property](https://mpv.io/manual/master/#options-speed)
|
||||
|
||||
### Speed > Reset
|
||||
|
||||
Resets the speed using the following command:
|
||||
|
||||
`set speed 1`
|
||||
|
||||
[set command](https://mpv.io/manual/master/#command-interface-set-%3Cproperty%3E-%22%3Cvalue%3E%22)
|
||||
|
||||
[speed property](https://mpv.io/manual/master/#options-speed)
|
||||
|
||||
### Extensions > Rating > 0stars
|
||||
|
||||
A plugin the writes the rating to the filename.
|
||||
|
||||
### View > On Top > Enable
|
||||
|
||||
Forces the player to stay on top of other windows using the following command:
|
||||
|
||||
`set ontop yes`
|
||||
|
||||
[set command](https://mpv.io/manual/master/#command-interface-set-%3Cproperty%3E-%22%3Cvalue%3E%22)
|
||||
|
||||
[ontop property](https://mpv.io/manual/master/#options-ontop)
|
||||
|
||||
### View > On Top > Disable
|
||||
|
||||
Disables the player to stay on top of other windows using the following command:
|
||||
|
||||
`set ontop no`
|
||||
|
||||
[set command](https://mpv.io/manual/master/#command-interface-set-%3Cproperty%3E-%22%3Cvalue%3E%22)
|
||||
|
||||
[ontop property](https://mpv.io/manual/master/#options-ontop)
|
||||
|
||||
### View > File Info
|
||||
|
||||
Shows info using a mpv.net command about the current file, shows length, position, formats, size and filename.
|
||||
|
||||
### View > Show Statistics
|
||||
|
||||
Show statistics using the following command:
|
||||
|
||||
`script-binding stats/display-stats`
|
||||
|
||||
[script-binding command](https://mpv.io/manual/master/#command-interface-script-binding)
|
||||
|
||||
### View > Toggle Statistics
|
||||
|
||||
Toggles statistics using the following command:
|
||||
|
||||
`script-binding stats/display-stats-toggle`
|
||||
|
||||
[script-binding command](https://mpv.io/manual/master/#command-interface-script-binding)
|
||||
|
||||
### View > Toggle OSC Visibility
|
||||
|
||||
Toggles OSC Visibility using the following command:
|
||||
|
||||
`script-binding osc/visibility`
|
||||
|
||||
[script-binding command](https://mpv.io/manual/master/#command-interface-script-binding)
|
||||
|
||||
### View > Show Playlist
|
||||
|
||||
Shows the playlist for 5 seconds using the following command:
|
||||
|
||||
`show-text ${playlist} 5000`
|
||||
|
||||
[show-text command](https://mpv.io/manual/master/#command-interface-show-text)
|
||||
|
||||
### View > Show Audio/Video/Subtitle List
|
||||
|
||||
Shows the Audio/Video/Subtitle list for 5 seconds using the following command:
|
||||
|
||||
`show-text ${track-list} 5000`
|
||||
|
||||
[show-text command](https://mpv.io/manual/master/#command-interface-show-text)
|
||||
|
||||
### Settings > Show Config Editor
|
||||
|
||||
Shows mpv.net's config editor.
|
||||
|
||||
### Settings > Show Input Editor
|
||||
|
||||
Shows mpv.net's key binding editor.
|
||||
|
||||
### Settings > Open Config Folder
|
||||
|
||||
Opens the config folder which contains:
|
||||
|
||||
mpv.conf file containing mpv settings
|
||||
|
||||
mpvnet.conf file containing mpv.net settings
|
||||
|
||||
input.conf containing mpv key bindings
|
||||
|
||||
User scripts and user extensions
|
||||
|
||||
### Tools > Command Palette
|
||||
|
||||
Shows the command palette window which allows to find mpv.net commands, it shows the command's location in the context menu and the key shortcut.
|
||||
|
||||
### Tools > Show History
|
||||
|
||||
When enabled shows a file that contains the playback history containing the time and filename.
|
||||
|
||||
### Tools > Set/clear A-B loop points
|
||||
|
||||
Enables to set loop start and end points using the following command:
|
||||
|
||||
`ab-loop`
|
||||
|
||||
[ab-loop command](https://mpv.io/manual/master/#command-interface-ab-loop)
|
||||
|
||||
### Tools > Toggle infinite file looping
|
||||
|
||||
Loops the current file infinitely using the following command:
|
||||
|
||||
cycle-values loop-file "inf" "no"
|
||||
|
||||
[cycle-values command](https://mpv.io/manual/master/#command-interface-cycle-values)
|
||||
|
||||
[loop-file command](https://mpv.io/manual/master/#options-loop)
|
||||
|
||||
### Tools > Cycle Hardware Decoding
|
||||
|
||||
Cycles the hwdec property to enable/disable hardware decoding using the following command:
|
||||
|
||||
`cycle-values hwdec "auto" "no"`
|
||||
|
||||
[cycle-values command](https://mpv.io/manual/master/#command-interface-cycle-values)
|
||||
|
||||
[hwdec property](https://mpv.io/manual/master/#options-hwdec)
|
||||
|
||||
### Tools > Execute mpv command
|
||||
|
||||
Allows to execute mpv commands.
|
||||
|
||||
### Tools > Manage File Associations
|
||||
|
||||
Allows to manage file associations.
|
||||
|
||||
### Help > Show mpv manual
|
||||
|
||||
Shows the [mpv manual](https://mpv.io/manual/stable/).
|
||||
|
||||
### Help > Show mpv default keys
|
||||
|
||||
Shows the [mpv default keys](https://github.com/mpv-player/mpv/blob/master/etc/input.conf)
|
||||
|
||||
### Help > Show mpv.net default keys
|
||||
|
||||
Shows the [mpv.net default keys](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt)
|
||||
|
||||
Help > Show mpv.net web site
|
||||
|
||||
Shows the [mpv.net web site](https://mpv-net.github.io/mpv.net-web-site/)
|
||||
|
||||
### Help > Show mpv.net manual
|
||||
|
||||
Shows the [mpv.net manual](https://github.com/stax76/mpv.net/blob/master/Manual.md)
|
||||
|
||||
### Help > About mpv.net
|
||||
|
||||
Shows the mpv.net about dialog.
|
||||
|
||||
### Exit
|
||||
|
||||
Exits mpv.net using the following command:
|
||||
|
||||
`quit`
|
||||
|
||||
[quit command](https://mpv.io/manual/master/#command-interface-quit-[%3Ccode%3E])
|
||||
|
||||
### Exit Watch Later
|
||||
|
||||
Exits mpv.net and remembers the position in the file using the following command:
|
||||
|
||||
`quit-watch-later`
|
||||
|
||||
[quit-watch-later command](https://mpv.io/manual/master/#command-interface-quit-watch-later)
|
||||
|
||||
## Command Line Interface
|
||||
|
||||
mpvnet implements a basic CLI to set mpv commands.
|
||||
|
||||
Example:
|
||||
|
||||
mpvnet --mute=yes <file|URL>
|
||||
|
||||
## 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:
|
||||
|
||||
```Text
|
||||
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.
|
||||
|
||||
```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>
|
||||
|
||||
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.
|
||||
|
||||
The key bindings and the context menu definitions are stored in the 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>
|
||||
183
README.md
@@ -1,26 +1,28 @@
|
||||
# mpv.net
|
||||

|
||||
|
||||
mpv.net is a modern media player for Windows that looks and works just like [mpv](https://mpv.io).
|
||||
# 🎞 mpv.net
|
||||
|
||||
mpv.net is a modern media player for Windows that works just like [mpv](https://mpv.io).
|
||||
|
||||
#### Based on libmpv
|
||||
|
||||
mpv.net is based on libmpv which offers a straightforward C API that was designed from the ground up to make mpv usable as a library and facilitate easy integration into other applications.
|
||||
mpv.net is based on libmpv which offers a straightforward C API that was designed from the ground up to make mpv usable as a library and facilitate easy integration into other applications. mpv is like vlc not based on DirectShow or Media Foundation.
|
||||
|
||||
#### CLI options
|
||||
#### Command Line Interface
|
||||
|
||||
mpv.net has the same [CLI options](https://mpv.io/manual/master/#options) as mpv.
|
||||
mpv.net has the [CLI of mpv](https://mpv.io/manual/master/#options).
|
||||
|
||||
#### High quality video output
|
||||
|
||||
mpv/libmpv has an OpenGL based video output that is capable of many features loved by videophiles, such as video scaling with popular high quality algorithms, color management, frame timing, interpolation, HDR, and more.
|
||||
libmpv has an OpenGL based video output that is capable of many features loved by videophiles, such as video scaling with popular high quality algorithms, color management, frame timing, interpolation, HDR, and more.
|
||||
|
||||
#### On Screen Controller
|
||||
|
||||
mpv.net uses the OSC of mpv/libmpv offering play controls with a modern flat design.
|
||||
The OSC of libmpv offers play controls with a modern flat design. ([Screenshot](#main-window-screenshot))
|
||||
|
||||
#### GPU video decoding
|
||||
|
||||
mpv/libmpv leverages the FFmpeg hwaccel APIs to support DXVA2 video decoding acceleration.
|
||||
libmpv leverages the FFmpeg hwaccel APIs to support DXVA2 video decoding acceleration.
|
||||
|
||||
#### Active development
|
||||
|
||||
@@ -31,6 +33,7 @@ Table of contents
|
||||
|
||||
- [Features](#features)
|
||||
- [Screenshots](#screenshots)
|
||||
- [Manual](#manual)
|
||||
- [Context Menu](#context-menu)
|
||||
- [Settings](#settings)
|
||||
- [Scripting](#scripting)
|
||||
@@ -38,22 +41,23 @@ Table of contents
|
||||
- [Architecture](#architecture)
|
||||
- [Support](#support)
|
||||
- [Links](#links)
|
||||
- [Download](#download)
|
||||
- [Changelog](#changelog)
|
||||
- [Download](#download)
|
||||
|
||||
### Features
|
||||
|
||||
- Customizable context menu defined in the same file as the key bindings ([Screenshot](#context-menu))
|
||||
- Searchable config dialog ([Screenshot](#config-editor))
|
||||
- Searchable input (key/mouse) binding editor ([Screenshot](#input-editor))
|
||||
- Searchable command palette to quickly launch commands and look for keys ([Screenshot](#command-palette))
|
||||
- Modern UI with dark mode ([Screenshot](#config-editor))
|
||||
- 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 input (key/mouse) binding editor ([Screenshot](#input-editor-screenshot), [Defaults](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt))
|
||||
- Searchable command palette to quickly launch commands and look for keys ([Screenshot](#command-palette-screenshot))
|
||||
- Modern UI with dark mode ([Screenshot](#config-editor-screenshot))
|
||||
- Addon/extension API for .NET languages
|
||||
- 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
|
||||
- Support of the same [CLI options](https://mpv.io/manual/master/#options) as mpv
|
||||
- [Command Line Interface](https://mpv.io/manual/master/#options)
|
||||
- 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
|
||||
- Search feature powered by [Everything](https://www.voidtools.com) to find and play media ([Screenshot](#media-search-screenshot))
|
||||
|
||||
### Screenshots
|
||||
|
||||
@@ -86,6 +90,16 @@ Just press Ctrl+Shift+P and find it easily in the searchable command palette.
|
||||
|
||||

|
||||
|
||||
#### Media Search Screenshot
|
||||
|
||||
Media search feature powered by [Everything](https://www.voidtools.com) to find and play media.
|
||||
|
||||

|
||||
|
||||
### Manual
|
||||
|
||||
[Manual](Manual.md)
|
||||
|
||||
### Context Menu
|
||||
|
||||
The context menu can be customized via input.conf file located in the config directory:
|
||||
@@ -102,66 +116,71 @@ input.conf defines mpv's key and mouse bindings and mpv.net uses comments to def
|
||||
|
||||
### Settings
|
||||
|
||||
mpv.net shares the settings with mpv, settings can be edited in a settings dialog or in a config file called mpv.conf located in the config directory:
|
||||
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:
|
||||
|
||||
```Text
|
||||
C:\Users\%username%\AppData\Roaming\mpv\mpv.conf
|
||||
```
|
||||
|
||||
or in a portable setup at:
|
||||
If a directory named portable_config next to the mpvnet.exe exists, all config will be loaded from this directory only.
|
||||
|
||||
```Text
|
||||
<startup>\portable_config\mpv.conf
|
||||
```
|
||||
|
||||
if it's missing mpv.net generates it with the following defaults:
|
||||
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>
|
||||
|
||||
### Scripting
|
||||
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.
|
||||
|
||||
Scripting is supported via Python, C#, Lua, JavaScript and PowerShell
|
||||
The key bindings and the context menu definitions are stored in the 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>
|
||||
|
||||
mpv.net supports almost all mpv settings and features, [limitations are listed in the wiki](https://github.com/stax76/mpv.net/wiki/Limitations).
|
||||
|
||||
### Scripting
|
||||
|
||||
[Scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting)
|
||||
|
||||
### Add-ons
|
||||
|
||||
Add-ons are located in the config directory:
|
||||
|
||||
```Text
|
||||
C:\Users\%username%\AppData\Roaming\mpv\Addons\ExampleAddon\ExampleAddon.dll
|
||||
```
|
||||
|
||||
The add-on filename must end with 'Addon.dll'.
|
||||
|
||||
Examples:
|
||||
|
||||
[RatingAddon.cs](https://github.com/stax76/mpv.net/blob/master/RatingAddon/RatingAddon.cs)
|
||||
|
||||
[CSScriptAddon.vb](https://github.com/stax76/mpv.net/blob/master/CSScriptAddon/CSScriptAddon.vb)
|
||||
[Add-on wiki page](https://github.com/stax76/mpv.net/wiki/Addons)
|
||||
|
||||
### Architecture
|
||||
|
||||
mpv.net is written in C# 7.0 and runs on the .NET framework 4.7 or higher.
|
||||
|
||||
The Add-on implementation is based on the Managed Extensibility Framework,
|
||||
the entire application code is accessible for add-ons and Python scripts.
|
||||
The Add-on 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
|
||||
is accessible for .NET compatible languages (C#, VB.NET, F#, Python, PowerShell),
|
||||
this decision was made to keep the code simple and lightweight.
|
||||
|
||||
Python scripting is implemented with IronPython which uses Python 2.7.
|
||||
|
||||
The main/video window is WinForms based, other windows are WPF based.
|
||||
The main/video window is WinForms based, all other windows are WPF based.
|
||||
|
||||
The config editor adds it's controls dynamically and uses TOML to define it's
|
||||
content, there are only two simple types, StringSetting and OptionSetting.
|
||||
|
||||
mpv.net was started 2017 and consists of about 9000 lines of code.
|
||||
mpv.net was started 2017 and consists of about 6000 lines of code and markup.
|
||||
|
||||
Third party components are:
|
||||
IDE, Editor: Visual Studio, Visual Studio Code.
|
||||
|
||||
- [libmpv](https://mpv.io/)
|
||||
- [MediaInfo](https://mediaarea.net/en/MediaInfo)
|
||||
- [Tommy (TOML parser)](https://github.com/dezhidki/Tommy)
|
||||
- [IronPython](https://ironpython.net/)
|
||||
Due to mpv.net being my first WPF app and mpv.net never meant to be a large
|
||||
application best practices and design pattern are not always applied.
|
||||
|
||||
Third party components:
|
||||
|
||||
- [libmpv, the heard and soul of mpv.net](https://mpv.io/)
|
||||
- [MediaInfo, no media related project could do without](https://mediaarea.net/en/MediaInfo)
|
||||
- [Tommy, a single file TOML parser](https://github.com/dezhidki/Tommy)
|
||||
- [IronPython, bringing Python to dotnet](https://ironpython.net/)
|
||||
- [CS-Script, scripting with C#](http://www.csscript.net/)
|
||||
- [Everything, a blazing fast file search service](https://www.voidtools.com)
|
||||
|
||||
### Support
|
||||
|
||||
@@ -171,6 +190,8 @@ Third party components are:
|
||||
|
||||
[Issue tracker to report bugs and request features](https://github.com/stax76/mpv.net/issues)
|
||||
|
||||
[frank.skare.de@gmail.com](mailto:frank.skare.de@gmail.com?Subject=mpv.net%20support)
|
||||
|
||||
### Links
|
||||
|
||||
mpv manual: <https://mpv.io/manual/master/>
|
||||
@@ -195,82 +216,10 @@ mpv bugs and requests: <https://mpv.io/bug-reports/>
|
||||
|
||||
mpv.net bugs and requests: <https://github.com/stax76/mpv.net/issues>
|
||||
|
||||
### Download
|
||||
|
||||
<https://github.com/stax76/mpv.net/releases>
|
||||
|
||||
### Changelog
|
||||
|
||||
### 3.3 (2019-05-01)
|
||||
[Changelog](Changelog.md)
|
||||
|
||||
- dark mode support was added to the command palette and partly to the input editor
|
||||
- a new icon was designed. [Website](https://mpv-net.github.io/mpv.net-web-site/)
|
||||
- all windows (main, conf, input, about, command palette) can now be closed
|
||||
by just pressing the Escape key
|
||||
- new feature added to open recent files and URLs with the context menu. [Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L33)
|
||||
- the info command (i key) now works also for URLs
|
||||
- CSScriptAddon add-on didn't load cs scripts from \<startup\>\\scripts
|
||||
- error handling was improved by showing an improved message box that supports a text copy feature, a support link and text heading and text folding
|
||||
- libmpv was updated
|
||||
### Download
|
||||
|
||||
### 3.2 (2019-04-27)
|
||||
|
||||
- mpvInputEdit and mpvConfEdit were discontinued and merged into
|
||||
mpvnet because separate apps were to difficult to work with
|
||||
- portable mode: in case no config folder exists and the
|
||||
startup folder has write access mpvnet will ask where
|
||||
the config folder should be created (portable or appdata)
|
||||
- there was an issue causing keys not working after a modal window was shown
|
||||
- there was a crash when no script folder existed in the conf folder
|
||||
- MediaInfo and youtube-dl were updated
|
||||
- a new JavaScript example script was added to the wiki and the
|
||||
script descriptions were improved. [Scripting Page](https://github.com/stax76/mpv.net/wiki/Scripting).
|
||||
- greatly improved README.md file and [github startpage](https://github.com/stax76/mpv.net)
|
||||
- About dialog added
|
||||
- the input editor shows only a closing message if actually a change was made
|
||||
- the input editor don't show confusing menu separators any longer. [Screenshot](https://github.com/stax76/mpv.net#input-editor)
|
||||
- new Command Palette feature added. [Screenshot](https://github.com/stax76/mpv.net#command-palette), [Default input binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L141)
|
||||
- the history feature had a bug causing files to be logged more than once
|
||||
|
||||
### 3.1 (2019-04-23)
|
||||
|
||||
- the Tracks and Chapters menu are now only added if default bindings exist and
|
||||
it's now possible to move the chapters menu to the top level by editing input.conf
|
||||
- mpvnet supports now like mpv a portable settings directory. If a directory named portable_config
|
||||
next to the mpvnet.exe exists, all config will be loaded and written in this directory.
|
||||
- there is now a portable download in 7zip format.
|
||||
|
||||
### 3.0 (2019-04-20)
|
||||
|
||||
- the history feature logs now only files that were opened longer than 90 seconds
|
||||
- the default input command for cycling the audio tracks was replaced with an
|
||||
mpv.net command that shows detailed track info and has no 'no audio' track. [Default binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L89).
|
||||
- new website at <https://mpv-net.github.io/mpv.net-web-site/>
|
||||
- the Tracks menu supports now MKV edition selection. [Default binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L106).
|
||||
- the Navigate menu supports now chapter selection. [Default binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L57).
|
||||
- opening the context menu was crashing if the default binding for Tracks was missing
|
||||
|
||||
### 2.9 (2019-04-16)
|
||||
|
||||
- clicking the right top corner in full screen mode
|
||||
closes the player but it did not work on all displays
|
||||
- the info display was changed to display the filename on top
|
||||
so it's not displayed in the middle of the screen
|
||||
- on start up of the config editor all text is now selected in the
|
||||
search text box so it's ready for a new search to be typed
|
||||
- the config editor was changed to write the settings to disk
|
||||
only if the settings were actually modified, also the message
|
||||
that says that the settings will be available on next start
|
||||
is now only shown if the settings were actually modified.
|
||||
- there was an instance in the context menu where the sub menu
|
||||
arrow was overlapping with the text
|
||||
- in the input editor when only one character is entered in the
|
||||
search text box the search is performed only in the input and
|
||||
not in the command or menu
|
||||
- in the input editor the routine that generates the input string
|
||||
was completely rewritten because it was adding Shift where it
|
||||
wasn't necessary (it took a huge amount of time to implement)
|
||||
- the context menu has a new track menu where the active track
|
||||
can be seen and selected, it shows video, audio and subtitle
|
||||
tracks with various metadata. [Menu default definition](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L104).
|
||||
The screenshots were updated showing the [new track menu](https://github.com/stax76/mpv.net#screenshots).
|
||||
<https://github.com/stax76/mpv.net/releases>
|
||||
@@ -13,8 +13,8 @@ Public Class CSScriptAddon
|
||||
Sub New()
|
||||
Dim scriptFiles As New List(Of String)
|
||||
|
||||
If Directory.Exists(mp.MpvConfFolder + "scripts") Then
|
||||
scriptFiles.AddRange(Directory.GetFiles(mp.MpvConfFolder + "scripts", "*.cs"))
|
||||
If Directory.Exists(mp.ConfFolder + "scripts") Then
|
||||
scriptFiles.AddRange(Directory.GetFiles(mp.ConfFolder + "scripts", "*.cs"))
|
||||
End If
|
||||
|
||||
If Directory.Exists(Application.StartupPath + "\scripts") Then
|
||||
@@ -28,7 +28,7 @@ Public Class CSScriptAddon
|
||||
Try
|
||||
CSScriptLibrary.CSScript.Evaluator.LoadCode(File.ReadAllText(i))
|
||||
Catch ex As Exception
|
||||
Sys.Msg.ShowException(ex)
|
||||
Msg.ShowException(ex)
|
||||
End Try
|
||||
Next
|
||||
End Sub
|
||||
@@ -47,6 +47,48 @@
|
||||
<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>
|
||||
@@ -114,7 +156,7 @@
|
||||
<Content Include="CSScriptLibrary.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\mpv.net\mpv.net.csproj">
|
||||
<ProjectReference Include="..\..\mpv.net\mpv.net.csproj">
|
||||
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
|
||||
<Name>mpv.net</Name>
|
||||
<Private>False</Private>
|
||||
@@ -30,6 +30,42 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\mpv.net\bin\x86\Addons\RatingAddon\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>..\mpv.net\bin\x86\Addons\RatingAddon\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\mpv.net\bin\x64\Addons\RatingAddon\</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\Addons\RatingAddon\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
@@ -46,7 +82,7 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\mpv.net\mpv.net.csproj">
|
||||
<ProjectReference Include="..\..\mpv.net\mpv.net.csproj">
|
||||
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
|
||||
<Name>mpv.net</Name>
|
||||
<Private>False</Private>
|
||||
36
addons/TestAddon/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using 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.
|
||||
[assembly: AssemblyTitle("TestAddon")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("TestAddon")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2019")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("06f854b0-00f9-4b53-94d9-0be65a7c55d8")]
|
||||
|
||||
// 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")]
|
||||
27
addons/TestAddon/TestAddon.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
92
addons/TestAddon/TestAddon.csproj
Normal file
@@ -0,0 +1,92 @@
|
||||
<?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>{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>TestAddon</RootNamespace>
|
||||
<AssemblyName>TestAddon</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</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 Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="TestAddon.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</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.CSharp.targets" />
|
||||
</Project>
|
||||
|
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 212 KiB |
|
Before Width: | Height: | Size: 277 KiB After Width: | Height: | Size: 214 KiB |
BIN
img/Main.png
|
Before Width: | Height: | Size: 2.9 MiB After Width: | Height: | Size: 5.8 MiB |
BIN
img/MediaSearch.png
Normal file
|
After Width: | Height: | Size: 125 KiB |
BIN
img/mpvnet.pdn
BIN
img/mpvnet.png
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.7 KiB |
54
mpv.net.sln
@@ -5,28 +5,70 @@ VisualStudioVersion = 16.0.28729.10
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mpv.net", "mpv.net\mpv.net.csproj", "{1751F378-8EDF-4B62-BE6D-304C7C287089}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatingAddon", "RatingAddon\RatingAddon.csproj", "{55C88710-539D-4402-84C8-31694841C731}"
|
||||
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CSScriptAddon", "addons\CSScriptAddon\CSScriptAddon.vbproj", "{71808A87-8B1C-4DF8-957C-D79C3B164CCA}"
|
||||
EndProject
|
||||
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CSScriptAddon", "CSScriptAddon\CSScriptAddon.vbproj", "{71808A87-8B1C-4DF8-957C-D79C3B164CCA}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatingAddon", "addons\RatingAddon\RatingAddon.csproj", "{55C88710-539D-4402-84C8-31694841C731}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestAddon", "addons\TestAddon\TestAddon.csproj", "{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
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.Build.0 = Debug|x64
|
||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.Build.0 = Debug|x86
|
||||
{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
|
||||
{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}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{55C88710-539D-4402-84C8-31694841C731}.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.Build.0 = Release|x64
|
||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.ActiveCfg = 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.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|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.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
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x64.Build.0 = Debug|x64
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x86.Build.0 = Debug|x86
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Navigation;
|
||||
|
||||
@@ -49,14 +50,16 @@ namespace DynamicGUI
|
||||
StringSetting stringSetting = new StringSetting();
|
||||
baseSetting = stringSetting;
|
||||
stringSetting.Default = setting["default"];
|
||||
if (setting.HasKey("folder")) stringSetting.IsFolder = true;
|
||||
}
|
||||
|
||||
baseSetting.Name = setting["name"];
|
||||
baseSetting.Filter = setting["filter"];
|
||||
|
||||
if (setting.HasKey("help")) baseSetting.Help = setting["help"];
|
||||
if (setting.HasKey("helpurl")) baseSetting.HelpURL = setting["helpurl"];
|
||||
if (setting.HasKey("width")) baseSetting.Width = setting["width"];
|
||||
if (setting.HasKey("type")) baseSetting.Type = setting["type"];
|
||||
|
||||
settingsList.Add(baseSetting);
|
||||
}
|
||||
return settingsList;
|
||||
@@ -72,12 +75,12 @@ namespace DynamicGUI
|
||||
public string Default { get; set; }
|
||||
public string HelpURL { get; set; }
|
||||
public string Filter { get; set; }
|
||||
public string Type { get; set; }
|
||||
public int Width { get; set; }
|
||||
}
|
||||
|
||||
public class StringSetting : SettingBase
|
||||
{
|
||||
public bool IsFolder { get; set; }
|
||||
}
|
||||
|
||||
public class OptionSetting : SettingBase
|
||||
@@ -100,13 +103,15 @@ namespace DynamicGUI
|
||||
set => _Text = value;
|
||||
}
|
||||
|
||||
public bool IsChecked
|
||||
public bool Checked
|
||||
{
|
||||
get => OptionSetting.Value == Name ;
|
||||
set {
|
||||
if (value)
|
||||
OptionSetting.Value = Name;
|
||||
}
|
||||
set { if (value) OptionSetting.Value = Name; }
|
||||
}
|
||||
|
||||
public Visibility Visibility
|
||||
{
|
||||
get => string.IsNullOrEmpty(Help) ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<WrapPanel Orientation="Vertical">
|
||||
<RadioButton x:Name="RadioButton" VerticalContentAlignment="Center" IsChecked="{Binding IsChecked}" GroupName="{Binding OptionSetting.Name}" Content="{Binding Text}" FontSize="16" FontWeight="Normal" VerticalAlignment="Top" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"></RadioButton>
|
||||
<TextBox x:Name="ItemHelpTextBox" TextWrapping="WrapWithOverflow" Text="{Binding Help}" 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>
|
||||
<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>
|
||||
<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>
|
||||
</WrapPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
|
||||
@@ -12,11 +12,13 @@ namespace DynamicGUI
|
||||
OptionSetting = optionSetting;
|
||||
InitializeComponent();
|
||||
TitleTextBox.Text = optionSetting.Name;
|
||||
if (string.IsNullOrEmpty(optionSetting.Help))
|
||||
HelpTextBox.Visibility = Visibility.Collapsed;
|
||||
HelpTextBox.Text = optionSetting.Help;
|
||||
ItemsControl.ItemsSource = optionSetting.Options;
|
||||
Link.SetURL(optionSetting.HelpURL);
|
||||
if (string.IsNullOrEmpty(optionSetting.HelpURL))
|
||||
LinkTextBlock.Visibility = Visibility.Collapsed;
|
||||
Link.SetURL(optionSetting.HelpURL);
|
||||
}
|
||||
|
||||
private string _SearchableText;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
xmlns:local="clr-namespace:DynamicGUI"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800" >
|
||||
d:DesignWidth="800">
|
||||
<Grid Margin="20,0">
|
||||
<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>
|
||||
@@ -15,10 +15,10 @@
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</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}}"/>
|
||||
<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"/>
|
||||
<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>
|
||||
<TextBox x:Name="HelpTextBox" TextWrapping="WrapWithOverflow" Margin="0,0,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="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>
|
||||
<TextBlock x:Name="LinkTextBlock" Margin="0,10">
|
||||
<local:HyperlinkEx x:Name="Link"></local:HyperlinkEx>
|
||||
</TextBlock>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
using System.Windows;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using WinForms = System.Windows.Forms;
|
||||
|
||||
namespace DynamicGUI
|
||||
{
|
||||
@@ -13,10 +17,10 @@ namespace DynamicGUI
|
||||
InitializeComponent();
|
||||
TitleTextBox.Text = stringSetting.Name;
|
||||
HelpTextBox.Text = stringSetting.Help;
|
||||
ValueTextBox.Text = stringSetting.Value;
|
||||
if (stringSetting.Width > 0)
|
||||
ValueTextBox.Width = stringSetting.Width;
|
||||
if (!StringSetting.IsFolder)
|
||||
ValueTextBox.Text = StringSetting.Value;
|
||||
if (StringSetting.Width > 0)
|
||||
ValueTextBox.Width = StringSetting.Width;
|
||||
if (StringSetting.Type != "folder" && StringSetting.Type != "color")
|
||||
Button.Visibility = Visibility.Hidden;
|
||||
Link.SetURL(StringSetting.HelpURL);
|
||||
if (string.IsNullOrEmpty(stringSetting.HelpURL))
|
||||
@@ -29,7 +33,6 @@ namespace DynamicGUI
|
||||
get {
|
||||
if (_SearchableText is null)
|
||||
_SearchableText = (TitleTextBox.Text + HelpTextBox.Text +ValueTextBox.Text).ToLower();
|
||||
|
||||
return _SearchableText;
|
||||
}
|
||||
}
|
||||
@@ -45,13 +48,56 @@ namespace DynamicGUI
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
using (var d = new System.Windows.Forms.FolderBrowserDialog())
|
||||
switch (StringSetting.Type)
|
||||
{
|
||||
d.Description = "Choose a folder.";
|
||||
d.SelectedPath = ValueTextBox.Text;
|
||||
if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||
ValueTextBox.Text = d.SelectedPath;
|
||||
case "folder":
|
||||
using (var d = new WinForms.FolderBrowserDialog())
|
||||
{
|
||||
d.Description = "Choose a folder.";
|
||||
d.SelectedPath = ValueTextBox.Text;
|
||||
if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||
ValueTextBox.Text = d.SelectedPath;
|
||||
}
|
||||
break;
|
||||
case "color":
|
||||
using (var d = new WinForms.ColorDialog())
|
||||
{
|
||||
d.FullOpen = true;
|
||||
try {
|
||||
d.Color = System.Drawing.ColorTranslator.FromHtml(ValueTextBox.Text);
|
||||
} catch { }
|
||||
if (d.ShowDialog() == WinForms.DialogResult.OK)
|
||||
ValueTextBox.Text = System.Drawing.ColorTranslator.ToHtml(d.Color);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ValueTextBox_TextChanged(object sender, TextChangedEventArgs e) => Update();
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (StringSetting.Type == "color")
|
||||
{
|
||||
Color c = Colors.Transparent;
|
||||
if (ValueTextBox.Text != "")
|
||||
{
|
||||
try {
|
||||
if (ValueTextBox.Text.Contains("/"))
|
||||
{
|
||||
string[] a = ValueTextBox.Text.Split('/');
|
||||
if (a.Length == 3)
|
||||
c = Color.FromRgb(ToByte(a[0]), ToByte(a[1]), ToByte(a[2]));
|
||||
else if (a.Length == 4)
|
||||
c = Color.FromArgb(ToByte(a[3]), ToByte(a[0]), ToByte(a[1]), ToByte(a[2]));
|
||||
}
|
||||
else
|
||||
c = (Color)ColorConverter.ConvertFromString(ValueTextBox.Text);
|
||||
} catch {}
|
||||
}
|
||||
ValueTextBox.Background = new SolidColorBrush(c);
|
||||
}
|
||||
Byte ToByte(string val) => Convert.ToByte(Convert.ToSingle(val, CultureInfo.InvariantCulture) * 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,505 +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.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<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" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</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" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="Timer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>30, 12</value>
|
||||
</metadata>
|
||||
<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">
|
||||
<value>
|
||||
AAABAAQAEBAAAAEAIABoBAAARgAAACAgAAABACAAqBAAAK4EAAAwMAAAAQAgAKglAABWFQAAAAAAAAEA
|
||||
IABKHQAA/joAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAMMOAADDDgAAAAAAAAAAAAAAAAAAAAAAAP/c
|
||||
uQD/3LgH/968SP/ct6j/16rk/9Kf+//Sn/v/16rj/9y3qP/evEj/3LgH/9y5AAAAAAAAAAAA/9u1AP/c
|
||||
uQD/3bkY/9y3kv/Ole7/t1j//6Us//+eGv//nhr//6Us//+3WP//zpXu/9y3kv/duRj/3LkA/9u1AP/b
|
||||
tgD/3bkY/9qysP/AcP//nRf//5MA//+TAP//kgD//5IA//+SAP//kwD//50X///AcP//2rKw/925GP/b
|
||||
tgD/3LgG/9y3kv/AcP//lwr//5MA//+UAf//mxL//6Us//+mLv//nBb//5QB//+TAP//lwr//8Bw///c
|
||||
t5L/3LgG/968Sf/OlO3/nRj//5MA//+VBP//sEf//8+X///ZsP//2a///9Gc//+1U///lwj//5MA//+d
|
||||
GP//zpTt/968Sf/ct6f/tlj//5MA//+TAP//r0X//9mv///Xq///0Zz//9y3///cuP//2rP//7ZW//+U
|
||||
Af//kwD//7ZY///ct6f/16ri/6Us//+TAP//mg///82S///duv//zZH//6Ij//+9aP//16v//9y4///S
|
||||
n///nhn//5IA//+lLP//16rj/9Kf+/+eGv//kgD//6Ml///Xq///3Lj//82R//+YC///lAL//6gy///P
|
||||
lv//2rP//6k2//+SAP//nhr//9Kf+//Sn/v/nhr//5IA//+jJf//16v//9y4///Nkv//mAv//5YH//+v
|
||||
RP//0p7//9qz//+pNv//kgD//54a///Sn/v/16ri/6Us//+TAP//mg///82S///duv//zpP//6Yu///D
|
||||
d///2bH//9y4///Sn///nhn//5IA//+lLP//16ri/9y3p/+2WP//kwD//5MA//+vRf//2a///9iu///V
|
||||
pP//3Lf//9y3///as///tlb//5QB//+TAP//tlj//9y3p//evEn/zpTt/50Y//+TAP//lQT//7BH///P
|
||||
lv//2a///9mv///RnP//tVP//5cI//+TAP//nRj//86U7f/evEn/3LgG/9y3kf/AcP//lwr//5MA//+U
|
||||
Af//mxL//6Us//+mLv//nBX//5QB//+TAP//lwr//8Bw///ct5L/3LgG/9u2AP/duRj/2rKw/8Bw//+d
|
||||
F///kwD//5MA//+SAP//kgD//5IA//+TAP//nRf//8Bw///asrD/3bkY/9u2AP/btQD/3LkA/925GP/c
|
||||
t5L/zpXu/7dY//+lLP//nhr//54a//+lLP//t1j//86V7v/ct5L/3bkY/9y5AP/btQAAAAAAAAAAAP/c
|
||||
uQD/3LcH/968SP/ct6j/16rk/9Kf+//Sn/v/16rk/9y3qP/evEj/3LcH/9y5AAAAAAAAAAAA4AcAAMAD
|
||||
AACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAADAAwAA4AcAACgA
|
||||
AAAgAAAAQAAAAAEAIAAAAAAAABAAAMMOAADDDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAP/btQD/27UE/9u1Kf/btWz/27Ws/9u12f/btvH/3Lf9/9y3/f/btvH/27XY/9u1q//b
|
||||
tWz/27Up/9u1BP/btQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAP/btQD/27UD/9u1N//btZf/27bf/9y4+//ctv//2bD//9Wn///ToP//06D//9Wn///Z
|
||||
sP//3Lb//9y4+//btt//27WX/9u1N//btQP/27UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAP/btQD/27UA/9u1Gf/btYn/27bq/9y3///WqP//xoD//7RT//+nMv//oCD//50X//+d
|
||||
F///oCD//6cy//+0U///xoD//9ao///ct///27bq/9u1if/btRn/27UA/9u1AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD/27UA/9u1AP/btTX/27XC/9y3/v/Wqf//vmv//6Mn//+WBv//kwD//5MA//+T
|
||||
AP//kwD//5MA//+TAP//kwD//5MA//+WBv//oyf//75r///Wqf//3Lf+/9u1wv/btTX/27UA/9u1AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA/9u1AP/btQD/27VB/9u12P/btv//y4z//6cw//+VA///kwD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+TAP//lQP//6cw///LjP//27b//9u12P/b
|
||||
tUH/27UA/9u1AAAAAAAAAAAAAAAAAP/btQD/27UA/9u1Nv/btdj/27X//8N4//+cFf//kwD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//5wV///D
|
||||
eP//27X//9u12P/btTb/27UA/9u1AAAAAAAAAAAA/9u1AP/btRr/27XB/9u2///DeP//mQ7//5MA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5MA//+TAP//kwD//5MA//+TAP//kwD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//kwD//5kO///DeP//27b//9u1wf/btRr/27UAAAAAAP/btQD/27UC/9u1if/ct///y4z//5wV//+T
|
||||
AP//lAD//5QA//+UAP//lAD//5MA//+VBP//oB7//60///+1VP//tlf//7BG//+jJ///lwn//5MA//+U
|
||||
AP//lAD//5QA//+UAP//kwD//5wV///LjP//3Lf//9u1if/btQL/27UA/9u1AP/btTf/27bo/9ap//+n
|
||||
Mf//kwD//5QA//+UAP//lAD//5QA//+UAf//oyf//8F0///UpP//2rT//9y3///ct///27X//9eq///I
|
||||
hP//qzr//5UF//+UAP//lAD//5QA//+UAP//kwD//6cx///Wqf//27bp/9u1N//btQD/27UC/9u1l//c
|
||||
t///vmv//5UC//+UAP//lAD//5QA//+UAP//lQP//7BH///Uo///3Lj//9u2///btf//27X//9u1///b
|
||||
tf//27b//9y4///Yrv//u2L//5gL//+UAP//lAD//5QA//+UAP//lQL//75r///ct///27WX/9u1A//b
|
||||
tSr/27be/9ao//+jJ///kwD//5QA//+UAP//lAD//5QA//+vRf//2Kz//9y3///btf//27T//9y2///b
|
||||
tv//27X//9u1///btf//27X//9u2///btf//vGX//5YF//+UAP//lAD//5QA//+TAP//oyf//9ao///b
|
||||
tt7/27Uq/9u1bP/cuPv/xoD//5YG//+UAP//lAD//5QA//+TAP//oSL//9Og///ct///27X//9y3///M
|
||||
kP//wHD//9it///ct///27X//9u1///btf//27X//9u2///ZsP//rUH//5MA//+UAP//lAD//5QA//+W
|
||||
Bv//xoD//9y4+//btWz/27Wr/9y2//+0U///kwD//5QA//+UAP//lAD//5QB//++av//3Lj//9u1///b
|
||||
tf//3Lj//8V+//+XCP//qjj//8uN///btf//27b//9u1///btf//27X//9y4///Ljf//mQ3//5QA//+U
|
||||
AP//lAD//5MA//+0U///3Lb//9u1rP/btdj/2bD//6cy//+TAP//lAD//5QA//+TAP//nBb//9Gc///c
|
||||
t///27X//9u1///cuP//xn///5UD//+TAP//mxH//7hb///Vpf//3Lf//9u1///btf//27X//9mv//+o
|
||||
Mv//kwD//5QA//+UAP//kwD//6cy///ZsP//27XY/9u28f/Vp///oCD//5MA//+UAP//lAD//5MA//+n
|
||||
Mf//2a///9u1///btf//27X//9y4///Hgf//lgT//5QA//+UAP//lAH//6Qo///Ffv//2rH//9u2///b
|
||||
tf//3Lf//7ZW//+TAP//lAD//5QA//+TAP//oCD//9Wn///btvH/3Lf9/9Og//+dF///kwD//5QA//+U
|
||||
AP//kwD//65C///btf//27X//9u1///btf//3Lj//8eB//+WBP//lAD//5QA//+UAP//kwD//5cI//+z
|
||||
T///16v//9u2///cuP//vmr//5QA//+UAP//lAD//5MA//+dF///06D//9y3/f/ct/3/06D//50X//+T
|
||||
AP//lAD//5QA//+TAP//rkL//9u1///btf//27X//9u1///cuP//x4L//5YE//+UAP//lAD//5QA//+T
|
||||
AP//oB7//8Fy///ZsP//27X//9y4//++av//lAD//5QA//+UAP//kwD//50X///ToP//3Lf9/9u28f/V
|
||||
p///oCD//5MA//+UAP//lAD//5MA//+nMf//2a///9u1///btf//27X//9y4///Hg///lgX//5QA//+T
|
||||
AP//lwn//7FK///RnP//3Lf//9u1///btf//3Lf//7ZW//+TAP//lAD//5QA//+TAP//oCD//9Wn///b
|
||||
tvH/27XY/9mw//+nMv//kwD//5QA//+UAP//kwD//5wV///RnP//3Lf//9u1///btf//3Lj//8eD//+V
|
||||
Bf//lAH//6Mm///FfP//2rL//9y3///btf//27X//9u1///Zr///qDL//5MA//+UAP//lAD//5MA//+n
|
||||
Mv//2bD//9u12P/btav/3Lb//7RT//+TAP//lAD//5QA//+UAP//lAH//75q///cuP//27X//9u1///c
|
||||
uP//yIT//5sS//+1VP//1KL//9y3///btf//27X//9u1///btf//3Lj//8uN//+ZDf//lAD//5QA//+U
|
||||
AP//kwD//7RT///ctv//27Wr/9u1bP/cuPv/xoD//5YG//+UAP//lAD//5QA//+TAP//oSL//9Of///c
|
||||
t///27X//9y2///RnP//yYj//9u0///ctv//27X//9u1///btf//27X//9u2///ZsP//rUH//5MA//+U
|
||||
AP//lAD//5QA//+WBv//xoD//9y4+//btWz/27Uq/9u23v/WqP//oyf//5MA//+UAP//lAD//5QA//+U
|
||||
AP//r0T//9es///ct///27X//9u2///ct///27X//9u1///btf//27X//9u1///btv//27T//7xl//+W
|
||||
Bf//lAD//5QA//+UAP//kwD//6Mn///WqP//27be/9u1Kv/btQL/27WW/9y3//++a///lQL//5QA//+U
|
||||
AP//lAD//5QA//+VA///sEf//9Sj///cuP//27b//9u1///btf//27X//9u1///btv//3Lj//9iu//+7
|
||||
Yv//mAr//5QA//+UAP//lAD//5QA//+VAv//vmv//9y3///btZb/27UC/9u1AP/btTf/27bo/9ap//+n
|
||||
Mf//kwD//5QA//+UAP//lAD//5QA//+UAf//oyf//8F0///UpP//2rT//9y3///ct///27X//9eq///I
|
||||
hP//qzr//5UF//+UAP//lAD//5QA//+UAP//kwD//6cx///Wqf//27bp/9u1N//btQD/27UA/9u1Av/b
|
||||
tYj/3Lf//8uM//+cFf//kwD//5QA//+UAP//lAD//5QA//+TAP//lQT//6Ae//+tP///tVT//7ZX//+w
|
||||
Rv//oyf//5cJ//+TAP//lAD//5QA//+UAP//lAD//5MA//+cFf//y4z//9y3///btYn/27UC/9u1AAAA
|
||||
AAD/27UA/9u1Gv/btcH/27b//8N4//+ZDv//kwD//5QA//+UAP//lAD//5QA//+UAP//kwD//5MA//+T
|
||||
AP//kwD//5MA//+TAP//lAD//5QA//+UAP//lAD//5QA//+TAP//mQ7//8N4///btv//27XB/9u1Gv/b
|
||||
tQAAAAAAAAAAAP/btQD/27UA/9u1Nf/btdj/27X//8N4//+cFf//kwD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//5wV///DeP//27X//9u12P/b
|
||||
tTX/27UA/9u1AAAAAAAAAAAAAAAAAP/btQD/27UA/9u1P//btdj/27b//8uM//+nMf//lQP//5MA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//5UD//+nMf//y4z//9u2///b
|
||||
tdj/27U//9u1AP/btQAAAAAAAAAAAAAAAAAAAAAAAAAAAP/btQD/27UA/9u1Nf/btcL/3Lf+/9ap//++
|
||||
a///oyf//5YG//+TAP//kwD//5MA//+TAP//kwD//5MA//+TAP//kwD//5YG//+jJ///vmv//9ap///c
|
||||
t/7/27XC/9u1Nf/btQD/27UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/btQD/27UA/9u1Gf/b
|
||||
tYn/27bq/9y3///WqP//xoD//7RT//+nMv//oCD//50X//+dF///oCD//6cy//+0U///xoD//9ao///c
|
||||
t///27bq/9u1if/btRn/27UA/9u1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD/27UA/9u1A//btTf/27WX/9u23//cuPv/3Lb//9mw///Vp///06D//9Og///Vp///2bD//9y2///c
|
||||
uPv/27bf/9u1l//btTf/27UD/9u1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA/9u1AP/btQT/27Up/9u1bP/btaz/27XZ/9u28f/ct/3/3Lf9/9u28f/b
|
||||
tdn/27Ws/9u1bP/btSn/27UE/9u1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AB//4A
|
||||
AH/8AAA/+AAAH/AAAA/gAAAHwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABgAAAAcAAAAPgAAAH8AAAD/gAAB/8AAA//gAAf/+A
|
||||
Af8oAAAAMAAAAGAAAAABACAAAAAAAAAkAADDDgAAww4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/27UA/9u1AP/btQ3/27U2/9u1bf/b
|
||||
taP/27XL/9u15f/btfX/27X+/9u1/v/btfT/27Xk/9u1y//btaH/27Vs/9u1Nv/btQ3/27UA/9u1AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9u1AP/btQP/27Un/9u1c//b
|
||||
tbz/27Xp/9u1/P/btf//27X//9u2///btv//3Lb//9y2///btv//27b//9u1///btf//27X8/9u16f/b
|
||||
tbz/27Vz/9u1J//btQP/27UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/btQD/27UC/9u1Lf/b
|
||||
tZD/27Xh/9u1/v/btf//3Lb//9y4///ct///2rP//9es///UpP//06D//9Og///UpP//16z//9qz///c
|
||||
t///3Lj//9y2///btf//27X+/9u14f/btZD/27Ut/9u1Av/btQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/27UA/9u1AP/b
|
||||
tRX/27V8/9u14v/btf//27X//9y3///btP//06H//8Z+//+3Wf//qzz//6Qo//+fHf//nRb//50W//+f
|
||||
Hf//pCj//6s8//+3Wf//xn7//9Oh///btP//3Lf//9u1///btf//27Xi/9u1fP/btRX/27UA/9u1AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/b
|
||||
tQD/27UA/9u1Ov/btb7/27X9/9u1///ct///2a///8mG//+xSv//nhv//5YF//+TAP//kwD//5MA//+T
|
||||
AP//kwD//5MA//+TAP//kwD//5MA//+TAP//lgX//54b//+xSv//yYb//9mv///ct///27X//9u1/f/b
|
||||
tb7/27U6/9u1AP/btQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA/9u1AP/btQT/27Vc/9u14v/btf//3Lb//9q0///JiP//qzv//5gK//+TAP//kwD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+TAP//mAr//6s7///J
|
||||
iP//2rT//9y2///btf//27Xi/9u1XP/btQT/27UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD/27UA/9u1Bf/btXD/27Xw/9u1///ct///1KP//7RT//+ZDv//kwD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5MA//+ZDv//tFP//9Sj///ct///27X//9u18P/btXD/27UF/9u1AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/btQD/27UE/9u1cP/btfT/27X//9y3///Mjv//pSv//5QB//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAH//6Ur///Mjv//3Lf//9u1///btfT/27Vw/9u1BP/b
|
||||
tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9u1AP/btQD/27Ve/9u18f/btf//27b//8eC//+e
|
||||
Gv//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+eGv//x4L//9u2///b
|
||||
tf//27Xx/9u1Xv/btQD/27UAAAAAAAAAAAAAAAAAAAAAAAAAAAD/27UA/9u1AP/btTv/27Xi/9u1///c
|
||||
t///x4L//5wV//+TAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+T
|
||||
AP//nBX//8eC///ct///27X//9u14v/btTv/27UA/9u1AAAAAAAAAAAAAAAAAAAAAAD/27UA/9u1Fv/b
|
||||
tb7/27X//9y3///Mj///nhr//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//kwD//5MA//+UAf//lQP//5UD//+UAf//kwD//5MA//+TAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//kwD//54a///Mjv//3Lf//9u1///btb7/27UW/9u1AAAAAAAAAAAAAAAAAP/b
|
||||
tQD/27UA/9u1e//btf7/3Lb//9Sj//+lLP//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5MA//+YC///pSz//7RS//+/bf//xHz//8Z////BdP//uV7//6s8//+dF///lAL//5MA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+lLP//1KP//9y2///btf7/27V8/9u1AP/b
|
||||
tQAAAAAAAAAAAP/btQD/27Ut/9u14P/btf//2rP//7RS//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+TAP//mQ7//7FL///Li///2K3//9y2///cuP//3Lj//9y4///cuP//3Lj//9qy///R
|
||||
nP//vGf//6Eh//+UAf//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//tFL//9qz///b
|
||||
tf//27Xh/9u1Lv/btQAAAAAA/9u1AP/btQL/27WR/9u1///ct///yYf//5kN//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QB//+mLf//yYj//9u0///ct///27b//9u1///btf//27X//9u1///b
|
||||
tf//27X//9u1///ct///3Lf//9Og//+zUP//lwj//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//mQ3//8mH///ct///27X//9u1kf/btQL/27UA/9u1AP/btSj/27Xh/9u1///Zr///qzv//5MA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAL//65C///Uo///3Lj//9u1///btf//27X//9u1///b
|
||||
tf//27X//9u1///btf//27X//9u1///btf//27X//9y3///asv//v23//5kO//+TAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//kwD//6s7///Zr///27X//9u14f/btSj/27UA/9u1AP/btXL/27X//9y3///J
|
||||
h///mAr//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//rUD//9eq///ct///27X//9u1///b
|
||||
tf//27b//9u2///btf//27X//9u1///btf//27X//9u1///btf//27X//9u1///btv//27b//8Bw//+Y
|
||||
Cv//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5gK///Jhv//3Lf//9u1///btXL/27UA/9u1Df/b
|
||||
tbv/27X//9u0//+xSv//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+jKP//06D//9y3///b
|
||||
tf//27X//9u1///btf//1qf//9it///ct///27X//9u1///btf//27X//9u1///btf//27X//9u1///b
|
||||
tf//27X//9q0//+2WP//lAH//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+xSv//27T//9u1///b
|
||||
tbv/27UN/9u1Nv/bten/3Lb//9Oh//+eG///kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5gK///G
|
||||
f///3Lj//9u1///btf//27X//9u1///cuP//wHD//6s8///Nkf//27b//9u2///btf//27X//9u1///b
|
||||
tf//27X//9u1///btf//27X//9y2///Vpv//pCr//5MA//+UAP//lAD//5QA//+UAP//lAD//5MA//+e
|
||||
G///06H//9y2///bten/27U2/9u1bP/btfz/3Lj//8Z///+WBf//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//kwD//6w9///Zsf//27X//9u1///btf//27X//9u1///cuP//vmv//5MA//+cFP//umD//9Wn///c
|
||||
t///27X//9u1///btf//27X//9u1///btf//27X//9u1///cuP//wnT//5UE//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+WBf//xn///9y4///btfz/27Vt/9u1of/btf//3Lf//7dZ//+TAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lgX//8V8///cuP//27X//9u1///btf//27X//9u1///cuP//vmv//5QA//+T
|
||||
AP//lAL//6Ut///Hgv//2rP//9y3///btf//27X//9u1///btf//27X//9u1///btv//1ab//6Ej//+T
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+TAP//t1n//9y3///btf//27Wi/9u1yv/btf//2rP//6s8//+T
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+TAP//nx3//9Sj///btv//27X//9u1///btf//27X//9u1///c
|
||||
uP//vmz//5QA//+UAP//lAD//5MA//+YC///sk7//9Kd///ct///27b//9u1///btf//27X//9u1///b
|
||||
tf//27b//7NP//+TAP//lAD//5QA//+UAP//lAD//5QA//+TAP//qzz//9qz///btf//27XK/9u15P/b
|
||||
tv//16z//6Qo//+TAP//lAD//5QA//+UAP//lAD//5QA//+TAP//qzv//9qy///btf//27X//9u1///b
|
||||
tf//27X//9u1///cuP//v27//5QA//+UAP//lAD//5QA//+UAP//kwD//6Af///Acf//2K7//9y3///b
|
||||
tf//27X//9u1///btf//3Lj//8J1//+VAf//lAD//5QA//+UAP//lAD//5QA//+TAP//pCj//9es///b
|
||||
tv//27Xk/9u19f/btv//1KT//58c//+TAP//lAD//5QA//+UAP//lAD//5QA//+TAP//tVP//9y3///b
|
||||
tf//27X//9u1///btf//27X//9u1///cuP//v2///5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+W
|
||||
Bv//qzz//82Q///btP//27X//9u1///btf//3Lf//8uL//+XCf//lAD//5QA//+UAP//lAD//5QA//+T
|
||||
AP//nx3//9Sk///btv//27X1/9u1/v/ctv//06D//50W//+TAP//lAD//5QA//+UAP//lAD//5QA//+T
|
||||
AP//umH//9y4///btf//27X//9u1///btf//27X//9u1///cuP//v2///5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//kwD//5sS///BdP//27X//9u1///btf//3Lf//8+W//+aDv//lAD//5QA//+U
|
||||
AP//lAD//5QA//+TAP//nRb//9Og///ctv//27X+/9u1/v/ctv//06D//50W//+TAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+TAP//umH//9y4///btf//27X//9u1///btf//27X//9u1///cuP//wG///5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+TAP//lwj//69E///QmP//27X//9u1///btf//3Lf//8+W//+a
|
||||
Dv//lAD//5QA//+UAP//lAD//5QA//+TAP//nRb//9Og///ctv//27X+/9u19f/btv//1KT//58d//+T
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+TAP//tVP//9y3///btf//27X//9u1///btf//27X//9u1///c
|
||||
uP//wHL//5QA//+UAP//lAD//5QA//+UAP//lAD//5QB//+hIv//w3f//9mx///ct///27X//9u1///b
|
||||
tf//3Lf//8uL//+XCf//lAD//5QA//+UAP//lAD//5QA//+TAP//nx3//9Sk///btv//27X1/9u15P/b
|
||||
tv//16z//6Qo//+TAP//lAD//5QA//+UAP//lAD//5QA//+TAP//qzv//9qy///btf//27X//9u1///b
|
||||
tf//27X//9u1///cuP//wXL//5QA//+UAP//lAD//5QA//+TAP//mAv//7NP///Sn///3Lf//9u1///b
|
||||
tf//27X//9u1///btf//3Lj//8J1//+VAf//lAD//5QA//+UAP//lAD//5QA//+TAP//pCj//9es///b
|
||||
tv//27Xk/9u1yv/btf//2rP//6s8//+TAP//lAD//5QA//+UAP//lAD//5QA//+TAP//nxz//9Sj///b
|
||||
tv//27X//9u1///btf//27X//9u1///cuP//wXL//5QA//+UAP//lAD//5QB//+kKf//xoH//9qz///c
|
||||
t///27X//9u1///btf//27X//9u1///btf//27b//7NP//+TAP//lAD//5QA//+UAP//lAD//5QA//+T
|
||||
AP//qzz//9qz///btf//27XK/9u1of/btf//3Lf//7dZ//+TAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lgX//8V8///cuP//27X//9u1///btf//27X//9u1///cuP//wXL//5QA//+TAP//mg///7dZ///V
|
||||
pf//3Lf//9u1///btf//27X//9u1///btf//27X//9u1///btv//1ab//6Ej//+TAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+TAP//t1n//9y3///btf//27Wh/9u1bP/btfz/3Lj//8Z///+WBf//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//kwD//6w9///Zsf//27X//9u1///btf//27X//9u1///cuP//wXX//5UE//+n
|
||||
Mv//yon//9u1///btv//27X//9u1///btf//27X//9u1///btf//27X//9u1///cuP//wnT//5UE//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+WBf//xn///9y4///btfz/27Vs/9u1Nv/bten/3Lb//9Oh//+e
|
||||
G///kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5gK///Gf///3Lj//9u1///btf//27X//9u1///c
|
||||
t///yIX//7tk///Wqf//3Lf//9u1///btf//27X//9u1///btf//27X//9u1///btf//27X//9y2///V
|
||||
pv//pCr//5MA//+UAP//lAD//5QA//+UAP//lAD//5MA//+eG///06H//9y2///bten/27U2/9u1Df/b
|
||||
tbv/27X//9u0//+xSv//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+jJ///06D//9y3///b
|
||||
tf//27X//9u1///btf//2rL//9u1///btv//27X//9u1///btf//27X//9u1///btf//27X//9u1///b
|
||||
tf//27X//9q0//+2V///lAH//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+xSv//27T//9u1///b
|
||||
tbv/27UN/9u1AP/btXL/27X//9y3///Jh///mAr//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//rUD//9ap///ct///27X//9u1///btf//27X//9u1///btf//27X//9u1///btf//27X//9u1///b
|
||||
tf//27X//9u1///btv//27X//8Bv//+YCv//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5gK///J
|
||||
h///3Lf//9u1///btXL/27UA/9u1AP/btSf/27Xg/9u1///Zr///qzv//5MA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAL//65C///Uo///3Lj//9u1///btf//27X//9u1///btf//27X//9u1///b
|
||||
tf//27X//9u1///btf//27X//9y3///asv//vmz//5kO//+TAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//kwD//6s7///Zr///27X//9u14P/btSf/27UA/9u1AP/btQH/27WQ/9u1///ct///yYf//5kN//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QB//+mLf//yYj//9u0///ct///27b//9u1///b
|
||||
tf//27X//9u1///btf//27X//9u1///ct///3Lf//9Og//+zUP//lwj//5MA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//mQ3//8mH///ct///27X//9u1kP/btQH/27UAAAAAAP/btQD/27Ut/9u14P/b
|
||||
tf//2rP//7RS//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+TAP//mQ7//7FL///K
|
||||
i///2Kz//9y2///cuP//3Lj//9y4///cuP//3Lj//9qy///RnP//vGf//6Eh//+UAf//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//tFL//9qz///btf//27Xh/9u1Lv/btQAAAAAAAAAAAP/b
|
||||
tQD/27UA/9u1e//btf3/3Lb//9Sj//+lLP//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5MA//+YC///pSz//7RS//+/bf//xHz//8Z////BdP//uV7//6s7//+dFv//lAL//5MA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+lLP//1KP//9y2///btf3/27V8/9u1AP/b
|
||||
tQAAAAAAAAAAAAAAAAD/27UA/9u1Fv/btb3/27X//9y3///Mj///nhr//5MA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//5MA//+UAf//lQP//5UD//+UAf//kwD//5MA//+T
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//54a///Mjv//3Lf//9u1///b
|
||||
tb3/27UW/9u1AAAAAAAAAAAAAAAAAAAAAAD/27UA/9u1AP/btTv/27Xh/9u1///ct///x4L//5wV//+T
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+TAP//nBX//8eC///c
|
||||
t///27X//9u14f/btTv/27UA/9u1AAAAAAAAAAAAAAAAAAAAAAAAAAAA/9u1AP/btQD/27Vc/9u18P/b
|
||||
tf//27b//8eC//+eGv//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+e
|
||||
Gv//x4L//9u2///btf//27Xw/9u1XP/btQD/27UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/b
|
||||
tQD/27UD/9u1b//btfL/27X//9y3///Mjv//pSv//5QB//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAH//6Ur///Mjv//3Lf//9u1///btfL/27Vv/9u1A//btQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD/27UA/9u1Bf/btW7/27Xw/9u1///ct///1KP//7VT//+ZDv//kwD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5MA//+ZDv//tVP//9Sj///ct///27X//9u18P/btW7/27UF/9u1AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9u1AP/btQT/27Vc/9u14v/btf//3Lb//9u0///J
|
||||
iP//qzv//5gK//+TAP//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5MA//+TAP//mAr//6s7///JiP//27T//9y2///btf//27Xi/9u1XP/btQT/27UAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/btQD/27UA/9u1Ov/b
|
||||
tb7/27X9/9u1///ct///2a///8mG//+xSv//nhv//5YF//+TAP//kwD//5MA//+TAP//kwD//5MA//+T
|
||||
AP//kwD//5MA//+TAP//lgX//54b//+xSv//yYb//9mv///ct///27X//9u1/f/btb7/27U6/9u1AP/b
|
||||
tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD/27UA/9u1AP/btRX/27V8/9u14v/btf//27X//9y3///btP//06H//8Z+//+3Wf//qzz//6Qo//+f
|
||||
HP//nRb//50W//+fHf//pCj//6s8//+3Wf//xn7//9Oh///btP//3Lf//9u1///btf//27Xi/9u1fP/b
|
||||
tRX/27UA/9u1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/btQD/27UC/9u1Lf/btZD/27Xh/9u1/v/btf//3Lb//9y4///c
|
||||
t///2rP//9es///UpP//06D//9Og///UpP//16z//9qz///ct///3Lj//9y2///btf//27X+/9u14f/b
|
||||
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
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -5,8 +5,6 @@ using System.ComponentModel.Composition.Hosting;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using Sys;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public class Addon
|
||||
@@ -28,7 +26,7 @@ namespace mpvnet
|
||||
foreach (string i in Directory.GetDirectories(dir))
|
||||
catalog.Catalogs.Add(new DirectoryCatalog(i, "*Addon.dll"));
|
||||
|
||||
dir = mp.MpvConfFolder + "\\Addons";
|
||||
dir = mp.ConfFolder + "\\Addons";
|
||||
|
||||
if (Directory.Exists(dir))
|
||||
foreach (string i in Directory.GetDirectories(dir))
|
||||
@@ -7,7 +7,7 @@ using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Interop;
|
||||
|
||||
using Sys;
|
||||
using VB = Microsoft.VisualBasic;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
@@ -28,7 +28,7 @@ namespace mpvnet
|
||||
Type type = typeof(Command);
|
||||
MethodInfo[] methods = type.GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
|
||||
|
||||
foreach (var i in methods)
|
||||
foreach (MethodInfo i in methods)
|
||||
{
|
||||
ParameterInfo[] parameters = i.GetParameters();
|
||||
|
||||
@@ -46,20 +46,15 @@ namespace mpvnet
|
||||
public static void open_files(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
using (var d = new OpenFileDialog())
|
||||
{
|
||||
d.Multiselect = true;
|
||||
d.Filter = Sys.GetFilter();
|
||||
|
||||
using (var d = new OpenFileDialog() { Multiselect = true })
|
||||
if (d.ShowDialog() == DialogResult.OK)
|
||||
mp.LoadFiles(d.FileNames);
|
||||
}
|
||||
mp.Load(d.FileNames);
|
||||
}));
|
||||
}
|
||||
|
||||
public static void open_conf_folder(string[] args)
|
||||
{
|
||||
Process.Start(mp.MpvConfFolder);
|
||||
Process.Start(mp.ConfFolder);
|
||||
}
|
||||
|
||||
public static void show_input_editor(string[] args)
|
||||
@@ -98,9 +93,18 @@ namespace mpvnet
|
||||
}));
|
||||
}
|
||||
|
||||
public static void show_media_search(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
var w = new EverythingWindow();
|
||||
new WindowInteropHelper(w).Owner = MainForm.Instance.Handle;
|
||||
w.ShowDialog();
|
||||
}));
|
||||
}
|
||||
|
||||
public static void show_history(string[] args)
|
||||
{
|
||||
var fp = mp.MpvConfFolder + "history.txt";
|
||||
var fp = mp.ConfFolder + "history.txt";
|
||||
|
||||
if (File.Exists(fp))
|
||||
Process.Start(fp);
|
||||
@@ -126,7 +130,7 @@ namespace mpvnet
|
||||
{
|
||||
fileSize = new FileInfo(path).Length;
|
||||
|
||||
if (FileAssociation.AudioTypes.Contains(Path.GetExtension(path).ToLower().TrimStart('.')))
|
||||
if (App.AudioTypes.Contains(Path.GetExtension(path).ToLower().TrimStart('.')))
|
||||
{
|
||||
using (MediaInfo mediaInfo = new MediaInfo(path))
|
||||
{
|
||||
@@ -152,7 +156,8 @@ namespace mpvnet
|
||||
|
||||
TimeSpan position = TimeSpan.FromSeconds(mp.get_property_number("time-pos"));
|
||||
TimeSpan duration2 = TimeSpan.FromSeconds(mp.get_property_number("duration"));
|
||||
string videoCodec = 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();
|
||||
|
||||
text = Path.GetFileName(path) + "\n" +
|
||||
FormatTime(position.TotalMinutes) + ":" +
|
||||
@@ -164,22 +169,23 @@ namespace mpvnet
|
||||
if (fileSize > 0)
|
||||
text += Convert.ToInt32(fileSize / 1024.0 / 1024.0).ToString() + " MB\n";
|
||||
|
||||
text += $"{videoCodec}\n";
|
||||
text += $"{videoFormat}\n{audioCodec}";
|
||||
|
||||
mp.commandv("show-text", text, "5000");
|
||||
string FormatTime(double value) => ((int)value).ToString("00");
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
Msg.ShowException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void execute_mpv_command(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
string command = Microsoft.VisualBasic.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegistryHelp.GetString("HKCU\\Software\\" + Application.ProductName, "RecentExecutedCommand"));
|
||||
string command = VB.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegistryHelp.GetString(App.RegPath, "RecentExecutedCommand"));
|
||||
if (string.IsNullOrEmpty(command)) return;
|
||||
RegistryHelp.SetObject("HKCU\\Software\\" + Application.ProductName, "RecentExecutedCommand", command);
|
||||
RegistryHelp.SetObject(App.RegPath, "RecentExecutedCommand", command);
|
||||
mp.command_string(command, false);
|
||||
}));
|
||||
}
|
||||
@@ -187,9 +193,9 @@ namespace mpvnet
|
||||
public static void open_url(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
string command = Microsoft.VisualBasic.Interaction.InputBox("Enter URL to be opened.");
|
||||
string command = VB.Interaction.InputBox("Enter URL to be opened.");
|
||||
if (string.IsNullOrEmpty(command)) return;
|
||||
mp.LoadFiles(command);
|
||||
mp.Load(command);
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -200,7 +206,6 @@ namespace mpvnet
|
||||
{
|
||||
d.InitialDirectory = Path.GetDirectoryName(mp.get_property_string("path", false));
|
||||
d.Multiselect = true;
|
||||
|
||||
if (d.ShowDialog() == DialogResult.OK)
|
||||
foreach (string i in d.FileNames)
|
||||
mp.commandv("sub-add", i);
|
||||
@@ -223,6 +228,16 @@ namespace mpvnet
|
||||
}));
|
||||
}
|
||||
|
||||
public static void add_files_to_playlist(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
using (var d = new OpenFileDialog() { Multiselect = true })
|
||||
if (d.ShowDialog() == DialogResult.OK)
|
||||
foreach(string file in d.FileNames)
|
||||
mp.commandv("loadfile", file, "append");
|
||||
}));
|
||||
}
|
||||
|
||||
public static void cycle_audio(string[] args)
|
||||
{
|
||||
string filePath = mp.get_property_string("path", false);
|
||||
@@ -239,5 +254,35 @@ namespace mpvnet
|
||||
mp.commandv("show-text", audTracks[aid - 1].Text.Substring(3), "5000");
|
||||
}
|
||||
}
|
||||
|
||||
public static void manage_file_associations(string[] args)
|
||||
{
|
||||
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 = Application.ExecutablePath;
|
||||
proc.StartInfo.Arguments = "--reg-file-assoc " + result;
|
||||
proc.StartInfo.Verb = "runas";
|
||||
try {
|
||||
proc.Start();
|
||||
}
|
||||
catch (Exception)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -12,18 +13,113 @@ using System.Runtime.Serialization;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using Microsoft.Win32;
|
||||
using VB = Microsoft.VisualBasic;
|
||||
|
||||
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 ClipboardMonitoring { get; set; } = "yes";
|
||||
|
||||
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 DarkMode { get; set; } = "always";
|
||||
public static string ProcessInstance { get; set; } = "single";
|
||||
|
||||
public static bool DebugMode { get; set; } = false;
|
||||
|
||||
public static bool IsDarkMode {
|
||||
get => (DarkMode == "system" && Sys.IsDarkTheme) || DarkMode == "always";
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
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 {
|
||||
string darkMode = MainForm.Instance.MpvNetDarkMode;
|
||||
object value = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", 1);
|
||||
if (value is null) value = 1;
|
||||
bool isDarkTheme = (int)value == 0;
|
||||
return (darkMode == "system" && isDarkTheme) || darkMode == "always";
|
||||
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 "clipboard-monitoring": ClipboardMonitoring = value; break;
|
||||
case "process-instance": ProcessInstance = value; break;
|
||||
case "dark-mode": DarkMode = value; break;
|
||||
case "debug-mode": DebugMode = value == "yes"; 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 switchName = i.Substring(2);
|
||||
|
||||
switch (switchName)
|
||||
{
|
||||
case "fs":
|
||||
case "fullscreen":
|
||||
mp.Fullscreen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,12 +147,6 @@ namespace mpvnet
|
||||
{ }
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string GetFilter()
|
||||
{
|
||||
string[] fileTypes = "264 265 3gp aac ac3 avc avi avs bmp divx dts dtshd dtshr dtsma eac3 evo flac flv h264 h265 hevc hvc jpg jpeg m2t m2ts m2v m4a m4v mka mkv mlp mov mp2 mp3 mp4 mpa mpeg mpg mpv mts ogg ogm opus pcm png pva raw rmvb thd thd+ac3 true-hd truehd ts vdr vob vpy w64 wav webm wmv y4m".Split(' ');
|
||||
return "*." + String.Join(";*.", fileTypes) + "|*." + String.Join(";*.", fileTypes) + "|All Files|*.*";
|
||||
}
|
||||
}
|
||||
|
||||
public class StringLogicalComparer : IComparer, IComparer<string>
|
||||
@@ -76,8 +166,6 @@ namespace mpvnet
|
||||
static string ExeFilename = Path.GetFileName(Application.ExecutablePath);
|
||||
static string ExeFilenameNoExt = Path.GetFileNameWithoutExtension(Application.ExecutablePath);
|
||||
static string[] Types;
|
||||
public static string[] VideoTypes = "mpg avi vob mp4 mkv avs 264 mov wmv flv h264 asf webm mpeg mpv y4m avc hevc 265 h265 m2v m2ts vpy mts webm m4v".Split(" ".ToCharArray());
|
||||
public static string[] AudioTypes = "mp2 mp3 ac3 wav w64 m4a dts dtsma dtshr dtshd eac3 thd thd+ac3 ogg mka aac opus flac mpa".Split(" ".ToCharArray());
|
||||
|
||||
public static void Register(string[] types)
|
||||
{
|
||||
@@ -96,9 +184,9 @@ namespace mpvnet
|
||||
RegistryHelp.SetObject($"HKCR\\Applications\\{ExeFilename}\\SupportedTypes", "." + ext, "");
|
||||
RegistryHelp.SetObject($"HKCR\\" + "." + ext, null, ExeFilenameNoExt + "." + ext);
|
||||
RegistryHelp.SetObject($"HKCR\\" + "." + ext + "\\OpenWithProgIDs", ExeFilenameNoExt + "." + ext, "");
|
||||
if (VideoTypes.Contains(ext))
|
||||
if (App.VideoTypes.Contains(ext))
|
||||
RegistryHelp.SetObject($"HKCR\\" + "." + ext, "PerceivedType", "video");
|
||||
if (AudioTypes.Contains(ext))
|
||||
if (App.AudioTypes.Contains(ext))
|
||||
RegistryHelp.SetObject($"HKCR\\" + "." + ext, "PerceivedType", "audio");
|
||||
RegistryHelp.SetObject($"HKCR\\" + ExeFilenameNoExt + "." + ext + "\\shell\\open", null, "Play with " + Application.ProductName);
|
||||
RegistryHelp.SetObject($"HKCR\\" + ExeFilenameNoExt + "." + ext + "\\shell\\open\\command", null, $"\"{ExePath}\" \"%1\"");
|
||||
@@ -151,14 +239,18 @@ namespace mpvnet
|
||||
|
||||
public static void RemoveKey(string path)
|
||||
{
|
||||
GetRootKey(path).DeleteSubKeyTree(path.Substring(5), false);
|
||||
try {
|
||||
GetRootKey(path).DeleteSubKeyTree(path.Substring(5), false);
|
||||
} catch { }
|
||||
}
|
||||
|
||||
public static void RemoveValue(string path, string name)
|
||||
{
|
||||
using (RegistryKey rk = GetRootKey(path).OpenSubKey(path.Substring(5), true))
|
||||
if (!(rk is null))
|
||||
rk.DeleteValue(name, false);
|
||||
try {
|
||||
using (RegistryKey rk = GetRootKey(path).OpenSubKey(path.Substring(5), true))
|
||||
if (!(rk is null))
|
||||
rk.DeleteValue(name, false);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
static RegistryKey GetRootKey(string path)
|
||||
@@ -180,7 +272,6 @@ namespace mpvnet
|
||||
public int ID { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class CommandItem : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
@@ -207,46 +298,70 @@ namespace mpvnet
|
||||
}
|
||||
}
|
||||
|
||||
public static ObservableCollection<CommandItem> GetItems(string content)
|
||||
{
|
||||
var items = new ObservableCollection<CommandItem>();
|
||||
|
||||
if (!string.IsNullOrEmpty(content))
|
||||
{
|
||||
foreach (string line in content.Split('\r', '\n'))
|
||||
{
|
||||
string val = line.Trim();
|
||||
if (val.StartsWith("#")) continue;
|
||||
if (!val.Contains(" ")) continue;
|
||||
CommandItem item = new CommandItem();
|
||||
item.Input = val.Substring(0, val.IndexOf(" "));
|
||||
if (item.Input == "_") item.Input = "";
|
||||
val = val.Substring(val.IndexOf(" ") + 1);
|
||||
|
||||
if (val.Contains("#menu:"))
|
||||
{
|
||||
item.Path = val.Substring(val.IndexOf("#menu:") + 6).Trim();
|
||||
val = val.Substring(0, val.IndexOf("#menu:"));
|
||||
if (item.Path.Contains(";"))
|
||||
item.Path = item.Path.Substring(item.Path.IndexOf(";") + 1).Trim();
|
||||
}
|
||||
|
||||
item.Command = val.Trim();
|
||||
if (item.Command == "")
|
||||
continue;
|
||||
if (item.Command.ToLower() == "ignore")
|
||||
item.Command = "";
|
||||
MigrateCommands(item);
|
||||
items.Add(item);
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private static ObservableCollection<CommandItem> _Items;
|
||||
|
||||
public static ObservableCollection<CommandItem> Items {
|
||||
get {
|
||||
if (_Items is null)
|
||||
{
|
||||
_Items = new ObservableCollection<CommandItem>();
|
||||
|
||||
if (File.Exists(mp.InputConfPath))
|
||||
{
|
||||
foreach (string line in File.ReadAllLines(mp.InputConfPath))
|
||||
{
|
||||
string val = line.Trim();
|
||||
if (val.StartsWith("#")) continue;
|
||||
if (!val.Contains(" ")) continue;
|
||||
CommandItem item = new CommandItem();
|
||||
item.Input = val.Substring(0, val.IndexOf(" ")).Replace("_", "");
|
||||
val = val.Substring(val.IndexOf(" ") + 1);
|
||||
|
||||
if (val.Contains("#menu:"))
|
||||
{
|
||||
item.Path = val.Substring(val.IndexOf("#menu:") + 6).Trim();
|
||||
val = val.Substring(0, val.IndexOf("#menu:"));
|
||||
|
||||
if (item.Path.Contains(";"))
|
||||
item.Path = item.Path.Substring(item.Path.IndexOf(";") + 1).Trim();
|
||||
}
|
||||
|
||||
item.Command = val.Trim();
|
||||
if (item.Command == "")
|
||||
continue;
|
||||
if (item.Command.ToLower() == "ignore")
|
||||
item.Command = "";
|
||||
_Items.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
_Items = GetItems(File.ReadAllText(mp.InputConfPath));
|
||||
return _Items;
|
||||
}
|
||||
}
|
||||
|
||||
public static void MigrateCommands(CommandItem item)
|
||||
{
|
||||
switch (item.Command)
|
||||
{
|
||||
case "script-message mpv.net show-prefs":
|
||||
item.Command = "script-message mpv.net show-conf-editor";
|
||||
break;
|
||||
case "script-message mpv.net show-keys":
|
||||
item.Command = "script-message mpv.net show-input-editor";
|
||||
break;
|
||||
case "script-message mpv.net history":
|
||||
item.Command = "script-message mpv.net show-history";
|
||||
break;
|
||||
case "script-message mpv.net open-config-folder":
|
||||
item.Command = "script-message open-conf-folder";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CursorHelp
|
||||
@@ -278,4 +393,15 @@ namespace mpvnet
|
||||
Math.Abs(screenPos.Y - Control.MousePosition.Y) > 10;
|
||||
}
|
||||
}
|
||||
|
||||
public class SingleProcess
|
||||
{
|
||||
public static int Message { get; } = RegisterWindowMessage("mpvnet_IPC");
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
static extern int RegisterWindowMessage(string id);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool AllowSetForegroundWindow(int dwProcessId);
|
||||
}
|
||||
}
|
||||
67
mpv.net/Misc/Program.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] args = Environment.GetCommandLineArgs().Skip(1).ToArray();
|
||||
|
||||
if (args.Length == 2 && args[0] == "--reg-file-assoc")
|
||||
{
|
||||
if (args[1] == "audio") FileAssociation.Register(App.AudioTypes);
|
||||
if (args[1] == "video") FileAssociation.Register(App.VideoTypes);
|
||||
if (args[1] == "unreg") FileAssociation.Unregister();
|
||||
return;
|
||||
}
|
||||
|
||||
App.Init();
|
||||
Mutex mutex = new Mutex(true, "mpvnetProcessInstance", out bool isFirst);
|
||||
|
||||
if ((App.ProcessInstance == "single" || App.ProcessInstance == "queue") && !isFirst)
|
||||
{
|
||||
List<string> files = new List<string>();
|
||||
|
||||
foreach (string arg in args)
|
||||
if (!arg.StartsWith("--") && (File.Exists(arg) || arg == "-" || arg.StartsWith("http")))
|
||||
files.Add(arg);
|
||||
|
||||
if (files.Count > 0)
|
||||
RegistryHelp.SetObject(App.RegPath, "ShellFiles", files.ToArray());
|
||||
|
||||
RegistryHelp.SetObject(App.RegPath, "ProcessInstanceMode", App.ProcessInstance);
|
||||
|
||||
foreach(Process process in Process.GetProcessesByName("mpvnet"))
|
||||
{
|
||||
try {
|
||||
SingleProcess.AllowSetForegroundWindow(process.Id);
|
||||
Native.SendMessage(process.MainWindowHandle, SingleProcess.Message, IntPtr.Zero, IntPtr.Zero);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
mutex.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new MainForm());
|
||||
mutex.Dispose();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Msg.ShowException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,12 +24,26 @@ namespace mpvnet
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool AdjustWindowRect(ref RECT lpRect, uint dwStyle, bool bMenu);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetWindowLongPtrW(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||
private static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
|
||||
private static extern IntPtr GetWindowLong64(IntPtr hWnd, int nIndex);
|
||||
|
||||
public static IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex)
|
||||
{
|
||||
if (IntPtr.Size == 8)
|
||||
return GetWindowLong64(hWnd, nIndex);
|
||||
else
|
||||
return GetWindowLong32(hWnd, nIndex);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
@@ -32,7 +32,7 @@ namespace mpvnet
|
||||
|
||||
public static void AddWindowBorders(IntPtr hwnd, ref Native.RECT rc)
|
||||
{
|
||||
Native.AdjustWindowRect(ref rc, (uint)Native.GetWindowLongPtrW(hwnd, -16 /* GWL_STYLE */), false);
|
||||
Native.AdjustWindowRect(ref rc, (uint)Native.GetWindowLongPtr(hwnd, -16 /* GWL_STYLE */), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
656
mpv.net/Native/TaskDialog.cs
Normal file
@@ -0,0 +1,656 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
public class Msg
|
||||
{
|
||||
private static string ShownMessages;
|
||||
|
||||
public static string SupportURL { get; set; }
|
||||
|
||||
public static void Show(string mainInstruction, string content = null)
|
||||
{
|
||||
Msg.Show(mainInstruction, content, MsgIcon.Info, MsgButtons.Ok, MsgResult.None);
|
||||
}
|
||||
|
||||
public static void ShowError(string mainInstruction, string content = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (TaskDialog<string> td = new TaskDialog<string>())
|
||||
{
|
||||
td.AllowCancel = false;
|
||||
|
||||
if (string.IsNullOrEmpty(content))
|
||||
{
|
||||
if (mainInstruction.Length < 80)
|
||||
td.MainInstruction = mainInstruction;
|
||||
else
|
||||
td.Content = mainInstruction;
|
||||
}
|
||||
else
|
||||
{
|
||||
td.MainInstruction = mainInstruction;
|
||||
td.Content = content;
|
||||
}
|
||||
|
||||
td.MainIcon = MsgIcon.Error;
|
||||
td.Footer = "[Copy Message](copymsg)";
|
||||
|
||||
if (!string.IsNullOrEmpty(Msg.SupportURL))
|
||||
td.Footer += $" [Contact Support]({SupportURL})";
|
||||
|
||||
td.Show();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
|
||||
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowException(Exception e)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (TaskDialog<string> td = new TaskDialog<string>())
|
||||
{
|
||||
td.MainInstruction = e.GetType().Name;
|
||||
td.Content = e.Message;
|
||||
td.MainIcon = MsgIcon.Error;
|
||||
td.ExpandedInformation = e.ToString();
|
||||
td.Footer = "[Copy Message](copymsg)";
|
||||
|
||||
if (!string.IsNullOrEmpty(Msg.SupportURL))
|
||||
td.Footer += $" [Contact Support]({SupportURL})";
|
||||
|
||||
td.Show();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
|
||||
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowWarning(string mainInstruction,
|
||||
string content = null,
|
||||
bool onlyOnce = false)
|
||||
{
|
||||
if (onlyOnce && Msg.ShownMessages != null &&
|
||||
Msg.ShownMessages.Contains(mainInstruction + content))
|
||||
return;
|
||||
|
||||
Msg.Show(mainInstruction, content, MsgIcon.Warning, MsgButtons.Ok, MsgResult.None);
|
||||
if (!onlyOnce) return;
|
||||
Msg.ShownMessages += mainInstruction + content;
|
||||
}
|
||||
|
||||
public static MsgResult ShowQuestion(string mainInstruction,
|
||||
MsgButtons buttons = MsgButtons.OkCancel)
|
||||
{
|
||||
return Msg.Show(mainInstruction, null, MsgIcon.None, buttons, MsgResult.None);
|
||||
}
|
||||
|
||||
public static MsgResult ShowQuestion(string mainInstruction,
|
||||
string content,
|
||||
MsgButtons buttons = MsgButtons.OkCancel)
|
||||
{
|
||||
return Msg.Show(mainInstruction, content, MsgIcon.None, buttons, MsgResult.None);
|
||||
}
|
||||
|
||||
public static MsgResult Show(string mainInstruction,
|
||||
string content,
|
||||
MsgIcon icon,
|
||||
MsgButtons buttons,
|
||||
MsgResult defaultButton = MsgResult.None)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (TaskDialog<MsgResult> td = new TaskDialog<MsgResult>())
|
||||
{
|
||||
td.AllowCancel = false;
|
||||
td.DefaultButton = defaultButton;
|
||||
td.MainIcon = icon;
|
||||
|
||||
if (content == null)
|
||||
{
|
||||
if (mainInstruction.Length < 80)
|
||||
td.MainInstruction = mainInstruction;
|
||||
else
|
||||
td.Content = mainInstruction;
|
||||
}
|
||||
else
|
||||
{
|
||||
td.MainInstruction = mainInstruction;
|
||||
td.Content = content;
|
||||
}
|
||||
if (buttons == MsgButtons.OkCancel)
|
||||
{
|
||||
td.AddButton("OK", MsgResult.OK);
|
||||
td.AddButton("Cancel", MsgResult.Cancel);
|
||||
}
|
||||
else
|
||||
td.CommonButtons = buttons;
|
||||
return td.Show();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (MsgResult)MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
|
||||
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TaskDialog<T> : TaskDialogNative, IDisposable
|
||||
{
|
||||
private Dictionary<int, T> IdValueDic;
|
||||
private Dictionary<int, string> IdTextDic;
|
||||
private List<int> CommandLinkShieldList;
|
||||
private IntPtr ButtonArray;
|
||||
private IntPtr RadioButtonArray;
|
||||
private List<TaskDialogNative.TASKDIALOG_BUTTON> Buttons;
|
||||
private List<TaskDialogNative.TASKDIALOG_BUTTON> RadioButtons;
|
||||
private TaskDialogNative.TASKDIALOGCONFIG Config;
|
||||
const int TDE_CONTENT = 0;
|
||||
const int TDE_EXPANDED_INFORMATION = 1;
|
||||
const int TDE_FOOTER = 2;
|
||||
const int TDE_MAIN_INSTRUCTION = 3;
|
||||
const int TDN_CREATED = 0;
|
||||
const int TDN_NAVIGATED = 1;
|
||||
const int TDN_BUTTON_CLICKED = 2;
|
||||
const int TDN_HYPERLINK_CLICKED = 3;
|
||||
const int TDN_TIMER = 4;
|
||||
const int TDN_DESTROYED = 5;
|
||||
const int TDN_RADIO_BUTTON_CLICKED = 6;
|
||||
const int TDN_DIALOG_CONSTRUCTED = 7;
|
||||
const int TDN_VERIFICATION_CLICKED = 8;
|
||||
const int TDN_HELP = 9;
|
||||
const int TDN_EXPANDO_BUTTON_CLICKED = 10;
|
||||
const int TDM_NAVIGATE_PAGE = 1125;
|
||||
const int TDM_CLICK_BUTTON = 1126;
|
||||
const int TDM_SET_MARQUEE_PROGRESS_BAR = 1127;
|
||||
const int TDM_SET_PROGRESS_BAR_STATE = 1128;
|
||||
const int TDM_SET_PROGRESS_BAR_RANGE = 1129;
|
||||
const int TDM_SET_PROGRESS_BAR_POS = 1130;
|
||||
const int TDM_SET_PROGRESS_BAR_MARQUEE = 1131;
|
||||
const int TDM_SET_ELEMENT_TEXT = 1132;
|
||||
const int TDM_CLICK_RADIO_BUTTON = 1134;
|
||||
const int TDM_ENABLE_BUTTON = 1135;
|
||||
const int TDM_ENABLE_RADIO_BUTTON = 1136;
|
||||
const int TDM_CLICK_VERIFICATION = 1137;
|
||||
const int TDM_UPDATE_ELEMENT_TEXT = 1138;
|
||||
const int TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE = 1139;
|
||||
const int TDM_UPDATE_ICON = 1140;
|
||||
private T SelectedValueValue;
|
||||
private string SelectedTextValue;
|
||||
private int TimeoutValue;
|
||||
private int ExitTickCount;
|
||||
private bool disposed;
|
||||
|
||||
public TaskDialog()
|
||||
{
|
||||
IdValueDic = new Dictionary<int, T>();
|
||||
IdTextDic = new Dictionary<int, string>();
|
||||
CommandLinkShieldList = new List<int>();
|
||||
Buttons = new List<TaskDialogNative.TASKDIALOG_BUTTON>();
|
||||
RadioButtons = new List<TaskDialogNative.TASKDIALOG_BUTTON>();
|
||||
_SelectedID = -1;
|
||||
Config = new TaskDialogNative.TASKDIALOGCONFIG();
|
||||
Config.cbSize = (uint)Marshal.SizeOf(Config);
|
||||
Config.hwndParent = GetHandle();
|
||||
Config.hInstance = IntPtr.Zero;
|
||||
Config.dwFlags = TaskDialogNative.TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION;
|
||||
Config.dwCommonButtons = MsgButtons.None;
|
||||
Config.MainIcon = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION(0);
|
||||
Config.FooterIcon = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION(0);
|
||||
Config.cxWidth = 0U;
|
||||
Config.cButtons = 0U;
|
||||
Config.cRadioButtons = 0U;
|
||||
Config.pButtons = IntPtr.Zero;
|
||||
Config.pRadioButtons = IntPtr.Zero;
|
||||
Config.nDefaultButton = 0;
|
||||
Config.nDefaultRadioButton = 0;
|
||||
Config.pszWindowTitle = ((AssemblyProductAttribute)Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true)[0]).Product;
|
||||
Config.pszMainInstruction = "";
|
||||
Config.pszContent = "";
|
||||
Config.pfCallback = new PFTASKDIALOGCALLBACK(this.DialogProc);
|
||||
}
|
||||
|
||||
public IntPtr GetHandle()
|
||||
{
|
||||
StringBuilder lpszFileName = new StringBuilder(260);
|
||||
IntPtr foregroundWindow = TaskDialogNative.GetForegroundWindow();
|
||||
TaskDialogNative.GetWindowModuleFileName(foregroundWindow, lpszFileName, 260U);
|
||||
|
||||
if (Path.GetFileName(lpszFileName.ToString().Replace(".vshost", "")) ==
|
||||
Path.GetFileName(Assembly.GetEntryAssembly().Location))
|
||||
return foregroundWindow;
|
||||
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
public bool AllowCancel {
|
||||
set {
|
||||
if (value)
|
||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION;
|
||||
else
|
||||
Config.dwFlags ^= TaskDialogNative.TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION;
|
||||
}
|
||||
}
|
||||
|
||||
public string MainInstruction {
|
||||
get => Config.pszMainInstruction;
|
||||
set => Config.pszMainInstruction = value;
|
||||
}
|
||||
|
||||
public string Content {
|
||||
get => Config.pszContent;
|
||||
set => Config.pszContent = ExpandMarkdownMarkup(value);
|
||||
}
|
||||
|
||||
public string ExpandedInformation {
|
||||
get => Config.pszExpandedInformation;
|
||||
set => Config.pszExpandedInformation = ExpandMarkdownMarkup(value);
|
||||
}
|
||||
|
||||
public string VerificationText {
|
||||
get => Config.pszVerificationText;
|
||||
set => Config.pszVerificationText = value;
|
||||
}
|
||||
|
||||
public MsgResult DefaultButton {
|
||||
get => (MsgResult)Config.nDefaultButton;
|
||||
set => Config.nDefaultButton = (int)value;
|
||||
}
|
||||
|
||||
public string Footer {
|
||||
get => Config.pszFooter;
|
||||
set => Config.pszFooter = ExpandMarkdownMarkup(value);
|
||||
}
|
||||
|
||||
public MsgIcon MainIcon {
|
||||
set => Config.MainIcon = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION((int)value);
|
||||
}
|
||||
|
||||
private int _SelectedID;
|
||||
|
||||
public int SelectedID {
|
||||
get => _SelectedID;
|
||||
set {
|
||||
foreach (var i in IdValueDic)
|
||||
if (i.Key == value) _SelectedID = value;
|
||||
}
|
||||
}
|
||||
|
||||
public T SelectedValue {
|
||||
get {
|
||||
if (IdValueDic.ContainsKey(SelectedID))
|
||||
return IdValueDic[SelectedID];
|
||||
return SelectedValueValue;
|
||||
}
|
||||
set => SelectedValueValue = value;
|
||||
}
|
||||
|
||||
public string SelectedText {
|
||||
get {
|
||||
if (IdTextDic.ContainsKey(SelectedID))
|
||||
return IdTextDic[SelectedID];
|
||||
return SelectedTextValue;
|
||||
}
|
||||
set => SelectedTextValue = value;
|
||||
}
|
||||
|
||||
public bool CheckBoxChecked {
|
||||
get => (Config.dwFlags & TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED) == TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
|
||||
set {
|
||||
if (value)
|
||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
|
||||
else
|
||||
Config.dwFlags ^= TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
|
||||
}
|
||||
}
|
||||
|
||||
public MsgButtons CommonButtons {
|
||||
get => Config.dwCommonButtons;
|
||||
set => Config.dwCommonButtons = value;
|
||||
}
|
||||
|
||||
public int Timeout {
|
||||
get => Convert.ToInt32(TimeoutValue / 1000.0);
|
||||
set {
|
||||
TimeoutValue = value * 1000;
|
||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_CALLBACK_TIMER;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddButton(string text, T value)
|
||||
{
|
||||
int n = 1000 + IdValueDic.Count + 1;
|
||||
IdValueDic[n] = value;
|
||||
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
|
||||
}
|
||||
|
||||
public string ExpandMarkdownMarkup(string value)
|
||||
{
|
||||
if (value.Contains("["))
|
||||
{
|
||||
Regex regex = new Regex(@"\[(.+)\]\((.+)\)");
|
||||
|
||||
if (regex.Match(value).Success)
|
||||
{
|
||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_ENABLE_HYPERLINKS;
|
||||
value = regex.Replace(value, "<a href=\"$2\">$1</a>");
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public void AddCommandLink(string text, T value)
|
||||
{
|
||||
int n = 1000 + IdValueDic.Count + 1;
|
||||
IdValueDic[n] = value == null ? (T)(object)text : value;
|
||||
IdTextDic[n] = text;
|
||||
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
|
||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
|
||||
}
|
||||
|
||||
public void AddCommandLink(string text, string description, T value, bool setShield = false)
|
||||
{
|
||||
int n = 1000 + IdValueDic.Count + 1;
|
||||
IdValueDic[n] = value;
|
||||
if (setShield) CommandLinkShieldList.Add(n);
|
||||
if (!string.IsNullOrEmpty(description)) text += "\n" + description;
|
||||
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
|
||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
|
||||
}
|
||||
|
||||
public void AddRadioButton(string text, T value)
|
||||
{
|
||||
int n = 1000 + IdValueDic.Count + 1;
|
||||
IdValueDic[n] = value;
|
||||
RadioButtons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
|
||||
}
|
||||
|
||||
public T Show()
|
||||
{
|
||||
MarshalDialogControlStructs();
|
||||
TaskDialogNative.TASKDIALOGCONFIG config = Config;
|
||||
int errorCode = TaskDialogNative.TaskDialogIndirect(config, out int dummy1, out int dummy2, out bool isChecked);
|
||||
if (errorCode < 0) Marshal.ThrowExceptionForHR(errorCode);
|
||||
CheckBoxChecked = isChecked;
|
||||
if (SelectedValue is MsgResult) SelectedValue = (T)(object)SelectedID;
|
||||
return SelectedValue;
|
||||
}
|
||||
|
||||
public int DialogProc(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam, IntPtr lpRefData)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case 0: //TDN_CREATED
|
||||
foreach (var i in CommandLinkShieldList)
|
||||
SendMessage(hwnd, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, new IntPtr(i), new IntPtr(1));
|
||||
break;
|
||||
case 2: //TDN_BUTTON_CLICKED
|
||||
case 6: //TDN_RADIO_BUTTON_CLICKED
|
||||
if (SelectedValue is MsgResult)
|
||||
_SelectedID = wParam.ToInt32();
|
||||
else
|
||||
SelectedID = wParam.ToInt32();
|
||||
break;
|
||||
case 3: //TDN_HYPERLINK_CLICKED
|
||||
string stringUni = Marshal.PtrToStringUni(lParam);
|
||||
if (stringUni.StartsWith("mailto") || stringUni.StartsWith("http"))
|
||||
Process.Start(stringUni);
|
||||
if (stringUni == "copymsg")
|
||||
{
|
||||
Thread thread = new Thread((ThreadStart)(() => {
|
||||
Clipboard.SetText(MainInstruction + "\r\n\r\n" + Content + "\r\n\r\n" + ExpandedInformation);
|
||||
MessageBox.Show("Message was copied to clipboard.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}));
|
||||
thread.SetApartmentState(ApartmentState.STA);
|
||||
thread.Start();
|
||||
}
|
||||
break;
|
||||
case 4: //TDN_TIMER
|
||||
if (ExitTickCount == 0) ExitTickCount = Environment.TickCount + Timeout * 1000;
|
||||
if (Environment.TickCount > ExitTickCount)
|
||||
TaskDialogNative.SendMessage(hwnd, 1126, new IntPtr(1), IntPtr.Zero);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void MarshalDialogControlStructs()
|
||||
{
|
||||
if (Buttons != null && Buttons.Count > 0)
|
||||
{
|
||||
ButtonArray = TaskDialog<T>.AllocateAndMarshalButtons(Buttons);
|
||||
Config.pButtons = ButtonArray;
|
||||
Config.cButtons = (uint)Buttons.Count;
|
||||
}
|
||||
|
||||
if (RadioButtons == null || RadioButtons.Count <= 0) return;
|
||||
RadioButtonArray = TaskDialog<T>.AllocateAndMarshalButtons(RadioButtons);
|
||||
Config.pRadioButtons = RadioButtonArray;
|
||||
Config.cRadioButtons = (uint)RadioButtons.Count;
|
||||
}
|
||||
|
||||
public static IntPtr AllocateAndMarshalButtons(List<TaskDialogNative.TASKDIALOG_BUTTON> structs)
|
||||
{
|
||||
var initialPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TASKDIALOG_BUTTON)) * structs.Count);
|
||||
var currentPtr = initialPtr;
|
||||
|
||||
foreach (var button in structs)
|
||||
{
|
||||
Marshal.StructureToPtr(button, currentPtr, false);
|
||||
currentPtr = (IntPtr)(currentPtr.ToInt64() + Marshal.SizeOf(button));
|
||||
}
|
||||
|
||||
return initialPtr;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~TaskDialog()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
protected void Dispose(bool disposing)
|
||||
{
|
||||
if (disposed) return;
|
||||
disposed = true;
|
||||
|
||||
if (ButtonArray != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(ButtonArray);
|
||||
ButtonArray = IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (RadioButtonArray != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(RadioButtonArray);
|
||||
RadioButtonArray = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public delegate int PFTASKDIALOGCALLBACK(
|
||||
IntPtr hwnd,
|
||||
uint msg,
|
||||
IntPtr wParam,
|
||||
IntPtr lParam,
|
||||
IntPtr lpRefData);
|
||||
|
||||
public class TaskDialogNative
|
||||
{
|
||||
[DllImport("comctl32", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
public static extern int TaskDialogIndirect(
|
||||
[In] TaskDialogNative.TASKDIALOGCONFIG pTaskConfig,
|
||||
out int pnButton,
|
||||
out int pnRadioButton,
|
||||
[MarshalAs(UnmanagedType.Bool)] out bool pVerificationFlagChecked);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetForegroundWindow();
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern uint GetWindowModuleFileName(
|
||||
IntPtr hwnd,
|
||||
StringBuilder lpszFileName,
|
||||
uint cchFileNameMax);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr SendMessage(
|
||||
IntPtr handle,
|
||||
int message,
|
||||
IntPtr wParam,
|
||||
IntPtr lParam);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
|
||||
public class TASKDIALOGCONFIG
|
||||
{
|
||||
public uint cbSize;
|
||||
public IntPtr hwndParent;
|
||||
public IntPtr hInstance;
|
||||
public TaskDialogNative.TASKDIALOG_FLAGS dwFlags;
|
||||
public MsgButtons dwCommonButtons;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszWindowTitle;
|
||||
public TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION MainIcon;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszMainInstruction;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszContent;
|
||||
public uint cButtons;
|
||||
public IntPtr pButtons;
|
||||
public int nDefaultButton;
|
||||
public uint cRadioButtons;
|
||||
public IntPtr pRadioButtons;
|
||||
public int nDefaultRadioButton;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszVerificationText;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszExpandedInformation;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszExpandedControlText;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszCollapsedControlText;
|
||||
public TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION FooterIcon;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszFooter;
|
||||
public PFTASKDIALOGCALLBACK pfCallback;
|
||||
public IntPtr lpCallbackData;
|
||||
public uint cxWidth;
|
||||
}
|
||||
|
||||
public enum TASKDIALOG_FLAGS
|
||||
{
|
||||
NONE = 0,
|
||||
TDF_ENABLE_HYPERLINKS = 1,
|
||||
TDF_USE_HICON_MAIN = 2,
|
||||
TDF_USE_HICON_FOOTER = 4,
|
||||
TDF_ALLOW_DIALOG_CANCELLATION = 8,
|
||||
TDF_USE_COMMAND_LINKS = 16,
|
||||
TDF_USE_COMMAND_LINKS_NO_ICON = 32,
|
||||
TDF_EXPAND_FOOTER_AREA = 64,
|
||||
TDF_EXPANDED_BY_DEFAULT = 128,
|
||||
TDF_VERIFICATION_FLAG_CHECKED = 256,
|
||||
TDF_SHOW_PROGRESS_BAR = 512,
|
||||
TDF_SHOW_MARQUEE_PROGRESS_BAR = 1024,
|
||||
TDF_CALLBACK_TIMER = 2048,
|
||||
TDF_POSITION_RELATIVE_TO_WINDOW = 4096,
|
||||
TDF_RTL_LAYOUT = 8192,
|
||||
TDF_NO_DEFAULT_RADIO_BUTTON = 16384,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
|
||||
public struct TASKDIALOGCONFIG_ICON_UNION
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public int hMainIcon;
|
||||
[FieldOffset(0)]
|
||||
public int pszIcon;
|
||||
[FieldOffset(0)]
|
||||
public IntPtr spacer;
|
||||
|
||||
public TASKDIALOGCONFIG_ICON_UNION(int i)
|
||||
{
|
||||
this = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION();
|
||||
spacer = IntPtr.Zero;
|
||||
pszIcon = 0;
|
||||
hMainIcon = i;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
|
||||
public struct TASKDIALOG_BUTTON
|
||||
{
|
||||
public int nButtonID;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszButtonText;
|
||||
|
||||
public TASKDIALOG_BUTTON(int n, string txt)
|
||||
{
|
||||
this = new TaskDialogNative.TASKDIALOG_BUTTON();
|
||||
nButtonID = n;
|
||||
pszButtonText = txt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum MsgButtons
|
||||
{
|
||||
None = 0,
|
||||
Ok = 1,
|
||||
Yes = 2,
|
||||
No = 4,
|
||||
YesNo = 6,
|
||||
Cancel = 8,
|
||||
OkCancel = 9,
|
||||
YesNoCancel = 14,
|
||||
Retry = 16,
|
||||
RetryCancel = 24,
|
||||
Close = 32,
|
||||
}
|
||||
|
||||
public enum MsgResult
|
||||
{
|
||||
None,
|
||||
OK,
|
||||
Cancel,
|
||||
Abort,
|
||||
Retry,
|
||||
Ignore,
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
public enum MsgIcon
|
||||
{
|
||||
None = 0,
|
||||
SecurityShieldGray = 65527,
|
||||
SecuritySuccess = 65528,
|
||||
SecurityError = 65529,
|
||||
SecurityWarning = 65530,
|
||||
SecurityShieldBlue = 65531,
|
||||
Shield = 65532,
|
||||
Info = 65533,
|
||||
Error = 65534,
|
||||
Warning = 65535,
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using Sys;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] args = Environment.GetCommandLineArgs();
|
||||
|
||||
if (args.Length == 3 && args[1] == "--reg-file-assoc")
|
||||
{
|
||||
if (args[2] == "audio") FileAssociation.Register(FileAssociation.AudioTypes);
|
||||
if (args[2] == "video") FileAssociation.Register(FileAssociation.VideoTypes);
|
||||
if (args[2] == "unregister") FileAssociation.Unregister();
|
||||
return;
|
||||
}
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new MainForm());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Msg.ShowException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,11 @@ using System.Runtime.InteropServices;
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("mpv.net")]
|
||||
[assembly: AssemblyDescription("A lightweight media player")]
|
||||
[assembly: AssemblyDescription("A modern media player")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("mpv.net")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017-2019 stax76")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017-2019 Frank Skare (stax76)")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("3.3.0.0")]
|
||||
[assembly: AssemblyFileVersion("3.3.0.0")]
|
||||
[assembly: AssemblyVersion("4.3.1.0")]
|
||||
[assembly: AssemblyFileVersion("4.3.1.0")]
|
||||
|
||||
87
mpv.net/Properties/Resources.Designer.cs
generated
@@ -60,30 +60,117 @@ namespace mpvnet.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to
|
||||
/// # This file defines the input (keys and mouse) bindings of mpv and mpv.net
|
||||
/// # and it also defines the context menu of mpv.net. mpv.net has an input
|
||||
/// # editor and an config editor as alternative to editing conf text files.
|
||||
/// # 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
|
||||
///
|
||||
/// # th [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string inputConf {
|
||||
get {
|
||||
return ResourceManager.GetString("inputConf", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to
|
||||
/// # This file defines the input (keys and mouse) bindings of mpv and mpv.net
|
||||
/// # and it also defines the context menu of mpv.net. mpv.net has an input
|
||||
/// # editor and an config editor as alternatives to editing conf text files.
|
||||
/// # 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
|
||||
///
|
||||
/// # t [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string inputConfHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("inputConfHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to
|
||||
///# mpv manual: https://mpv.io/manual/master/
|
||||
///
|
||||
///# mpv.net mpv.conf defaults: https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt
|
||||
///
|
||||
///input-ar-delay = 500
|
||||
///input-ar-rate = 20
|
||||
///volume = 50
|
||||
///hwdec = yes
|
||||
///keep-open = yes
|
||||
///keep-open-pause = no
|
||||
///osd-playing-msg = ${filename}
|
||||
///screenshot-directory = ~~desktop/
|
||||
///input-default-bindings = no
|
||||
///.
|
||||
/// </summary>
|
||||
internal static string mpvConf {
|
||||
get {
|
||||
return ResourceManager.GetString("mpvConf", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap mpvnet {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("mpvnet", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to [[settings]]
|
||||
///name = "dark-mode"
|
||||
///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]]
|
||||
///name = "clipboard-monitoring"
|
||||
///default = "yes"
|
||||
///filter = "mpv.net"
|
||||
///help = "Monitors the clipboard for URLs to play."
|
||||
///options = [{ name = "yes" },
|
||||
/// { name = "no" }].
|
||||
/// </summary>
|
||||
internal static string mpvNetConfToml {
|
||||
get {
|
||||
return ResourceManager.GetString("mpvNetConfToml", resourceCulture);
|
||||
|
||||
@@ -130,6 +130,9 @@
|
||||
<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">
|
||||
<value>..\Resources\mpvnet.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="mpvNetConfToml" 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>
|
||||
</data>
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
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...
|
||||
_ ignore #menu: Open > -
|
||||
_ script-message mpv.net add-files-to-playlist #menu: Open > Add files to playlist...
|
||||
Ctrl+S script-message mpv.net show-media-search #menu: Open > Show media search...
|
||||
_ ignore #menu: Open > -
|
||||
_ ignore #menu: Open > Recent
|
||||
|
||||
_ ignore #menu: -
|
||||
@@ -73,7 +76,7 @@
|
||||
Ctrl+BS set video-zoom 0; set video-pan-x 0; set video-pan-y 0 #menu: Pan & Scan > Reset
|
||||
|
||||
Ctrl+1 add contrast -1 #menu: Video > Decrease Contrast
|
||||
Ctrl+2 add contrast #menu: Video > Increase Contrast
|
||||
Ctrl+2 add contrast 1 #menu: Video > Increase Contrast
|
||||
_ ignore #menu: Video > -
|
||||
Ctrl+3 add brightness -1 #menu: Video > Decrease Brightness
|
||||
Ctrl+4 add brightness 1 #menu: Video > Increase Brightness
|
||||
@@ -90,8 +93,8 @@
|
||||
|
||||
KP7 script-message mpv.net cycle-audio #menu: Audio > Cycle/Next
|
||||
_ ignore #menu: Audio > -
|
||||
KP6 add audio-delay 0.100 #menu: Audio > Delay +0.1
|
||||
KP9 add audio-delay -0.100 #menu: Audio > Delay -0.1
|
||||
KP6 add audio-delay 0.1 #menu: Audio > Delay +0.1
|
||||
KP9 add audio-delay -0.1 #menu: Audio > Delay -0.1
|
||||
|
||||
KP8 cycle sub #menu: Subtitle > Cycle/Next
|
||||
v cycle sub-visibility #menu: Subtitle > Toggle Visibility
|
||||
@@ -112,7 +115,7 @@
|
||||
_ ignore #menu: Volume > -
|
||||
m cycle mute #menu: Volume > Mute
|
||||
|
||||
[ multiply speed 0.9 #menu: Speed > -10%
|
||||
[ multiply speed 1/1.1 #menu: Speed > -10%
|
||||
] multiply speed 1.1 #menu: Speed > +10%
|
||||
_ ignore #menu: Speed > -
|
||||
{ multiply speed 0.5 #menu: Speed > Half
|
||||
@@ -136,7 +139,7 @@
|
||||
F8 show-text ${playlist} 5000 #menu: View > Show Playlist
|
||||
F9 show-text ${track-list} 5000 #menu: View > Show Audio/Video/Subtitle List
|
||||
|
||||
Ctrl+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
|
||||
Ctrl+i script-message mpv.net show-input-editor #menu: Settings > Show Input Editor
|
||||
Ctrl+f script-message mpv.net open-conf-folder #menu: Settings > Open Config Folder
|
||||
|
||||
@@ -146,11 +149,13 @@
|
||||
L cycle-values loop-file "inf" "no" #menu: Tools > Toggle infinite file looping
|
||||
Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Cycle Hardware Decoding
|
||||
_ script-message mpv.net execute-mpv-command #menu: Tools > Execute mpv command...
|
||||
_ 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/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/blob/master/mpv.net/Resources/inputConf.txt #menu: Help > Show mpv.net default keys
|
||||
_ 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/blob/master/Manual.md #menu: Help > Show mpv.net manual
|
||||
_ ignore #menu: Help > -
|
||||
_ script-message mpv.net show-about #menu: Help > About mpv.net
|
||||
|
||||
@@ -173,4 +178,6 @@
|
||||
Wheel_Up add volume 10
|
||||
Wheel_Down add volume -10
|
||||
Prev playlist-prev
|
||||
Next playlist-next
|
||||
Next playlist-next
|
||||
|
||||
MBTN_LEFT_DBL cycle fullscreen
|
||||
@@ -3,38 +3,37 @@ name = "hwdec"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
helpurl = "https://mpv.io/manual/master/#options-hwdec"
|
||||
help = "--hwdec=<mode> 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 (Default)" },
|
||||
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 = "enable best hw decoder (see below)" },
|
||||
{ name = "yes", help = "exactly the same as auto" },
|
||||
{ name = "auto-copy", help = "enable best hw decoder with copy-back (see below)" },
|
||||
{ name = "dxva2", help = "requires --vo=gpu with --gpu-context=d3d11, --gpu-context=angle or --gpu-context=dxinterop (Windows only)" },
|
||||
{ name = "dxva2", help = "requires vo=gpu with gpu-context=d3d11, gpu-context=angle or gpu-context=dxinterop (Windows only)" },
|
||||
{ name = "dxva2-copy", help = "copies video back to system RAM (Windows only)" },
|
||||
{ name = "d3d11va", help = "requires --vo=gpu with --gpu-context=d3d11 or --gpu-context=angle (Windows 8+ only)" },
|
||||
{ name = "d3d11va", help = "requires vo=gpu with gpu-context=d3d11 or gpu-context=angle (Windows 8+ only)" },
|
||||
{ name = "d3d11va-copy", help = "copies video back to system RAM (Windows 8+ only)" },
|
||||
{ name = "cuda", help = "requires --vo=gpu (Any platform CUDA is available)" },
|
||||
{ name = "cuda", help = "requires vo=gpu (Any platform CUDA is available)" },
|
||||
{ name = "cuda-copy", help = "copies video back to system RAM (Any platform CUDA is available)" },
|
||||
{ name = "nvdec", help = "requires --vo=gpu (Any platform CUDA is available)" },
|
||||
{ name = "nvdec", help = "requires vo=gpu (Any platform CUDA is available)" },
|
||||
{ name = "nvdec-copy", help = "copies video back to system RAM (Any platform CUDA is available)" },
|
||||
{ name = "crystalhd", help = "copies video back to system RAM (Any platform supported by hardware)" },
|
||||
{ name = "rkmpp", help = "requires --vo=gpu (some RockChip devices only)" }]
|
||||
{ name = "rkmpp", help = "requires vo=gpu (some RockChip devices only)" }]
|
||||
|
||||
[[settings]]
|
||||
name = "gpu-api"
|
||||
default = "auto"
|
||||
filter = "Video"
|
||||
help = "--gpu-api=<type> Controls which type of graphics APIs will be accepted."
|
||||
options = [{ name = "auto", help = "Use any available API (Default)" },
|
||||
help = "Controls which type of graphics APIs will be accepted."
|
||||
options = [{ name = "auto", help = "Use any available API" },
|
||||
{ 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 = "d3d11", help = "Allow only --gpu-context=d3d11" }]
|
||||
{ name = "vulkan", help = "Allow only Vulkan (requires a valid/working spirv-compiler)" },
|
||||
{ name = "d3d11", help = "Allow only gpu-context=d3d11" }]
|
||||
|
||||
[[settings]]
|
||||
name = "gpu-context"
|
||||
default = "auto"
|
||||
filter = "Video"
|
||||
help = "--gpu-context=<sys> The value auto (the default) selects the GPU context. You can also pass help to get a complete list of compiled in backends (sorted by autoprobe order)."
|
||||
options = [{ name = "auto", help = "auto-select (Default)" },
|
||||
options = [{ name = "auto", help = "auto-select" },
|
||||
{ name = "win", help = "Win32/WGL" },
|
||||
{ name = "winvk", help = "VK_KHR_win32_surface" },
|
||||
{ name = "angle", help = "Direct3D11 through the OpenGL ES translation layer ANGLE. This supports almost everything the win backend does (if the ANGLE build is new enough)." },
|
||||
@@ -45,16 +44,16 @@ options = [{ name = "auto", help = "auto-select (Default)" },
|
||||
name = "vo"
|
||||
default = "gpu"
|
||||
filter = "Video"
|
||||
help = "Video output drivers to be used.\n\nFor more information visit:"
|
||||
helpurl = "https://mpv.io/manual/master/#video-output-drivers-vo"
|
||||
help = "--gpu=<mode> Video output drivers to be used. Default = gpu.\n\nFor more information visit:"
|
||||
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. (Default)" },
|
||||
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" }]
|
||||
|
||||
[[settings]]
|
||||
name = "video-sync"
|
||||
default = "audio"
|
||||
filter = "Video"
|
||||
help = "--video-sync=<audio|...> 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"
|
||||
options = [{ name = "audio" },
|
||||
{ name = "display-resample" },
|
||||
@@ -69,49 +68,49 @@ options = [{ name = "audio" },
|
||||
name = "scale"
|
||||
default = "bilinear"
|
||||
filter = "Video"
|
||||
help = "--scale=<filter> 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"
|
||||
options = [{ name = "bilinear", help = "Bilinear hardware texture filtering (fastest, very low quality). This is the default for compatibility reasons." },
|
||||
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"
|
||||
options = [{ name = "bilinear", help = "Bilinear hardware texture filtering (fastest, very low quality)." },
|
||||
{ name = "spline36", help = "Mid quality and speed. This is the default when using gpu-hq." },
|
||||
{ name = "lanczos", help = "Lanczos scaling. Provides mid quality and speed. Generally worse than spline36, but it results in a slightly sharper image which is good for some content types. The number of taps can be controlled with scale-radius, but is best left unchanged. (This filter is an alias for sinc-windowed sinc)" },
|
||||
{ name = "ewa_lanczos", help = "Elliptic weighted average Lanczos scaling. Also known as Jinc. Relatively slow, but very good quality. The radius can be controlled with scale-radius. Increasing the radius makes the filter sharper but adds more ringing. (This filter is an alias for jinc-windowed jinc)" },
|
||||
{ name = "ewa_lanczossharp", help = "A slightly sharpened version of ewa_lanczos, preconfigured to use an ideal radius and parameter. If your hardware can run it, this is probably what you should use by default." },
|
||||
{ name = "mitchell", help = "Mitchell-Netravali. The B and C parameters can be set with --scale-param1 and --scale-param2. This filter is very good at downscaling (see --dscale)." },
|
||||
{ name = "oversample", help = "A version of nearest neighbour that (naively) oversamples pixels, so that pixels overlapping edges get linearly interpolated instead of rounded. This essentially removes the small imperfections and judder artifacts caused by nearest-neighbour interpolation, in exchange for adding some blur. This filter is good at temporal interpolation, and also known as \"smoothmotion\" (see --tscale)." },
|
||||
{ name = "linear", help = "A --tscale filter." }]
|
||||
{ name = "mitchell", help = "Mitchell-Netravali. The B and C parameters can be set with scale-param1 and scale-param2. This filter is very good at downscaling (see dscale)." },
|
||||
{ name = "oversample", help = "A version of nearest neighbour that (naively) oversamples pixels, so that pixels overlapping edges get linearly interpolated instead of rounded. This essentially removes the small imperfections and judder artifacts caused by nearest-neighbour interpolation, in exchange for adding some blur. This filter is good at temporal interpolation, and also known as \"smoothmotion\" (see tscale)." },
|
||||
{ name = "linear", help = "A tscale filter." }]
|
||||
|
||||
[[settings]]
|
||||
name = "cscale"
|
||||
default = "bilinear"
|
||||
filter = "Video"
|
||||
help = "--cscale=<filter> As --scale, but for interpolating chroma information. If the image is not subsampled, this option is ignored entirely."
|
||||
options = [{ name = "bilinear", help = "Bilinear hardware texture filtering (fastest, very low quality). This is the default for compatibility reasons." },
|
||||
help = "As scale, but for interpolating chroma information. If the image is not subsampled, this option is ignored entirely."
|
||||
options = [{ name = "bilinear", help = "Bilinear hardware texture filtering (fastest, very low quality)." },
|
||||
{ name = "spline36", help = "Mid quality and speed. This is the default when using gpu-hq." },
|
||||
{ name = "lanczos", help = "Lanczos scaling. Provides mid quality and speed. Generally worse than spline36, but it results in a slightly sharper image which is good for some content types. The number of taps can be controlled with scale-radius, but is best left unchanged. (This filter is an alias for sinc-windowed sinc)" },
|
||||
{ name = "ewa_lanczos", help = "Elliptic weighted average Lanczos scaling. Also known as Jinc. Relatively slow, but very good quality. The radius can be controlled with scale-radius. Increasing the radius makes the filter sharper but adds more ringing. (This filter is an alias for jinc-windowed jinc)" },
|
||||
{ name = "ewa_lanczossharp", help = "A slightly sharpened version of ewa_lanczos, preconfigured to use an ideal radius and parameter. If your hardware can run it, this is probably what you should use by default." },
|
||||
{ name = "mitchell", help = "Mitchell-Netravali. The B and C parameters can be set with --scale-param1 and --scale-param2. This filter is very good at downscaling (see --dscale)." },
|
||||
{ name = "oversample", help = "A version of nearest neighbour that (naively) oversamples pixels, so that pixels overlapping edges get linearly interpolated instead of rounded. This essentially removes the small imperfections and judder artifacts caused by nearest-neighbour interpolation, in exchange for adding some blur. This filter is good at temporal interpolation, and also known as \"smoothmotion\" (see --tscale)." },
|
||||
{ name = "linear", help = "A --tscale filter." }]
|
||||
{ name = "mitchell", help = "Mitchell-Netravali. The B and C parameters can be set with scale-param1 and scale-param2. This filter is very good at downscaling (see dscale)." },
|
||||
{ name = "oversample", help = "A version of nearest neighbour that (naively) oversamples pixels, so that pixels overlapping edges get linearly interpolated instead of rounded. This essentially removes the small imperfections and judder artifacts caused by nearest-neighbour interpolation, in exchange for adding some blur. This filter is good at temporal interpolation, and also known as \"smoothmotion\" (see tscale)." },
|
||||
{ name = "linear", help = "A tscale filter." }]
|
||||
|
||||
[[settings]]
|
||||
name = "dscale"
|
||||
default = "bilinear"
|
||||
filter = "Video"
|
||||
help = "--dscale=<filter> Like --scale, but apply these filters on downscaling instead. If this option is unset, the filter implied by --scale will be applied."
|
||||
options = [{ name = "bilinear", help = "Bilinear hardware texture filtering (fastest, very low quality). This is the default for compatibility reasons." },
|
||||
help = "Like scale, but apply these filters on downscaling instead. If this option is unset, the filter implied by scale will be applied."
|
||||
options = [{ name = "bilinear", help = "Bilinear hardware texture filtering (fastest, very low quality)." },
|
||||
{ name = "spline36", help = "Mid quality and speed. This is the default when using gpu-hq." },
|
||||
{ name = "lanczos", help = "Lanczos scaling. Provides mid quality and speed. Generally worse than spline36, but it results in a slightly sharper image which is good for some content types. The number of taps can be controlled with scale-radius, but is best left unchanged. (This filter is an alias for sinc-windowed sinc)" },
|
||||
{ name = "ewa_lanczos", help = "Elliptic weighted average Lanczos scaling. Also known as Jinc. Relatively slow, but very good quality. The radius can be controlled with scale-radius. Increasing the radius makes the filter sharper but adds more ringing. (This filter is an alias for jinc-windowed jinc)" },
|
||||
{ name = "ewa_lanczossharp", help = "A slightly sharpened version of ewa_lanczos, preconfigured to use an ideal radius and parameter. If your hardware can run it, this is probably what you should use by default." },
|
||||
{ name = "mitchell", help = "Mitchell-Netravali. The B and C parameters can be set with --scale-param1 and --scale-param2. This filter is very good at downscaling (see --dscale)." },
|
||||
{ name = "oversample", help = "A version of nearest neighbour that (naively) oversamples pixels, so that pixels overlapping edges get linearly interpolated instead of rounded. This essentially removes the small imperfections and judder artifacts caused by nearest-neighbour interpolation, in exchange for adding some blur. This filter is good at temporal interpolation, and also known as \"smoothmotion\" (see --tscale)." },
|
||||
{ name = "linear", help = "A --tscale filter." }]
|
||||
{ name = "mitchell", help = "Mitchell-Netravali. The B and C parameters can be set with scale-param1 and scale-param2. This filter is very good at downscaling (see dscale)." },
|
||||
{ name = "oversample", help = "A version of nearest neighbour that (naively) oversamples pixels, so that pixels overlapping edges get linearly interpolated instead of rounded. This essentially removes the small imperfections and judder artifacts caused by nearest-neighbour interpolation, in exchange for adding some blur. This filter is good at temporal interpolation, and also known as \"smoothmotion\" (see tscale)." },
|
||||
{ name = "linear", help = "A tscale filter." }]
|
||||
|
||||
[[settings]]
|
||||
name = "dither-depth"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
help = "--dither-depth=<N|no|auto> Set dither target depth to N. Default: no. 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."
|
||||
options = [{ name = "no", help = "Disable any dithering done by mpv." },
|
||||
{ name = "auto", help = "Automatic selection. If output bit depth cannot be detected, 8 bits per component are assumed." },
|
||||
{ name = "8", help = "Dither to 8 bit output." }]
|
||||
@@ -120,7 +119,7 @@ options = [{ name = "no", help = "Disable any dithering done by mpv." },
|
||||
name = "correct-downscaling"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
help = "--correct-downscaling 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."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
@@ -128,7 +127,7 @@ options = [{ name = "yes" },
|
||||
name = "sigmoid-upscaling"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
help = "--sigmoid-upscaling 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."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
@@ -136,7 +135,7 @@ options = [{ name = "yes" },
|
||||
name = "deband"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
help = "--deband 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."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
@@ -144,59 +143,98 @@ options = [{ name = "yes" },
|
||||
name = "volume"
|
||||
default = "100"
|
||||
filter = "Audio"
|
||||
help = "--volume=<integer> 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 = "alang"
|
||||
default = ""
|
||||
filter = "Audio"
|
||||
help = "--alang=<languagecode[,languagecode,...]> 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]]
|
||||
name = "audio-file-auto"
|
||||
default = "no"
|
||||
filter = "Audio"
|
||||
help = "--audio-file-auto=<no|exact|fuzzy|all>, --no-audio-file-auto Load additional audio files matching the video filename. The parameter specifies how external audio files are matched."
|
||||
options = [{ name = "no", help = "Don't automatically load external audio files (default)." },
|
||||
help = "Load additional audio files matching the video filename. The parameter specifies how external audio files are matched."
|
||||
options = [{ name = "no", help = "Don't automatically load external audio files." },
|
||||
{ name = "exact", help = "Load the media filename with audio file extension." },
|
||||
{ name = "fuzzy", help = "Load all audio files containing media filename." },
|
||||
{ name = "all", help = "Load all audio files in the current and --audio-file-paths directories." }]
|
||||
{ name = "all", help = "Load all audio files in the current and audio-file-paths directories." }]
|
||||
|
||||
[[settings]]
|
||||
name = "slang"
|
||||
default = ""
|
||||
filter = "Subtitle"
|
||||
help = "--slang=<languagecode[,languagecode,...]> 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]]
|
||||
name = "sub-auto"
|
||||
default = "exact"
|
||||
filter = "Subtitle"
|
||||
help = "--sub-auto=<no|exact|fuzzy|all>, --no-sub-auto Load additional subtitle files matching the video filename. The parameter specifies how external subtitle files are matched. exact is enabled by default."
|
||||
help = "Load additional subtitle files matching the video filename. The parameter specifies how external subtitle files are matched. exact is enabled by default."
|
||||
options = [{ name = "no", help = "Don't automatically load external subtitle files." },
|
||||
{ name = "exact", help = "Load the media filename with subtitle file extension (Default)." },
|
||||
{ name = "exact", help = "Load the media filename with subtitle file extension." },
|
||||
{ name = "fuzzy", help = "Load all subs containing media filename." },
|
||||
{ name = "all", help = "Load all subs in the current and --sub-file-paths directories." }]
|
||||
{ name = "all", help = "Load all subs in the current and sub-file-paths directories." }]
|
||||
|
||||
[[settings]]
|
||||
name = "sub-font"
|
||||
default = ""
|
||||
filter = "Subtitle"
|
||||
help = "Specify font to use for subtitles that do not themselves specify a particular font. The default is sans-serif."
|
||||
|
||||
[[settings]]
|
||||
name = "sub-font-size"
|
||||
default = ""
|
||||
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"
|
||||
|
||||
[[settings]]
|
||||
name = "sub-color"
|
||||
default = ""
|
||||
type = "color"
|
||||
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"
|
||||
|
||||
[[settings]]
|
||||
name = "sub-border-color"
|
||||
default = ""
|
||||
type = "color"
|
||||
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)."
|
||||
|
||||
[[settings]]
|
||||
name = "sub-back-color"
|
||||
default = ""
|
||||
type = "color"
|
||||
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."
|
||||
|
||||
[[settings]]
|
||||
name = "screen"
|
||||
default = ""
|
||||
filter = "Screen"
|
||||
help = "--screen=<default|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. Default: default."
|
||||
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]]
|
||||
name = "osd-playing-msg"
|
||||
default = ""
|
||||
width = 300
|
||||
filter = "Screen"
|
||||
help = "--osd-playing-msg=<value> 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"
|
||||
|
||||
[[settings]]
|
||||
name = "osd-font-size"
|
||||
default = "55"
|
||||
filter = "Screen"
|
||||
help = "Specify the OSD font size. See sub-font-size for details. Default: 55"
|
||||
|
||||
[[settings]]
|
||||
name = "fullscreen"
|
||||
default = "no"
|
||||
filter = "Screen"
|
||||
help = "--fullscreen=<yes|no>, fs=<yes|no> Start the player in fullscreen mode. Default: no."
|
||||
help = "Start the player in fullscreen mode."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
@@ -204,21 +242,21 @@ options = [{ name = "yes" },
|
||||
name = "screenshot-directory"
|
||||
default = ""
|
||||
width = 500
|
||||
folder = true
|
||||
type = "folder"
|
||||
filter = "Screen"
|
||||
help = "--screenshot-directory=<value> 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 = "Store screenshots in this directory. This path is joined with the filename generated by screenshot-template. If the template filename is already absolute, the directory is ignored.\n\nIf the directory does not exist, it is created on the first screenshot. If it is not a directory, an error is generated when trying to write a screenshot.\n\nThis option is not set by default, and thus will write screenshots to the directory from which mpv was started. In pseudo-gui mode (see PSEUDO GUI MODE), this is set to the desktop."
|
||||
|
||||
[[settings]]
|
||||
name = "autofit"
|
||||
default = "50%"
|
||||
filter = "Screen"
|
||||
help = "--autofit=<percent value> 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 = "Set the initial window size in percent. Please note that this setting is only partly implemented in mpv.net, accepted are only integer values with percent sign added. Default: 50%"
|
||||
|
||||
[[settings]]
|
||||
name = "keep-open-pause"
|
||||
default = "yes"
|
||||
filter = "Playback"
|
||||
help = "--keep-open-pause=<yes|no> 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. Default: yes."
|
||||
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."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
@@ -226,22 +264,22 @@ options = [{ name = "yes" },
|
||||
name = "keep-open"
|
||||
default = "no"
|
||||
filter = "Playback"
|
||||
help = "--keep-open=<yes|no|always> 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."
|
||||
options = [{ name = "yes", help = "Don't terminate if the current file is the last playlist entry. Equivalent to --keep-open without arguments."},
|
||||
{ name = "no", help = "If the current file ends, go to the next file or terminate. (Default.)" },
|
||||
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."
|
||||
options = [{ name = "yes", help = "Don't terminate if the current file is the last playlist entry. Equivalent to keep-open without arguments."},
|
||||
{ name = "no", help = "If the current file ends, go to the next file or terminate." },
|
||||
{ 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."}]
|
||||
|
||||
[[settings]]
|
||||
name = "loop-file"
|
||||
default = ""
|
||||
filter = "Playback"
|
||||
help = "--loop-file=<N|inf|no>, loop=<N|inf|no> Loop a single file N times. inf means forever, no means normal playback. For compatibility, --loop-file and --loop-file=yes are also accepted, and are the same as --loop-file=inf.\n\nThe difference to --loop-playlist is that this doesn't loop the playlist, just the file itself. If the playlist contains only a single file, the difference between the two option is that this option performs a seek on loop, instead of reloading the file.\n\n--loop is an alias for this option."
|
||||
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."
|
||||
|
||||
[[settings]]
|
||||
name = "save-position-on-quit"
|
||||
default = "no"
|
||||
filter = "Playback"
|
||||
help = "--save-position-on-quit=<yes|no> 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" },
|
||||
{ name = "no" }]
|
||||
|
||||
@@ -249,29 +287,29 @@ options = [{ name = "yes" },
|
||||
name = "input-ar-delay"
|
||||
default = ""
|
||||
filter = "Input"
|
||||
help = "--input-ar-delay=<integer> Delay in milliseconds before we start to autorepeat a key (0 to disable)."
|
||||
help = "Delay in milliseconds before we start to autorepeat a key (0 to disable)."
|
||||
|
||||
[[settings]]
|
||||
name = "input-ar-rate"
|
||||
default = ""
|
||||
filter = "Input"
|
||||
help = "--input-ar-rate=<integer> Number of key presses to generate per second on autorepeat."
|
||||
help = "Number of key presses to generate per second on autorepeat."
|
||||
|
||||
[[settings]]
|
||||
name = "hr-seek"
|
||||
default = "absolute"
|
||||
filter = "Playback"
|
||||
help = "--hr-seek=<no|absolute|yes> 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."
|
||||
options = [{ name = "yes", help = "Use precise seeks whenever possible." },
|
||||
{ name = "no", help = "Never use precise seeks." },
|
||||
{ name = "absolute", help = "Use precise seeks if the seek is to an absolute position in the file, such as a chapter seek, but not for relative seeks like the default behavior of arrow keys (default)." },
|
||||
{ name = "absolute", help = "Use precise seeks if the seek is to an absolute position in the file, such as a chapter seek, but not for relative seeks like the default behavior of arrow keys." },
|
||||
{ name = "always", help = "Same as yes (for compatibility)." }]
|
||||
|
||||
[[settings]]
|
||||
name = "track-auto-selection"
|
||||
default = "yes"
|
||||
filter = "Playback"
|
||||
help = "--track-auto-selection=<yes|no> Enable the default track auto-selection (default: yes). 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."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
@@ -279,4 +317,4 @@ options = [{ name = "yes" },
|
||||
name = "loop-playlist"
|
||||
default = ""
|
||||
filter = "Playback"
|
||||
help = "--loop-playlist=<N|inf|force|no>, --loop-playlist Loops playback N times. A value of 1 plays it one time (default), 2 two times, etc. inf means forever. no is the same as 1 and disables looping. If several files are specified on command line, the entire playlist is looped. --loop-playlist is the same as --loop-playlist=inf.\n\nThe force mode is like inf, but does not skip playlist entries which have been marked as failing. This means the player might waste CPU time trying to loop a file that doesn't exist. But it might be useful for playing webradios under very bad network conditions."
|
||||
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."
|
||||
@@ -5,4 +5,29 @@ filter = "mpv.net"
|
||||
help = "Enables a dark theme."
|
||||
options = [{ name = "always" },
|
||||
{ name = "system" , help = "Available on Windows 10 or higher" },
|
||||
{ name = "never" }]
|
||||
{ name = "never" }]
|
||||
|
||||
[[settings]]
|
||||
name = "clipboard-monitoring"
|
||||
default = "yes"
|
||||
filter = "mpv.net"
|
||||
help = "Monitors the clipboard for URLs to play."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "process-instance"
|
||||
default = "single"
|
||||
filter = "mpv.net"
|
||||
help = "Defines if more then one mpv.net process is allowed."
|
||||
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 = "mpv.net"
|
||||
help = "Writes debug info to a file located on the desktop."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
BIN
mpv.net/Resources/mpvnet.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
@@ -5,8 +5,6 @@ using System.Management.Automation.Runspaces;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Sys;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public class PowerShellScript
|
||||
@@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
using Microsoft.Scripting;
|
||||
using Microsoft.Scripting.Hosting;
|
||||
|
||||
using IronPython.Hosting;
|
||||
using Sys;
|
||||
using PyRT = IronPython.Runtime;
|
||||
using IronPython.Runtime;
|
||||
using IronPython.Runtime.Operations;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
@@ -22,35 +24,36 @@ namespace mpvnet
|
||||
scope.ImportModule("clr");
|
||||
engine.Execute("import clr", scope);
|
||||
engine.Execute("clr.AddReference(\"mpvnet\")", scope);
|
||||
engine.Execute("import mpvnet", scope);
|
||||
engine.Execute("from mpvnet import *", scope);
|
||||
engine.Execute(code, scope);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Msg.ShowException(ex);
|
||||
if (ex is SyntaxErrorException e)
|
||||
Msg.ShowError($"{e.Line}, {e.Column}: " + ex.Message);
|
||||
else
|
||||
Msg.ShowException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PythonEventObject
|
||||
{
|
||||
public PyRT.PythonFunction PythonFunction { get; set; }
|
||||
public PythonFunction PythonFunction { get; set; }
|
||||
public EventInfo EventInfo { get; set; }
|
||||
public Delegate Delegate { get; set; }
|
||||
|
||||
public void Invoke()
|
||||
{
|
||||
PyRT.Operations.PythonCalls.Call(PythonFunction);
|
||||
}
|
||||
public void Invoke() => PythonCalls.Call(PythonFunction);
|
||||
|
||||
public void InvokeEndFileEventMode(EndFileEventMode arg)
|
||||
{
|
||||
PyRT.Operations.PythonCalls.Call(PythonFunction, new[] { arg });
|
||||
PythonCalls.Call(PythonFunction, new[] { arg });
|
||||
}
|
||||
|
||||
public void InvokeStrings(string[] arg)
|
||||
{
|
||||
PyRT.Operations.PythonCalls.Call(PythonFunction, new[] { arg });
|
||||
PythonCalls.Call(PythonFunction, new[] { arg });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,659 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Sys
|
||||
{
|
||||
public class Msg
|
||||
{
|
||||
private static string ShownMessages;
|
||||
|
||||
public static string SupportURL { get; set; }
|
||||
|
||||
public static void Show(string mainInstruction, string content = null)
|
||||
{
|
||||
Msg.Show(mainInstruction, content, MsgIcon.Info, MsgButtons.Ok, MsgResult.None);
|
||||
}
|
||||
|
||||
public static void ShowError(string mainInstruction, string content = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (TaskDialog<string> td = new TaskDialog<string>())
|
||||
{
|
||||
td.AllowCancel = false;
|
||||
|
||||
if (string.IsNullOrEmpty(content))
|
||||
{
|
||||
if (mainInstruction.Length < 80)
|
||||
td.MainInstruction = mainInstruction;
|
||||
else
|
||||
td.Content = mainInstruction;
|
||||
}
|
||||
else
|
||||
{
|
||||
td.MainInstruction = mainInstruction;
|
||||
td.Content = content;
|
||||
}
|
||||
|
||||
td.MainIcon = MsgIcon.Error;
|
||||
td.Footer = "[Copy Message](copymsg)";
|
||||
|
||||
if (!string.IsNullOrEmpty(Msg.SupportURL))
|
||||
td.Footer += $" [Contact Support]({SupportURL})";
|
||||
|
||||
td.Show();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
|
||||
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowException(Exception e)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (TaskDialog<string> td = new TaskDialog<string>())
|
||||
{
|
||||
td.MainInstruction = e.GetType().Name;
|
||||
td.Content = e.Message;
|
||||
td.MainIcon = MsgIcon.Error;
|
||||
td.ExpandedInformation = e.ToString();
|
||||
td.Footer = "[Copy Message](copymsg)";
|
||||
|
||||
if (!string.IsNullOrEmpty(Msg.SupportURL))
|
||||
td.Footer += $" [Contact Support]({SupportURL})";
|
||||
|
||||
td.Show();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
|
||||
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowWarning(string mainInstruction,
|
||||
string content = null,
|
||||
bool onlyOnce = false)
|
||||
{
|
||||
if (onlyOnce && Msg.ShownMessages != null &&
|
||||
Msg.ShownMessages.Contains(mainInstruction + content))
|
||||
return;
|
||||
|
||||
Msg.Show(mainInstruction, content, MsgIcon.Warning, MsgButtons.Ok, MsgResult.None);
|
||||
if (!onlyOnce) return;
|
||||
Msg.ShownMessages += mainInstruction + content;
|
||||
}
|
||||
|
||||
public static MsgResult ShowQuestion(string mainInstruction,
|
||||
MsgButtons buttons = MsgButtons.OkCancel)
|
||||
{
|
||||
return Msg.Show(mainInstruction, null, MsgIcon.None, buttons, MsgResult.None);
|
||||
}
|
||||
|
||||
public static MsgResult ShowQuestion(string mainInstruction,
|
||||
string content,
|
||||
MsgButtons buttons = MsgButtons.OkCancel)
|
||||
{
|
||||
return Msg.Show(mainInstruction, content, MsgIcon.None, buttons, MsgResult.None);
|
||||
}
|
||||
|
||||
public static MsgResult Show(string mainInstruction,
|
||||
string content,
|
||||
MsgIcon icon,
|
||||
MsgButtons buttons,
|
||||
MsgResult defaultButton = MsgResult.None)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (TaskDialog<MsgResult> td = new TaskDialog<MsgResult>())
|
||||
{
|
||||
td.AllowCancel = false;
|
||||
td.DefaultButton = defaultButton;
|
||||
td.MainIcon = icon;
|
||||
|
||||
if (content == null)
|
||||
{
|
||||
if (mainInstruction.Length < 80)
|
||||
td.MainInstruction = mainInstruction;
|
||||
else
|
||||
td.Content = mainInstruction;
|
||||
}
|
||||
else
|
||||
{
|
||||
td.MainInstruction = mainInstruction;
|
||||
td.Content = content;
|
||||
}
|
||||
if (buttons == MsgButtons.OkCancel)
|
||||
{
|
||||
td.AddButton("OK", MsgResult.OK);
|
||||
td.AddButton("Cancel", MsgResult.Cancel);
|
||||
}
|
||||
else
|
||||
td.CommonButtons = buttons;
|
||||
return td.Show();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (MsgResult)MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
|
||||
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TaskDialog<T> : TaskDialogNative, IDisposable
|
||||
{
|
||||
private Dictionary<int, T> IdValueDic;
|
||||
private Dictionary<int, string> IdTextDic;
|
||||
private List<int> CommandLinkShieldList;
|
||||
private IntPtr ButtonArray;
|
||||
private IntPtr RadioButtonArray;
|
||||
private List<TaskDialogNative.TASKDIALOG_BUTTON> Buttons;
|
||||
private List<TaskDialogNative.TASKDIALOG_BUTTON> RadioButtons;
|
||||
private TaskDialogNative.TASKDIALOGCONFIG Config;
|
||||
const int TDE_CONTENT = 0;
|
||||
const int TDE_EXPANDED_INFORMATION = 1;
|
||||
const int TDE_FOOTER = 2;
|
||||
const int TDE_MAIN_INSTRUCTION = 3;
|
||||
const int TDN_CREATED = 0;
|
||||
const int TDN_NAVIGATED = 1;
|
||||
const int TDN_BUTTON_CLICKED = 2;
|
||||
const int TDN_HYPERLINK_CLICKED = 3;
|
||||
const int TDN_TIMER = 4;
|
||||
const int TDN_DESTROYED = 5;
|
||||
const int TDN_RADIO_BUTTON_CLICKED = 6;
|
||||
const int TDN_DIALOG_CONSTRUCTED = 7;
|
||||
const int TDN_VERIFICATION_CLICKED = 8;
|
||||
const int TDN_HELP = 9;
|
||||
const int TDN_EXPANDO_BUTTON_CLICKED = 10;
|
||||
const int TDM_NAVIGATE_PAGE = 1125;
|
||||
const int TDM_CLICK_BUTTON = 1126;
|
||||
const int TDM_SET_MARQUEE_PROGRESS_BAR = 1127;
|
||||
const int TDM_SET_PROGRESS_BAR_STATE = 1128;
|
||||
const int TDM_SET_PROGRESS_BAR_RANGE = 1129;
|
||||
const int TDM_SET_PROGRESS_BAR_POS = 1130;
|
||||
const int TDM_SET_PROGRESS_BAR_MARQUEE = 1131;
|
||||
const int TDM_SET_ELEMENT_TEXT = 1132;
|
||||
const int TDM_CLICK_RADIO_BUTTON = 1134;
|
||||
const int TDM_ENABLE_BUTTON = 1135;
|
||||
const int TDM_ENABLE_RADIO_BUTTON = 1136;
|
||||
const int TDM_CLICK_VERIFICATION = 1137;
|
||||
const int TDM_UPDATE_ELEMENT_TEXT = 1138;
|
||||
const int TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE = 1139;
|
||||
const int TDM_UPDATE_ICON = 1140;
|
||||
private T SelectedValueValue;
|
||||
private string SelectedTextValue;
|
||||
private int TimeoutValue;
|
||||
private int ExitTickCount;
|
||||
private bool disposed;
|
||||
|
||||
public TaskDialog()
|
||||
{
|
||||
IdValueDic = new Dictionary<int, T>();
|
||||
IdTextDic = new Dictionary<int, string>();
|
||||
CommandLinkShieldList = new List<int>();
|
||||
Buttons = new List<TaskDialogNative.TASKDIALOG_BUTTON>();
|
||||
RadioButtons = new List<TaskDialogNative.TASKDIALOG_BUTTON>();
|
||||
_SelectedID = -1;
|
||||
Config = new TaskDialogNative.TASKDIALOGCONFIG();
|
||||
Config.cbSize = (uint)Marshal.SizeOf(Config);
|
||||
Config.hwndParent = GetHandle();
|
||||
Config.hInstance = IntPtr.Zero;
|
||||
Config.dwFlags = TaskDialogNative.TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION;
|
||||
Config.dwCommonButtons = MsgButtons.None;
|
||||
Config.MainIcon = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION(0);
|
||||
Config.FooterIcon = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION(0);
|
||||
Config.cxWidth = 0U;
|
||||
Config.cButtons = 0U;
|
||||
Config.cRadioButtons = 0U;
|
||||
Config.pButtons = IntPtr.Zero;
|
||||
Config.pRadioButtons = IntPtr.Zero;
|
||||
Config.nDefaultButton = 0;
|
||||
Config.nDefaultRadioButton = 0;
|
||||
Config.pszWindowTitle = ((AssemblyProductAttribute)Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true)[0]).Product;
|
||||
Config.pszMainInstruction = "";
|
||||
Config.pszContent = "";
|
||||
Config.pfCallback = new PFTASKDIALOGCALLBACK(this.DialogProc);
|
||||
}
|
||||
|
||||
public IntPtr GetHandle()
|
||||
{
|
||||
StringBuilder lpszFileName = new StringBuilder(260);
|
||||
IntPtr foregroundWindow = TaskDialogNative.GetForegroundWindow();
|
||||
TaskDialogNative.GetWindowModuleFileName(foregroundWindow, lpszFileName, 260U);
|
||||
|
||||
if (Path.GetFileName(lpszFileName.ToString().Replace(".vshost", "")) ==
|
||||
Path.GetFileName(Assembly.GetEntryAssembly().Location))
|
||||
return foregroundWindow;
|
||||
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
public bool AllowCancel {
|
||||
set {
|
||||
if (value)
|
||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION;
|
||||
else
|
||||
Config.dwFlags ^= TaskDialogNative.TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION;
|
||||
}
|
||||
}
|
||||
|
||||
public string MainInstruction {
|
||||
get => Config.pszMainInstruction;
|
||||
set => Config.pszMainInstruction = value;
|
||||
}
|
||||
|
||||
public string Content {
|
||||
get => Config.pszContent;
|
||||
set => Config.pszContent = ExpandMarkdownMarkup(value);
|
||||
}
|
||||
|
||||
public string ExpandedInformation {
|
||||
get => Config.pszExpandedInformation;
|
||||
set => Config.pszExpandedInformation = ExpandMarkdownMarkup(value);
|
||||
}
|
||||
|
||||
public string VerificationText {
|
||||
get => Config.pszVerificationText;
|
||||
set => Config.pszVerificationText = value;
|
||||
}
|
||||
|
||||
public MsgResult DefaultButton {
|
||||
get => (MsgResult)Config.nDefaultButton;
|
||||
set => Config.nDefaultButton = (int)value;
|
||||
}
|
||||
|
||||
public string Footer {
|
||||
get => Config.pszFooter;
|
||||
set => Config.pszFooter = ExpandMarkdownMarkup(value);
|
||||
}
|
||||
|
||||
public MsgIcon MainIcon {
|
||||
set => Config.MainIcon = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION((int)value);
|
||||
}
|
||||
|
||||
private int _SelectedID;
|
||||
|
||||
public int SelectedID {
|
||||
get => _SelectedID;
|
||||
set {
|
||||
foreach (var i in IdValueDic)
|
||||
if (i.Key == value) _SelectedID = value;
|
||||
}
|
||||
}
|
||||
|
||||
public T SelectedValue {
|
||||
get {
|
||||
if (IdValueDic.ContainsKey(SelectedID))
|
||||
return IdValueDic[SelectedID];
|
||||
return SelectedValueValue;
|
||||
}
|
||||
set => SelectedValueValue = value;
|
||||
}
|
||||
|
||||
public string SelectedText {
|
||||
get {
|
||||
if (IdTextDic.ContainsKey(SelectedID))
|
||||
return IdTextDic[SelectedID];
|
||||
return SelectedTextValue;
|
||||
}
|
||||
set => SelectedTextValue = value;
|
||||
}
|
||||
|
||||
public bool CheckBoxChecked {
|
||||
get => (Config.dwFlags & TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED) == TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
|
||||
set {
|
||||
if (value)
|
||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
|
||||
else
|
||||
Config.dwFlags ^= TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
|
||||
}
|
||||
}
|
||||
|
||||
public MsgButtons CommonButtons {
|
||||
get => Config.dwCommonButtons;
|
||||
set => Config.dwCommonButtons = value;
|
||||
}
|
||||
|
||||
public int Timeout {
|
||||
get => Convert.ToInt32(TimeoutValue / 1000.0);
|
||||
set {
|
||||
TimeoutValue = value * 1000;
|
||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_CALLBACK_TIMER;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddButton(string text, T value)
|
||||
{
|
||||
int n = 1000 + IdValueDic.Count + 1;
|
||||
IdValueDic[n] = value;
|
||||
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
|
||||
}
|
||||
|
||||
public string ExpandMarkdownMarkup(string value)
|
||||
{
|
||||
if (value.Contains("["))
|
||||
{
|
||||
Regex regex = new Regex(@"\[(.+)\]\((.+)\)");
|
||||
|
||||
if (regex.Match(value).Success)
|
||||
{
|
||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_ENABLE_HYPERLINKS;
|
||||
value = regex.Replace(value, "<a href=\"$2\">$1</a>");
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public void AddCommandLink(string text, T value)
|
||||
{
|
||||
int n = 1000 + IdValueDic.Count + 1;
|
||||
IdValueDic[n] = value == null ? (T)(object)text : value;
|
||||
IdTextDic[n] = text;
|
||||
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
|
||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
|
||||
}
|
||||
|
||||
public void AddCommandLink(string text, string description, T value, bool setShield = false)
|
||||
{
|
||||
int n = 1000 + IdValueDic.Count + 1;
|
||||
IdValueDic[n] = value;
|
||||
if (setShield) CommandLinkShieldList.Add(n);
|
||||
if (!string.IsNullOrEmpty(description)) text += "\n" + description;
|
||||
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
|
||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
|
||||
}
|
||||
|
||||
public void AddRadioButton(string text, T value)
|
||||
{
|
||||
int n = 1000 + IdValueDic.Count + 1;
|
||||
IdValueDic[n] = value;
|
||||
RadioButtons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
|
||||
}
|
||||
|
||||
public T Show()
|
||||
{
|
||||
MarshalDialogControlStructs();
|
||||
TaskDialogNative.TASKDIALOGCONFIG config = Config;
|
||||
int errorCode = TaskDialogNative.TaskDialogIndirect(config, out int dummy1, out int dummy2, out bool isChecked);
|
||||
if (errorCode < 0) Marshal.ThrowExceptionForHR(errorCode);
|
||||
CheckBoxChecked = isChecked;
|
||||
if (SelectedValue is MsgResult) SelectedValue = (T)(object)SelectedID;
|
||||
return SelectedValue;
|
||||
}
|
||||
|
||||
public int DialogProc(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam, IntPtr lpRefData)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case 0: //TDN_CREATED
|
||||
foreach (var i in CommandLinkShieldList)
|
||||
SendMessage(hwnd, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, new IntPtr(i), new IntPtr(1));
|
||||
break;
|
||||
case 2: //TDN_BUTTON_CLICKED
|
||||
case 6: //TDN_RADIO_BUTTON_CLICKED
|
||||
if (SelectedValue is MsgResult)
|
||||
_SelectedID = wParam.ToInt32();
|
||||
else
|
||||
SelectedID = wParam.ToInt32();
|
||||
break;
|
||||
case 3: //TDN_HYPERLINK_CLICKED
|
||||
string stringUni = Marshal.PtrToStringUni(lParam);
|
||||
if (stringUni.StartsWith("mailto") || stringUni.StartsWith("http"))
|
||||
Process.Start(stringUni);
|
||||
if (stringUni == "copymsg")
|
||||
{
|
||||
Thread thread = new Thread((ThreadStart)(() => {
|
||||
Clipboard.SetText(MainInstruction + "\r\n\r\n" + Content + "\r\n\r\n" + ExpandedInformation);
|
||||
MessageBox.Show("Message was copied to clipboard.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}));
|
||||
thread.SetApartmentState(ApartmentState.STA);
|
||||
thread.Start();
|
||||
}
|
||||
break;
|
||||
case 4: //TDN_TIMER
|
||||
if (ExitTickCount == 0) ExitTickCount = Environment.TickCount + Timeout * 1000;
|
||||
if (Environment.TickCount > ExitTickCount)
|
||||
TaskDialogNative.SendMessage(hwnd, 1126, new IntPtr(1), IntPtr.Zero);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void MarshalDialogControlStructs()
|
||||
{
|
||||
if (Buttons != null && Buttons.Count > 0)
|
||||
{
|
||||
ButtonArray = TaskDialog<T>.AllocateAndMarshalButtons(Buttons);
|
||||
Config.pButtons = ButtonArray;
|
||||
Config.cButtons = (uint)Buttons.Count;
|
||||
}
|
||||
|
||||
if (RadioButtons == null || RadioButtons.Count <= 0) return;
|
||||
RadioButtonArray = TaskDialog<T>.AllocateAndMarshalButtons(RadioButtons);
|
||||
Config.pRadioButtons = RadioButtonArray;
|
||||
Config.cRadioButtons = (uint)RadioButtons.Count;
|
||||
}
|
||||
|
||||
public static IntPtr AllocateAndMarshalButtons(List<TaskDialogNative.TASKDIALOG_BUTTON> structs)
|
||||
{
|
||||
var initialPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TASKDIALOG_BUTTON)) * structs.Count);
|
||||
var currentPtr = initialPtr;
|
||||
|
||||
foreach (var button in structs)
|
||||
{
|
||||
Marshal.StructureToPtr(button, currentPtr, false);
|
||||
currentPtr = (IntPtr)(currentPtr.ToInt64() + Marshal.SizeOf(button));
|
||||
}
|
||||
|
||||
return initialPtr;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~TaskDialog()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
protected void Dispose(bool disposing)
|
||||
{
|
||||
if (disposed) return;
|
||||
disposed = true;
|
||||
|
||||
if (ButtonArray != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(ButtonArray);
|
||||
ButtonArray = IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (RadioButtonArray != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(RadioButtonArray);
|
||||
RadioButtonArray = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public delegate int PFTASKDIALOGCALLBACK(
|
||||
IntPtr hwnd,
|
||||
uint msg,
|
||||
IntPtr wParam,
|
||||
IntPtr lParam,
|
||||
IntPtr lpRefData);
|
||||
|
||||
public class TaskDialogNative
|
||||
{
|
||||
[DllImport("comctl32", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
public static extern int TaskDialogIndirect(
|
||||
[In] TaskDialogNative.TASKDIALOGCONFIG pTaskConfig,
|
||||
out int pnButton,
|
||||
out int pnRadioButton,
|
||||
[MarshalAs(UnmanagedType.Bool)] out bool pVerificationFlagChecked);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetForegroundWindow();
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern uint GetWindowModuleFileName(
|
||||
IntPtr hwnd,
|
||||
StringBuilder lpszFileName,
|
||||
uint cchFileNameMax);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr SendMessage(
|
||||
IntPtr handle,
|
||||
int message,
|
||||
IntPtr wParam,
|
||||
IntPtr lParam);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
|
||||
public class TASKDIALOGCONFIG
|
||||
{
|
||||
public uint cbSize;
|
||||
public IntPtr hwndParent;
|
||||
public IntPtr hInstance;
|
||||
public TaskDialogNative.TASKDIALOG_FLAGS dwFlags;
|
||||
public MsgButtons dwCommonButtons;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszWindowTitle;
|
||||
public TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION MainIcon;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszMainInstruction;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszContent;
|
||||
public uint cButtons;
|
||||
public IntPtr pButtons;
|
||||
public int nDefaultButton;
|
||||
public uint cRadioButtons;
|
||||
public IntPtr pRadioButtons;
|
||||
public int nDefaultRadioButton;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszVerificationText;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszExpandedInformation;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszExpandedControlText;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszCollapsedControlText;
|
||||
public TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION FooterIcon;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszFooter;
|
||||
public PFTASKDIALOGCALLBACK pfCallback;
|
||||
public IntPtr lpCallbackData;
|
||||
public uint cxWidth;
|
||||
}
|
||||
|
||||
public enum TASKDIALOG_FLAGS
|
||||
{
|
||||
NONE = 0,
|
||||
TDF_ENABLE_HYPERLINKS = 1,
|
||||
TDF_USE_HICON_MAIN = 2,
|
||||
TDF_USE_HICON_FOOTER = 4,
|
||||
TDF_ALLOW_DIALOG_CANCELLATION = 8,
|
||||
TDF_USE_COMMAND_LINKS = 16,
|
||||
TDF_USE_COMMAND_LINKS_NO_ICON = 32,
|
||||
TDF_EXPAND_FOOTER_AREA = 64,
|
||||
TDF_EXPANDED_BY_DEFAULT = 128,
|
||||
TDF_VERIFICATION_FLAG_CHECKED = 256,
|
||||
TDF_SHOW_PROGRESS_BAR = 512,
|
||||
TDF_SHOW_MARQUEE_PROGRESS_BAR = 1024,
|
||||
TDF_CALLBACK_TIMER = 2048,
|
||||
TDF_POSITION_RELATIVE_TO_WINDOW = 4096,
|
||||
TDF_RTL_LAYOUT = 8192,
|
||||
TDF_NO_DEFAULT_RADIO_BUTTON = 16384,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
|
||||
public struct TASKDIALOGCONFIG_ICON_UNION
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public int hMainIcon;
|
||||
[FieldOffset(0)]
|
||||
public int pszIcon;
|
||||
[FieldOffset(0)]
|
||||
public IntPtr spacer;
|
||||
|
||||
public TASKDIALOGCONFIG_ICON_UNION(int i)
|
||||
{
|
||||
this = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION();
|
||||
spacer = IntPtr.Zero;
|
||||
pszIcon = 0;
|
||||
hMainIcon = i;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
|
||||
public struct TASKDIALOG_BUTTON
|
||||
{
|
||||
public int nButtonID;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszButtonText;
|
||||
|
||||
public TASKDIALOG_BUTTON(int n, string txt)
|
||||
{
|
||||
this = new TaskDialogNative.TASKDIALOG_BUTTON();
|
||||
nButtonID = n;
|
||||
pszButtonText = txt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum MsgButtons
|
||||
{
|
||||
None = 0,
|
||||
Ok = 1,
|
||||
Yes = 2,
|
||||
No = 4,
|
||||
YesNo = 6,
|
||||
Cancel = 8,
|
||||
OkCancel = 9,
|
||||
YesNoCancel = 14,
|
||||
Retry = 16,
|
||||
RetryCancel = 24,
|
||||
Close = 32,
|
||||
}
|
||||
|
||||
public enum MsgResult
|
||||
{
|
||||
None,
|
||||
OK,
|
||||
Cancel,
|
||||
Abort,
|
||||
Retry,
|
||||
Ignore,
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
public enum MsgIcon
|
||||
{
|
||||
None = 0,
|
||||
SecurityShieldGray = 65527,
|
||||
SecuritySuccess = 65528,
|
||||
SecurityError = 65529,
|
||||
SecurityWarning = 65530,
|
||||
SecurityShieldBlue = 65531,
|
||||
Shield = 65532,
|
||||
Info = 65533,
|
||||
Error = 65534,
|
||||
Warning = 65535,
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
@@ -13,11 +13,11 @@
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="1*" />
|
||||
<ColumnDefinition Width="6*" />
|
||||
<ColumnDefinition Width="100" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Controls:SearchTextBoxUserControl HintText="Find a setting" x:Name="SearchControl" Width="250" Margin="0,20,0,10" Grid.ColumnSpan="2" />
|
||||
<ScrollViewer x:Name="MainScrollViewer" VerticalScrollBarVisibility="Auto" Grid.Row="1" Grid.Column="1" 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>
|
||||
</ScrollViewer>
|
||||
<StackPanel Margin="20,0,0,0" Grid.Row="1">
|
||||
@@ -7,16 +7,16 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Linq;
|
||||
|
||||
using DynamicGUI;
|
||||
using Sys;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class ConfWindow : Window
|
||||
{
|
||||
private List<SettingBase> MpvSettingsDefinitions = Settings.LoadSettings(Properties.Resources.mpvConfToml);
|
||||
private List<SettingBase> MpvNetSettingsDefinitions = Settings.LoadSettings(Properties.Resources.mpvNetConfToml);
|
||||
private List<SettingBase> SettingsDefinitions = Settings.LoadSettings(Properties.Resources.mpvConfToml);
|
||||
private List<SettingBase> NetSettingsDefinitions = Settings.LoadSettings(Properties.Resources.mpvNetConfToml);
|
||||
private Dictionary<string, Dictionary<string, string>> Comments = new Dictionary<string, Dictionary<string, string>>();
|
||||
|
||||
public ObservableCollection<string> FilterStrings { get; } = new ObservableCollection<string>();
|
||||
@@ -26,10 +26,10 @@ namespace mpvnet
|
||||
InitializeComponent();
|
||||
DataContext = this;
|
||||
SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged;
|
||||
LoadSettings(MpvSettingsDefinitions, MpvConf);
|
||||
LoadSettings(MpvNetSettingsDefinitions, MpvNetConf);
|
||||
LoadSettings(SettingsDefinitions, Conf);
|
||||
LoadSettings(NetSettingsDefinitions, NetConf);
|
||||
SearchControl.Text = RegistryHelp.GetString(@"HKCU\Software\mpv.net", "config editor search");
|
||||
|
||||
|
||||
if (App.IsDarkMode)
|
||||
{
|
||||
Foreground = Brushes.White;
|
||||
@@ -80,21 +80,21 @@ namespace mpvnet
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, string> _mpvConf;
|
||||
private Dictionary<string, string> _Conf;
|
||||
|
||||
public Dictionary<string, string> MpvConf {
|
||||
public Dictionary<string, string> Conf {
|
||||
get {
|
||||
if (_mpvConf == null) _mpvConf = LoadConf(mp.MpvConfPath);
|
||||
return _mpvConf;
|
||||
if (_Conf == null) _Conf = LoadConf(mp.ConfPath);
|
||||
return _Conf;
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, string> _mpvNetConf;
|
||||
private Dictionary<string, string> _NetConf;
|
||||
|
||||
public Dictionary<string, string> MpvNetConf {
|
||||
public Dictionary<string, string> NetConf {
|
||||
get {
|
||||
if (_mpvNetConf == null) _mpvNetConf = LoadConf(mp.MpvNetConfPath);
|
||||
return _mpvNetConf;
|
||||
if (_NetConf == null) _NetConf = LoadConf(App.ConfFilePath);
|
||||
return _NetConf;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace mpvnet
|
||||
|
||||
if (left.StartsWith("#"))
|
||||
{
|
||||
Comments[filePath][left.TrimStart("#".ToCharArray())] = right;
|
||||
Comments[filePath][left.TrimStart('#')] = right;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -139,19 +139,19 @@ namespace mpvnet
|
||||
{
|
||||
bool isDirty = false;
|
||||
|
||||
foreach (SettingBase i in MpvSettingsDefinitions)
|
||||
foreach (SettingBase i in SettingsDefinitions)
|
||||
if (i.StartValue != i.Value)
|
||||
isDirty = true;
|
||||
|
||||
foreach (SettingBase i in MpvNetSettingsDefinitions)
|
||||
foreach (SettingBase i in NetSettingsDefinitions)
|
||||
if (i.StartValue != i.Value)
|
||||
isDirty = true;
|
||||
|
||||
if (!isDirty)
|
||||
return;
|
||||
|
||||
WriteToDisk(mp.MpvConfPath, MpvConf, MpvSettingsDefinitions);
|
||||
WriteToDisk(mp.MpvNetConfPath, MpvNetConf, MpvNetSettingsDefinitions);
|
||||
WriteToDisk(mp.ConfPath, Conf, SettingsDefinitions);
|
||||
WriteToDisk(App.ConfFilePath, NetConf, NetSettingsDefinitions);
|
||||
|
||||
Msg.Show("Changes will be available on next mpv.net startup.");
|
||||
}
|
||||
@@ -216,6 +216,8 @@ namespace mpvnet
|
||||
{
|
||||
SearchControl.SearchTextBox.SelectAll();
|
||||
Keyboard.Focus(SearchControl.SearchTextBox);
|
||||
foreach (var i in MainStackPanel.Children.OfType<StringSettingControl>())
|
||||
i.Update();
|
||||
}
|
||||
|
||||
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
@@ -226,7 +228,7 @@ namespace mpvnet
|
||||
|
||||
private void OpenSettingsTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Process.Start(Path.GetDirectoryName(mp.MpvConfPath));
|
||||
Process.Start(Path.GetDirectoryName(mp.ConfPath));
|
||||
}
|
||||
|
||||
private void ShowManualTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
23
mpv.net/WPF/EverythingWindow.xaml
Normal file
@@ -0,0 +1,23 @@
|
||||
<Window x:Class="mpvnet.EverythingWindow"
|
||||
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"
|
||||
mc:Ignorable="d"
|
||||
Title="Media File Search" Height="300" Width="600" ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterOwner" Loaded="Window_Loaded" FontSize="13">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBox Name="FilterTextBox" PreviewKeyDown="FilterTextBox_PreviewKeyDown" TextChanged="FilterTextBox_TextChanged"></TextBox>
|
||||
<ListView Name="ListView" Grid.Row="1" MouseUp="ListView_MouseUp" PreviewKeyDown="ListView_PreviewKeyDown">
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
</ListView>
|
||||
</Grid>
|
||||
</Window>
|
||||
168
mpv.net/WPF/EverythingWindow.xaml.cs
Normal file
@@ -0,0 +1,168 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class EverythingWindow : Window
|
||||
{
|
||||
public EverythingWindow()
|
||||
{
|
||||
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_PATH = 0x00000002;
|
||||
const int EVERYTHING_SORT_SIZE_DESCENDING = 6;
|
||||
|
||||
[DllImport("Everything.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern int Everything_SetSearch(string lpSearchString);
|
||||
|
||||
[DllImport("Everything.dll")]
|
||||
public static extern void Everything_SetRequestFlags(UInt32 dwRequestFlags);
|
||||
|
||||
[DllImport("Everything.dll")]
|
||||
public static extern void Everything_SetSort(UInt32 dwSortType);
|
||||
|
||||
[DllImport("Everything.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern bool Everything_Query(bool bWait);
|
||||
|
||||
[DllImport("Everything.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern void Everything_GetResultFullPathName(UInt32 nIndex, StringBuilder lpString, UInt32 nMaxCount);
|
||||
|
||||
[DllImport("Everything.dll")]
|
||||
public static extern bool Everything_GetResultSize(UInt32 nIndex, out long lpFileSize);
|
||||
|
||||
[DllImport("Everything.dll")]
|
||||
public static extern UInt32 Everything_GetNumResults();
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
|
||||
source.AddHook(new HwndSourceHook(WndProc));
|
||||
Keyboard.Focus(FilterTextBox);
|
||||
}
|
||||
|
||||
void SelectFirst()
|
||||
{
|
||||
if (ListView.Items.Count > 0)
|
||||
ListView.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
if (msg == 0x200 /*WM_MOUSEMOVE*/ && Mouse.LeftButton != MouseButtonState.Pressed)
|
||||
handled = true;
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
private void FilterTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Up:
|
||||
{
|
||||
int index = ListView.SelectedIndex;
|
||||
index -= 1;
|
||||
if (index < 0) index = 0;
|
||||
ListView.SelectedIndex = index;
|
||||
ListView.ScrollIntoView(ListView.SelectedItem);
|
||||
}
|
||||
break;
|
||||
case Key.Down:
|
||||
{
|
||||
int index = ListView.SelectedIndex;
|
||||
index += 1;
|
||||
if (index > ListView.Items.Count - 1) index = ListView.Items.Count - 1;
|
||||
ListView.SelectedIndex = index;
|
||||
ListView.ScrollIntoView(ListView.SelectedItem);
|
||||
}
|
||||
break;
|
||||
case Key.Escape:
|
||||
Close();
|
||||
break;
|
||||
case Key.Enter:
|
||||
Execute();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ListView_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Escape) Close();
|
||||
if (e.Key == Key.Enter) Execute();
|
||||
}
|
||||
|
||||
void Execute()
|
||||
{
|
||||
if (ListView.SelectedItem != null)
|
||||
mp.Load(ListView.SelectedItem as string);
|
||||
Keyboard.Focus(FilterTextBox);
|
||||
}
|
||||
|
||||
private void ListView_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Execute();
|
||||
}
|
||||
|
||||
private void FilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
string searchtext = FilterTextBox.Text;
|
||||
Task.Run(() => Search(searchtext));
|
||||
}
|
||||
|
||||
object LockObject = new object();
|
||||
|
||||
void Search(string searchtext)
|
||||
{
|
||||
lock (LockObject)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<string> items = new List<string>();
|
||||
UInt32 i;
|
||||
const int bufsize = 500;
|
||||
StringBuilder buf = new StringBuilder(bufsize);
|
||||
Everything_SetSearch(searchtext);
|
||||
Everything_SetRequestFlags(EVERYTHING_REQUEST_FILE_NAME | EVERYTHING_REQUEST_PATH);
|
||||
Everything_SetSort(EVERYTHING_SORT_SIZE_DESCENDING);
|
||||
Everything_Query(true);
|
||||
for (i = 0; i < Everything_GetNumResults(); i++)
|
||||
{
|
||||
Everything_GetResultFullPathName(i, buf, bufsize);
|
||||
string ext = Path.GetExtension(buf.ToString()).TrimStart('.').ToLower();
|
||||
if (App.AudioTypes.Contains(ext) || App.VideoTypes.Contains(ext))
|
||||
items.Add(buf.ToString());
|
||||
if (items.Count > 100) break;
|
||||
}
|
||||
Application.Current.Dispatcher.Invoke(() => {
|
||||
ListView.ItemsSource = items;
|
||||
SelectFirst();
|
||||
});
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Msg.ShowError("Search query failed.",
|
||||
"The search feature depends on [Everything](https://www.voidtools.com) being installed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Sys;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
@@ -31,10 +30,19 @@ namespace mpvnet
|
||||
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)
|
||||
{
|
||||
CollectionView.Refresh();
|
||||
@@ -2,26 +2,107 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:WPF="clr-namespace:WPF">
|
||||
|
||||
<Style TargetType="TextBox">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type TextBox}">
|
||||
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
|
||||
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsFocused" Value="true">
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{x:Static WPF:WPF.ThemeBrush}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style TargetType="TextBox">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type TextBox}">
|
||||
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
|
||||
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsFocused" Value="true">
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{x:Static WPF:WPF.ThemeBrush}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style TargetType="RadioButton">
|
||||
<Setter Property="Padding" Value="6 0 0 0" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="RadioButton">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition x:Name="LeftCol" Width="18" />
|
||||
<ColumnDefinition x:Name="RightCol" Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid x:Name="PART_CHECKBOX">
|
||||
<Ellipse
|
||||
x:Name="normal"
|
||||
Width="18"
|
||||
Height="18"
|
||||
Fill="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
|
||||
Stroke="{x:Static WPF:WPF.ThemeBrush}"
|
||||
StrokeThickness="2" />
|
||||
<Ellipse
|
||||
x:Name="Checked1"
|
||||
Width="8"
|
||||
Height="8"
|
||||
Fill="{TemplateBinding Foreground}"
|
||||
Opacity="0" />
|
||||
<Ellipse
|
||||
x:Name="disabled"
|
||||
Width="18"
|
||||
Height="18"
|
||||
Fill="{DynamicResource SemiTransparentWhiteBrush}"
|
||||
Opacity="0"
|
||||
StrokeThickness="{TemplateBinding BorderThickness}" />
|
||||
</Grid>
|
||||
<ContentPresenter
|
||||
x:Name="contentPresenter"
|
||||
Grid.Column="1"
|
||||
Margin="{TemplateBinding Padding}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentStringFormat="{TemplateBinding ContentStringFormat}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
|
||||
RecognizesAccessKey="True" />
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="contentPresenter"
|
||||
Storyboard.TargetProperty="(UIElement.Opacity)"
|
||||
To=".55"
|
||||
Duration="0" />
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="disabled"
|
||||
Storyboard.TargetProperty="(UIElement.Opacity)"
|
||||
To="1"
|
||||
Duration="0" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup x:Name="CheckStates">
|
||||
<VisualState x:Name="Checked">
|
||||
<Storyboard>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="Checked1"
|
||||
Storyboard.TargetProperty="(UIElement.Opacity)"
|
||||
To="1"
|
||||
Duration="0" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Unchecked" />
|
||||
<VisualState x:Name="Indeterminate" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
@@ -10,8 +10,6 @@ using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Diagnostics;
|
||||
|
||||
using Sys;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class MainForm : Form
|
||||
@@ -26,15 +24,6 @@ namespace mpvnet
|
||||
bool IgnoreDpiChanged = true;
|
||||
List<string> RecentFiles;
|
||||
|
||||
public string MpvNetDarkMode { get; set; } = "always";
|
||||
public bool MpvFullscreen { get; set; }
|
||||
public float MpvAutofit { get; set; } = 0.50f;
|
||||
public int MpvScreen { get; set; } = -1;
|
||||
public string MpvSid { get; set; } = "";
|
||||
public string MpvAid { get; set; } = "";
|
||||
public string MpvVid { get; set; } = "";
|
||||
public int MpvEdition { get; set; }
|
||||
|
||||
public MainForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -51,25 +40,18 @@ namespace mpvnet
|
||||
MinimumSize = new Size(FontHeight * 16, FontHeight * 9);
|
||||
Text += " " + Application.ProductVersion;
|
||||
|
||||
object recent = RegistryHelp.GetObject("HKCU\\Software\\" + Application.ProductName, "Recent");
|
||||
object recent = RegistryHelp.GetObject(App.RegPath, "Recent");
|
||||
|
||||
if (recent is string[] r)
|
||||
RecentFiles = new List<string>(r);
|
||||
else
|
||||
RecentFiles = new List<string>();
|
||||
|
||||
foreach (var i in mp.mpvConf)
|
||||
ProcessMpvProperty(i.Key, i.Value);
|
||||
|
||||
foreach (var i in mp.mpvNetConf)
|
||||
ProcessMpvNetProperty(i.Key, i.Value);
|
||||
|
||||
ProcessCommandLineEarly();
|
||||
|
||||
if (MpvScreen == -1) MpvScreen = Array.IndexOf(Screen.AllScreens, Screen.PrimaryScreen);
|
||||
SetScreen(MpvScreen);
|
||||
|
||||
ChangeFullscreen(MpvFullscreen);
|
||||
var dummy = mp.Conf;
|
||||
App.ProcessCommandLineEarly();
|
||||
if (mp.Screen == -1) mp.Screen = Array.IndexOf(Screen.AllScreens, Screen.PrimaryScreen);
|
||||
SetScreen(mp.Screen);
|
||||
ChangeFullscreen(mp.Fullscreen);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -96,7 +78,7 @@ namespace mpvnet
|
||||
{
|
||||
MenuItem mi = new MenuItem(track.Text);
|
||||
mi.Action = () => { mp.commandv("set", "vid", track.ID.ToString()); };
|
||||
mi.Checked = MpvVid == track.ID.ToString();
|
||||
mi.Checked = mp.Vid == track.ID.ToString();
|
||||
trackMenuItem.DropDownItems.Add(mi);
|
||||
}
|
||||
|
||||
@@ -107,7 +89,7 @@ namespace mpvnet
|
||||
{
|
||||
MenuItem mi = new MenuItem(track.Text);
|
||||
mi.Action = () => { mp.commandv("set", "aid", track.ID.ToString()); };
|
||||
mi.Checked = MpvAid == track.ID.ToString();
|
||||
mi.Checked = mp.Aid == track.ID.ToString();
|
||||
trackMenuItem.DropDownItems.Add(mi);
|
||||
}
|
||||
|
||||
@@ -118,7 +100,7 @@ namespace mpvnet
|
||||
{
|
||||
MenuItem mi = new MenuItem(track.Text);
|
||||
mi.Action = () => { mp.commandv("set", "sid", track.ID.ToString()); };
|
||||
mi.Checked = MpvSid == track.ID.ToString();
|
||||
mi.Checked = mp.Sid == track.ID.ToString();
|
||||
trackMenuItem.DropDownItems.Add(mi);
|
||||
}
|
||||
|
||||
@@ -126,7 +108,7 @@ namespace mpvnet
|
||||
{
|
||||
MenuItem mi = new MenuItem("S: No subtitles");
|
||||
mi.Action = () => { mp.commandv("set", "sid", "no"); };
|
||||
mi.Checked = MpvSid == "no";
|
||||
mi.Checked = mp.Sid == "no";
|
||||
trackMenuItem.DropDownItems.Add(mi);
|
||||
}
|
||||
|
||||
@@ -137,7 +119,7 @@ namespace mpvnet
|
||||
{
|
||||
MenuItem mi = new MenuItem(track.Text);
|
||||
mi.Action = () => { mp.commandv("set", "edition", track.ID.ToString()); };
|
||||
mi.Checked = MpvEdition == track.ID;
|
||||
mi.Checked = mp.Edition == track.ID;
|
||||
trackMenuItem.DropDownItems.Add(mi);
|
||||
}
|
||||
}
|
||||
@@ -168,7 +150,7 @@ namespace mpvnet
|
||||
recent.DropDownItems.Clear();
|
||||
|
||||
foreach (string path in RecentFiles)
|
||||
MenuItem.Add(recent.DropDownItems, path, () => mp.LoadFiles(path));
|
||||
MenuItem.Add(recent.DropDownItems, path, () => mp.Load(path));
|
||||
|
||||
recent.DropDownItems.Add(new ToolStripSeparator());
|
||||
MenuItem mi = new MenuItem("Clear List");
|
||||
@@ -217,7 +199,7 @@ namespace mpvnet
|
||||
{
|
||||
if (IsFullscreen || mp.VideoSize.Width == 0) return;
|
||||
Screen screen = Screen.FromControl(this);
|
||||
int height = Convert.ToInt32(screen.Bounds.Height * MpvAutofit);
|
||||
int height = Convert.ToInt32(screen.Bounds.Height * mp.Autofit);
|
||||
int width = Convert.ToInt32(height * mp.VideoSize.Width / (double)mp.VideoSize.Height);
|
||||
Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
|
||||
var rect = new Native.RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height));
|
||||
@@ -232,7 +214,7 @@ namespace mpvnet
|
||||
if (IsFullscreen || mp.VideoSize.Width == 0) return;
|
||||
Screen screen = Screen.FromControl(this);
|
||||
int height = ClientSize.Height;
|
||||
if (height > screen.Bounds.Height * 0.9) height = Convert.ToInt32(screen.Bounds.Height * MpvAutofit);
|
||||
if (height > screen.Bounds.Height * 0.9) height = Convert.ToInt32(screen.Bounds.Height * mp.Autofit);
|
||||
int width = Convert.ToInt32(height * mp.VideoSize.Width / (double)mp.VideoSize.Height);
|
||||
Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
|
||||
var rect = new Native.RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height));
|
||||
@@ -240,124 +222,38 @@ namespace mpvnet
|
||||
int left = middlePos.X - rect.Width / 2;
|
||||
int top = middlePos.Y - rect.Height / 2;
|
||||
Screen[] screens = Screen.AllScreens;
|
||||
if (left < screens[0].Bounds.Left) left = screens[0].Bounds.Left;
|
||||
int maxLeft = screens[0].Bounds.Left + screens.Select((sc) => sc.Bounds.Width).Sum() - rect.Width - SystemInformation.CaptionHeight;
|
||||
if (left > maxLeft) left = maxLeft;
|
||||
Native.SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */, left, top, rect.Width, rect.Height, 4 /* SWP_NOZORDER */);
|
||||
}
|
||||
|
||||
protected 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);
|
||||
ProcessMpvProperty(left, right);
|
||||
ProcessMpvNetProperty(left, right);
|
||||
}
|
||||
else
|
||||
{
|
||||
string switchName = i.Substring(2);
|
||||
|
||||
switch (switchName)
|
||||
{
|
||||
case "fs":
|
||||
case "fullscreen":
|
||||
MpvFullscreen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessMpvProperty(string name, string value)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case "autofit":
|
||||
if (value.Length == 3 && value.EndsWith("%"))
|
||||
if (int.TryParse(value.Substring(0, 2), out int result))
|
||||
MpvAutofit = result / 100f;
|
||||
break;
|
||||
case "fs":
|
||||
case "fullscreen":
|
||||
MpvFullscreen = value == "yes";
|
||||
break;
|
||||
case "screen":
|
||||
MpvScreen = Convert.ToInt32(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessMpvNetProperty(string name, string value)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case "dark-mode":
|
||||
MpvNetDarkMode = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void BuildMenu()
|
||||
{
|
||||
string content = File.ReadAllText(mp.InputConfPath);
|
||||
List<string> lines = null;
|
||||
Dictionary<string, string> commandInputDic = new Dictionary<string, string>();
|
||||
var items = CommandItem.GetItems(content);
|
||||
|
||||
if (content.Contains("#menu:"))
|
||||
lines = content.Split("\r\n".ToCharArray()).ToList();
|
||||
else
|
||||
if (!content.Contains("#menu:"))
|
||||
{
|
||||
lines = Properties.Resources.inputConf.Split("\r\n".ToCharArray()).ToList();
|
||||
|
||||
foreach (string i in content.Split("\r\n".ToCharArray()))
|
||||
{
|
||||
string line = i.Trim();
|
||||
if (line.StartsWith("#") || !line.Contains(" ")) continue;
|
||||
string input = line.Substring(0, line.IndexOf(" ")).Trim();
|
||||
string command = line.Substring(line.IndexOf(" ") + 1).Trim();
|
||||
commandInputDic[command] = input;
|
||||
}
|
||||
var defaultItems = CommandItem.GetItems(Properties.Resources.inputConf);
|
||||
foreach (CommandItem item in items)
|
||||
foreach (CommandItem defaultItem in defaultItems)
|
||||
if (item.Command == defaultItem.Command)
|
||||
defaultItem.Input = item.Input;
|
||||
items = defaultItems;
|
||||
}
|
||||
|
||||
foreach (string line in lines)
|
||||
foreach (CommandItem item in items)
|
||||
{
|
||||
if (!line.Contains("#menu:")) continue;
|
||||
string left = line.Substring(0, line.IndexOf("#menu:")).Trim();
|
||||
if (left.StartsWith("#")) continue;
|
||||
string command = left.Substring(left.IndexOf(" ") + 1).Trim();
|
||||
string menu = line.Substring(line.IndexOf("#menu:") + "#menu:".Length).Trim();
|
||||
string input = left.Substring(0, left.IndexOf(" "));
|
||||
if (input == "_") input = "";
|
||||
if (menu.Contains(";")) input = menu.Substring(0, menu.IndexOf(";")).Trim();
|
||||
string path = menu.Substring(menu.IndexOf(";") + 1).Trim().Replace("&", "&&");
|
||||
if (path == "" || command == "") continue;
|
||||
|
||||
if (commandInputDic.Count > 0)
|
||||
if (commandInputDic.ContainsKey(command))
|
||||
input = commandInputDic[command];
|
||||
else
|
||||
input = "";
|
||||
|
||||
if (string.IsNullOrEmpty(item.Path))
|
||||
continue;
|
||||
string path = item.Path.Replace("&", "&&");
|
||||
MenuItem menuItem = ContextMenu.Add(path, () => {
|
||||
try {
|
||||
mp.command_string(command);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
mp.command_string(item.Command);
|
||||
} catch (Exception ex) {
|
||||
Msg.ShowException(ex);
|
||||
}
|
||||
});
|
||||
|
||||
if (menuItem != null)
|
||||
menuItem.ShortcutKeyDisplayString = input + " ";
|
||||
menuItem.ShortcutKeyDisplayString = item.Input + " ";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,7 +262,12 @@ namespace mpvnet
|
||||
private void Mp_FileLoaded()
|
||||
{
|
||||
string path = mp.get_property_string("path");
|
||||
BeginInvoke(new Action(() => { Text = Path.GetFileName(path) + " - mpv.net " + Application.ProductVersion; }));
|
||||
BeginInvoke(new Action(() => {
|
||||
if (File.Exists(path) || path.StartsWith("http"))
|
||||
Text = Path.GetFileName(path) + " - mpv.net " + Application.ProductVersion;
|
||||
else
|
||||
Text = "mpv.net " + Application.ProductVersion;
|
||||
}));
|
||||
if (RecentFiles.Contains(path)) RecentFiles.Remove(path);
|
||||
RecentFiles.Insert(0, path);
|
||||
if (RecentFiles.Count > 15) RecentFiles.RemoveAt(15);
|
||||
@@ -434,16 +335,20 @@ namespace mpvnet
|
||||
case 0x0104: // WM_SYSKEYDOWN
|
||||
case 0x0105: // WM_SYSKEYUP
|
||||
case 0x020A: // WM_MOUSEWHEEL
|
||||
if (mp.MpvWindowHandle != IntPtr.Zero)
|
||||
Native.SendMessage(mp.MpvWindowHandle, m.Msg, m.WParam, m.LParam);
|
||||
if (mp.WindowHandle != IntPtr.Zero)
|
||||
Native.SendMessage(mp.WindowHandle, m.Msg, m.WParam, m.LParam);
|
||||
break;
|
||||
case 0x0200: // WM_MOUSEMOVE
|
||||
Point pos = PointToClient(Cursor.Position);
|
||||
mp.command_string($"mouse {pos.X} {pos.Y}");
|
||||
if (CursorHelp.IsPosDifferent(LastCursorPosChanged)) CursorHelp.Show();
|
||||
break;
|
||||
case 0x319: // WM_APPCOMMAND
|
||||
if (mp.MpvWindowHandle != IntPtr.Zero)
|
||||
Native.PostMessage(mp.MpvWindowHandle, m.Msg, m.WParam, m.LParam);
|
||||
if (mp.WindowHandle != IntPtr.Zero)
|
||||
Native.PostMessage(mp.WindowHandle, m.Msg, m.WParam, m.LParam);
|
||||
break;
|
||||
case 0x203: // Native.WM.LBUTTONDBLCLK
|
||||
if (!IsMouseInOSC())
|
||||
mp.command_string("cycle fullscreen");
|
||||
if (!IsMouseInOSC()) mp.command_string("cycle fullscreen");
|
||||
break;
|
||||
case 0x02E0: // WM_DPICHANGED
|
||||
if (IgnoreDpiChanged) break;
|
||||
@@ -469,6 +374,30 @@ namespace mpvnet
|
||||
m.Result = new IntPtr(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m.Msg == SingleProcess.Message)
|
||||
{
|
||||
object filesObject = RegistryHelp.GetObject(App.RegPath, "ShellFiles");
|
||||
|
||||
if (filesObject is string[] files)
|
||||
{
|
||||
switch (RegistryHelp.GetString(App.RegPath, "ProcessInstanceMode"))
|
||||
{
|
||||
case "single":
|
||||
mp.Load(files);
|
||||
break;
|
||||
case "queue":
|
||||
foreach (string file in files)
|
||||
mp.commandv("loadfile", file, "append");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RegistryHelp.RemoveValue(App.RegPath, "ShellFiles");
|
||||
Activate();
|
||||
return;
|
||||
}
|
||||
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
@@ -483,9 +412,9 @@ namespace mpvnet
|
||||
{
|
||||
base.OnDragDrop(e);
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
mp.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as String[]);
|
||||
mp.Load(e.Data.GetData(DataFormats.FileDrop) as String[]);
|
||||
if (e.Data.GetDataPresent(DataFormats.Text))
|
||||
mp.LoadFiles(e.Data.GetData(DataFormats.Text).ToString());
|
||||
mp.Load(e.Data.GetData(DataFormats.Text).ToString());
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
@@ -505,15 +434,6 @@ namespace mpvnet
|
||||
mp.commandv("quit");
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseMove(e);
|
||||
mp.command_string($"mouse {e.X} {e.Y}");
|
||||
|
||||
if (CursorHelp.IsPosDifferent(LastCursorPosChanged))
|
||||
CursorHelp.Show();
|
||||
}
|
||||
|
||||
bool IsMouseInOSC() => PointToClient(Control.MousePosition).Y > ClientSize.Height * 0.9;
|
||||
|
||||
void Timer_Tick(object sender, EventArgs e)
|
||||
@@ -549,32 +469,38 @@ namespace mpvnet
|
||||
|
||||
void mpPropChangeOnTop(bool value) => BeginInvoke(new Action(() => TopMost = value));
|
||||
|
||||
void mpPropChangeAid(string value) => MpvAid = value;
|
||||
void mpPropChangeAid(string value) => mp.Aid = value;
|
||||
|
||||
void mpPropChangeSid(string value) => MpvSid = value;
|
||||
void mpPropChangeSid(string value) => mp.Sid = value;
|
||||
|
||||
void mpPropChangeVid(string value) => MpvVid = value;
|
||||
void mpPropChangeVid(string value) => mp.Vid = value;
|
||||
|
||||
void mpPropChangeEdition(int value) => MpvEdition = value;
|
||||
void mpPropChangeEdition(int value) => mp.Edition = value;
|
||||
|
||||
protected override void OnShown(EventArgs e)
|
||||
{
|
||||
base.OnShown(e);
|
||||
if ((MpvNetDarkMode == "system" && Sys.IsDarkTheme) || MpvNetDarkMode == "always")
|
||||
ToolStripRendererEx.ColorTheme = Color.Black;
|
||||
if (App.IsDarkMode) ToolStripRendererEx.ColorTheme = Color.Black;
|
||||
ContextMenu = new ContextMenuStripEx(components);
|
||||
ContextMenu.Opened += ContextMenu_Opened;
|
||||
ContextMenu.Opening += ContextMenu_Opening;
|
||||
BuildMenu();
|
||||
ContextMenuStrip = ContextMenu;
|
||||
IgnoreDpiChanged = false;
|
||||
CheckYouTube();
|
||||
CheckURLinClipboard();
|
||||
}
|
||||
|
||||
protected override void OnResize(EventArgs e)
|
||||
{
|
||||
base.OnResize(e);
|
||||
if (mp.IsLogoVisible) mp.ShowLogo();
|
||||
}
|
||||
|
||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||
{
|
||||
base.OnFormClosed(e);
|
||||
RegistryHelp.SetObject("HKCU\\Software\\" + Application.ProductName, "Recent", RecentFiles.ToArray());
|
||||
RegistryHelp.SetObject(App.RegPath, "Recent", RecentFiles.ToArray());
|
||||
App.Exit();
|
||||
mp.commandv("quit");
|
||||
mp.AutoResetEvent.WaitOne(3000);
|
||||
}
|
||||
@@ -588,19 +514,20 @@ namespace mpvnet
|
||||
protected override void OnActivated(EventArgs e)
|
||||
{
|
||||
base.OnActivated(e);
|
||||
CheckYouTube();
|
||||
CheckURLinClipboard();
|
||||
}
|
||||
|
||||
void CheckYouTube()
|
||||
void CheckURLinClipboard()
|
||||
{
|
||||
if (App.ClipboardMonitoring != "yes") return;
|
||||
string clipboard = Clipboard.GetText();
|
||||
|
||||
if (clipboard.StartsWith("https://www.youtube.com/watch?") && RegistryHelp.GetString("HKCU\\Software\\" + Application.ProductName, "LastYouTubeURL") != clipboard && Visible)
|
||||
if (clipboard.StartsWith("http") && RegistryHelp.GetString(App.RegPath, "LastURL") != clipboard && Visible)
|
||||
{
|
||||
RegistryHelp.SetObject("HKCU\\Software\\" + Application.ProductName, "LastYouTubeURL", clipboard);
|
||||
RegistryHelp.SetObject(App.RegPath, "LastURL", clipboard);
|
||||
|
||||
if (Msg.ShowQuestion("Play YouTube URL?", clipboard) == MsgResult.OK)
|
||||
mp.LoadFiles(clipboard);
|
||||
if (Msg.ShowQuestion("Play URL?", clipboard) == MsgResult.OK)
|
||||
mp.Load(clipboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
544
mpv.net/WinForms/MainForm.resx
Normal file
@@ -0,0 +1,544 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<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" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</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" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="Timer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>30, 12</value>
|
||||
</metadata>
|
||||
<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">
|
||||
<value>
|
||||
AAABAAUAEBAAAAEAIABoBAAAVgAAABgYAAABACAAiAkAAL4EAAAgIAAAAQAgAKgQAABGDgAAMDAAAAEA
|
||||
IACoJQAA7h4AAAAAAAABACAAzhwAAJZEAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAADDDgAAww4AAAAA
|
||||
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
|
||||
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
|
||||
Ov//lwj//5QA//+UAP7/lACK/5QABP+UAEH/lADp/5QA//+WBv//sVD//8aK///KlP//x4z//8eN///I
|
||||
jv//x4v//7NW//+XCP//lAD//5QA6f+UAEH/lACe/5QA//+TAP//qDf//8aK///Ijv//5Mj//926///J
|
||||
kP//xov//8eM///Hi///qj7//5QA//+UAP//lACe/5QA2/+UAP//lgb//7pp///Ijv//yI3//+zZ///+
|
||||
/v//7Nn//9Ki///HjP//yI7//71v//+XCf//lAD//5QA2/+UAPT/lAD//5oR///BfP//x43//8eN///s
|
||||
2P/////////////58///373//8iP///CgP//nBb//5MA//+UAPT/lAD0/5QA//+aEf//wXv//8eN///H
|
||||
jf//7Nj/////////////9u3//9u1///Ijv//wn///5wW//+TAP//lAD0/5QA2/+UAP//lgb//7ln///I
|
||||
jv//x43//+zY///9/P//6dL//8+c///Gi///yI7//7xt//+XCP//lAD//5QA2/+UAJ3/lAD//5MA//+m
|
||||
M///xoj//8iO///iw///27T//8iO///Gi///x43//8aK//+pOf//lAD//5QA//+UAJ3/lABB/5QA6f+U
|
||||
AP//lQT//69J///GiP//ypL//8eN///Hjf//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
|
||||
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/lAAAAAAAAAAAAAD/lAAA/5QABf+UAEH/lACe/5QA3P+UAPX/lAD1/5QA3P+UAJ7/lABB/5QABf+U
|
||||
AAAAAAAAAAAAAOAHAADAAwAAgAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AACAAQAAwAMAAOAHAAAoAAAAGAAAADAAAAABACAAAAAAAAAJAADDDgAAww4AAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD/lAAA/5QABP+UADD/lAB8/5QAvf+UAOP/lADz/5QA8/+UAOP/lAC9/5QAfP+U
|
||||
ADD/lAAE/5QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5QAAP+UAAD/lAAo/5QAk/+U
|
||||
AOP/lAD9/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA/f+UAOP/lACT/5QAKf+UAAD/lAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD/lAAA/5QAA/+UAFf/lADa/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA2v+UAFj/lAAD/5QAAAAAAAAAAAAAAAAAAP+UAAD/lAAD/5QAa/+U
|
||||
AO//lAD//5QA//+UAP//lAD//5MA//+TAP//kwD//5MA//+TAP//kwD//5QA//+UAP//lAD//5QA//+U
|
||||
APD/lABr/5QAA/+UAAAAAAAA/5QAAP+UAAD/lABY/5QA7/+UAP//lAD//5QA//+TAP//lQT//54c//+p
|
||||
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
|
||||
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
|
||||
AJP/lAAD/5QAMf+UAOL/lAD//5QA//+TAP//nhz//8B6///Ijv//x4z//9Wp///Qn///xov//8eM///H
|
||||
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
|
||||
CP//lAD//5QA//+UAP3/lAB8/5QAvf+UAP//lAD//5MA//+fHv//xIP//8eN///HjP//xov//+XK////
|
||||
/////vz//+3a///So///x4v//8eL///HjP//x4z//8WH//+iJ///kwD//5QA//+UAP//lAC8/5QA4v+U
|
||||
AP//lAD//5MA//+qO///x43//8eM///HjP//xov//+XJ///////////////////58///4cL//8uU///H
|
||||
i///x4z//8iO//+uR///kwD//5QA//+UAP//lADi/5QA8v+UAP//lAD//5MA//+vS///yI7//8eM///H
|
||||
jP//xov//+XJ/////////////////////////v7///Hi///Rof//x4v//8iO//+zVv//lAD//5QA//+U
|
||||
AP//lADy/5QA8v+UAP//lAD//5MA//+vSf//yI7//8eM///HjP//xov//+TI////////////////////
|
||||
/////fv//+rU///Om///x4v//8iO//+zVf//lAD//5QA//+UAP//lADy/5QA4v+UAP//lAD//5MA//+p
|
||||
OP//x4z//8eM///HjP//xov//+TH///////////////////16///27T//8iP///Hi///x4z//8iO//+t
|
||||
RP//kwD//5QA//+UAP//lADi/5QAvP+UAP//lAD//5MA//+eG///w4H//8eN///HjP//xov//+TH////
|
||||
/////Pn//+jQ///Om///xov//8eM///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
|
||||
jP//yI7//7dh//+WBv//lAD//5QA//+UAP3/lAB7/5QAMf+UAOL/lAD//5QA//+UAP//nBf//750///I
|
||||
jv//x4z//9Ki///Omv//xor//8eM///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
|
||||
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//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
|
||||
AAD/lAAD/5QAav+UAO//lAD//5QA//+UAP//lAD//5QA//+TAP//kwD//5MA//+TAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAPD/lABr/5QAA/+UAAAAAAAAAAAAAAAAAAD/lAAA/5QAA/+UAFf/lADZ/5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA2v+UAFj/lAAD/5QAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA/5QAAP+UAAD/lAAo/5QAk/+UAOP/lAD9/5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA/f+UAOP/lACT/5QAKP+UAAD/lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD/lAAA/5QABP+UADD/lAB8/5QAvf+UAOP/lADz/5QA8/+UAOP/lAC9/5QAfP+UADD/lAAE/5QAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA/AA/APgAHwDgAAcAwAADAMAAAwCAAAEAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAABAMAAAwDAAAMA4AAHAPgAHwD8AD8AKAAAACAA
|
||||
AABAAAAAAQAgAAAAAAAAEAAAww4AAMMOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA/5QAAP+UAAL/lAAd/5QAWv+UAJr/lADI/5QA5P+UAO//lADv/5QA5P+UAMj/lACa/5QAWv+U
|
||||
AB7/lAAC/5QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA/5QAAP+UAAH/lAAq/5QAh/+UANT/lAD3/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD4/5QA1P+UAIf/lAAr/5QAAv+UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA/5QAAP+UAAD/lAAS/5QAeP+UAOH/lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAOH/lAB5/5QAEv+UAAD/lAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAP+UAAD/lAAA/5QAKf+UALL/lAD8/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAPz/lACz/5QAKv+UAAD/lAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD/lAAA/5QAAP+UADT/lADM/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5MA//+TAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lADN/5QANP+U
|
||||
AAD/lAAAAAAAAAAAAAAAAAAA/5QAAP+UAAD/lAAq/5QAzP+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//kwD//5UE//+ZDv//nBb//5wW//+aEP//lgX//5MA//+TAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lADN/5QAKv+UAAD/lAAAAAAAAAAAAAD/lAAA/5QAEv+UALL/lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAH//5wV//+rP///uGP//793///Cf///wn///8B5//+5Z///rUT//50a//+UAv//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
|
||||
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
|
||||
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
|
||||
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
|
||||
jP//x4z//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
|
||||
7///3rv//8qS///Gi///x4z//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
|
||||
uv/////////////+/P//7tz//9Ol///HjP//x4v//8eM///HjP//x4z//8eM///Ijv//slH//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lACa/5QAyP+UAP//lAD//5QA//+UAP//lgX//7lm///Ijv//x4z//8eM///H
|
||||
jP//xor//926////////////////////////+fT//+LD///Llf//xor//8eM///HjP//x4z//8iO//+9
|
||||
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//x43//8OB//+dGv//kwD//5QA//+UAP//lAD//5QA4/+UAO//lAD//5QA//+UAP//kwD//5wW///C
|
||||
f///x43//8eM///HjP//x4z//8aK///duf////////////////////////////////////////z4///k
|
||||
x///yZD//8eM///HjP//xYb//6Ah//+TAP//lAD//5QA//+UAP//lADv/5QA7/+UAP//lAD//5QA//+U
|
||||
AP//nBX//8J////Hjf//x4z//8eM///HjP//xor//924////////////////////////////////////
|
||||
////9u3//9u2///Ijv//x4z//8eM///Fhv//oCH//5MA//+UAP//lAD//5QA//+UAO//lADj/5QA//+U
|
||||
AP//lAD//5QA//+ZDv//v3f//8eN///HjP//x4z//8eM///Giv//3Lf/////////////////////////
|
||||
/////Pr//+nR///PnP//xov//8eM///HjP//x43//8OA//+dGP//kwD//5QA//+UAP//lAD//5QA4/+U
|
||||
AMj/lAD//5QA//+UAP//lAD//5UE//+4Yv//yI7//8eM///HjP//x4z//8aK///ct///////////////
|
||||
//////////Xq///asv//yI7//8aL///HjP//x4z//8eM///Ijv//vG///5cJ//+UAP//lAD//5QA//+U
|
||||
AP//lADI/5QAmv+UAP//lAD//5QA//+UAP//kwD//6o8///HjP//x4z//8eM///HjP//xor//9y3////
|
||||
//////////z5///nzv//zpr//8aL///HjP//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
|
||||
iv//27b////+///z5///2K///8iO///Hi///x4z//8eM///HjP//x4z//8eM///Hjf//wn7//54b//+T
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
jv//x4v//750//+pOf//lgf//5QA//+UAP//lAD//5QA//+UAP//lAD9/5QAeP+UAAD/lAAAAAAAAP+U
|
||||
AAD/lAAS/5QAsf+UAP//lAD//5QA//+UAP//lAD//5QA//+TAP//mAz//6Uv//+zVf//u2z//791//+/
|
||||
dv//vG7//7RZ//+nNf//mg///5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UALL/lAAS/5QAAAAA
|
||||
AAAAAAAA/5QAAP+UAAD/lAAp/5QAy/+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//5QB//+X
|
||||
B///mAz//5kN//+XCP//lAH//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lADM/5QAKf+U
|
||||
AAD/lAAAAAAAAAAAAAAAAAAA/5QAAP+UAAD/lAAz/5QAy/+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QAzP+U
|
||||
ADT/lAAA/5QAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5QAAP+UAAD/lAAo/5QAsv+UAPz/lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA/P+U
|
||||
ALP/lAAp/5QAAP+UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5QAAP+UAAD/lAAR/5QAd/+U
|
||||
AOH/lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AOH/lAB4/5QAEv+UAAD/lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+U
|
||||
AAD/lAAB/5QAKv+UAIf/lADU/5QA9/+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA+P+U
|
||||
ANT/lACH/5QAK/+UAAH/lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD/lAAA/5QAAv+UAB3/lABa/5QAmv+UAMj/lADk/5QA7/+UAO//lADk/5QAyP+U
|
||||
AJr/lABa/5QAHv+UAAL/lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/gAH//gAAf/wA
|
||||
AD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAgAAAAYAAAAHAAAADwAAAA+AAAAfwAAAP+AAAH/wAAD/+AAB//4AB/ygA
|
||||
AAAwAAAAYAAAAAEAIAAAAAAAACQAAMMOAADDDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+UAAD/lAAA/5QABf+UACL/lABU/5QAif+U
|
||||
AK//lADP/5QA3/+UAOn/lADp/5QA3/+UAND/lACw/5QAif+UAFT/lAAj/5QABv+UAAD/lAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/lAAA/5QAAP+UABr/lABZ/5QApf+U
|
||||
ANv/lAD2/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAPb/lADb/5QApv+U
|
||||
AFn/lAAa/5QAAP+UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5QAAP+UAAD/lAAe/5QAdv+U
|
||||
ANL/lAD7/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAPv/lADS/5QAdv+UAB7/lAAA/5QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+UAAD/lAAA/5QADP+U
|
||||
AGH/lADS/5QA/f+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA/f+UANP/lABi/5QADf+UAAD/lAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5QAAP+U
|
||||
AAD/lAAn/5QAqP+UAPj/lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD5/5QAqf+U
|
||||
ACf/lAAA/5QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD/lAAA/5QAAP+UAEb/lADR/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UANL/lABH/5QAAf+UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAP+UAAD/lAAC/5QAV/+UAOT/lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lADl/5QAWf+UAAL/lAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA/5QAAP+UAAD/lABX/5QA6v+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+TAP//kwD//5MA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA6/+UAFn/lAAA/5QAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/lAAA/5QAAP+UAEf/lADk/5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//5MA//+VAv//mAr//5wW//+dGf//nRn//5wX//+Z
|
||||
DP//lQT//5MA//+TAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AOX/lABH/5QAAP+UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+UAAD/lAAA/5QAJ/+UANH/lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+VA///nRn//6o8//+2Xv//vXL//8J+///D
|
||||
gf//w4H//8J///++dP//uGL//6xD//+fHv//lgb//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lADS/5QAKP+UAAD/lAAAAAAAAAAAAAAAAAAAAAAAAP+UAAD/lAAM/5QAp/+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAH//58f//+0WP//wn///8eM///I
|
||||
jv//yI7//8eN///Hjf//x43//8eN///Ijf//yI7//8eN///Eg///uGL//6Mp//+VBP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QAqf+UAA3/lAAAAAAAAAAAAAAAAAAA/5QAAP+U
|
||||
AAD/lABi/5QA+P+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+XCv//rUT//8J////I
|
||||
jv//x43//8eM///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///Hjf//yI7//8SF//+y
|
||||
Uv//mhH//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA+f+UAGP/lAAA/5QAAAAA
|
||||
AAAAAAAA/5QAAP+UAB//lADS/5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5sU//+3
|
||||
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
|
||||
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
|
||||
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//+YCv//t2D//8iO///HjP//x4z//8eM///HjP//ypL//82Z///Gi///x4z//8eM///H
|
||||
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//5QB//+uSP//x4z//8eM///HjP//x4z//8eM///Gi///0aD///Hj///c
|
||||
uP//yZD//8aL///HjP//x4z//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
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//6Ag///DgP//x43//8eM///HjP//x4z//8eM///G
|
||||
i///0aD///v2///9/P//7Nf//9Gh///Hi///x4v//8eM///HjP//x4z//8eM///HjP//x4z//8eM///H
|
||||
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
|
||||
jP//x4z//8eM///Gi///0aD///v2//////////////jx///gv///ypP//8aL///HjP//x4z//8eM///H
|
||||
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
|
||||
jf//x4z//8eM///HjP//x4z//8eM///Gi///0aD///v2///////////////////+/f//797//9Sn///H
|
||||
jP//x4v//8eM///HjP//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//rEH//8eN///HjP//x4z//8eM///HjP//x4z//8eM///Gi///0aD///v2////////////////////
|
||||
//////////r1///jxv//zJf//8aK///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8iO//+0
|
||||
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////
|
||||
/////////////////////////////////v//8uX//9iu///Ijv//xov//8eM///HjP//x4z//8eM///H
|
||||
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
|
||||
i///0J7///r1//////////////////////////////////////////////z4///nzv//zpv//8aL///H
|
||||
jP//x4z//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
|
||||
jP//x4z//8eM///Gi///0J7///r1////////////////////////////////////////////////////
|
||||
////9ev//9u1///JkP//x4z//8eM///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
|
||||
jP//x4z//8eM///HjP//x4z//8eM///Gi///0J7///r1////////////////////////////////////
|
||||
//////////////////////////38///p0f//y5T//8eM///HjP//x4z//8eM///Gif//pCv//5MA//+U
|
||||
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////////////////////
|
||||
//////////////////////////////////////////bs///ct///yY///8eM///HjP//x4z//8eM///G
|
||||
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////
|
||||
///////////////////////////////////////////////8+v//6dH//8+c///Gi///x4z//8eM///H
|
||||
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
|
||||
i///z5z///nz//////////////////////////////////////////////Tp///asv//yI7//8aL///H
|
||||
jP//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
|
||||
jP//x4z//8eM///Gi///z5z///nz///////////////////////////////////8+f//587//86a///G
|
||||
i///x4z//8eM///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
|
||||
jP//x4z//8eM///HjP//x4z//8eM///Gi///z5z///nz//////////////////////////7///Pn///Y
|
||||
r///yI7//8eL///HjP//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//mxX//8F7///Hjf//x4z//8eM///HjP//x4z//8eM///Hi///z5z///nz///////////////////7
|
||||
9///5cr//82Y///Gi///x4z//8eM///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
|
||||
AP//lAD//5QA//+UAP//lAH//7BO///Ijf//x4z//8eM///HjP//x4z//8eM///Hi///zpv///jy////
|
||||
//////7///Lk///WrP//x43//8eL///HjP//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
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5wX///Aef//yI3//8eM///HjP//x4z//8eM///H
|
||||
i///zpv///ny///79v//48f//8yW///Giv//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///H
|
||||
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
|
||||
jP//x4z//8eM///Hi///zpr//+rU///Vqf//x4z//8eL///HjP//x4z//8eM///HjP//x4z//8eM///H
|
||||
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
|
||||
Bf//sU///8eM///HjP//x4z//8eM///HjP//yI7//8mR///Gi///x4z//8eM///HjP//x4z//8eM///H
|
||||
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//mAv//7Va///Hi///x43//8eM///HjP//x4z//8eM///HjP//x4z//8eM///H
|
||||
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//+UAP//lAD//5cJ//+wTP//xYb//8iO///HjP//x4z//8eM///H
|
||||
jP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eN///Giv//tVv//5oR//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UANH/lAAf/5QAAAAAAAAAAAAA/5QAAP+U
|
||||
AAD/lABg/5QA+P+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+VBP//pTD//71x///H
|
||||
jP//yI7//8eM///HjP//x4z//8eM///HjP//x4z//8eM///HjP//x4z//8eM///Ijf//yI3//8B5//+q
|
||||
Pf//lwj//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA+P+UAGL/lAAA/5QAAAAA
|
||||
AAAAAAAAAAAAAP+UAAD/lAAL/5QApv+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//kwD//5oQ//+sQf//vG7//8WH///Ijv//yI7//8iO///Ijv//yI7//8iO///Ijv//yI7//8aJ//+/
|
||||
df//r0v//5wX//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QAqP+U
|
||||
AAz/lAAAAAAAAAAAAAAAAAAAAAAAAP+UAAD/lAAA/5QAJv+UAND/lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//mAv//6In//+uR///tl7//7xv//++c///vnP//71x//+4
|
||||
Yv//sEz//6Qt//+ZD///lAH//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lADR/5QAJ/+UAAD/lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/lAAA/5QAAP+UAEX/lADj/5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+TAP//lQL//5cJ//+Y
|
||||
C///mAv//5gK//+VA///lAD//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAOP/lABG/5QAAP+UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5QAAP+U
|
||||
AAD/lABV/5QA6f+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA6v+UAFf/lAAA/5QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAP+UAAD/lAAB/5QAVf+UAOP/lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lADk/5QAV/+UAAL/lAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/lAAA/5QAAP+UAEX/lADR/5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UANL/lABH/5QAAf+UAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5QAAP+UAAD/lAAm/5QApv+U
|
||||
APj/lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD4/5QAqP+UACf/lAAA/5QAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+U
|
||||
AAD/lAAA/5QAC/+UAGD/lADS/5QA/f+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA/f+UANP/lABh/5QADP+U
|
||||
AAD/lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA/5QAAP+UAAD/lAAe/5QAdv+UANL/lAD7/5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAPv/lADS/5QAdv+U
|
||||
AB7/lAAA/5QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
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
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -56,6 +56,46 @@
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="IKVM.Reflection, Version=7.2.4630.5, Culture=neutral, PublicKeyToken=13235d27fcbfff58, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
@@ -97,16 +137,20 @@
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Addon.cs" />
|
||||
<Compile Include="Misc\Addon.cs" />
|
||||
<Page Include="Controls\SearchTextBoxUserControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Windows\AboutWindow.xaml">
|
||||
<Page Include="WPF\AboutWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Windows\CommandPaletteWindow.xaml">
|
||||
<Page Include="WPF\EverythingWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="WPF\CommandPaletteWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
@@ -125,50 +169,52 @@
|
||||
<DependentUpon>StringSettingControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="DynamicGUI\Tommy.cs" />
|
||||
<Compile Include="MediaInfo.cs" />
|
||||
<Compile Include="Menu.cs">
|
||||
<Compile Include="Native\MediaInfo.cs" />
|
||||
<Compile Include="WinForms\Menu.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="PowerShellScript.cs" />
|
||||
<Compile Include="Scripting\PowerShellScript.cs" />
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="PythonScript.cs" />
|
||||
<Compile Include="libmpv.cs" />
|
||||
<Compile Include="MainForm.cs">
|
||||
<Compile Include="Scripting\PythonScript.cs" />
|
||||
<Compile Include="mpv\libmpv.cs" />
|
||||
<Compile Include="WinForms\MainForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainForm.Designer.cs">
|
||||
<Compile Include="WinForms\MainForm.Designer.cs">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Misc.cs" />
|
||||
<Compile Include="mp.cs" />
|
||||
<Compile Include="Command.cs" />
|
||||
<Compile Include="Native.cs" />
|
||||
<Compile Include="NativeHelp.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Misc\Misc.cs" />
|
||||
<Compile Include="mpv\mp.cs" />
|
||||
<Compile Include="Misc\Command.cs" />
|
||||
<Compile Include="Native\Native.cs" />
|
||||
<Compile Include="Native\NativeHelp.cs" />
|
||||
<Compile Include="Misc\Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Sys\TaskDialog.cs" />
|
||||
<Compile Include="Windows\CommandPaletteWindow.xaml.cs">
|
||||
<Compile Include="Native\TaskDialog.cs" />
|
||||
<Compile Include="WPF\EverythingWindow.xaml.cs">
|
||||
<DependentUpon>EverythingWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="WPF\CommandPaletteWindow.xaml.cs">
|
||||
<DependentUpon>CommandPaletteWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Windows\ConfWindow.xaml.cs">
|
||||
<Compile Include="WPF\ConfWindow.xaml.cs">
|
||||
<DependentUpon>ConfWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Windows\AboutWindow.xaml.cs">
|
||||
<Compile Include="WPF\AboutWindow.xaml.cs">
|
||||
<DependentUpon>AboutWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Windows\LearnWindow.xaml.cs">
|
||||
<Compile Include="WPF\LearnWindow.xaml.cs">
|
||||
<DependentUpon>LearnWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Windows\InputWindow.xaml.cs">
|
||||
<Compile Include="WPF\InputWindow.xaml.cs">
|
||||
<DependentUpon>InputWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="trash.cs" />
|
||||
<Compile Include="WPF\WPF.cs" />
|
||||
<EmbeddedResource Include="MainForm.resx">
|
||||
<EmbeddedResource Include="WinForms\MainForm.resx">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
@@ -177,8 +223,17 @@
|
||||
<SubType>Designer</SubType>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="..\Changelog.md">
|
||||
<Link>Changelog.md</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="..\Manual.md">
|
||||
<Link>Manual.md</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="..\README.md">
|
||||
<Link>README.md</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="app.manifest" />
|
||||
<None Include="packages.config" />
|
||||
@@ -198,6 +253,7 @@
|
||||
<Content Include="mpvnet.ico" />
|
||||
<Content Include="Resources\mpvConf.txt" />
|
||||
<Content Include="Resources\mpvConfToml.txt" />
|
||||
<None Include="Resources\mpvnet.png" />
|
||||
<Content Include="Resources\mpvNetConfToml.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -205,7 +261,6 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Resources\inputConfHeader.txt" />
|
||||
<Content Include="screenshot.jpg" />
|
||||
<Content Include="Resources\inputConf.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -217,19 +272,20 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Windows\ConfWindow.xaml">
|
||||
<Page Include="WPF\ConfWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Windows\LearnWindow.xaml">
|
||||
<Page Include="WPF\LearnWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Windows\InputWindow.xaml">
|
||||
<Page Include="WPF\InputWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -11,13 +13,9 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using Sys;
|
||||
|
||||
using static mpvnet.libmpv;
|
||||
using static mpvnet.Native;
|
||||
|
||||
using PyRT = IronPython.Runtime;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public delegate void MpvBoolPropChangeHandler(string propName, bool value);
|
||||
@@ -25,7 +23,7 @@ namespace mpvnet
|
||||
public class mp
|
||||
{
|
||||
public static event Action VideoSizeChanged;
|
||||
// Lua/JS evens libmpv events
|
||||
// Lua/JS event libmpv event
|
||||
|
||||
// MPV_EVENT_NONE
|
||||
public static event Action Shutdown; // shutdown MPV_EVENT_SHUTDOWN
|
||||
@@ -54,9 +52,10 @@ namespace mpvnet
|
||||
public static event Action QueueOverflow; // MPV_EVENT_QUEUE_OVERFLOW
|
||||
public static event Action Hook; // MPV_EVENT_HOOK
|
||||
|
||||
public static IntPtr MpvHandle { get; set; }
|
||||
public static IntPtr MpvWindowHandle { get; set; }
|
||||
public static IntPtr Handle { get; set; }
|
||||
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<int>>> IntPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<int>>>();
|
||||
public static List<KeyValuePair<string, Action<string>>> StringPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<string>>>();
|
||||
@@ -66,21 +65,30 @@ namespace mpvnet
|
||||
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 string InputConfPath { get; } = MpvConfFolder + "\\input.conf";
|
||||
public static string MpvConfPath { get; } = MpvConfFolder + "\\mpv.conf";
|
||||
public static string MpvNetConfPath { get; } = MpvConfFolder + "\\mpvnet.conf";
|
||||
public static string InputConfPath { get; } = ConfFolder + "\\input.conf";
|
||||
public static string ConfPath { get; } = ConfFolder + "\\mpv.conf";
|
||||
|
||||
static string _MpvConfFolder;
|
||||
public static bool Fullscreen { get; set; }
|
||||
public static float Autofit { get; set; } = 0.50f;
|
||||
public static int Screen { get; set; } = -1;
|
||||
public static string Sid { get; set; } = "";
|
||||
public static string Aid { get; set; } = "";
|
||||
public static string Vid { get; set; } = "";
|
||||
public static int Edition { get; set; }
|
||||
|
||||
public static string MpvConfFolder {
|
||||
static string _ConfFolder;
|
||||
|
||||
public static string ConfFolder {
|
||||
get {
|
||||
if (_MpvConfFolder == null)
|
||||
if (_ConfFolder == null)
|
||||
{
|
||||
string portableFolder = Application.StartupPath + "\\portable_config\\";
|
||||
string appdataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\";
|
||||
string startupFolder = Application.StartupPath + "\\";
|
||||
|
||||
if (!Directory.Exists(appdataFolder) && !Directory.Exists(portableFolder) &&
|
||||
Sys.IsDirectoryWritable(Application.StartupPath))
|
||||
Sys.IsDirectoryWritable(Application.StartupPath) &&
|
||||
!File.Exists(startupFolder + "mpv.conf"))
|
||||
{
|
||||
using (TaskDialog<string> td = new TaskDialog<string>())
|
||||
{
|
||||
@@ -88,75 +96,64 @@ namespace mpvnet
|
||||
td.Content = "[MPV documentation about files on Windows.](https://mpv.io/manual/master/#files-on-windows)";
|
||||
td.AddCommandLink("appdata", appdataFolder, appdataFolder);
|
||||
td.AddCommandLink("portable", portableFolder, portableFolder);
|
||||
td.AddCommandLink("startup", startupFolder, startupFolder);
|
||||
td.AllowCancel = false;
|
||||
_MpvConfFolder = td.Show();
|
||||
_ConfFolder = td.Show();
|
||||
}
|
||||
}
|
||||
else
|
||||
if (Directory.Exists(portableFolder))
|
||||
_MpvConfFolder = portableFolder;
|
||||
else
|
||||
_MpvConfFolder = 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(_MpvConfFolder)) _MpvConfFolder = appdataFolder;
|
||||
if (!Directory.Exists(_MpvConfFolder)) Directory.CreateDirectory(_MpvConfFolder);
|
||||
if (string.IsNullOrEmpty(_ConfFolder)) _ConfFolder = appdataFolder;
|
||||
if (!Directory.Exists(_ConfFolder)) Directory.CreateDirectory(_ConfFolder);
|
||||
|
||||
if (!File.Exists(_MpvConfFolder + "\\input.conf"))
|
||||
File.WriteAllText(_MpvConfFolder + "\\input.conf", Properties.Resources.inputConf);
|
||||
if (!File.Exists(_ConfFolder + "\\input.conf"))
|
||||
File.WriteAllText(_ConfFolder + "\\input.conf", Properties.Resources.inputConf);
|
||||
|
||||
if (!File.Exists(_MpvConfFolder + "\\mpv.conf"))
|
||||
File.WriteAllText(_MpvConfFolder + "\\mpv.conf", Properties.Resources.mpvConf);
|
||||
if (!File.Exists(_ConfFolder + "\\mpv.conf"))
|
||||
File.WriteAllText(_ConfFolder + "\\mpv.conf", Properties.Resources.mpvConf);
|
||||
}
|
||||
return _MpvConfFolder;
|
||||
return _ConfFolder;
|
||||
}
|
||||
}
|
||||
|
||||
static Dictionary<string, string> _mpvConf;
|
||||
static Dictionary<string, string> _Conf;
|
||||
|
||||
public static Dictionary<string, string> mpvConf {
|
||||
public static Dictionary<string, string> Conf {
|
||||
get {
|
||||
if (_mpvConf == null)
|
||||
if (_Conf == null)
|
||||
{
|
||||
_mpvConf = new Dictionary<string, string>();
|
||||
_Conf = new Dictionary<string, string>();
|
||||
|
||||
if (File.Exists(MpvConfPath))
|
||||
foreach (var i in File.ReadAllLines(MpvConfPath))
|
||||
if (File.Exists(ConfPath))
|
||||
foreach (var i in File.ReadAllLines(ConfPath))
|
||||
if (i.Contains("=") && ! i.StartsWith("#"))
|
||||
_mpvConf[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)
|
||||
ProcessProperty(i.Key, i.Value);
|
||||
}
|
||||
return _mpvConf;
|
||||
}
|
||||
}
|
||||
|
||||
static Dictionary<string, string> _mpvNetConf;
|
||||
|
||||
public static Dictionary<string, string> mpvNetConf {
|
||||
get {
|
||||
if (_mpvNetConf == null)
|
||||
{
|
||||
_mpvNetConf = new Dictionary<string, string>();
|
||||
|
||||
if (File.Exists(MpvNetConfPath))
|
||||
foreach (string i in File.ReadAllLines(MpvNetConfPath))
|
||||
if (i.Contains("=") && !i.StartsWith("#"))
|
||||
_mpvNetConf[i.Substring(0, i.IndexOf("=")).Trim()] = i.Substring(i.IndexOf("=") + 1).Trim();
|
||||
}
|
||||
return _mpvNetConf;
|
||||
return _Conf;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
string dummy = MpvConfFolder;
|
||||
string dummy = ConfFolder;
|
||||
LoadLibrary("mpv-1.dll");
|
||||
MpvHandle = mpv_create();
|
||||
Handle = mpv_create();
|
||||
set_property_string("input-default-bindings", "yes");
|
||||
set_property_string("osc", "yes");
|
||||
set_property_string("config", "yes");
|
||||
set_property_string("wid", MainForm.Hwnd.ToString());
|
||||
set_property_string("force-window", "yes");
|
||||
set_property_string("input-media-keys", "yes");
|
||||
mpv_initialize(MpvHandle);
|
||||
mpv_initialize(Handle);
|
||||
ShowLogo();
|
||||
ProcessCommandLine();
|
||||
Task.Run(() => { LoadScripts(); });
|
||||
Task.Run(() => { Addon = new Addon(); });
|
||||
@@ -180,8 +177,8 @@ namespace mpvnet
|
||||
if (Path.GetExtension(scriptPath) == ".ps1")
|
||||
PowerShellScript.Init(scriptPath);
|
||||
|
||||
if (Directory.Exists(mp.MpvConfFolder + "Scripts"))
|
||||
foreach (var scriptPath in Directory.GetFiles(mp.MpvConfFolder + "Scripts"))
|
||||
if (Directory.Exists(mp.ConfFolder + "Scripts"))
|
||||
foreach (var scriptPath in Directory.GetFiles(mp.ConfFolder + "Scripts"))
|
||||
if (Path.GetExtension(scriptPath) == ".py")
|
||||
PythonScripts.Add(new PythonScript(File.ReadAllText(scriptPath)));
|
||||
else if (Path.GetExtension(scriptPath) == ".ps1")
|
||||
@@ -192,11 +189,14 @@ namespace mpvnet
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
IntPtr ptr = mpv_wait_event(MpvHandle, -1);
|
||||
IntPtr ptr = mpv_wait_event(Handle, -1);
|
||||
mpv_event evt = (mpv_event)Marshal.PtrToStructure(ptr, typeof(mpv_event));
|
||||
|
||||
if (MpvWindowHandle == IntPtr.Zero)
|
||||
MpvWindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null);
|
||||
if (WindowHandle == IntPtr.Zero)
|
||||
{
|
||||
WindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null);
|
||||
//Native.EnableWindow(WindowHandle, true);
|
||||
}
|
||||
|
||||
//Debug.WriteLine(evt.event_id.ToString());
|
||||
|
||||
@@ -226,11 +226,12 @@ namespace mpvnet
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_END_FILE:
|
||||
var end_fileData = (mpv_event_end_file)Marshal.PtrToStructure(evt.data, typeof(mpv_event_end_file));
|
||||
EndFile?.Invoke((EndFileEventMode)end_fileData.reason);
|
||||
EndFileEventMode reason = (EndFileEventMode)end_fileData.reason;
|
||||
EndFile?.Invoke(reason);
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_FILE_LOADED:
|
||||
HideLogo();
|
||||
FileLoaded?.Invoke();
|
||||
LoadFolder();
|
||||
WriteHistory(mp.get_property_string("path"));
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_TRACKS_CHANGED:
|
||||
@@ -241,6 +242,8 @@ namespace mpvnet
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_IDLE:
|
||||
Idle?.Invoke();
|
||||
if (mp.get_property_int("playlist-count") == 0)
|
||||
ShowLogo();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_PAUSE:
|
||||
Pause?.Invoke();
|
||||
@@ -343,9 +346,18 @@ namespace mpvnet
|
||||
}
|
||||
}
|
||||
|
||||
static void HideLogo()
|
||||
{
|
||||
if (IsLogoVisible)
|
||||
{
|
||||
mp.commandv("overlay-remove", "0");
|
||||
IsLogoVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
static List<PythonEventObject> PythonEventObjects = new List<PythonEventObject>();
|
||||
|
||||
public static void register_event(string name, PyRT.PythonFunction pyFunc)
|
||||
public static void register_event(string name, IronPython.Runtime.PythonFunction pyFunc)
|
||||
{
|
||||
foreach (var eventInfo in typeof(mp).GetEvents())
|
||||
{
|
||||
@@ -380,7 +392,7 @@ namespace mpvnet
|
||||
}
|
||||
}
|
||||
|
||||
public static void unregister_event(PyRT.PythonFunction pyFunc)
|
||||
public static void unregister_event(IronPython.Runtime.PythonFunction pyFunc)
|
||||
{
|
||||
foreach (var eventObjects in PythonEventObjects)
|
||||
if (eventObjects.PythonFunction == pyFunc)
|
||||
@@ -389,11 +401,11 @@ namespace mpvnet
|
||||
|
||||
public static void commandv(params string[] args)
|
||||
{
|
||||
if (MpvHandle == IntPtr.Zero)
|
||||
if (Handle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
IntPtr mainPtr = AllocateUtf8IntPtrArrayWithSentinel(args, out IntPtr[] byteArrayPointers);
|
||||
int err = mpv_command(MpvHandle, mainPtr);
|
||||
int err = mpv_command(Handle, mainPtr);
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{(mpv_error)err}");
|
||||
@@ -406,10 +418,10 @@ namespace mpvnet
|
||||
|
||||
public static void command_string(string command, bool throwException = false)
|
||||
{
|
||||
if (MpvHandle == IntPtr.Zero)
|
||||
if (Handle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
int err = mpv_command_string(MpvHandle, command);
|
||||
int err = mpv_command_string(Handle, command);
|
||||
|
||||
if (err < 0 && throwException)
|
||||
throw new Exception($"{(mpv_error)err}\r\n\r\n" + command);
|
||||
@@ -418,7 +430,7 @@ namespace mpvnet
|
||||
public static void set_property_string(string name, string value, bool throwOnException = false)
|
||||
{
|
||||
byte[] bytes = GetUtf8Bytes(value);
|
||||
int err = mpv_set_property(MpvHandle, 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)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
@@ -428,7 +440,7 @@ namespace mpvnet
|
||||
{
|
||||
try
|
||||
{
|
||||
int err = mpv_get_property(MpvHandle, 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}");
|
||||
@@ -447,7 +459,7 @@ namespace mpvnet
|
||||
|
||||
public static int get_property_int(string name, bool throwOnException = false)
|
||||
{
|
||||
int err = mpv_get_property(MpvHandle, 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)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
@@ -458,7 +470,7 @@ namespace mpvnet
|
||||
public static double get_property_number(string name, bool throwOnException = false)
|
||||
{
|
||||
double val = 0;
|
||||
int err = mpv_get_property(MpvHandle, 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)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
@@ -468,7 +480,7 @@ namespace mpvnet
|
||||
|
||||
public static bool get_property_bool(string name, bool throwOnException = false)
|
||||
{
|
||||
int err = mpv_get_property(MpvHandle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_FLAG, out IntPtr lpBuffer);
|
||||
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}");
|
||||
@@ -479,7 +491,7 @@ namespace mpvnet
|
||||
public static void set_property_int(string name, int value, bool throwOnException = false)
|
||||
{
|
||||
Int64 val = value;
|
||||
int err = mpv_set_property(MpvHandle, 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}");
|
||||
@@ -487,7 +499,7 @@ namespace mpvnet
|
||||
|
||||
public static void observe_property_int(string name, Action<int> action)
|
||||
{
|
||||
int err = mpv_observe_property(MpvHandle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_INT64);
|
||||
int err = mpv_observe_property(Handle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_INT64);
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
@@ -497,7 +509,7 @@ namespace mpvnet
|
||||
|
||||
public static void observe_property_bool(string name, Action<bool> action)
|
||||
{
|
||||
int err = mpv_observe_property(MpvHandle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_FLAG);
|
||||
int err = mpv_observe_property(Handle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_FLAG);
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
@@ -507,7 +519,7 @@ namespace mpvnet
|
||||
|
||||
public static void observe_property_string(string name, Action<string> action)
|
||||
{
|
||||
int err = mpv_observe_property(MpvHandle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_STRING);
|
||||
int err = mpv_observe_property(Handle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_STRING);
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
@@ -518,12 +530,19 @@ namespace mpvnet
|
||||
protected static void ProcessCommandLine()
|
||||
{
|
||||
var args = Environment.GetCommandLineArgs().Skip(1);
|
||||
List<string> files = new List<string>();
|
||||
|
||||
foreach (string i in args)
|
||||
if (!i.StartsWith("--") && File.Exists(i))
|
||||
mp.commandv("loadfile", i, "append");
|
||||
{
|
||||
if (!i.StartsWith("--") && (File.Exists(i) || i == "-" || i.StartsWith("http")))
|
||||
{
|
||||
files.Add(i);
|
||||
if (i.StartsWith("http"))
|
||||
RegistryHelp.SetObject(App.RegPath, "LastURL", i);
|
||||
}
|
||||
}
|
||||
|
||||
mp.set_property_string("playlist-pos", "0");
|
||||
mp.Load(files.ToArray());
|
||||
|
||||
foreach (string i in args)
|
||||
{
|
||||
@@ -541,46 +560,38 @@ namespace mpvnet
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadFiles(params string[] files)
|
||||
public static void Load(params string[] files)
|
||||
{
|
||||
int count = mp.get_property_int("playlist-count");
|
||||
if (files is null || files.Length == 0) return;
|
||||
HideLogo();
|
||||
|
||||
foreach (string file in files)
|
||||
mp.commandv("loadfile", file, "append");
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
if (App.SubtitleTypes.Contains(Path.GetExtension(files[i]).TrimStart('.').ToLower()))
|
||||
mp.commandv("sub-add", files[i]);
|
||||
else
|
||||
if (i == 0)
|
||||
mp.commandv("loadfile", files[i]);
|
||||
else
|
||||
mp.commandv("loadfile", files[i], "append");
|
||||
|
||||
mp.set_property_int("playlist-pos", count);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
mp.commandv("playlist-remove", "0");
|
||||
|
||||
mp.LoadFolder();
|
||||
Task.Run(() => LoadFolder()); // user reported race condition
|
||||
}
|
||||
|
||||
static bool WasFolderLoaded;
|
||||
|
||||
static void LoadFolder()
|
||||
{
|
||||
if (WasFolderLoaded) return;
|
||||
|
||||
if (get_property_int("playlist-count") == 1)
|
||||
{
|
||||
string path = get_property_string("path");
|
||||
if (!Directory.Exists(Path.GetDirectoryName(path))) return;
|
||||
string[] types = "264 265 3gp aac ac3 avc avi avs bmp divx dts dtshd dtshr dtsma eac3 evo flac flv h264 h265 hevc hvc jpg jpeg m2t m2ts m2v m4a m4v mka mkv mlp mov mp2 mp3 mp4 mpa mpeg mpg mpv mts ogg ogm opus pcm png pva raw rmvb thd thd+ac3 true-hd truehd ts vdr vob vpy w64 wav webm wmv y4m".Split(' ');
|
||||
List<string> files = Directory.GetFiles(Path.GetDirectoryName(path)).ToList();
|
||||
files = files.Where((file) => types.Contains(Path.GetExtension(file).TrimStart(".".ToCharArray()).ToLower())).ToList();
|
||||
files.Sort(new StringLogicalComparer());
|
||||
int index = files.IndexOf(path);
|
||||
files.Remove(path);
|
||||
|
||||
foreach (string i in files)
|
||||
commandv("loadfile", i, "append");
|
||||
|
||||
if (index > 0)
|
||||
commandv("playlist-move", "0", (index + 1).ToString());
|
||||
}
|
||||
|
||||
WasFolderLoaded = true;
|
||||
Thread.Sleep(50); // user reported race condition
|
||||
string path = mp.get_property_string("path");
|
||||
if (!File.Exists(path) || get_property_int("playlist-count") != 1) return;
|
||||
List<string> files = Directory.GetFiles(Path.GetDirectoryName(path)).ToList();
|
||||
files = files.Where((file) =>
|
||||
App.VideoTypes.Contains(Path.GetExtension(file).TrimStart('.').ToLower()) ||
|
||||
App.AudioTypes.Contains(Path.GetExtension(file).TrimStart('.').ToLower())).ToList();
|
||||
files.Sort(new StringLogicalComparer());
|
||||
int index = files.IndexOf(path);
|
||||
files.Remove(path);
|
||||
foreach (string i in files)
|
||||
commandv("loadfile", i, "append");
|
||||
if (index > 0) commandv("playlist-move", "0", (index + 1).ToString());
|
||||
}
|
||||
|
||||
static IntPtr AllocateUtf8IntPtrArrayWithSentinel(string[] arr, out IntPtr[] byteArrayPointers)
|
||||
@@ -633,7 +644,7 @@ namespace mpvnet
|
||||
|
||||
if (File.Exists(LastHistoryPath) && totalMinutes > 1)
|
||||
{
|
||||
string historyFilepath = mp.MpvConfFolder + "history.txt";
|
||||
string historyFilepath = mp.ConfFolder + "history.txt";
|
||||
|
||||
File.AppendAllText(historyFilepath, DateTime.Now.ToString().Substring(0, 16) +
|
||||
" " + totalMinutes.ToString().PadLeft(3) + " " +
|
||||
@@ -644,6 +655,48 @@ namespace mpvnet
|
||||
LastHistoryStartDateTime = DateTime.Now;
|
||||
}
|
||||
|
||||
public static void ShowLogo()
|
||||
{
|
||||
if (MainForm.Instance is null) return;
|
||||
Rectangle cr = MainForm.Instance.ClientRectangle;
|
||||
if (cr.Width == 0 || cr.Height == 0) return;
|
||||
|
||||
using (Bitmap b = new Bitmap(cr.Width, cr.Height))
|
||||
{
|
||||
using (Graphics g = Graphics.FromImage(b))
|
||||
{
|
||||
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
g.Clear(Color.Black);
|
||||
int iconWidth = cr.Height / 7;
|
||||
Rectangle r = new Rectangle(cr.Width / 2 - iconWidth / 2, cr.Height / 2 - iconWidth / 2, iconWidth, iconWidth);
|
||||
g.DrawImage(Properties.Resources.mpvnet, r);
|
||||
BitmapData bd = b.LockBits(cr, ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
|
||||
mp.commandv("overlay-add", "0", "0", "0", "&" + bd.Scan0.ToInt64().ToString(), "0", "bgra", bd.Width.ToString(), bd.Height.ToString(), bd.Stride.ToString());
|
||||
b.UnlockBits(bd);
|
||||
IsLogoVisible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ProcessProperty(string name, string value)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case "autofit":
|
||||
if (value.Length == 3 && value.EndsWith("%"))
|
||||
if (int.TryParse(value.Substring(0, 2), out int result))
|
||||
mp.Autofit = result / 100f;
|
||||
break;
|
||||
case "fs":
|
||||
case "fullscreen":
|
||||
mp.Fullscreen = value == "yes";
|
||||
break;
|
||||
case "screen":
|
||||
mp.Screen = Convert.ToInt32(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ReadMetaData()
|
||||
{
|
||||
lock (MediaTracks)
|
||||
@@ -665,7 +718,7 @@ namespace mpvnet
|
||||
Add(track, mi.GetVideo(i, "Forced") == "Yes" ? "Forced" : "");
|
||||
Add(track, mi.GetVideo(i, "Default") == "Yes" ? "Default" : "");
|
||||
Add(track, mi.GetVideo(i, "Title"));
|
||||
track.Text = "V: " + track.Text.Trim(" ,".ToCharArray());
|
||||
track.Text = "V: " + track.Text.Trim(' ', ',');
|
||||
track.Type = "v";
|
||||
track.ID = i + 1;
|
||||
MediaTracks.Add(track);
|
||||
@@ -685,7 +738,7 @@ namespace mpvnet
|
||||
Add(track, mi.GetAudio(i, "Forced") == "Yes" ? "Forced" : "");
|
||||
Add(track, mi.GetAudio(i, "Default") == "Yes" ? "Default" : "");
|
||||
Add(track, mi.GetAudio(i, "Title"));
|
||||
track.Text = "A: " + track.Text.Trim(" ,".ToCharArray());
|
||||
track.Text = "A: " + track.Text.Trim(' ', ',');
|
||||
track.Type = "a";
|
||||
track.ID = i + 1;
|
||||
MediaTracks.Add(track);
|
||||
@@ -702,7 +755,7 @@ namespace mpvnet
|
||||
Add(track, mi.GetText(i, "Forced") == "Yes" ? "Forced" : "");
|
||||
Add(track, mi.GetText(i, "Default") == "Yes" ? "Default" : "");
|
||||
Add(track, mi.GetText(i, "Title"));
|
||||
track.Text = "S: " + track.Text.Trim(" ,".ToCharArray());
|
||||
track.Text = "S: " + track.Text.Trim(' ', ',');
|
||||
track.Type = "s";
|
||||
track.ID = i + 1;
|
||||
MediaTracks.Add(track);
|
||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 497 KiB |
@@ -1,22 +0,0 @@
|
||||
//public static string GetAssociatedApplication(string ext)
|
||||
//{
|
||||
// uint returnValue = 0U;
|
||||
// // ASSOCF_VERIFY, ASSOCSTR_EXECUTABLE
|
||||
// if (1 == Native.AssocQueryString(0x40, 2, ext, null, null, ref returnValue))
|
||||
// {
|
||||
// if (returnValue > 0)
|
||||
// {
|
||||
// StringBuilder sb = new StringBuilder(Convert.ToInt32(returnValue));
|
||||
// // ASSOCF_VERIFY, ASSOCSTR_EXECUTABLE
|
||||
// if (0 == Native.AssocQueryString(0x40, 2, ext, null, sb, ref returnValue))
|
||||
// {
|
||||
// var ret = sb.ToString();
|
||||
// if (File.Exists(ret)) return ret;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return "";
|
||||
//}
|
||||
|
||||
//[DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
//public static extern uint AssocQueryString(uint flags, uint str, string pszAssoc, string pszExtra, StringBuilder pszOut, ref uint pcchOut);
|
||||
@@ -1,7 +0,0 @@
|
||||
$scriptDir = Split-Path -Path $PSCommandPath -Parent
|
||||
$exePath = $scriptDir + "\mpv.net\bin\mpvnet.exe"
|
||||
$version = [Diagnostics.FileVersionInfo]::GetVersionInfo($exePath).FileVersion
|
||||
$desktopDir = [Environment]::GetFolderPath("Desktop")
|
||||
$targetDir = $desktopDir + "\mpv.net-portable-x64-" + $version
|
||||
Copy-Item $scriptDir\mpv.net\bin $targetDir -Recurse -Exclude System.Management.Automation.xml -Force
|
||||
& "C:\Program Files\7-Zip\7z.exe" a -t7z -mx9 "$targetDir.7z" -r "$targetDir\*"
|
||||
26
setup.iss
@@ -1,18 +1,30 @@
|
||||
#define MyAppName "mpv.net"
|
||||
#define MyAppVersion GetFileVersion("mpv.net\bin\mpvnet.exe")
|
||||
#define MyAppExeName "mpvnet.exe"
|
||||
#define MyAppSourceDir "mpv.net\bin"
|
||||
|
||||
#ifndef arch
|
||||
#define arch "x64"
|
||||
#endif
|
||||
|
||||
#if arch == "x64"
|
||||
#define MyAppSourceDir "mpv.net\bin\x64"
|
||||
#define MyAppVersion GetFileVersion("mpv.net\bin\x64\mpvnet.exe")
|
||||
#else
|
||||
#define MyAppSourceDir "mpv.net\bin\x86"
|
||||
#define MyAppVersion GetFileVersion("mpv.net\bin\x86\mpvnet.exe")
|
||||
#endif
|
||||
|
||||
[Setup]
|
||||
AppId={{9AA2B100-BEF3-44D0-B819-D8FC3C4D557D}}
|
||||
AppName={#MyAppName}
|
||||
AppVersion={#MyAppVersion}
|
||||
AppPublisher=Frank Skare (stax76)
|
||||
ArchitecturesInstallIn64BitMode=x64
|
||||
#if arch == "x64"
|
||||
ArchitecturesInstallIn64BitMode=x64
|
||||
#endif
|
||||
Compression=lzma2
|
||||
DefaultDirName={pf}\{#MyAppName}
|
||||
OutputBaseFilename=mpvnet-setup-x64-{#MyAppVersion}
|
||||
OutputDir=C:\Users\frank\Desktop
|
||||
DefaultDirName={commonpf}\{#MyAppName}
|
||||
OutputBaseFilename=mpv.net-setup-{#arch}-{#MyAppVersion}
|
||||
OutputDir={#GetEnv('USERPROFILE')}\Desktop
|
||||
DefaultGroupName={#MyAppName}
|
||||
SetupIconFile=mpv.net\mpvnet.ico
|
||||
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||
@@ -29,4 +41,4 @@ Filename: "{app}\{#MyAppExeName}"; Description: "Associate video file extensions
|
||||
Filename: "{app}\{#MyAppExeName}"; Description: "Associate audio file extensions?"; Flags: postinstall unchecked runascurrentuser runhidden nowait; Parameters: "--reg-file-assoc audio"
|
||||
|
||||
[UninstallRun]
|
||||
Filename: "{app}\{#MyAppExeName}"; Flags: runascurrentuser runhidden; Parameters: "--reg-file-assoc unregister"
|
||||
Filename: "{app}\{#MyAppExeName}"; Flags: runascurrentuser runhidden; Parameters: "--reg-file-assoc unreg"
|
||||
48
setup.ps1
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||