Compare commits

...

943 Commits
9.10 ... master

Author SHA1 Message Date
Josef Nemec
6894a9fd17
Updated localizations 2025-12-30 09:59:12 +01:00
Josef Nemec
0ff5138603
10.47 version bump 2025-12-29 10:01:33 +01:00
Jeshibu
464bc962a7
New: Automatically autofill sorting name when saving game edit window (by @Jeshibu) 2025-12-28 15:45:35 +01:00
Josef Nemec
d57ce71c0a
Fix: Updated web view component 2025-12-28 11:45:45 +01:00
Josef Nemec
775e3152d8
Diag reporting duplicate installed addons when running in portable mode 2025-12-28 11:40:54 +01:00
Josef Nemec
f109e48c49
Fixed GetLibraryPlugin crash 2025-12-28 11:23:43 +01:00
Josef Nemec
05441d38f9
Playnite detecting other Playnite apps incorrectly as Playnite itself already running 2025-12-25 18:48:16 +01:00
Josef Nemec
bef7cf9597
GetLatestCompatiblePackageTest updated 2025-12-23 22:52:10 +01:00
Josef Nemec
367f2a405d
Another Playnite/Windows corruption detections tweak 2025-12-23 20:43:21 +01:00
Josef Nemec
abd1d5357f
New: Ability to install or re-install specific addon version 2025-12-23 19:57:17 +01:00
Josef Nemec
4b541c85d6
Updated SDK version in extension templates 2025-12-19 13:34:13 +01:00
Josef Nemec
f5062424e8
Fix: Start on system boot option not working in some cases 2025-12-13 21:57:03 +01:00
Josef Nemec
3aeb1516f4
Detect specific GPU driver crash related app crash 2025-12-12 17:47:03 +01:00
Josef Nemec
7a35bec1ea
Actually properly fixing #4201 this time 2025-12-10 23:07:48 +01:00
Josef Nemec
45f7bcb972
Fix: Updated image handling component 2025-12-10 22:59:42 +01:00
Josef Nemec
6480e1cda5
Fix: Possible crash related to games with misconfigured file paths #4201 2025-12-09 15:02:04 +01:00
Josef Nemec
3297aeb9e0
10.46 version bump 2025-12-07 15:36:56 +01:00
Josef Nemec
1e19ce02bd
Fix: Crash handling not detecting extension crashes correctly 2025-12-07 15:36:43 +01:00
Josef Nemec
81a66b1b0c
10.45 version bump 2025-12-01 07:38:29 +01:00
Josef Nemec
f687ef0cc2
Crash parsing improvements 2025-11-29 16:26:26 +01:00
Josef Nemec
5033ede22f
Fix: Emulator startup script might get overwritten on game startup 2025-11-29 16:04:45 +01:00
Josef Nemec
67f57e1844
SDK: Added support for cancelling installation process from within InstallController 2025-11-28 09:26:09 +01:00
Josef Nemec
df654fadb6
Added detection of specific installation corruption 2025-11-24 13:58:53 +01:00
Josef Nemec
74de5423ca
10.44 version bump 2025-11-19 18:04:04 +01:00
Josef Nemec
f83c38f7bb
Updated localizations 2025-11-19 18:03:38 +01:00
Josef Nemec
066d6aa169
Debug comment left in accidently 2025-11-18 22:55:37 +01:00
Josef Nemec
03bf3ac0a8
Tweaks to crash detection 2025-11-18 22:47:59 +01:00
Josef Nemec
268522d04e
Updated SDL controller database 2025-11-18 20:21:24 +01:00
Josef Nemec
c136792790
Small tweaks to online installer 2025-11-18 19:43:52 +01:00
Josef Nemec
814ddac821
Fix: Fully manually added games no longer default to installed state #4176 2025-11-18 19:08:55 +01:00
Josef Nemec
c16619337d
Fix: Random game picker via F6 doesn't work in Fullscren mode #3780 2025-11-18 18:52:45 +01:00
Josef Nemec
9148d65126
Fix: Playnite doesn't open in Fullscreen mode when auto data backups are enabled #4075 2025-11-18 18:39:58 +01:00
Josef Nemec
c0c2521639
Fix: Improved manual update check process #4125 2025-11-18 17:27:53 +01:00
Josef Nemec
0a37c666a7
Fix: Playnite not working properly when FIPS enforcement policy is enabled (by Rast1234) 2025-11-18 16:18:26 +01:00
Josef Nemec
cdc6ccdc39
Fix: Increased maximum of selectable columns and rows in Fullscreen mode 2025-11-18 15:47:16 +01:00
Josef Nemec
36446d210c
Fix: Library update is skipped when making or restoring backup 2025-11-18 15:47:16 +01:00
CanRanBan
62768aee71
Fix: Default interface language is not selected properly (by CanRanBan)
This prevents using an unexpected language if "Windows display language" and other "Language & region" settings don't match.
2025-11-18 15:46:09 +01:00
Josef Nemec
7e2e9da03b
Update README.md 2025-11-16 17:30:14 +01:00
Josef Nemec
50f35fc3bf
Update pull_request_template.md 2025-11-16 17:29:53 +01:00
Josef Nemec
77604caf71
10.43 version bump 2025-11-02 13:27:01 +01:00
Josef Nemec
107cfceb96
Fix: Updated image handling library 2025-11-01 16:10:23 +01:00
Josef Nemec
9cb4d06107
Fix: Optimizations to addon update check 2025-11-01 16:10:04 +01:00
Josef Nemec
ec84070d95
Merge remote-tracking branch 'github/devel' 2025-10-28 14:44:32 +01:00
Josef Nemec
16fc7df776
Themes version bump 2025-10-28 14:44:10 +01:00
Denis Medvedev
7b70f2712f
Fix: Window restoration in Fullscreen mode (by DenisionSoft)
* Fix window restoration in Fullscreen mode

* Revert RestoreWindows fallbacks

* chore
2025-10-28 14:33:13 +01:00
Josef Nemec
ea4f26ac50
Updated list of files for Toolbox to strip during addon packaging 2025-10-28 12:40:34 +01:00
Josef Nemec
6816635125
Updated localizations 2025-10-28 11:43:42 +01:00
Josef Nemec
b226c08ec0
10.42 version bump 2025-10-28 11:36:36 +01:00
Josef Nemec
e44dc0df32
Another case where we might be doing a lot of calls to GitHub quickly resulting in 429 if user has a lot of addons installed #4156 2025-10-28 09:36:59 +01:00
Josef Nemec
3ad9d4288f
List virtualization doesn't work on addons view, causing a lot more network calls than needed #4156 2025-10-28 09:23:30 +01:00
Josef Nemec
699dedf5f3
Fix: High memory usage during emulation scan 2025-10-27 20:46:09 +01:00
Josef Nemec
16942a6073
New: Added option to restore Playnite via playnite://playnite/restore uri 2025-10-27 20:09:25 +01:00
Josef Nemec
ed20d6d2dc
SDK: Removed global user-agent override for web views. Plugins should now handle override individually if they need it to function properly.
This was done because there are some captcha system that were failing because we were masking as Firefox while being Chrome based. The original override was to fix some Google website that didn't like the opposite, but this seems now more compatible in general, especially with captcha systems.
2025-10-27 09:45:06 +01:00
Josef Nemec
a44fa41a8c
Fix: Updated web view component 2025-10-27 09:41:25 +01:00
Josef Nemec
94bf35fa3d
Fix: Crash when closing keyboard search using Alt-F4 #4150 2025-10-26 18:31:20 +01:00
Josef Nemec
dde38e4136
Merge branch 'devel' 2025-10-26 17:53:11 +01:00
Josef Nemec
4d5fb929d5
Merge branch 'master' into devel 2025-10-26 17:52:46 +01:00
jonosellier
42022a2093
Add support for theming ProgressWindow.xaml (#4147)
* Add support for theming ProgressWindow.xaml

* Fix template

* Layout change
2025-10-26 17:42:27 +01:00
Josef Nemec
f1cbbc418d
10.41 version bump 2025-10-05 10:03:22 +02:00
Josef Nemec
c00445a33e
Fixed error code check for "device not ready" errors 2025-10-04 19:06:54 +02:00
Josef Nemec
6ff11c2bf5
Fix: Description text not being wrapped properly when Asian characters are present #4128 2025-10-04 18:10:20 +02:00
Josef Nemec
50728257d3
Web view init tweak 2025-10-01 19:36:32 +02:00
Josef Nemec
f32afd1087
10.40 version bump 2025-10-01 19:34:41 +02:00
Josef Nemec
1d8d1f1a2a
Fix: Features requiring web views not working properly when Playnite is running as admin #4130 2025-10-01 19:34:17 +02:00
Josef Nemec
417b88901a
10.39 version bump 2025-09-29 09:24:33 +02:00
Josef Nemec
05f9d2a2cb
Fix: Images not loading properly with image scaler set to "alternative" 2025-09-28 20:30:02 +02:00
Josef Nemec
76d93543e0
Offscreen web view blowing up on null reference 2025-09-28 14:55:19 +02:00
Josef Nemec
35ca484ff7
New: Added option to assign user score in Fullscreen's game menu 2025-09-28 13:59:02 +02:00
Jeshibu
74aad5d714
Fix: Single-value fields no longer listen to "match all filters" option (by @Jeshibu)
* Filter refactor

Removed some duplicate code, and made single-value fields no longer listen to "match all filters"

* Added test setup

* Added more tests, only the boolean filters left now

* Full game filtering test coverage

* Fixed version filter matching games without version
2025-09-26 09:14:47 +02:00
Josef Nemec
07b96f4d7d
Updated localizations 2025-09-24 13:56:33 +02:00
Josef Nemec
3245d76dd0
10.38 version bump 2025-09-24 13:52:35 +02:00
Josef Nemec
a5cb7135d6
SDK version bump 2025-09-24 13:51:40 +02:00
Josef Nemec
2ca5c57408
SDK: Option to read individual web view resources as they are loaded 2025-09-24 13:26:25 +02:00
Josef Nemec
1bd8ade1f0
SDK: Added new option to control whether search result cache is used on specific SearchContext 2025-09-23 20:39:25 +02:00
Josef Nemec
9f82f71463
Fix: Emoji and other multi-character glyphs not rendering properly in game descriptions #4048 2025-09-23 13:07:59 +02:00
Josef Nemec
b3020edbac
Small error log correction 2025-09-23 10:06:16 +02:00
Josef Nemec
8dc6f1572f
Skip loading plugins that don't have Id specified #4062 2025-09-23 10:03:27 +02:00
Josef Nemec
c405080b27
Fix: Game status screen in Fullscreen mode can loose input focus in some cases #4064 2025-09-22 22:08:39 +02:00
Josef Nemec
3300269ea1
Extra error code logging for crashes 2025-09-22 21:25:50 +02:00
Josef Nemec
641f45b4af
Clarify emulator startup error when exe is not found 2025-09-22 21:25:37 +02:00
Josef Nemec
77cc78733a
SDK: Added method for toggling between details and list views in Fullscreen mode 2025-09-22 20:33:42 +02:00
Josef Nemec
83320df7df
New: Added CTRL-SHIFT-P shortcut to Fullscreen mode for opening SDK PowerShell instance 2025-09-22 20:32:50 +02:00
Josef Nemec
82029ca907
SDK: Added methods for getting user sorted filter presets 2025-09-22 20:17:45 +02:00
Josef Nemec
cc4dc68ba3
SDK: Added API method to open game edit dialog 2025-09-22 20:01:32 +02:00
Josef Nemec
4594621aa5
SDK: Added cmdline options to force Fullscreen mode into specific window resolution (fullscreenwidth and fullscreenheight) 2025-09-22 19:51:56 +02:00
Josef Nemec
4f83fc8f5d
Fix: Various crash fixes 2025-09-22 18:28:31 +02:00
Josef Nemec
c0b82391fe
Fix: Some themes can't be previewed in Blend properly 2025-09-22 16:00:26 +02:00
Josef Nemec
891b63bd0f
SDK: Option to set initial directory to file system dialogs 2025-09-22 15:07:34 +02:00
Josef Nemec
09f65c765a
Fix: webp and avif images not rendering correctly 2025-09-22 12:15:40 +02:00
Josef Nemec
fd3f981270
Fix: Updated audio and controller input component 2025-09-21 16:19:40 +02:00
Josef Nemec
7508794f6f
Fix: Updated web view component 2025-09-21 16:17:55 +02:00
Josef Nemec
a1720895cc
Added longPathAware manifest 2025-09-20 21:12:09 +02:00
Josef Nemec
9a9eadc419
Fix: Emulation related SDK events not working properly 2025-09-20 17:00:06 +02:00
Paul
bdebf009f3
Avoid named pipe conflicts, when other executing programs bind their endpoint to "net.pipe://localhost" as their base address (#4053) 2025-07-10 12:06:18 +02:00
Josef Nemec
36a9439b37 Added SHA256 extra string hashing method 2025-06-18 17:48:45 +02:00
Josef Nemec
31225440c1 10.37 version bump 2025-06-16 17:48:09 +02:00
Josef Nemec
049fcc4526 ymir emulator assigned to Saturn platform 2025-06-16 17:45:48 +02:00
Brandon
70f7ae0408
New: Added jgenesis emulator profile (by darklinkpower) 2025-06-16 17:45:02 +02:00
Munt
954f166cf7
New: Added Ymir emulator profile (by MuntKaicho) 2025-06-16 17:43:33 +02:00
Josef Nemec
9aa99451d0 Fix: Background music not restoring playback correctly after exiting a game #4045 2025-06-16 17:42:30 +02:00
Josef Nemec
653bd46810 Added Windows version anti-spoofing 2025-06-15 21:11:21 +02:00
Josef Nemec
0cf6193ef1 Removed discontinued emulators from platforms list 2025-06-14 12:08:41 +02:00
Josef Nemec
c265fb02d6 Fix: gopher64 emulator profile not working properly 2025-06-14 12:06:32 +02:00
Josef Nemec
eb4a6593e2 Fix: Possible crash when opening extensions menu in Fullscreen mode 2025-06-14 12:04:17 +02:00
Josef Nemec
8ee01d3cf7 Couple fixes related to Fullscreen game list rendering 2025-06-12 13:52:04 +02:00
Josef Nemec
043cd6937b Updated localizations 2025-06-12 10:16:55 +02:00
Josef Nemec
38024ad644 10.36 version bump 2025-06-11 21:58:14 +02:00
Josef Nemec
32cd48ec7e SDK and Theme API version bump 2025-06-11 21:50:32 +02:00
Josef Nemec
1545c67f99 Build script fix for deleing output folder in use 2025-06-11 17:08:37 +02:00
Josef Nemec
e27cd6e52f Toolbox crash when making new theme 2025-06-11 17:08:19 +02:00
Josef Nemec
1286e81c43 Small fix to update checks 2025-06-11 17:08:04 +02:00
Josef Nemec
38804bdc2f New: Automatic library data backups are enabled by default for new installations 2025-06-11 11:44:03 +02:00
Josef Nemec
ac5246ea78 Removed debug message 2025-06-10 21:29:09 +02:00
Josef Nemec
b10a4f9df6 Fix: Fullscreen mode preventing system from going to sleep #2932 2025-06-10 21:23:19 +02:00
Josef Nemec
ff2fa7258a SDK: Added callback method for processing gamepad inputs 2025-06-10 12:17:33 +02:00
Josef Nemec
546a750b28 SDK: CreateWindow now works in Fullscreen mode 2025-06-09 20:44:55 +02:00
Josef Nemec
ff4c748600 New: Software tools, 3rd party clients and extension menu items are available in Fullscreen mode 2025-06-09 20:10:57 +02:00
Josef Nemec
fb41277253 Fix: Better handling of errors and download cancellations when adding metadata files from http sources 2025-06-05 17:28:22 +02:00
Josef Nemec
9655e9766d Toolbox not parsing directory paths properly in some cases 2025-06-05 16:54:44 +02:00
Josef Nemec
a9eb258b54 New: Added support for changing user data folder via --userdatadir cmdline argument 2025-06-05 16:47:00 +02:00
Josef Nemec
acec5ff30c Fix: Updated gamepad input library and gamepad database 2025-06-05 14:08:39 +02:00
Josef Nemec
ee569b1217 Fix: Updated web view library 2025-06-05 13:57:30 +02:00
Josef Nemec
274d3dcc18 Fix: FilteredGames and SelectedGames not returning any data in PowerShell scripts sometimes 2025-06-05 13:23:26 +02:00
Josef Nemec
efd6ca3043 Stats view design time class not loading properly 2025-06-05 08:55:39 +02:00
Josef Nemec
a8264d3a0f Fix: Playnite variables are not expanded in startup scripts #3738 2025-06-05 08:46:22 +02:00
Josef Nemec
22c699d647 Fixed null reference in InvertedBooleanToVisibilityConverter #3995 2025-06-04 20:31:36 +02:00
Josef Nemec
5a09e924c5 New: Added gopher64 emulator profile #3996 2025-06-04 20:29:08 +02:00
Josef Nemec
e1db07f59c Fix: Explorer "icon" is not highlighted when the explorer panel is opened #4015 2025-06-04 20:19:58 +02:00
Josef Nemec
76bca4b756 Fix: Third-party client is shut down even while another game from the same client is being installed #4017 2025-06-04 20:14:52 +02:00
Josef Nemec
726bfee156 Updated platforms list #4029 #4030 2025-06-04 17:16:36 +02:00
Josef Nemec
1805473f60 New: Added option to track games by specific process name 2025-06-03 19:24:27 +02:00
Josef Nemec
d8a8e38276 Fix: System shutdown from Fullscreen mode doesn't behave exactly the same as start menu shutdown #3947 2025-06-03 17:34:02 +02:00
Brandon
f97b68475c
New: Added close button to Explorer Panel (by darklinkpower)
* Add close button to Explorer Panel

* Vertically align button
2025-06-02 11:40:58 +02:00
Mark Jansen
02e55e1e30
Add GameProvider statistics (#3950) (by learn-more)
Fixes #3949
2025-05-28 13:00:30 +02:00
Jeshibu
a53ea74af3
Added error dialog when trying to bulk download metadata with no fields enabled (#4031) 2025-05-28 12:57:37 +02:00
Jeshibu
a5acdf38a9
shadPS4: exclude patch directories (#4033) (by JupiterJesus) 2025-05-28 12:56:40 +02:00
Jeshibu
485c5292b1
Update Lime3DS emulator exe (#4026) 2025-05-27 20:37:05 +02:00
Josef Nemec
b840a34f5d Issue template updates 2025-04-14 08:57:44 +02:00
Josef Nemec
0d6ecf6e0a
Updated Windows version requirement 2025-03-01 08:23:09 +01:00
Josef Nemec
75372a6d70 10.35 version bump 2025-01-27 16:43:14 +01:00
Josef Nemec
ce0caeaa33 Fix: PluginStatus and SettingsBinding markups not available to themes in Fullscreen mode 2025-01-27 16:25:50 +01:00
Josef Nemec
8e54aca7ed Updated localizations 2025-01-27 12:45:40 +01:00
Josef Nemec
8d1a3c11a9 SDL and SDL controller DB updated 2025-01-27 12:21:05 +01:00
Jeshibu
cf9c3fae82
Added Lime3DS emulator profile (#3927) 2025-01-27 08:44:05 +01:00
Josef Nemec
961100a36f Merge branch 'devel' 2025-01-25 09:07:50 +01:00
Vaughn
fba7c5c83a
Added shadPS4 emulator support (#3909) 2025-01-25 09:07:16 +01:00
Brandon
8f5eb2c167
Retroarch updates (#3915)
* Add cores to retroarch ignore script and sort alphabetically

* Fix error if core info file doesn't have a core name

* Fix error if core info file doesn't have a systemname

* Update Retroarch emulation profile
2025-01-25 09:07:07 +01:00
Liam Scholte
f0ed21cb9d
fix: prevent HDR from being activated in Windows 24H2 when closing a game (#3916)
Co-authored-by: Josef Nemec <nemecjosef@gmail.com>
2025-01-25 09:06:09 +01:00
Josef Nemec
05edfc21d7 Merge branch 'master' into devel 2025-01-04 17:09:52 +01:00
Josef Nemec
fdb2a8652a readme update 2024-10-31 08:25:35 +01:00
Josef Nemec
2afc8359d8 10.34 version bump 2024-08-13 14:46:57 +02:00
Josef Nemec
a821d10dbc Updated localizations 2024-08-12 13:44:32 +02:00
Josef Nemec
5e5786f6c8 Added page log dump in case web image search fails 2024-08-12 13:39:57 +02:00
Josef Nemec
4efc2fb6c4 CefSharp updated 2024-08-12 13:39:36 +02:00
Josef Nemec
665aad0ccd SDL2 updated 2024-08-12 13:39:21 +02:00
Josef Nemec
5dfb0b1dd9 10.33 version bump 2024-04-15 10:54:22 +02:00
Josef Nemec
caa6ca6951 Updated localizations 2024-04-15 10:54:00 +02:00
Josef Nemec
0e73be1b05 Fix: Crash in Fullscreen mode after library update 2024-04-15 10:51:14 +02:00
Josef Nemec
aaadf99cfe Fix: Crash when shutting down Playnite while also connecting/disconnecting controller devices 2024-04-15 10:50:49 +02:00
Josef Nemec
79e19cc5f6 Fix: Crash when parsing release dates on specific Windows locale settings 2024-04-15 10:50:18 +02:00
Josef Nemec
e6e8b36cb3 Fix: Shutting down system from Playnite causes application exit script not work properly sometimes 2024-04-11 15:19:53 +02:00
Josef Nemec
df52f03d3d Fix: Play time not being counted properly if system is suspended during gameplay #1389 2024-04-11 14:58:43 +02:00
Josef Nemec
5d78389514 Fix: List of disabled controllers is sometimes erased after disabling new devices #3668 2024-04-08 17:02:35 +02:00
Josef Nemec
07110f9779 Added ko-fi to funding list 2024-04-05 17:51:12 +02:00
Josef Nemec
a0ef9331c5 Fix: Updated web view library 2024-04-05 17:49:53 +02:00
Josef Nemec
0d4a992708 Fix: Updated controller input and audio playback (SDL) libraries 2024-04-05 17:49:23 +02:00
Josef Nemec
01521d4f84 Fix: Background music starts from scratch instead of resuming when exiting a game #3687 2024-04-05 17:24:38 +02:00
Josef Nemec
c222d51953 Added Ko-fi links 2024-04-05 14:12:13 +02:00
Josef Nemec
bd47f60b01 Fix: Automatically focus search input field on search dialog #3701 2024-04-05 13:48:45 +02:00
Josef Nemec
8c5a747819 Fix: Updated emulator profiles #3683 #3707 2024-04-05 13:41:45 +02:00
Josef Nemec
9f58828fd8 Fix: "Hide imported" option on scan folder dialog doesn't prevent games from being imported #3708 2024-04-05 13:37:04 +02:00
Josef Nemec
ef9effdd27 Forgot to remove some debug messages 2023-12-20 11:24:16 +01:00
Josef Nemec
642ce6fc4c 10.32 version bump 2023-12-20 10:34:56 +01:00
Josef Nemec
06d6314b9b Fix: Extra selection sound played on startup in Fullscreen mode #3626 2023-12-20 10:34:48 +01:00
Josef Nemec
aba112c06a Fix: Some controller buttons do not work after restoring system for hibernation #3630 2023-12-20 10:34:12 +01:00
Josef Nemec
413a65be71 10.31 version bump 2023-12-13 18:23:24 +01:00
Josef Nemec
2c34720ad5 Fix: Crash on startup in Desktop mode 2023-12-13 18:22:48 +01:00
Josef Nemec
d1b69409b4 Updated localizations 2023-12-13 13:37:35 +01:00
Josef Nemec
9f02a8dd93 10.30 version bump 2023-12-13 11:30:12 +01:00
Josef Nemec
ea276512f2 Small fix for AddMissing list method 2023-12-11 17:53:38 +01:00
Josef Nemec
ef0a2d88d8 Show message if no controller is detected in input settings 2023-12-11 16:57:27 +01:00
Josef Nemec
836137d1da New: Installation status added to the explorer panel #1740 2023-12-11 12:42:13 +01:00
Josef Nemec
c5ba48b097 SDK version bump 2023-12-11 12:41:19 +01:00
Josef Nemec
b97d78d3e3 Themes API version bump 2023-12-11 12:41:11 +01:00
Josef Nemec
c92ac029cf Prevent startup on Windows 7 and 8 (updated web view no longer supports them) 2023-12-10 19:29:32 +01:00
Josef Nemec
9bd0f7e523 New: Emulation scanner exclusions now support relative definitions and regular expressions #3618 2023-12-10 19:28:52 +01:00
Josef Nemec
99046fb49f Updated 3rd party license file 2023-12-10 19:27:22 +01:00
Josef Nemec
a617a5786d Fix: Updated web view component 2023-12-10 19:27:07 +01:00
Josef Nemec
96f6221448 Fix: Multi game edit dialog shows warning about unsaved changes even if no changes have been made #3599 2023-12-07 16:09:40 +01:00
Josef Nemec
6b7ab24e76 Fix: Some windows fail to properly restore saved size 2023-12-07 16:09:40 +01:00
Josef Nemec
fe46a55e5f Fix: Settings window doesn't remember size and position #3167 2023-12-07 16:09:40 +01:00
Josef Nemec
836c18cb26 New: Options to add system lock and logout actions to Fullscreen main menu #3563 2023-12-07 16:09:40 +01:00
Josef Nemec
5e383291db New: {ReleaseYear} variable can be used in web image search string #3526 2023-12-07 16:09:40 +01:00
Josef Nemec
bf68c8cc64 New: Statistics view allows filtering by installed state #2609 2023-12-07 16:09:40 +01:00
Josef Nemec
21f9e3efd2 Fix: Changing Desktop mode settings that require restart no longer switches to Fullscreen mode after restart #2790 2023-12-07 16:09:40 +01:00
Josef Nemec
676a2bc3c1 Fix: Emulation scanner importing duplicates if assigned roms are missing names #2765 2023-12-07 16:09:40 +01:00
Josef Nemec
5cdd1a2d3e Updated emulator profiles #3581 2023-12-07 16:09:40 +01:00
Josef Nemec
6859e9dd89 New: Install size is automatically calculated after game finishes installing #3162 2023-12-07 16:09:40 +01:00
Josef Nemec
40b72eacc0 Fix: Adding new game doesn't properly set modified date as well #3152 2023-12-07 16:09:40 +01:00
Josef Nemec
deb2ce3598 New: Software tools can execute scripts 2023-12-07 16:09:40 +01:00
Josef Nemec
1951654f68 Fix: Game selection is not remember on app restart 2023-12-07 16:09:40 +01:00
Josef Nemec
e7b478af8d About Playnite window polish #2810 2023-12-07 16:09:40 +01:00
Josef Nemec
e4c8cf95a6 Fix: Game menu showing some items incorrectly #2191 2023-12-07 16:09:40 +01:00
Josef Nemec
750e19441a New: Option to restore Playnite window only when game was launched from UI #1853
New: Option to close Playnite after game exits #2505
New: Option to restore Playnite window only when game was launched from UI #1853
2023-12-07 16:09:40 +01:00
Josef Nemec
8680e53c2c Removed uninstall app list dump from diag packages 2023-12-07 16:09:40 +01:00
Josef Nemec
8109ad325f Removed assignment of game icon from Play action 2023-12-07 16:09:40 +01:00
Josef Nemec
0a19c614aa Removed version stats collection 2023-12-07 16:09:40 +01:00
Josef Nemec
4a1ccbb4f8 New: Added option to completely disable program and addon update checks 2023-12-07 16:09:39 +01:00
Josef Nemec
b14d643b87 Removed Twitter link 2023-12-07 16:09:39 +01:00
Josef Nemec
790b6b1d8c New: Option to customize folder tracking timings 2023-12-07 16:09:39 +01:00
Josef Nemec
edb556bdca New: Audio and gamepad input handling ported to SDL2 (support for DirectInput controllers) #684 2023-12-07 16:09:39 +01:00
Josef Nemec
4c03306ff4 SDK version bump 6.10 2023-10-17 10:16:38 +02:00
Josef Nemec
1c2897f2dd Updated localizations 2023-10-17 10:08:09 +02:00
Josef Nemec
0ea205ece5 10.20 version bump 2023-10-16 13:11:28 +02:00
Josef Nemec
0d1c06dafc Don't crash if GameContextChanged from plugin throws 2023-10-16 13:11:09 +02:00
Josef Nemec
215d4492f1 Discord link update 2023-10-16 11:54:24 +02:00
Josef Nemec
502331175b readme update 2023-10-16 11:54:13 +02:00
Josef Nemec
e4369f31aa Fix: "Match all filters" option doesn't properly filter lists when "None" field state is selected 2023-10-14 19:33:02 +02:00
Josef Nemec
00d4887f2b New: Ruffle emulator profile 2023-10-13 11:12:24 +02:00
Josef Nemec
3adefef807 New: Data editing dialogs now show warning about unsaved changes when closing 2023-10-12 19:36:33 +02:00
Josef Nemec
9437dbf34d Fix: Some windows do not fit properly on 768p screens 2023-10-11 16:03:28 +02:00
Josef Nemec
ade485bfa9 SDK: ActiveFullscreenView added to MainView API 2023-10-11 15:30:48 +02:00
Josef Nemec
42e3a894a1 Some plugin methods being called multiple times instead of once when needed 2023-10-11 13:05:00 +02:00
Josef Nemec
5d92080d32 New: Added chd support to PPSSPP profiles 2023-10-11 12:53:23 +02:00
Josef Nemec
de76a5ee00 Changed handling of user manual URLs 2023-10-09 13:15:41 +02:00
Josef Nemec
5d0440e41b Help menu update 2023-10-02 12:49:29 +02:00
Josef Nemec
d3e540a4e5 Fix: Cancelling game startup from via a script or an extension doesn't set UI state properly in Fullscreen mode 2023-10-02 12:34:50 +02:00
Josef Nemec
2d08a74bbf Fix: Emulation scanner exclusions don't work properly on nested folders 2023-10-02 11:01:47 +02:00
Brandon
5b60061b08
New: Global search result order rankinng improvements (by darklinkpower)
* Sort keyboard launcher results by Levenshtein Distance

* Ignore case during distance calculation

* Subsequently order by name and installation status

* Use fuzzy matching using JaroWinkler similarity

* Fix some broken tests

* Add JaroWinkler filter match tests

* Add JeroWrenklinSimilarityTests and LevenshteinDistanceTests

* Rename file
2023-10-02 10:25:19 +02:00
Josef Nemec
eb006a3ee2 Fix: Crash when shutting down Playnite related to Discord integration 2023-10-02 10:19:52 +02:00
Josef Nemec
34f5c569bb Fix: Crash when assigning new category 2023-10-02 10:15:48 +02:00
Josef Nemec
0a022e4587 New: {PlayniteDir} variable can be used in software tools paths 2023-10-02 10:06:45 +02:00
Josef Nemec
ede248e0ab New: Crashes related to lack of disk space are reported as such 2023-10-02 10:05:12 +02:00
Josef Nemec
bea776f6d2 Tests not building 2023-10-02 10:01:41 +02:00
Josef Nemec
85d15baf6f Fix: Localized strings not displaying properly under certain Windows language settings #3565 2023-09-27 09:31:59 +02:00
Isaac Guerrero
d6c74a5bcf
Update importGames.ps1 to support portable install and relative path (#3564)
* Update importGames.ps1 to support portable install and relative path

Two changes:

1) Search for scummvm.ini in the scan directory first, then search appdata if not found.

2) Updated the $rompath construction to support relative paths in the scummvm.ini file. $anyFunc also had to be updated to properly identify games already imported using relative paths.

* fix indented code to match style

accidentally used tabs instead of spaces. corrected this.
2023-09-27 08:34:12 +02:00
Josef Nemec
b1e1ade3d9 Fix: Cancelling metadata download stuck on on long timeout doesn't work properly 2023-09-11 09:55:48 +02:00
Josef Nemec
b47d8ce76c 10.19 version bump 2023-09-11 09:10:19 +02:00
Josef Nemec
0471ceb97a Updated localizations 2023-09-11 09:05:03 +02:00
Josef Nemec
9b60abf8f2 Fix: Games imported via .lnk files are sometimes wrongly named #3535 2023-09-11 09:02:20 +02:00
Josef Nemec
d1634e849b New: Added profile for QT6 based RPCS3 versions 2023-09-08 10:39:06 +02:00
Josef Nemec
642cb3f6fb New: Long running global searches no longer prevent from typing new requets 2023-09-08 10:29:15 +02:00
Josef Nemec
431abb4ee5 New: Double click on global search results invokes primary action 2023-09-08 10:28:40 +02:00
Josef Nemec
d41e29a5a2 Fix: Crash when tracking games with invalid installation data 2023-09-08 10:27:53 +02:00
Josef Nemec
9067546916 Fix: Fullscreen crash with invalid view settings 2023-09-08 10:27:17 +02:00
Josef Nemec
ec46359e7a Fix: Crash when launching Fullscreen exe first after fresh installation 2023-09-08 10:26:55 +02:00
Josef Nemec
4ec4e4256c New: Option to control SafeSearch settings when using web image search #3516 2023-09-08 10:26:17 +02:00
Josef Nemec
1d205595e7 Fix: UI freezes for a long time when downloading unavailable image via web search 2023-09-08 10:25:09 +02:00
Josef Nemec
fa46d0408c Updated localizations 2023-06-22 11:55:55 +02:00
Josef Nemec
2427d80ce1 10.18 version bump 2023-06-22 11:47:55 +02:00
Josef Nemec
048fd3ad26 Fix: Crash when an extension is fetching selected games #3450 2023-06-22 11:43:25 +02:00
Josef Nemec
a0b8002b34 10.17 version bump 2023-06-13 12:07:52 +02:00
Josef Nemec
3bc56e650e Updated localizations 2023-06-13 12:07:39 +02:00
Josef Nemec
13198290a0 Fix: Metadata plugins being incorrectly disposed during bulk metadata download 2023-06-12 04:40:48 -07:00
Josef Nemec
2b32cb4236 New: Added BigPEmu emulator profile #3430 2023-06-12 04:37:49 -07:00
Josef Nemec
d5ceb576b1 .gg file support for PicoDrive profile #3415 2023-06-12 04:17:55 -07:00
Josef Nemec
465bf27047 Fix: Crash when installing a game via SDK #3432 2023-06-12 04:05:48 -07:00
Josef Nemec
2dd7c41c16 Doc sources removed, moved to separate repo 2023-05-15 04:39:42 -07:00
Josef Nemec
9d19b25fac Pull request notif update 2023-05-15 04:34:01 -07:00
Josef Nemec
d3068730a8
Update README.md 2023-05-10 15:44:16 +02:00
Josef Nemec
fd9e160746 10.16 version bump 2023-05-05 09:35:41 +02:00
Josef Nemec
e24f93827c Fix: Desktop mode window state issues introduced with 10.15 update 2023-05-05 09:35:16 +02:00
Josef Nemec
39e7ff0569 GetResponseCode wrongly downloading the entire file + headers support 2023-05-03 14:42:20 +02:00
Josef Nemec
ee15d63efd Window not rendering properly after restoring from closed to tray 2023-05-03 13:23:42 +02:00
Josef Nemec
653c110709 10.15 version bump 2023-05-03 12:58:11 +02:00
Josef Nemec
21b666a3a1 Localization updates 2023-05-03 12:26:22 +02:00
Josef Nemec
26b8e1f9a7 Fix: Application/window restore issues in Fullscreen mode 2023-05-03 12:24:19 +02:00
Josef Nemec
d34ab58f7a Doc updates 2023-05-03 11:11:32 +02:00
Josef Nemec
8834be12f9 Fix: MS Store apps and games not showing up on manual scan dialog sometimes 2023-05-03 11:10:35 +02:00
Josef Nemec
344719c82f Doc update 2023-04-29 11:48:27 +02:00
Josef Nemec
d2b1870512 New: Clear options to remove or keep completion untouched after playing a game for the first time 2023-04-29 11:46:15 +02:00
Josef Nemec
e693a935f3 Don't limit explorer panel dropdown height to show all items at the same time 2023-04-26 13:06:24 +02:00
Josef Nemec
7ef242812b Fix: Random crash when closing a window 2023-04-26 12:50:09 +02:00
Josef Nemec
33a49edf02 Possible null reference in RelayCommand 2023-04-26 12:16:02 +02:00
Josef Nemec
84bc65f39e Platforms list databases update 2023-04-26 12:04:05 +02:00
Josef Nemec
6db9b61cfa Fix: Games imported via folder scan dialog have empty GameId field 2023-04-26 11:46:52 +02:00
Josef Nemec
377fcb9b75 Fix: Plugin settings opened in a dedicated window can display incorrectly 2023-04-26 11:30:18 +02:00
Josef Nemec
e168f8cead Fix: Search term exclusions can't be used on web image search dialog 2023-04-26 11:26:19 +02:00
Josef Nemec
49dbca774e Default installed game import window size not large enough for some languages 2023-04-26 11:03:06 +02:00
Josef Nemec
d2d3a03168 Merge remote-tracking branch 'origin/devel' 2023-04-17 13:30:46 +02:00
Riley Nielsen
96d246c4ac
Fix: Updated Bizhawk and MelonDS emulator profiles (by Coloradohusky) 2023-04-17 13:30:19 +02:00
Josef Nemec
005f02dc6f 10.14 version bump 2023-04-10 07:55:32 +02:00
Josef Nemec
673a38d1f8 Fix: 'Xinput Device Support' setting reverts to its default behavior upon losing and regaining window focus #3375 2023-04-10 07:52:48 +02:00
Josef Nemec
07c71e611e Fix: Crash when editing filter presets via library manager 2023-04-10 07:42:23 +02:00
Josef Nemec
0c85acbf61 10.13 version bump 2023-04-05 09:57:23 +02:00
Josef Nemec
a2ca4e0da4 Updated localizations 2023-04-05 09:52:10 +02:00
Josef Nemec
89dd631c29 Show progress window in task bar 2023-04-05 09:40:28 +02:00
Josef Nemec
37e29f28a0 Fix: Updated PCSX2 emulator profile 2023-04-03 11:48:14 +02:00
Josef Nemec
dada5264b2 Fix: Filter preset order doesn't properly update on explorer panel 2023-04-03 11:43:19 +02:00
Josef Nemec
71e93a9630 Revert "file checksum test failing"
This reverts commit 490f8208e82b0f87987cf5efad87bb5573647816.
2023-03-31 12:04:05 +02:00
Josef Nemec
490f8208e8 file checksum test failing 2023-03-31 11:51:55 +02:00
Josef Nemec
53450b6fb1 Fix: Better name handling of gzip ROM files #3357 2023-03-31 11:49:34 +02:00
Josef Nemec
a3030925a9 Possible crash in FS mode when using a theme with custom game list panel 2023-03-31 10:33:42 +02:00
Josef Nemec
7e2dfa7fda Updated localizations 2023-03-31 10:30:06 +02:00
Josef Nemec
3bda573777 Fix: Metadata download sometimes failing on game edit dialog 2023-03-31 10:23:50 +02:00
Josef Nemec
16273c943b Merge remote-tracking branch 'origin/devel' 2023-03-31 10:00:00 +02:00
Jeshibu
297f5a770c
Fix: Future release dates get day-of-week display values (by Jeshibu)
* DateTimes test: future dates are not displayed as weekdays

* Fixed future dates displaying as weekdays
2023-03-31 09:59:08 +02:00
Josef Nemec
58fe736c16 Fix: Install size on stats view is calculated incorrectly 2023-03-31 09:55:50 +02:00
Josef Nemec
0f8c104b88 Merge branch 'master' into devel 2023-03-20 10:54:15 +01:00
Josef Nemec
55cee73946 Fix: Theme previews not working in Blend 2023-03-20 10:53:40 +01:00
Josef Nemec
fa2a28c977 10.12 version bump 2023-03-17 14:59:28 +01:00
Josef Nemec
a8e10ee316 Fix: Possible company duplication when downloading metadata via game edit dialog 2023-03-17 14:58:59 +01:00
Josef Nemec
75ddd43ff1 Theme API version bump 2023-03-17 11:32:29 +01:00
Josef Nemec
b124418eb9 Fix: Creating new fields from game edit dialog is not working properly #3343 2023-03-17 11:14:47 +01:00
Josef Nemec
6ed93b4ffd Fix: Compatibility issues with some existing themes 2023-03-17 11:12:11 +01:00
Josef Nemec
3f48a96484 Merge remote-tracking branch 'origin/devel' 2023-03-17 09:04:38 +01:00
Brandon
9ef99bb9e0
Fix filter presets name changes not saving upon restart (#3340) 2023-03-17 09:04:24 +01:00
Brandon
1a14c9e44f
Add m3u format to Nintendo Gamecube profile of Dolphin emulator (#3341) 2023-03-17 09:03:50 +01:00
Josef Nemec
966d3c45fc 10.11 version bump 2023-03-15 21:55:57 +01:00
Josef Nemec
4e67e7e6a7 Fix: Crash on startup with eMixedNite theme 2023-03-15 21:55:05 +01:00
Josef Nemec
946b542c85 Merge branch 'master' into devel 2023-03-15 12:51:22 +01:00
Josef Nemec
e4101472d4 Removed reference to deleted converter 2023-03-15 10:37:42 +01:00
Josef Nemec
bd16943ab3 Some platforms not properly referenced in RA profiles 2023-03-15 10:37:10 +01:00
Josef Nemec
ce888b456f Updated localizations 2023-03-15 10:23:41 +01:00
Josef Nemec
41e7440f71 SDK version bump 2023-03-15 10:20:20 +01:00
Josef Nemec
2cda95ed85 Sorting by ROM list doesn't work 2023-03-15 10:00:08 +01:00
Josef Nemec
21f836767b
10.10 version bump 2023-03-13 10:47:41 +01:00
Josef Nemec
2d8da1c48d Fixes to game merging during emulation scan 2023-03-11 12:16:30 +01:00
Josef Nemec
a60a72e3fe New: Option to show assigned ROMs on List view 2023-03-11 11:34:10 +01:00
Josef Nemec
7ce8fb09e3 Define user agent in HttpDownloader requests 2023-03-09 20:58:56 +01:00
Josef Nemec
313839f987 loc constants update 2023-03-09 13:31:59 +01:00
Josef Nemec
985a939127 Merge remote-tracking branch 'origin/devel' 2023-03-09 13:31:33 +01:00
Josef Nemec
d6314395cb New: Option to control whether related ROM files should be merged during emulation scan 2023-03-09 13:31:15 +01:00
Josef Nemec
196d4f9777 New: Option to minimize Fullscreen mode from main menu #1695 2023-03-09 12:58:00 +01:00
Josef Nemec
c745a76160 loc constants update 2023-03-09 12:45:22 +01:00
Josef Nemec
97ee0ffd3d Fix: Lag when selecting game with long description text 2023-03-09 12:44:57 +01:00
Brandon
16a6e4c197
Support to indicate number of days played in game time played format (#3317)
* Support to indicate number of days played in game time played format

* Change days string format

* Add test

* Update test
2023-03-07 23:05:30 +01:00
Brandon
dd466bbd0f
Support to display total install size in statistics view (#3327)
* Support to display total install size in statistics view

* Make TotalInstallSize type not nullable

* Make variable not nullable
2023-03-07 23:04:27 +01:00
Josef Nemec
998623a257 Handle crashes related to library file corruption 2023-03-07 13:35:04 +01:00
Josef Nemec
14aa930c04 Don't show crash dialog when running under Wine 2023-03-07 13:03:00 +01:00
Josef Nemec
081bbd3329 Don't show crash dialog on Deck under Wine 2023-03-07 12:56:59 +01:00
Josef Nemec
8f9a0a5256 Filter preset binding exception on startup 2023-03-07 12:24:00 +01:00
Josef Nemec
10a8f8dc14 Merge remote-tracking branch 'origin/devel' 2023-03-07 12:08:10 +01:00
Josef Nemec
6444da103d Merge remote-tracking branch 'origin/devel' 2023-03-07 11:49:52 +01:00
Brandon
851979f718
Add filter presets to Library Manager. Support for custom sorting. (#3258)
* Add FilterPresets section to Library Manager

* Add support to use custom order for filter presets

* Fix typo

* Fix crash if no preset is selected

* Fix getting settings many times

* Support to set Show on Fullscreen Mode in library manager

* Make newly added filter presets show last. Refactor to use single sorting method for Filter Presets

* Remove unused variable

* Implement Sorted Filter Presets test

* Remove ClearFilterPresets method in tests

* Remove getClone parameter from GetSortedFilterPresets method

* Sort unsaved items at the end of the list

* Add test to verify unsaved items are sorted at the end of the list

* Remove use of dictionary and unnecessary ToList
2023-03-07 11:49:09 +01:00
Brandon
af2696d6ff
Add support to display game Added Date in game details (#3316)
* Add support to display added time in game details

* Remove duplicate code

* Set display to disabled by default
2023-03-07 11:38:03 +01:00
Josef Nemec
dd138fb6d3 Localization resources are not working in test projects 2023-03-07 11:20:09 +01:00
Brandon
712f3e136d
Fix RetroArch script creating duplicate profiles (#3310)
* Restore previous RA emulator profile

* Fix RetroArch profile generator script creating duplicate profiles

* Update RetroArch emulator profile

* Revert "Update RetroArch emulator profile"

This reverts commit 64ea054b591eccdf2db167e32081b303b899bafa.

* Script: Fix line endings and missing new line in RA profile

* Update RetroArch emulator profile. Again.

* Revert "Update RetroArch emulator profile. Again."

This reverts commit c0365bdf7c7741324c471df2945591f6a110df1a.

* Script: Fix in case platform of existing profile is not detected

* Generate RA emulator profile. Last time I swear
2023-03-07 10:44:56 +01:00
Josef Nemec
6e480a181a Better validation of metadata returned by metadata plugins 2023-03-07 10:43:10 +01:00
Josef Nemec
ab7976db22 Option to configure tracking delay in process monitor 2023-03-06 18:05:08 +01:00
Josef Nemec
1efe594562 Fix: Name field is overwritten during metadata download even if download of missing fields is enabled 2023-03-06 17:08:23 +01:00
Josef Nemec
e5862b1f34 Enable search on doc website 2023-03-06 16:52:24 +01:00
Josef Nemec
7f7919e001 Fix: Games can't be relaunched from tray menu if game tracking bugs out 2023-03-06 16:26:26 +01:00
Josef Nemec
d73c5fecb6 Fix: Close to tray on startup not working if backup is also performed on startup 2023-03-06 16:08:09 +01:00
Josef Nemec
0525b492c2 New: Option to hide already imported games on folder scan dialog 2023-03-06 15:53:17 +01:00
Josef Nemec
5fbc2358e6 New: Fuzzy matching support in name filter 2023-03-06 14:27:06 +01:00
Josef Nemec
d4877fb105 Some converters crashing XAML preview 2023-03-06 14:18:38 +01:00
Josef Nemec
b6b695962d Disable HDR related function on Win 7 and 8 2023-03-06 13:12:15 +01:00
Josef Nemec
d286723721 Merge remote-tracking branch 'origin/devel'
# Conflicts:
#	source/Playnite/GamesEditor.cs
2023-03-06 13:07:32 +01:00
Liam Scholte
01ed24134d
Show game name in the confirmation dialog before removing game (#3318)
* Show game name in the confirmation dialog before removing game

* Fixes bug where closing "remove game" dialog without using the action buttons will remove the game rather than cancel the operation
2023-03-06 12:35:54 +01:00
Josef Nemec
a275dd2882 Automatically focus search box when selecting game fields on game edit window 2023-03-06 12:17:21 +01:00
Liam Scholte
128a7733cc
Activate HDR When Game Launches (#3290)
* Adds a toggle to each game to activate HDR upon launching the game and disable on exit

* Adds name to contributors file

* Replaces C++/CLI implementation of HdrUtilities with C#

* Fixes summary string for HDR game setting to be more correct

* Removes HDR toggle from game context menu in desktop mode (remains in fullscreen mode)

* Moves P/Invoke code into Playnite repo and reuses existing code

* Addresses review comments

* Modifies fullscreen HDR strings to be consistent with desktop mode strings

* Ensure that HDR state is only reset back to original state if all games requiring HDR are exited

* Updates enum value name for consistency

* Updates error logging
2023-03-04 13:17:57 +01:00
Josef Nemec
2abbb3b3c0 SDK: Added a method for deleting domain webview cookies matching specific regex 2023-03-04 13:15:33 +01:00
Josef Nemec
43a747b64d Fix: $SourceAction variable not available in post scripts #3328 2023-03-04 12:36:19 +01:00
Josef Nemec
0d9cd61838 New: Added support for playnite://playnite/search URI to open global search #3326 2023-03-04 12:17:45 +01:00
Josef Nemec
16df9569c6
Update README.md 2023-02-28 13:01:24 +01:00
Josef Nemec
f263ec6f0f
Update README.md 2023-02-26 11:10:33 +01:00
Brandon
7037e9869b
Emulation updates (#3289)
* Update Mesen Emulator Profile

* Create ares emulator profile

* Remove unneeded wildcard in StartupExecutable

* Create blueMSX emulator profile

* Make emulator Id lowercase

* Add new emulation platforms

* Create script to generate and update RetroArch profile definitions

* Script fix

* Update RetroArch emulator profile definitions

* ares emu - Add SG-1000 emulator profile

* Fix ares WonderSwan console extensions being swapped
2023-02-16 11:13:00 +01:00
Rioluu
e637ff1e53
Add fullscreen mode to jump list (#3220)
* Add fullscreen mode to jump list

* Add Rioluu to contributors.txt

---------

Co-authored-by: Rioluu <rioluu@protonmail.com>
Co-authored-by: Josef Nemec <nemecjosef@gmail.com>
2023-02-13 10:03:19 +01:00
Brandon
84a7675d3e
Fix LastActivity not being updated to existing game on library update (#3270) 2023-02-13 10:00:05 +01:00
Rosalie
5c2934f7ef
Add --fullscreen & --quit-after-emulation to RMG (#3297) 2023-02-13 09:58:20 +01:00
NekuSoul
4c27649f27
Fix: Proton existing in Steam library causes install size scan error #3280 (#3286) 2023-02-13 09:57:31 +01:00
Josef Nemec
25694585b8 Stats view percentage calculations will fail on invalid data 2023-01-24 15:43:36 +01:00
Josef Nemec
733f451bbb Crash if list converters are used on non-collection object 2023-01-24 14:54:17 +01:00
Josef Nemec
63222f8824 Better error message when emulator executable is not found during game startup 2023-01-24 13:42:17 +01:00
Josef Nemec
decf7ab36c Some strings not being translatable #3233 2023-01-24 13:23:50 +01:00
Josef Nemec
16d9b27ca7 New: Backup configurations now support additional OutputDir variable to set target backup folder instead of just OutputFile #3257 2023-01-24 12:44:34 +01:00
Josef Nemec
49f696e30b Zoom steps are different when zooming in and out in grid view with the arrow keys #3245 2023-01-24 11:36:16 +01:00
Josef Nemec
a3d1788a29 Fix: $StartedProcessId variable not available to emulator scripts 2023-01-24 11:09:27 +01:00
Josef Nemec
4f41dbd52c Use explicit MaxDepth for JSON serialization 2023-01-24 10:43:54 +01:00
Josef Nemec
4546b781da Toolbox theme packaging includes some VS related files that should be excluded #3269 2023-01-24 10:37:55 +01:00
Josef Nemec
aa05b62f99 Case insensitive game name comparison during metadata download #3261 2023-01-24 09:56:04 +01:00
Josef Nemec
f40422782e Fix: Various fixes to manual metadata download 2023-01-24 09:50:14 +01:00
Josef Nemec
e2aac0a4a4
Update README.md 2023-01-07 11:39:56 +01:00
Josef Nemec
cef3868da1 Online installer can install into a wrong folder when starting install using Enter 2022-12-28 21:20:23 +01:00
Josef Nemec
1baf5e8a30 Updated .NET target version in theme templates 2022-12-28 21:17:58 +01:00
Josef Nemec
250aa96b8f FCEUX emulation profile update 2022-12-28 21:12:29 +01:00
Josef Nemec
b92d96cb24 New: Option to choose tracking mode for emulator processes 2022-12-28 21:08:19 +01:00
Josef Nemec
e1ad7fd011 x64 build target 2022-12-23 09:51:24 +01:00
Josef Nemec
54488a22fa Updated localizations 2022-12-22 18:20:04 +01:00
Josef Nemec
78be2d3024 SDK: Added OnGameStartupCancelled application event 2022-12-22 17:58:49 +01:00
Josef Nemec
88bba7eece SDK nuget readme 2022-12-15 20:21:32 +01:00
Josef Nemec
aa64aacb14 Updated localizations 2022-12-15 09:53:30 +01:00
Josef Nemec
b758f08dd9 SDK changelog update 2022-12-14 11:49:15 +01:00
Josef Nemec
7c22b85a69 10.9 version bump 2022-12-14 11:48:10 +01:00
Josef Nemec
b49bbd4f3b SDK version bump 2022-12-14 11:47:47 +01:00
Josef Nemec
dff379c663 Changed timer log severity 2022-12-14 11:47:09 +01:00
Josef Nemec
2cf5df86e2 Force English culture info for log messages 2022-12-13 19:05:19 +01:00
Josef Nemec
eb05b57fbb Added "64bit SSE4 QT" PCSX2 profile 2022-12-13 17:21:10 +01:00
Josef Nemec
0ec7741227 doxfx style update 2022-12-13 11:59:25 +01:00
Josef Nemec
73243de216 Updated localizations 2022-12-13 10:58:43 +01:00
Josef Nemec
3483d4f4d1 Calculate localization progress only from main language file 2022-12-13 10:58:32 +01:00
Josef Nemec
e94d36dfd8 Merge remote-tracking branch 'origin/devel' 2022-12-13 10:19:53 +01:00
Brandon
90e758d104
New: Acronyms search support in name filter and global search (by darklinkpower) 2022-12-13 08:57:42 +01:00
Josef Nemec
1ea3518a15 Removed obsolete comment 2022-12-12 15:46:47 +01:00
Brandon
caf001609e
Add main menu buttons to restart Playnite (#3205) 2022-12-12 10:27:54 +01:00
Josef Nemec
86c432b697 Fix: Tweaks to software tools configuration window #3195 2022-12-11 19:08:03 +01:00
Josef Nemec
d291ce27ac Better error reporting for failures in emulation scanner settings 2022-12-11 15:53:10 +01:00
Josef Nemec
766d355a83 Removed forum link 2022-12-10 10:45:15 +01:00
Josef Nemec
14d51bc351 Ryujinx profile fix 2022-12-10 10:43:30 +01:00
Josef Nemec
efdf643166 New: Added Avalonia profile for Ryujinx emulator 2022-12-09 20:11:18 +01:00
Josef Nemec
6280520b31 Jump list category is not localized 2022-12-09 20:02:04 +01:00
Josef Nemec
4f515c566e Merge remote-tracking branch 'origin/devel' 2022-12-09 19:48:43 +01:00
Brandon
4df1c2c981
New: Add support to show favorite games in tray (by darklinkpower) 2022-12-09 19:48:12 +01:00
Josef Nemec
e97e0251ea typo fix 2022-12-09 19:46:27 +01:00
Josef Nemec
3db3d4a01a Crash when setting sorting names during library update 2022-12-09 19:32:52 +01:00
Josef Nemec
48f398b4bd Fix: Games not being detected during emulation scan due to ROM file extension case sensitivity #3197 2022-12-09 19:23:06 +01:00
gamingexpert13
ef8d5f1cd6
Add info for switching active theme (#3193)
This info for setting your active theme should really/also be on the "How to: Themes" page but I couldn't figure out how to edit that.
https://github.com/JosefNemec/Playnite/wiki/How-to:-Themes

Info on how to change your active/applied theme isn't available anywhere that I could find. I could only find a reddit post with someone else asking the same question. We both assumed you could toggle a theme active in the Addons>Installed>Themes window (like how Firefox etc does it). [That would also be a nice addition to the program.]
My next guess was that in the main dropdown menu there was a Theme submenu, or View>Theme or Add-ons>Theme or Extensions>Theme or something where I could select my active theme. I was wrong again so I had to look through help docs and then just do an internet search.

It is also not intuitive that you have to activate Fullscreen mode separately before you can choose the theme for that view in settings (it would be helpful to show 2 options in the regular settings, one for Desktop Theme and one for Fullscreen Theme. I do see that there's a completely different Settings UI in fullscreen mode though so it's probably fine to leave that side as is). [As a sidenote, I also assumed there would be a fullscreen button on the top-right like the steam big picture mode button in the steam ui.]

Anyway, thanks for your work on this great program!
2022-12-08 11:42:05 +01:00
Josef Nemec
91918b7aca Merge branch 'master' into devel 2022-12-01 10:03:32 +01:00
Josef Nemec
4525b3977d 10.8 version bump 2022-12-01 09:24:12 +01:00
Josef Nemec
68414e9b34 Fix: Some emulated games won't start properly when {EmulatorDir} is used as game installation folder 2022-12-01 09:18:50 +01:00
Josef Nemec
910e4f26d8 Updated localizations 2022-12-01 08:44:39 +01:00
Josef Nemec
5bd51dfeeb Fix: Some windows don't remember last position and size 2022-12-01 08:33:21 +01:00
Josef Nemec
c1a3c272d9 Fix: Various issues related to metadata download from game edit dialog 2022-11-30 22:05:41 +01:00
Josef Nemec
60200a826a Fix: Opening game's installation folder doesn't work if {EmulatorDir} variable is used in install folder path 2022-11-30 22:03:32 +01:00
Josef Nemec
a5c71e1284 Small tweaks to string extension methods 2022-11-30 15:26:24 +01:00
Josef Nemec
07fdf8b018 Fix: Crash when importing non-exe file as software tool 2022-11-30 10:49:17 +01:00
Josef Nemec
d1df302efb Fix: Safe mode is not carried over when switching application modes 2022-11-30 10:35:08 +01:00
Josef Nemec
c28edfa482 Remove forum references from docs 2022-11-29 13:03:03 +01:00
Josef Nemec
7b48a16fe9 Fix: View settings not being saved during system shutdown 2022-11-29 13:00:12 +01:00
Josef Nemec
dda57636eb Merge branch 'master' into devel 2022-11-28 13:13:19 +01:00
Dawid K
50b91154c8
Cleans up Ubisoft Connect naming (#3173) 2022-11-26 20:03:11 +01:00
Josef Nemec
b4eeff8fc4
Removed forums link from readme 2022-11-16 12:17:12 +01:00
Josef Nemec
1dcbdb36d1 Updated localizations 2022-11-15 11:53:27 +01:00
Josef Nemec
74278dd14f 10.7 version bump 2022-11-15 11:50:26 +01:00
Josef Nemec
56d6707b7f Another attempt to fix mysterious dialog result crash... 2022-11-15 11:46:32 +01:00
Josef Nemec
1784d2cb10 SDK version bump 2022-11-15 11:03:31 +01:00
Josef Nemec
979ed6e693 SDK: Added overload to ExpandGameVariables for expanding {EmulatorDir} variable #3161 2022-11-15 11:01:18 +01:00
Josef Nemec
9ed6cf38fb Set required PowerShell version in various scripts 2022-11-14 22:27:28 +01:00
Josef Nemec
a592653dc9 Build script fails on detecting msbuild location 2022-11-14 22:27:08 +01:00
Josef Nemec
5560d4a096 Update install size scan date if install size is changed manually 2022-11-14 11:29:33 +01:00
Josef Nemec
3e0ed361ad Updated localizations 2022-11-11 11:46:43 +01:00
Josef Nemec
f6e01a7304 Fix: Some theme styles can't be previewed in Blend #3158 2022-11-11 11:29:13 +01:00
Josef Nemec
a7e74cd1c2 Crash when importing emulated games after splitting them 2022-11-11 10:29:31 +01:00
Josef Nemec
d3ded3b6ae 10.6 version bump 2022-11-10 12:50:40 +01:00
Josef Nemec
937cd39148 Revert "Fix: Global search doesn't work immediately after clicking away to main Playnite window #3072"
This reverts commit ab4f0ba76182fdbb5781c1422b1d3d21d22c289d.
2022-11-10 12:47:55 +01:00
Josef Nemec
b5db5537f4 10.5 version bump 2022-11-09 12:51:17 +01:00
Josef Nemec
9c3008fad1 Fix: Some Fullscreen themes causing crash on startup 2022-11-09 12:50:55 +01:00
Josef Nemec
9857cb4741 Small change to first time startup progress dialog 2022-11-09 11:33:55 +01:00
Josef Nemec
5e53c31906 10.4 version bump 2022-11-09 11:33:01 +01:00
Josef Nemec
61371f92a2 Updated localizations 2022-11-09 11:04:54 +01:00
Josef Nemec
eab8ba6b28 Theme API version bump 2022-11-09 10:37:46 +01:00
Josef Nemec
ba48df9613 SDK version bump 2022-11-08 21:00:33 +01:00
Josef Nemec
af95d5c286 CefSharp 107 update 2022-11-08 19:16:12 +01:00
Josef Nemec
e08635337f Auto backup settings view is not configured properly 2022-11-08 15:14:07 +01:00
Josef Nemec
6b87389d1a Window position restore is not working correctly 2022-11-07 10:32:04 +01:00
Josef Nemec
d72bb108e3 Crash when metadata plugin is badly implemented 2022-11-06 12:10:54 +01:00
Josef Nemec
8e67105c93 Crash after game import related to post import game processing 2022-11-06 11:41:31 +01:00
Josef Nemec
133dc5f119 Doc updates 2022-11-06 11:21:43 +01:00
Josef Nemec
a47fcdc59a Fixes to detection of installed UWP apps 2022-11-06 11:19:43 +01:00
Josef Nemec
bb53c96615 Minor doc fix 2022-11-05 12:43:09 +01:00
Josef Nemec
5970336718 Added M64Py emulator profile #3143 2022-11-04 14:57:50 +01:00
Josef Nemec
2ab29a7f30 Added DOSBox emulator profile 2022-11-04 14:49:58 +01:00
Josef Nemec
1d164769a0 Sort emulators and profiles on game startup selection list 2022-11-04 11:21:07 +01:00
Josef Nemec
1bfa8e8506 Small tweak to ROM assignment view 2022-11-04 11:20:24 +01:00
Josef Nemec
c6c978cfad Small tweak to ScummVM game import 2022-11-03 16:55:13 +01:00
Josef Nemec
8c6843c2fd Disable horizontal scrollbar on global search view 2022-11-03 16:52:40 +01:00
Josef Nemec
950f9fc713 Small string change 2022-11-03 16:41:09 +01:00
Josef Nemec
c68a9b4dc1 Small string change 2022-11-03 16:07:36 +01:00
Josef Nemec
d96f1b8a16 Fix: Accessibility (screen reader) support fixes 2022-11-03 16:06:25 +01:00
Josef Nemec
82470d2f6d Fix: Various library backup related issues #3101 2022-10-25 19:58:03 +02:00
Josef Nemec
69b625acfc UpdateGameInstallSizeTest test timing fix 2022-10-25 17:56:09 +02:00
Josef Nemec
31c5e3136d Fix: Performance improvements to emulation scan #3108 2022-10-25 17:55:53 +02:00
Josef Nemec
27a366890b Installer C# version change 2022-10-25 10:47:23 +02:00
Josef Nemec
3ed242333f Gracefully handle additional failures in emulation scanner 2022-10-24 20:50:30 +02:00
Josef Nemec
1994d001eb Download emulators windows is slow to open 2022-10-24 19:29:19 +02:00
Josef Nemec
7842423a35 Fix: Game menu can't be scrolled when overflowing outside of screen #3073 2022-10-24 18:54:12 +02:00
Josef Nemec
e118cbd381 Fix: Position on secondary screens is not saved properly in Desktop mode 2022-10-24 18:30:22 +02:00
Josef Nemec
1d4025f4b9 New: Option to import emulated games with play action configuration set to emulator/profile select on startup 2022-10-24 15:34:00 +02:00
Josef Nemec
20efd93196 Metadata download of install size can force last modified date of a game to change even if no install size was updated 2022-10-24 15:02:11 +02:00
Brandon
cca64425be
Only close notifications panel if there isn't any notification (#3142) 2022-10-24 14:59:01 +02:00
Josef Nemec
6a77c85b35 New: {EmulatorDir} and {PlayniteDir} variables can be used in emulation config scan path 2022-10-24 14:20:08 +02:00
Josef Nemec
6d18d14995 SDK: playnite:// uri handler doesn't parse some arguments properly 2022-10-24 11:54:53 +02:00
Josef Nemec
d12fd019a5 Made list of default extensions installed during first time startup dynamic 2022-10-23 17:07:00 +02:00
Josef Nemec
fcf39062ca Import error when library plugin returns null from GetGames method 2022-10-23 17:04:32 +02:00
Josef Nemec
fa40a5fabb Fix: Install size is not being automatically calculated for games added manually via "Add game" menu 2022-10-19 16:55:19 +02:00
Brandon
bd7d433d78
Scan size symlink fixes and longs Path fix (#3137)
* Fix ScanSize failing in Symlinks with invalid targets

* Paths: Fix failure in paths with 258 and 259 characters

* Refactored GetDirectorySize* methods

* Add comment explaining path length value

* Use getSizeOnDisk parameter for GetDirectorySize
2022-10-19 16:30:02 +02:00
Josef Nemec
e02fd37308 SDK: PluginSettings and other markups can be now used inside MultiBinding 2022-10-19 16:29:00 +02:00
Josef Nemec
764c2b0a53 Plugins are not sorted properly on some views 2022-10-19 15:15:42 +02:00
Brandon
61b56f780c
Scan install size when updating emulation libraries (#3100)
* Update install sizes when importing emulated games

* Use progress message depending on scan context

* Remove "Emulated" from import loc string

* Change UpdateGamesInstallSizes argument type

* Add cancel token check at start of UpdateGamesInstallSizes method
2022-10-19 12:53:33 +02:00
Josef Nemec
72fae4ba24 Fix: Better support for gdi Dreamcast dumps 2022-10-18 21:34:27 +02:00
Josef Nemec
815a63e3db Tweak to ROM assignment UI 2022-10-18 20:20:33 +02:00
Josef Nemec
db32dcfc16 Fix: Import of emulated cue and m3u files doesn't work properly on long paths #3084 2022-10-18 19:24:11 +02:00
Josef Nemec
6b446151f1 Fix: Additional active filters message is shown in Fullscreen mode even if only filter preset settings are used #3113 2022-10-18 17:53:24 +02:00
Josef Nemec
d53ceffec7 Tab key navigation can escape from some views in Fullscreen mode #3117 2022-10-18 17:45:29 +02:00
Josef Nemec
27f3b20e38 Fix: Hiding mouse cursor in Fullscreen mouse doesn't disable mouse input handling #3136 2022-10-18 17:24:33 +02:00
Josef Nemec
5206a37939 Workaround for application restore not working properly in some cases 2022-10-18 15:22:07 +02:00
Josef Nemec
fecdf56731 Fix: Average play time is calculated incorrectly 2022-10-18 11:25:19 +02:00
Josef Nemec
8a50df4916 Fix: Backup operations failing due to long path files 2022-10-17 16:06:30 +02:00
Josef Nemec
066c12b776 Collect install file info in diag package only for root files 2022-10-17 14:05:57 +02:00
Josef Nemec
9f27b70738 Filter item selection in Fullscreen mode is not being sorted by name 2022-10-17 14:01:36 +02:00
Josef Nemec
01d0b37e37 Update library menu is not being sorted 2022-10-17 13:58:58 +02:00
Josef Nemec
dbb637062c SDK: Toolbox utility can verify addon manifests 2022-10-13 14:44:26 +02:00
Josef Nemec
617f995032 Sort emulator scanner configurations 2022-10-11 11:37:07 +02:00
Josef Nemec
fe3c0db2d4 Polish to external extensions settings view 2022-10-10 18:30:28 +02:00
Josef Nemec
3ea431d893 SDK: Database methods for getting filtered games #3122 2022-10-10 18:18:40 +02:00
Josef Nemec
ab4f0ba761 Fix: Global search doesn't work immediately after clicking away to main Playnite window #3072 2022-10-10 16:37:50 +02:00
Josef Nemec
716d711103 Fixed some missing localization strings #3092 2022-10-10 16:00:11 +02:00
Josef Nemec
9f524fcc3b New: Application startup script is not executed in safe mode #3121 2022-10-10 15:57:01 +02:00
Josef Nemec
6c203e34a2 Show notification if no metadata source is available when downloading metadata from game edit window 2022-10-10 15:09:56 +02:00
Josef Nemec
469ea22896 Directory selection boxes on For developers settings view 2022-10-10 15:01:49 +02:00
Josef Nemec
7273751a23 Failures in top panel extension buttons can crash Playnite 2022-10-02 21:13:48 +02:00
Josef Nemec
151eb08387 Merge remote-tracking branch 'origin/devel'
# Conflicts:
#	source/Playnite.DesktopApp/ViewModels/GameEditViewModelFieldChecks.cs
2022-09-30 13:43:32 +02:00
Brandon
b446685527
Fix Updating CompletionStatus shows data change on Advanced tab (#3114) 2022-09-30 11:15:01 +02:00
Brandon
58094b3766
Fix CommunityScore radio button is not checked in Metadata diff window (#3115) 2022-09-30 11:14:29 +02:00
Josef Nemec
4a26add24f Metadata download progress is not visible if install size calculation on library update is enabled 2022-09-27 13:54:28 +02:00
Josef Nemec
71f091b763 Errors related to addon installation of new manually installed addons in the very first Playnite instance after installation 2022-09-27 13:53:49 +02:00
Josef Nemec
f217c76b56 10.3 version bump 2022-09-27 13:27:42 +02:00
Josef Nemec
89c0f48feb Sdk version bump 2022-09-27 13:25:26 +02:00
Josef Nemec
dc3e8f3313 Updated localizations 2022-09-27 13:18:52 +02:00
Josef Nemec
d6967bc159 Merge remote-tracking branch 'origin/devel' 2022-09-27 12:59:08 +02:00
Josef Nemec
703e3bab13 Crash when generating software tools items in main menu 2022-09-27 12:57:33 +02:00
Josef Nemec
350b359fc5 Go to details from random selection game dialog is allowed even when no game is available 2022-09-27 12:53:48 +02:00
Josef Nemec
c1d58a94b3 Fix: Daily update triggers don't work properly #3096 2022-09-27 12:51:44 +02:00
Josef Nemec
268f3acd12 A string can't be localized #3092 2022-09-27 11:51:17 +02:00
Josef Nemec
356d3858e3 Fix: Can't confirm changes when editing game field with a controller in Fullscreen mode #3087 2022-09-27 11:43:34 +02:00
Josef Nemec
90de50ec24 New: Option to specify partial release date display format #3094 2022-09-27 11:36:45 +02:00
Josef Nemec
019dc14900 Possible recursion in ThemeFileBinding 2022-09-27 10:34:01 +02:00
Josef Nemec
18ce695e20 Fix: "Start minimized" option not working #3071 2022-09-26 19:04:57 +02:00
Jeshibu
df96760f4c
manual/emulators.md typo fix (#3099) 2022-09-26 11:15:18 +02:00
Brandon
7adba8f42e
Create install size scan tests (#3059)
* Create tests

* Fix first test section not correctly executing

* Move SizeScan test files

* Use TempDirectory.Create for test temp dir

* Remove unneeded delete file call

* Add test for directory long paths
2022-09-25 16:32:32 +02:00
Brandon
1ab72765b5
Add support to filter by InstallSize and RecentActivity. Group by RecentActivity (#3060)
* Add support to filter by InstallSize on Filter and Explorer Panel

* Add support for FullscreenMode

* Add support to filter by InstallSize on Filter and Explorer Panel

* Add support to filter by RecentActivity on FullscreenMode

* Add support to group by RecentActivity
2022-09-25 16:31:11 +02:00
Brandon
e013fd22f2
Skip install size metadata download if game is installed and has value (#3064) 2022-09-25 14:27:26 +02:00
Brandon
273a0c1d3e
Fix size on disk scan failing for long paths (#3070) 2022-09-25 14:26:47 +02:00
Brandon
0bf33a87ab
Fix infinite loop on size scan when folder name is whitespace (#3085) 2022-09-25 14:23:04 +02:00
Brandon
3c04ac6d38
Fix updating install size show data change on "Advanced" tab (#3080) 2022-09-25 14:21:06 +02:00
Josef Nemec
d540d67d27 10.2 version bump 2022-09-24 13:12:41 +02:00
Josef Nemec
971d462cbb Fix: Play time data being lost in some cases if automatic time import is set to "Always" 2022-09-24 12:54:46 +02:00
Josef Nemec
cde8c992b4 Crash when toggling item selection in FS while while there are no items in the list 2022-09-22 16:32:40 +02:00
Josef Nemec
8ad1266613 Show converter value for install size on metadata comparison dialog 2022-09-22 12:16:22 +02:00
Brandon
c127b10077
Install size is not properly used when downloading metadata from game edit window 2022-09-22 12:11:24 +02:00
Josef Nemec
d27e5cfb03 10.1 version bump 2022-09-22 11:55:24 +02:00
Josef Nemec
847c26ac93 Merge branch 'devel' 2022-09-22 11:54:47 +02:00
Josef Nemec
5b7f670116 Updated localizations 2022-09-22 11:51:18 +02:00
Josef Nemec
5cbd03f8fb Updated doc manifest 2022-09-22 11:51:01 +02:00
Josef Nemec
b784905ea9 Updated SDK changelog 2022-09-22 11:47:33 +02:00
Josef Nemec
66663f2f9b GetInstallDrive should never completely fail 2022-09-22 11:45:22 +02:00
Josef Nemec
fd6cbb6b5c Theme API version bump 2022-09-22 11:40:10 +02:00
Josef Nemec
752a174219 Migrate startup update settings from P9 2022-09-22 11:37:02 +02:00
Brandon
837a12b0bc
Display progress during size scan on library update (#3063) 2022-09-22 11:18:48 +02:00
Josef Nemec
3bc01f3935 Increased default Desktop window size 2022-09-22 11:18:27 +02:00
Brandon
4d79098f31
Fix incorrect GridEx RowCount in details views (#3062) 2022-09-22 10:36:05 +02:00
Josef Nemec
758331aa6a Potential deadlock with global progress dialogs 2022-09-21 16:46:03 +02:00
Josef Nemec
30aa952b7f Merge branch 'master' into devel
# Conflicts:
#	source/Playnite/Localization/LocSource.xaml
2022-09-21 15:48:54 +02:00
Josef Nemec
0ca9176b09 # Conflicts:
#	source/Playnite/GamesCollectionViewEntry.cs
#	source/Playnite/Localization/LocSource.xaml
#	source/Playnite/Settings/DetailsVisibilitySettings.cs
#	source/Playnite/Settings/PlayniteSettings.cs
#	source/PlayniteSDK/Models/FilterPreset.cs
#	source/PlayniteSDK/Models/Game.cs
2022-09-21 16:00:26 +02:00
Brandon
d95ececa0a
New: Added install size field (by darklinkpower) 2022-09-21 15:33:25 +02:00
Brandon
c648418b77
Add TopPanel View Random Game Selector button (#3032)
* Add TopPanel View Random Game Selector button

* Fix KeyGesture not working

* Made Random instance static

* Use GlobalRandom

* Change top panel tooltip string
2022-09-19 22:32:19 +02:00
Josef Nemec
a06812339b GlobalRandom random NextBytes fix 2022-09-19 15:34:34 +02:00
Josef Nemec
54b882e4cc SDK changelog update 2022-09-19 14:12:13 +02:00
Josef Nemec
a2107dc4e7 SDK version bump 2022-09-19 14:07:50 +02:00
Josef Nemec
9c7b79ffda SDK: Built-in emulator profiles exposed in the SDK 2022-09-19 14:07:24 +02:00
Josef Nemec
1386f5abdd Process starter tests failing on Windows 11 2022-09-19 13:41:09 +02:00
Josef Nemec
a5ff8162ab Memory size detection doesn't work in virtual machine 2022-09-19 13:40:41 +02:00
Josef Nemec
4acaa7eaa8 Doc for how to switch search contexts 2022-09-18 20:25:00 +02:00
Josef Nemec
f92814b45c Added doc for web image search string variables 2022-09-18 20:00:49 +02:00
Josef Nemec
b4357a2f37 New: Option to configure default web image search terms #2227 2022-09-15 13:13:54 +02:00
Josef Nemec
6aac3674f5 SDK: Ability to switch indeterminate state of progress bar from ActivateGlobalProgress call 2022-09-14 17:09:28 +02:00
Josef Nemec
ce834146ff Prevent list flashing when switching contexts on global search view 2022-09-14 16:43:35 +02:00
Josef Nemec
f37b278beb Fix: http icons don't properly on global search view 2022-09-14 16:23:46 +02:00
Josef Nemec
cc1b75f269 Fix: Search view shows sorting names instead of the actual game names #3049 2022-09-14 16:21:56 +02:00
Josef Nemec
f879806984 Fix: Emulated playlist child files imported during scan despite playlist file being already imported 2022-09-10 15:36:01 +02:00
Josef Nemec
207a4ac699 Fix: Checkbox to show only assigned items is not visible on game edit window dropdowns 2022-09-10 15:03:00 +02:00
Josef Nemec
18312ce69b New: Right-click on top panel's filter button clears all filters #1892 2022-09-10 14:55:55 +02:00
Josef Nemec
818f67515c Fix: Search window appearance settings don't work properly with some game fields 2022-09-10 14:52:58 +02:00
Josef Nemec
2137b5839c Theme diff update 2022-09-06 14:09:04 +02:00
Josef Nemec
3dcfe90f7a Merge branch 'devel' 2022-09-06 13:55:09 +02:00
Josef Nemec
5b0ac6698a Backup operations show safe startup warning in Release config builds 2022-09-06 13:25:11 +02:00
Josef Nemec
eea978caa4 Fix: Choppy/missed inputs when multiple controllers are connected #2995 2022-09-06 12:56:19 +02:00
Josef Nemec
444fb1333b Backup restore fixes 2022-09-06 12:41:00 +02:00
Josef Nemec
cbbe47eac8 Emulated games using built-in profiles don't start 2022-09-06 10:19:51 +02:00
Brandon
43249ad8d3
Add simple64 emulator profile (#3043) 2022-09-06 09:57:25 +02:00
Josef Nemec
3565ff6a5f Merge branch 'master' into devel
# Conflicts:
#	doc/manual/emulators.md
#	doc/tutorials/extensions/plugins.md
#	doc/tutorials/toc.yml
#	source/Playnite/Properties/AssemblyInfo.cs
2022-09-06 09:56:51 +02:00
Josef Nemec
21a5ab4f0a Updated docs 2022-09-05 10:33:34 +02:00
Josef Nemec
b08d5f2028 Updated localizations 2022-09-05 10:07:17 +02:00
Josef Nemec
ed9e5f0f93 Changed context menu setup on List view 2022-09-02 20:11:21 +02:00
Josef Nemec
cbffb408d8 Wrong messaging after generating new theme via Toolbox 2022-09-01 18:36:51 +02:00
Josef Nemec
7d78293e0e Doc update 2022-09-01 18:26:55 +02:00
Josef Nemec
1ed6ad1317 Game details are not cleared if a game is removed and also not selected in the game list 2022-08-31 18:50:05 +02:00
Josef Nemec
a8ab171fb9 Option to show update notifications only for patch releases 2022-08-31 18:38:45 +02:00
Josef Nemec
9596ca51de DuckStation emu profile update 2022-08-31 17:02:39 +02:00
Josef Nemec
1573ff95e6 Refactoring related to search window styles and added an option to configure game fields 2022-08-31 17:02:39 +02:00
Josef Nemec
fcc3636f5c Doc updates 2022-08-31 17:02:39 +02:00
Josef Nemec
e9e9be7d4e Option to close individual notifications 2022-08-31 17:02:39 +02:00
Josef Nemec
d6b3f52ae3 Crash when adding new item into the library and some items with null names are present 2022-08-31 17:02:39 +02:00
Josef Nemec
47115bbd6e Wrong extension can be reported as a source of a crash if multiple extensions are part of the stack 2022-08-31 17:02:39 +02:00
Josef Nemec
732cff18f0 Don't show game selection highlight if item is not focused 2022-08-31 17:02:39 +02:00
Josef Nemec
da96e9ce44 Converters can be now used with ThemeFileBinding while PathFormat is defined 2022-08-31 17:02:39 +02:00
Josef Nemec
ac10c7a701 Emulator and EmulatorProfile variables not being generated for emulator scripts 2022-08-31 17:02:39 +02:00
Josef Nemec
2cff60f31b Added PluginConverter markup extension 2022-08-31 17:02:39 +02:00
Josef Nemec
68a0f9bf4d Small improvements to Settings markup if DirectValue is used 2022-08-31 17:02:39 +02:00
Josef Nemec
b25c25a136 Changes are not properly saved on game edit dialog after closing it via Enter key #3013 2022-08-31 17:02:39 +02:00
Josef Nemec
15d5b5b2af Possible null reference when creating windows from designer 2022-08-31 17:02:39 +02:00
Josef Nemec
087f65677d Case sensitivity fixes for playlist file handling during emulation scan 2022-08-31 17:02:39 +02:00
Josef Nemec
8197dfc201 Tweaks to Toolbox and plugin creation 2022-08-31 17:02:39 +02:00
Josef Nemec
08b2274890 English language localization file generated with plugin templates 2022-08-31 17:02:39 +02:00
Josef Nemec
c8b650286c Doc updates 2022-08-31 17:02:39 +02:00
Josef Nemec
c21203a93d New: Option to start on boot closed to tray 2022-08-31 17:02:39 +02:00
Josef Nemec
b3f31b0b84 Some play actions can be launched in an unsupported way from game menu 2022-08-31 17:02:39 +02:00
Josef Nemec
773217b579 Some script variables are not generated for emulator and test scripts 2022-08-31 17:02:39 +02:00
LemmusLemmus
c9c59d039e
Fix typos (#3023) 2022-08-24 17:25:03 +02:00
Brandon
e67ba59baf
Add Rosalie's Mupen GUI emulator profile (#3030) 2022-08-24 15:04:21 +02:00
Brandon
5224edbd35
Fix not possible to use TextWrap in CheckBox control (#3009)
* Fix not possible to use TextWrap in CheckBox control

* Set DockPanel.Dock
2022-08-24 15:02:06 +02:00
Jeshibu
61286e0eeb
Made Version field filter case insensitive (#3027)
* Made Version field filter case insensitive

* Made version filtering string comparison ordinal
2022-08-24 11:43:16 +02:00
Josef Nemec
25e1a5b4a1 Doc updates 2022-08-12 12:16:42 +02:00
Josef Nemec
8cc0a8d267 tutorial: C# extension using vscode in windows (#3015)
# Conflicts:
#	doc/tutorials/toc.yml
2022-08-12 11:20:54 +02:00
Alvaro
4f8ffb0278
tutorial: C# extension using vscode in windows (#3015) 2022-08-12 11:18:46 +02:00
Josef Nemec
220480ff7a Directory delete can fail if directory object itself is read-only 2022-07-28 12:08:31 +02:00
Josef Nemec
c41c5194fe Search context description is not visible with themes that use opaque TextBox 2022-07-28 11:08:36 +02:00
Josef Nemec
f1f8c844d3 Metadata settings view doesn't use global style for ToggleButton #3001 2022-07-28 11:04:17 +02:00
Josef Nemec
ade8c682cd Main Desktop view doesn't load properly in design view 2022-07-28 10:57:45 +02:00
Josef Nemec
1b0e6209d4 Don't force WindowStyle on MessageBoxWindow 2022-07-28 10:57:20 +02:00
Josef Nemec
a1268d191f Game selection handling fixes in Desktop mode #2997 2022-07-28 10:47:51 +02:00
Josef Nemec
76ed9c0152 Grid view game details are not populated after clicking on game info button 2022-07-28 10:46:03 +02:00
Josef Nemec
15ebf28f05 Game extension fixes related to platform handling 2022-07-28 10:29:11 +02:00
Josef Nemec
2fb2c98c68 Better error messaging when starting a process with missing path 2022-07-28 09:43:38 +02:00
Josef Nemec
66d71f6ed0 Fixed default DuckStation emulator arguments 2022-07-28 09:36:05 +02:00
Josef Nemec
89208035bc Removed unsused string 2022-07-28 09:29:00 +02:00
Brandon
b8b76e6584
Update game LastActivity, PlayCount and Completion Status on Running state instead or Launching (#2975) 2022-07-23 10:57:55 +02:00
Jeshibu
b17555e3a2
Sortable name autofill tweaks (#2977)
* SortableNameConverter: tweaked for X-Wing and Daemon X Machina

* SortableNameConverter: excluded Mega Man X Legacy Collection

* SortableNameConverter: ignored loose L/C/D/M/DC/DX numerals

* SortableNameConverter: fixed "X-word" throwing exception
2022-07-23 10:54:08 +02:00
Josef Nemec
ae57d8a284 Remove event handlers when disposing web views 2022-07-23 10:51:17 +02:00
Brandon
34ad611fb1
Add StringToUpperCaseConverter (#2987) 2022-07-23 10:15:57 +02:00
Wilted
7e0e2148e1
Fix typo (#2993) 2022-07-23 09:56:44 +02:00
Brandon
3d9a5d64d4
Add platforms to SearchView GameItem subtext (#2976) 2022-07-22 17:27:56 +02:00
Brandon
bbeaffd195
Open details on GridView for SearchView if active view (#2979) 2022-07-22 16:39:48 +02:00
Brandon
f6545534d1
Open details on GridView for Random Game Picker if active view (#2978) 2022-07-22 16:39:16 +02:00
Josef Nemec
5ffc66cf87 Built-in emulator profile list is not sorted when adding new profile to an emulator 2022-07-22 15:23:35 +02:00
Josef Nemec
4904831783 Added identifiers to window instances 2022-07-22 15:20:23 +02:00
Josef Nemec
dafaad9a61 Games started via URL trigger InvokeOnStarted two times #2988 2022-07-22 15:09:12 +02:00
Josef Nemec
eeef95804c Fixed handling of cookie related methods in web views 2022-07-22 14:38:53 +02:00
Josef Nemec
4e17416f86 Typo fix 2022-07-11 10:29:31 +02:00
Josef Nemec
b48e5872f2 P10 SDK changelog 2022-07-07 16:54:00 +02:00
Josef Nemec
23c1b5456a Version bumps to P10 2022-07-07 16:53:49 +02:00
Josef Nemec
d8c0cfa68a ForcePlayTimeSync accidentally removed from settings SDK API 2022-07-07 16:45:02 +02:00
Josef Nemec
f9d6b2208e Updated CefSharp dependency 2022-07-07 13:32:25 +02:00
Josef Nemec
468725179f Polish related to game edit window and save state checkboxes 2022-07-07 12:43:38 +02:00
Josef Nemec
2a4412c6d6 Media downloads via Google Images don't work 2022-07-07 12:08:50 +02:00
Josef Nemec
823e3f1442 Media downloads via Google Images don't work 2022-07-07 11:58:49 +02:00
Josef Nemec
a03ffbc65e 9.19 release 2022-07-07 10:32:28 +02:00
Josef Nemec
86194038e8 Media downloads via Google Images don't work 2022-07-07 10:29:02 +02:00
Josef Nemec
4982133062 Fixed null bindings on GoogleImageDownloadWindow 2022-07-07 10:25:13 +02:00
Josef Nemec
c24966d211 Media downloads via Google Images don't work 2022-07-07 10:24:01 +02:00
Josef Nemec
18edc9aa65 Typo fixes 2022-07-07 10:22:45 +02:00
Josef Nemec
62112bb4d5 Fullscreen filter panel doesn't focus properly when opened for the first time 2022-07-06 18:31:00 +02:00
Josef Nemec
bd3a4a125f Filter panel in Fullscreen mode doesn't scroll properly when using big font size #2588 2022-07-06 18:27:23 +02:00
Josef Nemec
f0b0039989 Filter presets are not scrolled into view when switching them in Fullscreen mode #2931 2022-07-06 17:25:26 +02:00
Josef Nemec
56f6f0f54b Some fullscreen views can't be closed using Backspace key 2022-07-06 12:38:35 +02:00
Josef Nemec
8976d7a3d6 Include help links in global search 2022-07-06 12:37:59 +02:00
Josef Nemec
4c73fa2ac5 Additional info for UWP app list failure 2022-07-06 12:37:47 +02:00
Josef Nemec
ffdfbdfcf0 Changed default smooth scrolling settings 2022-07-06 12:37:24 +02:00
Josef Nemec
c5962da43d Doc update 2022-07-06 11:15:27 +02:00
Josef Nemec
f2418eb7ca New: Library backup and restore #912 2022-07-05 18:55:38 +02:00
Josef Nemec
8e19a94c80 Doc fixes 2022-07-05 16:14:17 +02:00
Josef Nemec
5a53d97816 Better handling of desktop settings page indexes 2022-06-27 13:18:26 +02:00
Josef Nemec
4630dbbcab Some search items loose icons when navigating from nested search context 2022-06-27 13:17:40 +02:00
Josef Nemec
007261dd71 Small tweak to GetFullscreenItemSpacingMargin 2022-06-27 12:26:56 +02:00
Josef Nemec
9119a70233 Allow for more space between game covers in Fullscreen mode #2958 2022-06-27 12:24:12 +02:00
Josef Nemec
709a48adc2 Fix: Extension installation prompt is opened in the background #2957 2022-06-27 12:06:19 +02:00
Josef Nemec
dfb7375d3c Various global search fixes and improvements 2022-06-27 12:05:50 +02:00
Josef Nemec
d5a716b27e Global search SDK docs 2022-06-27 11:57:36 +02:00
Josef Nemec
f1326ae995 Block major version update on 32bit systems 2022-06-27 11:28:07 +02:00
Josef Nemec
c8b8c7e47d Deadlock in http downloader 2022-06-27 11:25:01 +02:00
Josef Nemec
df622595df Added missing SDK comments 2022-06-14 17:48:22 +02:00
Josef Nemec
7350fba5f7 Show game link URL in global search results 2022-06-14 17:48:09 +02:00
Josef Nemec
346db4bd57 Removed unused field 2022-06-13 19:28:24 +02:00
Josef Nemec
7afd1afe50 Adjusted background image load delay in Desktop mode 2022-06-13 18:02:02 +02:00
Josef Nemec
1bd1adf606 Added doc for buffer db updates 2022-06-13 17:44:08 +02:00
Josef Nemec
11e6c8ff0c Option to go to game details from random game selection dialog #2954 2022-06-13 16:05:55 +02:00
Josef Nemec
69d44436d4 Crash when selecting filter preset in Fullscreen mode 2022-06-13 16:05:25 +02:00
Josef Nemec
4b4b061b56 Mark currently assigned completion status when chaning it via game menu #2953 2022-06-13 15:40:13 +02:00
Josef Nemec
d9acdc249e Partially reverted adc6846a8d54ef18740f973acada4a5dd6f5be1c because it could cause slowdowns in UI when some extensions update items in DB
Will be properly fixed after move to .NET 6
2022-06-13 15:36:41 +02:00
Josef Nemec
89ff94b8a4 Close search window just by clicking outside of it 2022-06-13 14:06:04 +02:00
Josef Nemec
3ad410738d Unified buffer update methods in database API 2022-06-13 12:17:06 +02:00
Josef Nemec
9afd846369 Some menu actions start with @ in global search 2022-06-11 15:03:38 +02:00
Josef Nemec
6dc213ef1f English string update 2022-06-11 12:13:17 +02:00
Josef Nemec
50e90b49a8 Fixes and improvements to global search based on darklinkpower's TED talk 2022-06-10 22:25:31 +02:00
Josef Nemec
42f34ee8f1 Saved window position is not properly constrained to connected displays if DPI changes 2022-06-10 15:42:17 +02:00
Josef Nemec
e3bf7c1f1e Highlight selected range on sliders 2022-06-10 12:18:01 +02:00
Josef Nemec
3a4c04abdd Fixed scrollbar shenanigans on settings window 2022-06-09 17:42:34 +02:00
Josef Nemec
56d09a4a29 TGA metadata files are not properly converted on import 2022-06-09 12:14:45 +02:00
Josef Nemec
fe0b7af137 Grid View items disappear before they are fully out of view while scrolling #2923 2022-06-08 16:28:41 +02:00
Josef Nemec
2d78f3e637 Game list doesn't update properly after switching filter preset in Fullscreen mode #2583 2022-06-07 18:52:01 +02:00
Josef Nemec
e0de8c1dce Updated timings for Fullscreen smooth scrolling 2022-06-07 18:35:47 +02:00
Josef Nemec
a7094ad550 Support .WUA extension for Cemu (Wii U) emulator #2949 2022-06-07 13:42:48 +02:00
Josef Nemec
46a403af6a Fix: Details view scroll position doesn't reset on game selection change 2022-06-07 13:41:07 +02:00
Josef Nemec
52f87a589d FIx: Cursor position jumping around under specific conditions #2663 2022-06-07 13:35:00 +02:00
Josef Nemec
6b760441bd Don't show split option when importing emulated games with only one rom detected 2022-06-07 12:26:02 +02:00
Josef Nemec
1815f6b1eb Option to override platform assignment on emulation scanner #2598 2022-06-07 12:21:39 +02:00
Josef Nemec
512b816bc5 Removed obsolete property 2022-06-07 09:50:33 +02:00
Josef Nemec
b85221fef4 {EmulatorDir} variable not expanded in emulator scripts 2022-06-06 15:01:57 +02:00
Josef Nemec
76282796f2 License file being overwritten with one from dependencies 2022-06-06 14:42:50 +02:00
Josef Nemec
659a7e4780 Library update process and events are executed on startup even when no update actually takes place 2022-06-06 14:33:05 +02:00
Josef Nemec
e390aad518 New: Exclusion list support for emulation scanners #2691 2022-06-06 14:27:01 +02:00
Josef Nemec
21b51226c7 Reset game selection after switching views to keep P9 behaviour 2022-06-02 11:53:51 +02:00
Josef Nemec
f31d75386b Roms property in GamesCollectionViewEntry #2942 2022-06-02 11:25:47 +02:00
Josef Nemec
8339c02fd0 SDK: Added access to window host for web views #2940 2022-06-02 11:22:30 +02:00
Josef Nemec
adc6846a8d Some game menu actions are very slow on large number of games 2022-05-30 21:21:32 +02:00
Josef Nemec
9c414df219 New: Option to open filter preset selection via Left Stick button or R key 2022-05-30 19:22:03 +02:00
Josef Nemec
2c7fa9455e Font preview when selecting application fonts #2323 2022-05-30 19:10:43 +02:00
Josef Nemec
e666fed4b7 Loading list of available languages is too slow 2022-05-30 19:09:37 +02:00
Josef Nemec
1989c5e035 ComboBox is unable to virtualize its items list 2022-05-30 19:00:29 +02:00
Josef Nemec
c7e7df5ab0 Better visual indicator of selected item for filter preset panel in Fullscreen mode #2927 2022-05-30 17:26:23 +02:00
Josef Nemec
1fdbdf1746 New: Smooth scrolling for game lists #835 2022-05-30 17:04:17 +02:00
Josef Nemec
13367e3f4f Fixed to keyboard handling on AboutWindow 2022-05-30 15:27:04 +02:00
Josef Nemec
4394293e8c Fixed startup arguments for QT version of PCSX2 #2934 2022-05-30 14:09:48 +02:00
Josef Nemec
440769047d SDK: Added option to cancel game launch during OnGameStarting event #2930 2022-05-30 14:07:42 +02:00
Josef Nemec
0684bc563a Extension package verification fix 2022-05-30 13:47:46 +02:00
Josef Nemec
80d526c896 New: Global search view #1413 2022-05-30 13:45:32 +02:00
Brandon
d73c886f1b
Ignore config, redistributables and game engine executables during executables scan #2919 (#2920) 2022-05-20 09:54:02 +02:00
Josef Nemec
cb99606805 Smooth scrolling work in progress 2022-05-16 11:46:44 +02:00
Josef Nemec
11c5c311a2 Scrollviewers don't work properly on settings window 2022-05-16 10:33:40 +02:00
Josef Nemec
9ead1e94a4 Inverted confirmation/back button settings are not applied on some panels 2022-05-13 11:37:28 +02:00
Josef Nemec
188cb57964 New: Option to assign game fields in Fullscreen mode 2022-05-13 11:06:18 +02:00
Josef Nemec
f532e4933a Better detection of improperly packaged addons 2022-05-12 16:15:15 +02:00
Josef Nemec
d33a96a595 Removed temporary debug messages 2022-05-12 13:27:58 +02:00
Josef Nemec
f1a0755b63 Don't include duplicate games (from multiple groups) in OnGameSelected event 2022-05-12 13:26:47 +02:00
Josef Nemec
106fc48114 Fixed broken Blend previews 2022-05-12 10:51:39 +02:00
Josef Nemec
4e82a31d56 Refactoring of game selection bindings in Desktop mode 2022-05-11 23:01:33 +02:00
Josef Nemec
95ba4fad16 Window event handlers in WindowFactory not being removed 2022-05-11 11:41:29 +02:00
Josef Nemec
d94a2555c9 Action selection dialog refactoring 2022-05-11 11:40:57 +02:00
Josef Nemec
e6367eb61d OnGameStopped event not being called when launching is manually cancelled #2882 2022-05-10 10:28:45 +02:00
Josef Nemec
a690eef012 Pass information to OnGameStopped event whether game tracking was cancelled manually 2022-05-09 20:50:41 +02:00
Josef Nemec
8f4e34f7da New: Menu to set completion status in Fullscreen mode #2353 2022-05-09 15:24:58 +02:00
Josef Nemec
c31ceddf6f New: Added BGB emulator profiles #2829 2022-05-09 13:48:08 +02:00
Josef Nemec
50a28feea7 Updated CEF init error message 2022-05-09 12:48:57 +02:00
Josef Nemec
eb7433e993 CEF load failure is not properly handled 2022-05-09 12:43:39 +02:00
Josef Nemec
98fe3740ed Fix: Fullscreen mode doesn't adjust properly to screen resolution changes #2714 2022-05-09 12:32:57 +02:00
Josef Nemec
285d2bbeaf Fix: Sidebar doesn't update properly without re-launching Playnite #2571 2022-05-09 11:52:34 +02:00
Josef Nemec
9f7086698a Updated "get more themes" link #2906 2022-05-09 10:19:33 +02:00
Josef Nemec
8db6599e16 Option to create new completion status from game edit window 2022-05-08 17:22:06 +02:00
Josef Nemec
6f0ca4b654 Windows version detection not working correctly #2917 2022-05-08 13:43:29 +02:00
Josef Nemec
207fbd39a7 Merge branch 'master' into devel
# Conflicts:
#	source/Playnite.DesktopApp/Controls/GridViewPanel.cs
2022-05-08 10:54:59 +02:00
Josef Nemec
0f5538cb32 Updated localizations 2022-05-06 12:07:23 +02:00
Josef Nemec
29d3d0cde9 9.18 version bump 2022-05-06 12:03:42 +02:00
Josef Nemec
55f642f802 Fix: Grid view rendering glitches when grouping is enabled #2527 2022-05-06 11:27:33 +02:00
Josef Nemec
8275bda346 Crash when removing games while grouping is enabled 2022-05-06 11:27:25 +02:00
Josef Nemec
a8b0aa0034 Updated CefSharp 2022-05-06 11:26:55 +02:00
Josef Nemec
bd07350136 Updated CefSharp 2022-05-05 17:31:28 +02:00
Josef Nemec
8cc176bc83 Wrong window instance handling when showing non-modal window 2022-05-05 16:33:03 +02:00
Josef Nemec
23b4d96b2d New: Option to exclude hidden games on statistics view #2890 2022-05-05 12:39:32 +02:00
Josef Nemec
1ba76f3d77 Fix: {InstallDirName} variable is not expanded properly in some cases #2860 2022-05-05 12:24:31 +02:00
Josef Nemec
70940ed52e Crash when removing games while grouping is enabled (fix for fix) 2022-05-04 21:06:17 +02:00
Josef Nemec
a4495dcc41 Added DatabaseObject EqualsTest 2022-05-04 15:28:17 +02:00
Josef Nemec
7c6c11497e Fixed comment 2022-05-04 15:24:01 +02:00
Josef Nemec
a4ace08da0 Fix: Grid view rendering glitches when grouping is enabled #2527 2022-05-04 15:22:50 +02:00
Josef Nemec
42bfd94c5e Crash when removing games while grouping is enabled 2022-05-04 14:37:14 +02:00
Josef Nemec
ceb69b0e58 Performance optimization to library filter 2022-05-04 13:26:16 +02:00
Josef Nemec
77352deb0b Better handling of m3u files when scanning emulated games 2022-05-03 14:21:21 +02:00
Josef Nemec
308dfce73d Trim ROM file type names when scanning emulated games 2022-05-03 12:52:39 +02:00
Josef Nemec
1e996a0877 Refactoring to Desktop's game menu 2022-05-03 12:18:36 +02:00
Josef Nemec
07f9eb8114 Merge remote-tracking branch 'origin/master' into devel
# Conflicts:
#	source/Playnite/Database/GameDatabase.cs
#	source/Playnite/Emulation/Emulators/PCSX2/emulator.yaml
2022-05-03 11:54:13 +02:00
Josef Nemec
8bafed434c Removed settings load error handling that never worked properly 2022-05-02 20:39:26 +02:00
Josef Nemec
3cb88a26e9 Notifications not working Fullscreen mode 2022-05-02 19:55:56 +02:00
Josef Nemec
ebef613735 Fallback emu game detection using ROM file name as game serial 2022-05-02 18:24:16 +02:00
Josef Nemec
5549a86c37 Better handling of emulated game files stored in long paths (260+ chars) 2022-05-02 17:35:04 +02:00
Josef Nemec
5901a83512 Added gdi file type to NullDC profile 2022-05-02 17:19:33 +02:00
Josef Nemec
c17018f17b Don't allow installation of themes that include Playnite binaries 2022-05-02 15:32:07 +02:00
Josef Nemec
8087fc3a3d SDK: Added parameterless versions of InvokeOnUninstalled and InvokeOnStarted methods 2022-05-02 15:24:15 +02:00
Josef Nemec
e4b66a0b2d Installer: Don't allow installation into Program Files 2022-05-02 15:03:44 +02:00
Josef Nemec
e7460cb47e SDK: Exposed UI thread's dispatcher 2022-05-02 14:56:13 +02:00
Josef Nemec
14da669c64 New: Skip library update on startup if not connected to the Internet 2022-05-02 14:03:57 +02:00
Josef Nemec
f5c42ce133 Moved system tray option to General section 2022-05-02 13:08:31 +02:00
Josef Nemec
a296279ca9 Removed obsolete settings sections 2022-05-02 13:05:07 +02:00
Josef Nemec
dc115b0509 New: Options to control update check behaviour 2022-05-02 13:01:49 +02:00
Josef Nemec
9a331db707 Keyboard navigation on action selection dialog in Desktop mode #2786 2022-04-29 13:13:41 +02:00
Josef Nemec
6ddf09e52e SDK: Support for themes to use localized resources like extensions 2022-04-29 13:12:12 +02:00
Josef Nemec
1f8be488c0 Small tweak to addons update view 2022-04-28 19:23:51 +02:00
Josef Nemec
4a6fe7144e New: Option to disable scan of archives during emulation import 2022-04-28 19:15:08 +02:00
Josef Nemec
90f855cd7a New: Option to exclude subfolders from emulation scan #2574 2022-04-28 16:53:36 +02:00
Josef Nemec
b515bd62dc New: Option to hide game name from details panels 2022-04-28 15:20:40 +02:00
Josef Nemec
1ff4d7b80d Pass StartedProcessId to game scripts 2022-04-28 15:09:38 +02:00
Josef Nemec
e73af0b0a3 New: Option to restart in safe mode from Fullscreen mode 2022-04-28 14:43:07 +02:00
Josef Nemec
69b039d132 Small refactor in manifest files 2022-04-27 10:31:16 +02:00
Josef Nemec
f03f113c34 Updated docs 2022-04-22 15:36:43 +02:00
Josef Nemec
93c776513a 9.17 version bump 2022-04-21 16:03:44 +02:00
Josef Nemec
77139db532 Updated localizations 2022-04-21 16:00:18 +02:00
Josef Nemec
6d68174f42 Selecting a game is laggy after switching views #2812 2022-04-21 15:55:15 +02:00
Jeshibu
c9ad3a3b28
Made "last played" update when the library indicates a later last played date and "Prioritize play time for supported libraries" is enabled (#2891) 2022-04-21 15:54:38 +02:00
Josef Nemec
248d0a7439 ProcessMonitor is not handling failures correctly 2022-04-21 15:53:03 +02:00
Josef Nemec
2b0d4a4732 Crash stack failing to be parsed 2022-04-21 15:53:03 +02:00
Josef Nemec
9f38af9d2f Crash when opening game menu in Fullscreen mode via mouse 2022-04-21 15:53:03 +02:00
Josef Nemec
dcbed19fcf Crash when loading theme file reference 2022-04-21 15:53:03 +02:00
Josef Nemec
a6b6caa1d5
Update config.yml 2022-04-20 23:08:13 +02:00
Josef Nemec
1bfc74d8f9 Crash when adding new game 2022-04-20 20:41:28 +02:00
Josef Nemec
95d4aab90a Add actual Windows version (not Microsoft's made up one) to diag package 2022-04-20 20:07:51 +02:00
Josef Nemec
572e2363da Crash when restarting Playnite 2022-04-20 20:00:30 +02:00
Josef Nemec
e9e85d0789 Add info about elevated permissions into diag package 2022-04-20 19:57:28 +02:00
Josef Nemec
d4eaf11cde Fix: List view columns can be accidentally hidden by resizing #2257 2022-04-20 19:47:01 +02:00
Josef Nemec
ad33cf6a31 Fix: Play actions keep reappearing after being removed from already imported games #2718
# Conflicts:
#	source/Playnite/Database/GameDatabase.cs
2022-04-20 19:46:34 +02:00
Josef Nemec
31602a43fe Filter invalid classname characters #2835 2022-04-20 18:21:23 +02:00
Josef Nemec
9d66fa2056 Fix: Bulk metadata import not updating game name #2482 2022-04-20 13:11:07 +02:00
Josef Nemec
0aa89af583 New: PCSX2 nightly and dev emulator profiles #2871 2022-04-20 12:30:43 +02:00
Josef Nemec
0024a78b59 Fix: Playnite crashes when closing progress dialog using ATL-F4 or via window menu #2883 2022-04-20 12:11:54 +02:00
Josef Nemec
165f35dc2b Game edit clean up related to "save changes" checkboxes 2022-04-19 16:50:47 +02:00
Josef Nemec
8c4f763163 Removed remnants of wikipedia metadata provider 2022-04-19 16:07:58 +02:00
Josef Nemec
e71d605693 New: Option to override installation status on automatically imported games #2879 2022-04-19 16:06:41 +02:00
Josef Nemec
0051721dfb Removed JsonRpcClient 2022-04-19 10:11:43 +02:00
Josef Nemec
7d022f490a Small GetFinalPathName improvement 2022-04-19 10:10:47 +02:00
Brandon
87a8dfff81
Rever issues checkboxes (#2880)
* Update bug_report.yml

* Update feature_request.yml
2022-04-06 18:38:57 +02:00
Brandon
8ad0f5647d
Update issues template to use checkboxes (#2878)
* Update feature_request.yml

* Update feature_request.yml

* Update feature_request.yml

* Update bug_report.yml
2022-04-05 20:44:45 +02:00
Josef Nemec
6e7d3b043f Doc updates 2022-04-04 18:36:50 +02:00
Brandon
eb19fcb579
Playtime sync rework (#2821) 2022-03-14 20:59:16 +01:00
Josef Nemec
81bfa113d5 Fix: Restoring existing Fullscreen instance by starting its executable doesn't properly focus on opened views #2781 2022-03-14 13:24:26 +01:00
Josef Nemec
ed9edd305a Merge branch 'master' into devel 2022-03-14 13:13:54 +01:00
Josef Nemec
a77f8c3e5f doc update 2022-03-14 13:10:37 +01:00
Josef Nemec
f83d555683 Revert "New: Option to swap A/B gamepad bindings in Fullscreen mode #2003"
This reverts commit 0554b725d1e59c9e6b58df2e01074ad02c3df2c4.
2022-03-14 13:08:03 +01:00
Josef Nemec
877480bbf2 Revert "SDK: Started process ID can be passed to OnGameStarted event #2751"
This reverts commit 1722e16892334902601366c54ab6592205903bd3.
2022-03-14 13:07:46 +01:00
Josef Nemec
8583eede87 New: "Choose on startup" option for emulator play actions also available on emulator level 2022-03-14 13:06:52 +01:00
Josef Nemec
6831b351d5 Proper CopyDiffTo test implementation on all classes 2022-03-03 15:04:10 +01:00
Josef Nemec
a564e2c9fa LOC constants updates 2022-03-03 10:26:05 +01:00
Josef Nemec
0bbb056ff8 Better keyboard input support on Fullscreen mode's text input dialog 2022-03-02 14:41:49 +01:00
Josef Nemec
189b005689 Use Source Url in manifest file in addon database as a weblink to the sources #2551 2022-03-02 14:12:13 +01:00
Josef Nemec
c060288502 Revert "SDK: Web view isolation for each extension"
This reverts commit d209e07bfec3bfc8393e5dea8268fdef79fbaeb7.
2022-03-02 13:45:39 +01:00
Josef Nemec
b0250bd764 New: Option for Xbox / Guide controller button to restore Fullscreen mode #1527 2022-03-02 10:38:30 +01:00
Josef Nemec
6d108e3fd6 New: Option to only accept inputs from primary gamepad #1755 2022-03-01 17:41:09 +01:00
Josef Nemec
90e099601a Added m3u as supported file type to sum emulation profiles #2570 2022-03-01 17:01:03 +01:00
Josef Nemec
77fdd28c9a Added m3u as supported file type to sum emulation profiles #2570 2022-03-01 17:00:35 +01:00
Josef Nemec
2b53707d36 Space button binding for Fullscreen text input #2575 2022-03-01 16:01:51 +01:00
Josef Nemec
85ce9267a1 Better handling of multi-disk ROM names #2573 2022-03-01 13:15:47 +01:00
Josef Nemec
460906990c Small refactoring related to directory path handling 2022-03-01 09:14:17 +01:00
Josef Nemec
67c8958f46 Import manually added games with Play action pointing to exe's full path 2022-02-28 18:07:41 +01:00
Josef Nemec
b098aca69f Import emulators using relative paths if possible 2022-02-28 17:51:21 +01:00
Josef Nemec
73e7a95ab1 New: Option to import emulated games under related file paths (enabled by default) 2022-02-28 17:13:40 +01:00
Josef Nemec
b857d57348 added TestApp 2022-02-23 17:17:18 +01:00
Josef Nemec
1a761e90b8 Small refactoring of long path handling 2022-02-23 17:16:37 +01:00
Josef Nemec
7be345a286 Fix: Importing emulated games from UNC shares doesn't work properly #2697 2022-02-23 11:36:59 +01:00
Josef Nemec
5ca6f0c428 Crash when assigning emulator play action 2022-02-22 15:45:45 +01:00
Josef Nemec
d015e44b90 Fix: Some game variables are not expanded properly in emulator configuration strings #2726 2022-02-22 15:45:22 +01:00
Josef Nemec
8fb8ca4bcf Fix: Launching a game via random selection dialog can lead to wrong game being shown as running #2723 2022-02-22 14:05:18 +01:00
Josef Nemec
f9e23b8d73 Fix: Scrolling performance in Fullscreen mode slows down after opening game details for the first time #2739 2022-02-21 15:31:47 +01:00
Josef Nemec
2e911e99c7 Fix: Games show wrong background image when scrolling through game list quickly #2348 2022-02-21 15:07:59 +01:00
Josef Nemec
fd4397f5f6 Merge branch 'master' into devel
# Conflicts:
#	source/Playnite.DesktopApp/ViewModels/DesktopAppViewModel.cs
#	source/Playnite.FullscreenApp/ViewModels/FullscreenAppViewModel.cs
2022-02-18 13:15:35 +01:00
Josef Nemec
1722e16892 SDK: Started process ID can be passed to OnGameStarted event #2751 2022-02-18 13:14:35 +01:00
Josef Nemec
0554b725d1 New: Option to swap A/B gamepad bindings in Fullscreen mode #2003 2022-02-17 20:09:42 +01:00
Josef Nemec
35727c405a 9.16 version bump 2022-02-15 11:40:31 +01:00
Josef Nemec
6eeff82211 Updated localizations 2022-02-15 11:19:08 +01:00
Josef Nemec
0878dae889 Updated emulator profiles 2022-02-15 11:11:44 +01:00
Josef Nemec
d41a6a2ff7 Optimizations to how view entry properties are loaded and updated 2022-02-15 11:04:16 +01:00
Josef Nemec
8a0b231362 Fix: Clicking in the empty area of the zoom moves the bar but doesn't change zoom #2597 2022-02-15 10:09:35 +01:00
Josef Nemec
442007ae66 Fix: Clicking empty part of horizontal scrollbar moves view vertically #2749 2022-02-15 09:59:38 +01:00
Josef Nemec
cde8de80af Selecting a game is laggy after switching views #2812 2022-02-14 18:44:04 +01:00
Josef Nemec
42e331c57d Fix: No "Select Sound" is played when selecting a game with the mouse in Fullscreen mode #2434 2022-02-14 16:45:56 +01:00
Josef Nemec
d2f46970f0 Fix: List view columns can be accidentally hidden by resizing #2257 2022-02-14 16:25:16 +01:00
Josef Nemec
4a8efd6ba4 Fix: Play actions keep reappearing after being removed from already imported games #2718 2022-02-14 16:08:10 +01:00
Josef Nemec
34b06255cc Library updates trigger an ItemCollectionChanged event for each game #266 2022-02-14 16:03:08 +01:00
Josef Nemec
3e378ae28d Small tests refactoring 2022-02-14 14:24:26 +01:00
Josef Nemec
9077258e1b Fix: Emulator Scanner Does Not Pick Up ROMs With Double Extensions (i.e. the PICO-8 "p8.png" format) #2768 2022-02-14 14:24:22 +01:00
Josef Nemec
73fb67b1f3 Updated emulator profiles 2022-02-14 10:03:02 +01:00
UrbanCMC
9a1424a076
Parse doubles according to user culture (#2793)
* Parse doubles according to current culture

* Restore unused usings
2022-02-13 12:02:31 +01:00
Josef Nemec
044518ee53 Doc update 2022-02-09 20:08:37 +01:00
Josef Nemec
d209e07bfe SDK: Web view isolation for each extension 2022-02-09 20:08:31 +01:00
Josef Nemec
72aedcc758 Playnite API instance handling refactoring 2022-02-09 14:18:50 +01:00
Josef Nemec
ce1dbe28cc SDK: Changed default user agent for web views 2022-02-08 17:32:22 +01:00
Josef Nemec
ff13c8c3e9 Enable display of group items count by default 2022-02-08 16:41:15 +01:00
UrbanCMC
67ded8f8cb
Fix typo in 'IsUninstalling' property name (#2794) 2022-02-08 16:27:18 +01:00
Josef Nemec
a416f22c0b Optimizations to how view entry properties are loaded and updated 2022-02-08 11:35:18 +01:00
Josef Nemec
f2f8bd69ab StartGame API method doesn't work when launched from custom thread 2022-02-08 10:47:52 +01:00
Josef Nemec
4b99faf902 Small log fix 2022-02-08 08:34:45 +01:00
Josef Nemec
56f7ec13dc Import exclusion list as DataGrid with sorting 2022-02-07 11:01:18 +01:00
Josef Nemec
8301e60cc1 Disable major version updates on Windows 7 and 8 #2666 2022-02-05 14:23:05 +01:00
Josef Nemec
f098292de9 Show error when packaging extension without manifest file 2022-02-05 14:05:07 +01:00
Josef Nemec
741572c373 Themes: Control gallery available in Blend 2022-02-04 14:13:53 +01:00
Josef Nemec
1ff77d0618 New: Quality of life improvements to metadata download configuration window 2022-02-03 15:20:24 +01:00
Josef Nemec
4b2e44622a Cleanup in progress dialog usage 2022-02-02 18:42:38 +01:00
Josef Nemec
6331beb7b2 Some serialization tests 2022-02-02 13:33:38 +01:00
Josef Nemec
1ee2b711f8 SDK: Try* data serialization methods now have overload that returns serialization error 2022-02-01 10:25:05 +01:00
Josef Nemec
dbf5723470 New: Added game tracking mode that only tracks originally started process 2022-01-31 13:26:32 +01:00
Josef Nemec
571b8f93d5 New: Launching specific mode executable switches existing instance to that mode 2022-01-30 14:45:09 +01:00
Josef Nemec
015d3203fe New: Option to define startup and shutdown application scripts 2022-01-29 15:54:51 +01:00
Josef Nemec
61dc95df16 Merge branch 'master' into devel
# Conflicts:
#	source/Playnite/Localization/LocalizationKeys.cs
2022-01-28 21:26:04 +01:00
Josef Nemec
aa93a0c7c1 SDK: filter settings exposed in SDK 2022-01-28 21:24:48 +01:00
Josef Nemec
4c955d50fb Removed unused wikipedia metadata provider 2022-01-28 21:23:36 +01:00
Josef Nemec
1de9d49ad3 Removed unused wikipedia metadata provider 2022-01-28 21:23:36 +01:00
Josef Nemec
950be21db0 Removed unused strings 2022-01-26 11:52:20 +01:00
Josef Nemec
52e7140ea2 Removed unused strings 2022-01-25 10:51:35 +01:00
Josef Nemec
3daa4b01f0 Removed unused strings 2022-01-25 10:47:46 +01:00
Josef Nemec
20ff365bf0 Removed unused strings 2022-01-24 16:40:56 +01:00
Josef Nemec
00bb9440e1 Doc update 2022-01-24 11:51:51 +01:00
Josef Nemec
a89475b5f1 9.15 version bump 2022-01-24 11:42:06 +01:00
Josef Nemec
b243ccc8ec Localization updates 2022-01-24 09:39:13 +01:00
Josef Nemec
eabadf617b SDK version bump 2022-01-23 18:45:54 +01:00
Josef Nemec
0b22eeeed3 Fix: OnGameStopped stopped event is called too early #2634 2022-01-23 18:45:44 +01:00
Josef Nemec
85ec0a5529 Fix: Folder scan ignores some executables incorrectly #2766 2022-01-23 17:29:00 +01:00
Josef Nemec
ae832a90b8 Doc updates 2022-01-23 17:25:38 +01:00
Josef Nemec
e402d81301 Doc updates 2022-01-23 17:17:29 +01:00
Josef Nemec
1529482cee Fix: Crash when filtering only assigned items on game edit dialog 2022-01-23 17:09:36 +01:00
Josef Nemec
d5e0472d76 Comment change 2022-01-23 17:02:36 +01:00
Josef Nemec
b44a515f58 Small test plugin change 2022-01-23 17:02:22 +01:00
Josef Nemec
bd8c75078a Fix: Switching application modes doesn't work properly when switching during library update 2022-01-21 18:41:20 +01:00
Josef Nemec
5ef02ad277 Fix: Crash when renaming library fields 2022-01-21 11:59:59 +01:00
Josef Nemec
9c3dd524d0 Fix: Crash if sidebar related resources are missing 2022-01-21 11:48:34 +01:00
Josef Nemec
9377328cd6 Fix: Possible delay or deadlock when shutting down Playnite externally 2022-01-21 11:38:07 +01:00
Josef Nemec
ae3c14bfab Fix: Creating OffscreenWebView from SDK with custom user agent fails 2022-01-21 10:33:30 +01:00
Josef Nemec
bd8e2c5bc3 Platform name fix 2022-01-21 10:25:26 +01:00
erri120
d59ab132bd Log all exceptions when loading Plugins (#2760)
Assembly.GetTypes() can throw a ReflectionTypeLoadException which
contains all exceptions thrown by the class loader in the
LoaderExceptions property.

Resolves #2758
2022-01-21 09:49:58 +01:00
erri120
ebdd6ca8ff
Log all exceptions when loading Plugins (#2760)
Assembly.GetTypes() can throw a ReflectionTypeLoadException which
contains all exceptions thrown by the class loader in the
LoaderExceptions property.

Resolves #2758
2022-01-20 15:27:03 +01:00
Jeshibu
4743a55d8f
New: Ability to auto-fill the Sorting Name field when importing games (by Jeshibu) 2022-01-15 10:58:51 +01:00
Josef Nemec
4fd8ad68c4 Doc update 2022-01-13 15:07:27 +01:00
Josef Nemec
b5889eb123 Doc update 2022-01-09 11:20:39 +01:00
Josef Nemec
d7a40c8a97 Doc update 2022-01-09 11:16:06 +01:00
Josef Nemec
0b0f3c38bd
Update README.md 2022-01-04 13:41:10 +01:00
Jeshibu
c320280911
Added filter textbox use when "Match all filters" is checked (#2703) 2022-01-03 13:33:44 +01:00
Josef Nemec
9596f6a5fb 9.14 version bump 2021-12-31 11:13:24 +01:00
Josef Nemec
4cf021d998 6.2.1 SDK version bump 2021-12-31 11:11:47 +01:00
Josef Nemec
c270700e69 Updated localizations 2021-12-31 11:10:05 +01:00
Josef Nemec
02328aa2db Fix: Crash when cancelling already cancelled progress dialog 2021-12-31 10:54:42 +01:00
Josef Nemec
58bb31a265 Fix: Possible deadlock when getting WebView cookies using SDK #2733 2021-12-31 10:37:51 +01:00
Josef Nemec
23117b130f Test plugin update 2021-12-31 10:36:54 +01:00
Josef Nemec
e881643b8d Fix: Publisher and Developer info not being saved properly in some cases #2731 2021-12-31 10:25:00 +01:00
Josef Nemec
3e8b6222e1 9.13 version bump 2021-12-29 11:18:22 +01:00
Josef Nemec
47e5c2f849 Fix: Application deadlock when starting add-on installation externally 2021-12-29 11:17:55 +01:00
Josef Nemec
5a0d41cb21 Fix: 3rd party clients menu fails to load completely if some plugins fails to provide data for it #2717 2021-12-20 12:39:00 +01:00
Josef Nemec
deda98f223 Small refactor in manifest files 2021-12-20 12:38:02 +01:00
Josef Nemec
5544b34716 Merge branch 'master' into devel 2021-12-18 11:42:16 +01:00
Josef Nemec
49cbcd6aa3 9.12 version bump 2021-12-17 09:36:55 +01:00
Josef Nemec
d08dcc0440 Fix: Possible window freeze when browsing add-ons while network connection to add-on manifests is slow #2680 2021-12-16 14:44:42 +01:00
Josef Nemec
253b47630e Fix: Metadata are downloaded twice first time application is started 2021-12-16 12:14:09 +01:00
Josef Nemec
e579dd8b33 Fix: updated localizations 2021-12-16 12:14:04 +01:00
Josef Nemec
ca585cbad2 Added chd as supported file type for PCSX2 2021-12-16 12:00:55 +01:00
Josef Nemec
9cb4df4571 Fix: Scanning RPCS3 games fails completely if any of games have damaged metadata files 2021-12-16 10:46:03 +01:00
Josef Nemec
aed07c4ed1 Fix: Crash if audio files in Fullscreen mode fail to load properly 2021-12-16 10:30:44 +01:00
Josef Nemec
c11ebbf2d4 Fix: Rare crash when changing view settings in Desktop mode 2021-12-16 10:30:17 +01:00
Josef Nemec
e5f5ed64d4 Fix: Crash when opening game menu in Fullscreen mode 2021-12-16 10:15:22 +01:00
Josef Nemec
49dec948b6
Update bug_report.yml 2021-12-11 12:29:49 +01:00
Josef Nemec
585617c3e9
Update feature_request.yml 2021-12-11 12:29:21 +01:00
Josef Nemec
77270a29f2
Create feature_request.yml 2021-12-11 12:26:32 +01:00
Josef Nemec
48877c8bad
Create bug_report.yml 2021-12-11 12:20:48 +01:00
Josef Nemec
cb0ff5a111 Use default language based on locale settings #906 2021-12-08 10:53:22 +01:00
Josef Nemec
78b120a959 Extension main menu items are listed multiple times #2688 2021-12-05 14:00:07 +01:00
Josef Nemec
d65fd2cd50 Doc update 2021-12-05 13:46:49 +01:00
Josef Nemec
a43dfa0a47 New: Option to start interactive PowerShell console with Playnite SDK #1967 2021-12-05 13:46:42 +01:00
Josef Nemec
e662a4c61c SDK: Added ShowErrorMessage method without caption 2021-12-03 13:18:03 +01:00
Josef Nemec
445d3b0058 Merge branch 'master' into devel 2021-12-03 09:33:44 +01:00
Josef Nemec
6e209dad21 9.11 version bump 2021-12-01 14:03:12 +01:00
Josef Nemec
cb79d854d3 Updated localizations 2021-12-01 14:02:50 +01:00
Josef Nemec
35fb47caa9 Default theme is unnecessarily loaded on startup 2021-12-01 13:56:10 +01:00
Josef Nemec
1c9d59e16f Typo fix 2021-11-30 15:18:40 +01:00
Josef Nemec
2887537efe Fix: Games and emulators using startup scripts don't start properly 2021-11-30 15:17:03 +01:00
Josef Nemec
4b9efd9e6b Fix: Changing Fullscreen settings which require application request doesn't offer restart option 2021-11-30 15:13:41 +01:00
Josef Nemec
b582ed7022 Fix: Theme previews don't work in Blend editor 2021-11-30 11:04:49 +01:00
Josef Nemec
7dc72cfd8a Fix: Updated extension templates to use the latest SDK version 2021-11-30 11:04:25 +01:00
Josef Nemec
b2e3cd443f Fix: Made slight adjustments to Nahimic service warning message 2021-11-30 11:04:02 +01:00
Josef Nemec
b3b9119048 Doc updates 2021-11-29 14:20:42 +01:00
Psycho
0c563827a5
Fixed ILogger's typos (#2660)
There were some small typos in ILogger's descriptions.
2021-11-23 16:31:50 +01:00
802 changed files with 69743 additions and 23738 deletions

1
.github/FUNDING.yml vendored
View File

@ -1,3 +1,4 @@
# These are supported funding model platforms
patreon: playnite
ko_fi: playnite

View File

@ -1,28 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Before creating bug report**
- Please use issue search in the repository first. If the bug is something really obvious there's a high change it was already reported.
- Make sure that the issue is not caused by custom theme or extension. You can restart Playnite in "safe mode" from help menu to quickly test it.
- Check list of known issues https://github.com/JosefNemec/Playnite/wiki/Known-Issues
**Integration issues**
If an issue is related to library integrations, use separate [extensions repository](https://github.com/JosefNemec/PlayniteExtensions) to file a report.
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
If it's not clear from the description how to reproduce the issue please add clear steps to reproduce the behavior.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Diagnostics ID**
Please generate diagnostics package from "About Playnite" menu and attach identifier you received. If the issue is a crash bug, you can generate diag. package directly from crash dialog.

39
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@ -0,0 +1,39 @@
name: Bug report
description: Create a report to help us improve
labels: ['bug']
body:
- type: markdown
attributes:
value: |
**Before creating bug report:**
- Please post in English language only!
- Please use issue search in the repository first. If the bug is something really obvious there's a high change it was already reported.
- Make sure that the issue is not caused by custom theme or extension. You can restart Playnite in "safe mode" from help menu to quickly test it.
- Check list of known issues https://github.com/JosefNemec/Playnite/wiki/Known-Issues
**Integration issues**
If an issue is related to library integrations, use separate [extensions repository](https://github.com/JosefNemec/PlayniteExtensions) to file a report.
- type: textarea
attributes:
label: Bug Description
description: A clear and concise description of what the bug is.
validations:
required: true
- type: textarea
attributes:
label: To Reproduce
description: If it''s not clear from the description how to reproduce the issue please add clear steps to reproduce the behavior.
validations:
required: false
- type: input
attributes:
label: Diagnostics ID
description: 'Please generate diagnostics package from "About Playnite" menu and attach identifier you received. If the issue is a crash bug, you can generate diag. package directly from crash dialog.'
validations:
required: true
- type: textarea
attributes:
label: Screenshots
description: If applicable, add screenshots to help explain your problem.
validations:
required: false

View File

@ -1,8 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Playnite Discord server
url: https://discord.gg/BrtABqe
url: https://playnite.link/discord
about: Official Discord server for general chat and support with Playnite.
- name: Playnite SDK documentation
url: https://playnite.link/docs/
about: Useful documentation when creating pluings and themes.
about: Useful documentation when creating plugins and themes.

View File

@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Integration features**
If a feature request is related to library integrations, use separate [extensions repository](https://github.com/JosefNemec/PlayniteExtensions) to file a request.
**Check for existing issue**
Please use issue search in the repository if your feature request is something really obvious there's a high change it was already requested.
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Screenshots**
If applicable, add screenshots to help explain requested changes.

View File

@ -0,0 +1,26 @@
name: Feature request
description: Suggest an idea for this project
labels: ['enhancement']
body:
- type: markdown
attributes:
value: |
Please post in English language only!
**Integration features**
If a feature request is related to library integrations, use separate [extensions repository](https://github.com/JosefNemec/PlayniteExtensions) to file a request.
**Check for existing issue**
Please use issue search in the repository if your feature request is something really obvious there's a high change it was already requested.
- type: textarea
attributes:
label: Feature description
description: A clear and concise description of feature you want to be added.
validations:
required: true
- type: textarea
attributes:
label: Screenshots
description: If applicable, add screenshots to help explain requested changes.
validations:
required: false

View File

@ -1,4 +1,3 @@
I have verified that:
- [ ] These changes work, by building the application and testing them.
- [ ] Pull request is targeting `devel` branch.
- [ ] I added myself into [contributors file](https://github.com/JosefNemec/Playnite/blob/devel/source/Playnite.DesktopApp/Resources/contributors.txt) if I want to receive contribution credit in the application itself.
Pull requests are generally on pause because majority of code base is being rewritten for Playnite 11.
Smaller "safe" changes for P10 might get accepted based on what they and if they come with test coverage. If you plan to work on bigger changes, please discuss it first in related issue or on Discord, thank you.

View File

@ -1,6 +1,6 @@
# <img src="https://playnite.link/applogo.png" width="32"> Playnite [![Crowdin](https://badges.crowdin.net/playnite/localized.svg)](https://crowdin.com/project/playnite)
An open source video game library manager and launcher with support for 3rd party libraries like Steam, GOG, Origin, Battle.net and Uplay. Includes game emulation support, providing one unified interface for your games.
An open source video game library manager and launcher with support for 3rd party libraries like Steam, Epic, GOG, EA App, Battle.net and [others](https://playnite.link/addons.html). Includes game emulation support, providing one unified interface for your games.
Screenshots are available at the [Homepage](http://playnite.link/)
@ -16,43 +16,44 @@ Download
Grab the latest installer or portable package from the [download](https://playnite.link/download.html) page. Playnite will automatically notify you about a new version upon release.
Requirements: Windows 7, 8 or 10 and [.NET Framework 4.6.2](https://www.microsoft.com/en-us/download/details.aspx?id=53344)
Requirements: Windows 10 or 11
Extensions
FAQ, Known Issues, user manual
---------
Playnite can be extended with plugins (written in .NET languages) or by scripts (PowerShell and IronPython are currently supported).
See the [extensions portal](https://playnite.link/docs/) for tutorials and the full API documentation.
FAQ
---------
Can be found [on the wiki](https://github.com/JosefNemec/Playnite/wiki/Frequently-Asked-Questions)
Known Issues
---------
The list of known issues and solutions can be found [on the wiki](https://github.com/JosefNemec/Playnite/wiki/Known-Issues).
Privacy Statement
---------
Playnite doesn't store any user information and you don't need to provide any information to import installed games. Account connection process is usually done via official login web forms and only the web session cookies or tokens are stored, the same way when you login to those services via the web browser.
All information about your library is stored locally on your PC.
Can be found [here](https://api.playnite.link/docs/)
Questions, issues etc.
---------
If you find a bug please file an [issue](https://github.com/JosefNemec/Playnite/issues) and if relevant (crashes, broken features) please attach a diagnostics package, which can be created from inside the "About Playnite..." submenu.
Biggest community around Playnite currently gathers on our [Discord server](https://discord.gg/hSFvmN6) and [Forums](https://playnite.link/forum). You can also follow [@AppPlaynite](https://twitter.com/AppPlaynite) for general updates.
Biggest community around Playnite currently gathers on our [Discord server](https://playnite.link/discord) and [Reddit](https://www.reddit.com/r/playnite/).
Contributions
Privacy Statement
---------
### Translations
See the [How to: Translations](https://github.com/JosefNemec/Playnite/wiki/How-to:-Translations) wiki page.
Playnite itself doesn't store any user information and you generally don't need to provide any information to import installed games. All game library data is stored locally on your PC.
### Themes
See the [How to: Themes](https://github.com/JosefNemec/Playnite/wiki/How-to%3A-Themes) wiki page.
Account connection process depends on how a library plugin is implemented, but is usually done via official login web forms and only the web session cookies or tokens are stored, the same way when you login to those services via the web browser.
Add-ons
---------
Playnite can be extended with plugins (written in .NET languages), PowerShell scripts and user interface themes.
See the [extensions portal](https://api.playnite.link/docs/tutorials/index.html) for more information about how to make these addons.
Translations
---------
We use Crowdin to manage localization, please join our project if you want to submit translations:
https://crowdin.com/project/playnite
Proofreading changes to original English strings can be submitted by creating pull request for [LocSource.xaml](https://github.com/JosefNemec/Playnite/blob/devel/source/Playnite/Localization/LocSource.xaml) file.
Code Contributions
---------
Pull requests are generally on pause because majority of code base is being rewritten for Playnite 11. Smaller "safe" changes for P10 might get accepted based on what they and if they come with test coverage. If you plan to work on bigger changes, please discuss it first in related issue or on Discord, thank you.
### Code Contributions
Please ask in the related issue first before starting implementing something to make sure that nobody else is already working on it. If an issue doesn't exist for your feature/bug fix, create one first.
Regarding code styling, there are only a few major rules:
@ -60,20 +61,24 @@ Regarding code styling, there are only a few major rules:
- private fields and properties should use camelCase (without underscore)
- all methods (private and public) should use PascalCase
- use spaces instead of tabs with 4 spaces width
- add empty line between code block end `}` and additional expression
- always encapsulate the code body after *if, for, foreach, while* etc. with curly braces:
```csharp
if (true)
{
DoSomething()
DoSomething();
}
DoSomethingElse();
```
instead of
```csharp
if (true)
DoSomething()
DoSomething();
DoSomethingElse();
```
Branches
@ -85,7 +90,7 @@ Branches
Roadmap
---------
You can see the planned versions with their features in the [milestones overview](https://github.com/JosefNemec/Playnite/milestones).
Playnite is currently being rewritten from scratch for next major version release 11. The work is being done in private repository until beta release, after which the code will be release in this repository under the same license as current version 10 release. There is no list of planned changes and new features for version 11.
Development
---------
@ -99,7 +104,6 @@ Others
[![jetbrains](https://user-images.githubusercontent.com/3874087/128503701-884cdae4-3283-4d67-8ad1-6103e777a660.png)](https://www.jetbrains.com/?from=Playnite)
Code signing courtesy of [SignPath](https://about.signpath.io)
[![Capture](https://user-images.githubusercontent.com/3874087/128503363-9c39f8cd-9900-4a8b-83f2-81359d4fc731.PNG)](https://about.signpath.io)
This program uses free code signing provided by [SignPath.io](https://signpath.io?utm_source=foundation&utm_medium=github&utm_campaign=playnite), and a free code signing certificate by the [SignPath Foundation](https://signpath.org?utm_source=foundation&utm_medium=github&utm_campaign=playnite)
[![Capture](https://user-images.githubusercontent.com/3874087/128503363-9c39f8cd-9900-4a8b-83f2-81359d4fc731.PNG)](https://about.signpath.io?utm_source=foundation&utm_medium=github&utm_campaign=playnite)

View File

@ -1,36 +1,330 @@
Playnite.SDK.dll
Playnite.SDK.pdb
Playnite.SDK.xml
Playnite.Common.dll
Playnite.Common.pdb
LiteDB.dll
LiteDB.xml
Newtonsoft.Json.dll
Newtonsoft.Json.xml
System.IO.Abstractions.dll
System.IO.Abstractions.xml
NLog.dll
NLog.xml
Windows.winmd
AngleSharp.dll
AngleSharp.xml
YamlDotNet.dll
YamlDotNet.xml
Nett.dll
Nett.xml
Microsoft.WindowsAPICodePack.dll
Microsoft.WindowsAPICodePack.Shell.dll
SQLNado.dll
Markdig.dll
Markdig.xml
Markdig.pdb
NAudio.dll
NAudio.xml
CefSharp.dll
CefSharp.BrowserSubprocess.Core.dll
CefSharp.Core.dll
CefSharp.Core.Runtime.dll
CefSharp.OffScreen.dll
CefSharp.Wpf.dll
CommandLine.dll
concrt140.dll
Crc32.NET.dll
Crc32.NET.xml
d3dcompiler_47.dll
DiscordRPC.dll
Flurl.dll
Flurl.xml
Hardcodet.Wpf.TaskbarNotification.dll
HtmlRenderer.dll
HtmlRenderer.xml
HtmlRenderer.WPF.dll
HtmlRenderer.WPF.xml
chrome_elf.dll
libcef.dll
libEGL.dll
libGLESv2.dll
LiteDB.dll
Magick.Native-Q8-x86.dll
Magick.NET.Core.dll
Magick.NET.SystemWindowsMedia.dll
Magick.NET-Q8-x86.dll
Markdig.dll
Microsoft.Dynamic.dll
Microsoft.Practices.ServiceLocation.dll
Microsoft.Scripting.dll
Microsoft.Scripting.Metadata.dll
Microsoft.VisualStudio.CodeCoverage.Shim.dll
Microsoft.Win32.Primitives.dll
Microsoft.WindowsAPICodePack.dll
Microsoft.WindowsAPICodePack.ExtendedLinguisticServices.dll
Microsoft.WindowsAPICodePack.Sensors.dll
Microsoft.WindowsAPICodePack.Shell.dll
Microsoft.WindowsAPICodePack.ShellExtensions.dll
Microsoft.Xaml.Behaviors.dll
msvcp140.dll
msvcp140_1.dll
msvcp140_2.dll
msvcp140_atomic_wait.dll
msvcp140_codecvt_ids.dll
netstandard.dll
Nett.dll
Newtonsoft.Json.dll
NLog.dll
PhotoSauce.MagicScaler.dll
Playnite.dll
Playnite.SDK.dll
Polly.dll
Prism.dll
Prism.Wpf.dll
protobuf-net.dll
SDL2.dll
SDL2_mixer.dll
SharpCompress.dll
sqlite3.x86.dll
SQLNado.dll
System.AppContext.dll
System.Buffers.dll
System.Collections.dll
System.Collections.Concurrent.dll
System.Collections.NonGeneric.dll
System.Collections.Specialized.dll
System.ComponentModel.dll
System.ComponentModel.EventBasedAsync.dll
System.ComponentModel.Primitives.dll
System.ComponentModel.TypeConverter.dll
System.Console.dll
System.Data.Common.dll
System.Diagnostics.Contracts.dll
System.Diagnostics.Debug.dll
System.Diagnostics.FileVersionInfo.dll
System.Diagnostics.Process.dll
System.Diagnostics.StackTrace.dll
System.Diagnostics.TextWriterTraceListener.dll
System.Diagnostics.Tools.dll
System.Diagnostics.TraceSource.dll
System.Diagnostics.Tracing.dll
System.Drawing.Primitives.dll
System.Dynamic.Runtime.dll
System.Globalization.dll
System.Globalization.Calendars.dll
System.Globalization.Extensions.dll
System.IO.dll
System.IO.Abstractions.dll
System.IO.Compression.dll
System.IO.Compression.ZipFile.dll
System.IO.FileSystem.dll
System.IO.FileSystem.DriveInfo.dll
System.IO.FileSystem.Primitives.dll
System.IO.FileSystem.Watcher.dll
System.IO.IsolatedStorage.dll
System.IO.MemoryMappedFiles.dll
System.IO.Pipes.dll
System.IO.UnmanagedMemoryStream.dll
System.Linq.dll
System.Linq.Expressions.dll
System.Linq.Parallel.dll
System.Linq.Queryable.dll
System.Memory.dll
System.Net.Http.dll
System.Net.NameResolution.dll
System.Net.NetworkInformation.dll
System.Net.Ping.dll
System.Net.Primitives.dll
System.Net.Requests.dll
System.Net.Security.dll
System.Net.Sockets.dll
System.Net.WebHeaderCollection.dll
System.Net.WebSockets.dll
System.Net.WebSockets.Client.dll
System.Numerics.Vectors.dll
System.ObjectModel.dll
System.Reflection.dll
System.Reflection.Extensions.dll
System.Reflection.Primitives.dll
System.Resources.Reader.dll
System.Resources.ResourceManager.dll
System.Resources.Writer.dll
System.Runtime.dll
System.Runtime.CompilerServices.Unsafe.dll
System.Runtime.CompilerServices.VisualC.dll
System.Runtime.Extensions.dll
System.Runtime.Handles.dll
System.Runtime.InteropServices.dll
System.Runtime.InteropServices.RuntimeInformation.dll
System.Runtime.Numerics.dll
System.Runtime.Serialization.Formatters.dll
System.Runtime.Serialization.Json.dll
System.Runtime.Serialization.Primitives.dll
System.Runtime.Serialization.Xml.dll
System.Security.Claims.dll
System.Security.Cryptography.Algorithms.dll
System.Security.Cryptography.Csp.dll
System.Security.Cryptography.Encoding.dll
System.Security.Cryptography.Primitives.dll
System.Security.Cryptography.X509Certificates.dll
System.Security.Principal.dll
System.Security.SecureString.dll
System.Text.Encoding.dll
System.Text.Encoding.Extensions.dll
System.Text.RegularExpressions.dll
System.Threading.dll
System.Threading.Overlapped.dll
System.Threading.Tasks.dll
System.Threading.Tasks.Parallel.dll
System.Threading.Thread.dll
System.Threading.ThreadPool.dll
System.Threading.Timer.dll
System.ValueTuple.dll
System.Windows.Interactivity.dll
System.Xml.ReaderWriter.dll
System.Xml.XDocument.dll
System.Xml.XmlDocument.dll
System.Xml.XmlSerializer.dll
System.Xml.XPath.dll
System.Xml.XPath.XDocument.dll
vccorlib140.dll
vcruntime140.dll
vcruntime140_threads.dll
vk_swiftshader.dll
vulkan-1.dll
YamlDotNet.dll
AngleSharp.xml
CefSharp.xml
CefSharp.BrowserSubprocess.Core.xml
CefSharp.Core.xml
CefSharp.Core.Runtime.xml
CefSharp.OffScreen.xml
CefSharp.Wpf.xml
CommandLine.xml
concrt140.xml
Crc32.NET.xml
d3dcompiler_47.xml
DiscordRPC.xml
Flurl.xml
Hardcodet.Wpf.TaskbarNotification.xml
HtmlRenderer.xml
HtmlRenderer.WPF.xml
chrome_elf.xml
libcef.xml
libEGL.xml
libGLESv2.xml
LiteDB.xml
Magick.Native-Q8-x86.xml
Magick.NET.Core.xml
Magick.NET.SystemWindowsMedia.xml
Magick.NET-Q8-x86.xml
Markdig.xml
Microsoft.Dynamic.xml
Microsoft.Practices.ServiceLocation.xml
Microsoft.Scripting.xml
Microsoft.Scripting.Metadata.xml
Microsoft.VisualStudio.CodeCoverage.Shim.xml
Microsoft.Win32.Primitives.xml
Microsoft.WindowsAPICodePack.xml
Microsoft.WindowsAPICodePack.ExtendedLinguisticServices.xml
Microsoft.WindowsAPICodePack.Sensors.xml
Microsoft.WindowsAPICodePack.Shell.xml
Microsoft.WindowsAPICodePack.ShellExtensions.xml
Microsoft.Xaml.Behaviors.xml
msvcp140.xml
msvcp140_1.xml
msvcp140_2.xml
msvcp140_atomic_wait.xml
msvcp140_codecvt_ids.xml
netstandard.xml
Nett.xml
Newtonsoft.Json.xml
NLog.xml
PhotoSauce.MagicScaler.xml
Playnite.xml
Playnite.SDK.xml
Polly.xml
Prism.xml
Prism.Wpf.xml
protobuf-net.xml
SDL2.xml
SDL2_mixer.xml
SharpCompress.xml
sqlite3.x86.xml
SQLNado.xml
System.AppContext.xml
System.Buffers.xml
System.Collections.xml
System.Collections.Concurrent.xml
System.Collections.NonGeneric.xml
System.Collections.Specialized.xml
System.ComponentModel.xml
System.ComponentModel.EventBasedAsync.xml
System.ComponentModel.Primitives.xml
System.ComponentModel.TypeConverter.xml
System.Console.xml
System.Data.Common.xml
System.Diagnostics.Contracts.xml
System.Diagnostics.Debug.xml
System.Diagnostics.FileVersionInfo.xml
System.Diagnostics.Process.xml
System.Diagnostics.StackTrace.xml
System.Diagnostics.TextWriterTraceListener.xml
System.Diagnostics.Tools.xml
System.Diagnostics.TraceSource.xml
System.Diagnostics.Tracing.xml
System.Drawing.Primitives.xml
System.Dynamic.Runtime.xml
System.Globalization.xml
System.Globalization.Calendars.xml
System.Globalization.Extensions.xml
System.IO.xml
System.IO.Abstractions.xml
System.IO.Compression.xml
System.IO.Compression.ZipFile.xml
System.IO.FileSystem.xml
System.IO.FileSystem.DriveInfo.xml
System.IO.FileSystem.Primitives.xml
System.IO.FileSystem.Watcher.xml
System.IO.IsolatedStorage.xml
System.IO.MemoryMappedFiles.xml
System.IO.Pipes.xml
System.IO.UnmanagedMemoryStream.xml
System.Linq.xml
System.Linq.Expressions.xml
System.Linq.Parallel.xml
System.Linq.Queryable.xml
System.Memory.xml
System.Net.Http.xml
System.Net.NameResolution.xml
System.Net.NetworkInformation.xml
System.Net.Ping.xml
System.Net.Primitives.xml
System.Net.Requests.xml
System.Net.Security.xml
System.Net.Sockets.xml
System.Net.WebHeaderCollection.xml
System.Net.WebSockets.xml
System.Net.WebSockets.Client.xml
System.Numerics.Vectors.xml
System.ObjectModel.xml
System.Reflection.xml
System.Reflection.Extensions.xml
System.Reflection.Primitives.xml
System.Resources.Reader.xml
System.Resources.ResourceManager.xml
System.Resources.Writer.xml
System.Runtime.xml
System.Runtime.CompilerServices.Unsafe.xml
System.Runtime.CompilerServices.VisualC.xml
System.Runtime.Extensions.xml
System.Runtime.Handles.xml
System.Runtime.InteropServices.xml
System.Runtime.InteropServices.RuntimeInformation.xml
System.Runtime.Numerics.xml
System.Runtime.Serialization.Formatters.xml
System.Runtime.Serialization.Json.xml
System.Runtime.Serialization.Primitives.xml
System.Runtime.Serialization.Xml.xml
System.Security.Claims.xml
System.Security.Cryptography.Algorithms.xml
System.Security.Cryptography.Csp.xml
System.Security.Cryptography.Encoding.xml
System.Security.Cryptography.Primitives.xml
System.Security.Cryptography.X509Certificates.xml
System.Security.Principal.xml
System.Security.SecureString.xml
System.Text.Encoding.xml
System.Text.Encoding.Extensions.xml
System.Text.RegularExpressions.xml
System.Threading.xml
System.Threading.Overlapped.xml
System.Threading.Tasks.xml
System.Threading.Tasks.Parallel.xml
System.Threading.Thread.xml
System.Threading.ThreadPool.xml
System.Threading.Timer.xml
System.ValueTuple.xml
System.Windows.Interactivity.xml
System.Xml.ReaderWriter.xml
System.Xml.XDocument.xml
System.Xml.XmlDocument.xml
System.Xml.XmlSerializer.xml
System.Xml.XPath.xml
System.Xml.XPath.XDocument.xml
vccorlib140.xml
vcruntime140.xml
vcruntime140_threads.xml
vk_swiftshader.xml
vulkan-1.xml
YamlDotNet.xml

View File

@ -17,10 +17,12 @@
<dependencies>
<group targetFramework=".NETFramework4.6.2" />
</dependencies>
<readme>docs\readme.md</readme>
</metadata>
<files>
<file src="{OutDir}\Playnite.SDK.dll" target="lib\net462\Playnite.SDK.dll" />
<file src="{OutDir}\Playnite.SDK.xml" target="lib\net462\Playnite.SDK.xml" />
<file src="..\source\Playnite.DesktopApp\Themes\Desktop\Default\Images\applogo.png" target="images\" />
<file src="..\source\PlayniteSDK\readme.md" target="docs\" />
</files>
</package>

View File

@ -1,3 +1,5 @@
#Requires -Version 7
$ErrorActionPreference = "Stop"
Add-Type -AssemblyName "PresentationFramework"

View File

@ -1,3 +1,5 @@
#Requires -Version 7
$ErrorActionPreference = "Stop"
Add-Type -AssemblyName "PresentationFramework"

View File

@ -1,4 +1,6 @@
param(
#Requires -Version 7
param(
# Build configuration
[ValidateSet("Release", "Debug")]
[string]$Configuration = "Release",
@ -121,7 +123,7 @@ if (!$SkipBuild)
{
if (Test-Path $OutputDir)
{
Remove-Item $OutputDir -Recurse -Force
Remove-Item "$OutputDir\*" -Recurse -Force
}
if ($LicensedDependenciesUrl)

View File

@ -1,21 +0,0 @@
param(
[switch]$SkipMetadata
)
$ErrorActionPreference = "Stop"
& .\common.ps1
if (!$SkipMetadata)
{
$metadata = StartAndWait "docfx" "metadata" "..\doc\"
if ($metadata -ne 0)
{
throw "Failed to build doc metadata."
}
}
$build = StartAndWait "docfx" "build" "..\doc\"
if ($build -ne 0)
{
throw "Failed to build doc."
}

View File

@ -1,3 +1,5 @@
#Requires -Version 7
$ErrorActionPreference = "Stop"
& .\common.ps1

View File

@ -1,4 +1,6 @@
param(
#Requires -Version 7
param(
[ValidateSet("Release", "Debug")]
[string]$Configuration = "Release",
[string]$OutputPath = (Join-Path $PWD "$($Configuration)SDK"),

View File

@ -1,4 +1,6 @@
$global:NugetUrl = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
#Requires -Version 7
$global:NugetUrl = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
function global:StartAndWait()
{
@ -53,20 +55,14 @@ function global:Get-MsBuildPath()
if (-not (Get-Command -Name $VSWHERE_CMD -Type Application -ErrorAction Ignore))
{
$VSWHERE_CMD = "..\source\packages\vswhere.2.6.7\tools\vswhere.exe"
$VSWHERE_CMD = "..\source\packages\vswhere.*\tools\vswhere.exe"
if (-not (Get-Command -Name $VSWHERE_CMD -Type Application -ErrorAction Ignore))
{
Invoke-Nuget "install vswhere -Version 2.6.7 -SolutionDirectory `"$solutionDir`"" | Out-Null
Invoke-Nuget "install vswhere -SolutionDirectory `"$solutionDir`"" | Out-Null
}
}
$path = & $VSWHERE_CMD -version "[15.0,16.0)" -requires Microsoft.Component.MSBuild -find "MSBuild\**\Bin\MSBuild.exe" -latest | Select-Object -First 1
if ($path -and (Test-Path $path))
{
return $path
}
$path = & $VSWHERE_CMD -version "[16.0,17.0)" -requires Microsoft.Component.MSBuild -find "MSBuild\**\Bin\MSBuild.exe" -latest | Select-Object -First 1
$path = & $VSWHERE_CMD -latest -requires Microsoft.Component.MSBuild -find "MSBuild\**\Bin\MSBuild.exe" -latest | Select-Object -First 1
if ($path -and (Test-Path $path))
{
return $path

View File

@ -0,0 +1,487 @@
param(
[Parameter(Mandatory=$true)]
[string]$RetroArchDir,
[Parameter(Mandatory=$true)]
[string]$PlayniteSourceDirectory
)
$ErrorActionPreference = "Stop"
if (!(Get-InstalledModule "powershell-yaml" -EA 0))
{
Install-Module powershell-yaml
}
function Get-IsYamlValid
{
param (
[Parameter(Mandatory=$true)]
[string] $yamlContent
)
try {
$yamlContent | ConvertFrom-Yaml | Out-Null
return $true
} catch {
return $false
}
}
function ParseInfoFile()
{
param(
[Parameter(Mandatory=$true)]
[string]$Path
)
$properties = @{}
foreach ($line in (Get-Content $Path))
{
if ($line.StartsWith("#"))
{
continue
}
if ($line -match "^(.*)\s*=\s*`"(.*)`"$")
{
$property = $Matches[1].Trim()
if (!$properties.ContainsKey($property))
{
$properties.Add($property, $Matches[2].Trim())
}
}
}
return $properties
}
$emulationDirPath = [System.IO.Path]::Combine($PlayniteSourceDirectory, "Playnite", "Emulation")
$platformsDefinitionPath = [System.IO.Path]::Combine($emulationDirPath, "Platforms.yaml")
$retroArchEmuDefinitionPath = [System.IO.Path]::Combine($emulationDirPath, "Emulators", "RetroArch", "emulator.yaml")
if (!(Test-Path $platformsDefinitionPath -Type Leaf))
{
Write-Host "Playnite platforms definition file not found in $platformsDefinitionPath" -ForegroundColor Yellow
return
}
$ignoreList = @(
"00_example_libretro.info",
"2048_libretro.info",
"3dengine_libretro.info",
"advanced_tests_libretro.info",
"bk_libretro.info",
"boom3_libretro.info",
"boom3_xp_libretro.info",
"cannonball_libretro.info",
"chaigame_libretro.info",
"chailove_libretro.info",
"craft_libretro.info",
"cruzes_libretro.info",
"dhewm3_libretro.info",
"dinothawr_libretro.info",
"ecwolf_libretro.info",
"ffmpeg_libretro.info",
"freechaf_libretro.info",
"freej2me_libretro.info",
"gme_libretro.info",
"hbmame_libretro.info",
"imageviewer_libretro.info",
"lutro_libretro.info",
"mojozork_libretro.info",
"mpv_libretro.info",
"mrboom_libretro.info",
"mu_libretro.info",
"nxengine_libretro.info",
"oberon_libretro.info",
"openlara_libretro.info",
"opentyrian_libretro.info",
"pascal_pong_libretro.info",
"pocketcdg_libretro.info",
"pokemini_libretro.info",
"prboom_libretro.info",
"quasi88_libretro.info",
"redbook_libretro.info",
"reminiscence_libretro.info",
"remotejoy_libretro.info",
"rvvm_libretro.info",
"scummvm_libretro.info",
"simcp_libretro.info",
"squirreljme_libretro.info",
"stonesoup_libretro.info",
"test_libretro.info",
"test_netplay_libretro.info",
"testaudio_callback_libretro.info",
"testaudio_no_callback_libretro.info",
"testaudio_playback_wav_libretro.info",
"testgl_compute_shaders_libretro.info",
"testgl_ff_libretro.info",
"testgl_libretro.info",
"testinput_buttontest_libretro.info",
"testretroluxury_libretro.info",
"testsw_libretro.info",
"testsw_vram_libretro.info",
"testvulkan_async_compute_libretro.info",
"testvulkan_libretro.info",
"thepowdertoy_libretro.info",
"tic80_libretro.info",
"tyrquake_libretro.info",
"ume2015_libretro.info",
"uw8_libretro.info",
"vaporspec_libretro.info",
"vitaquake2-rogue_libretro.info",
"vitaquake2-xatrix_libretro.info",
"vitaquake2-zaero_libretro.info",
"vitaquake2_libretro.info",
"vitaquake3_libretro.info",
"vitavoyager_libretro.info",
"wasm4_libretro.info",
"x1_libretro.info",
"xrick_libretro.info"
)
$retroarchArcadeSystems = @(
"16-bit (Various)",
"16-bit + 32X (Various)",
"Arcade (various)",
"CP System I",
"CP System II",
"CP System III",
"Multi (various)",
"Neo Geo"
)
$retroarchMiscSystems = @(
"2003 Game Engine",
"4",
"CHIP-8",
"Handheld Electronic", #Handheld Electronic (GW)
"LowRes NX", #LowRes NX
"Magnavox Odyssey2", #133 Philips Videopac G7000
"Mega Duck", # Mega Duck
"Moonlight", # Moonlight,
"PICO8", # PICO-8
"Pong Game Clone", # Gong,
"RPG Maker 2000",
"SEGA Visual Memory Unit", #VeMUlator / Sega VMU
"Uzebox" # Uzebox (Uzem)
)
$raCoreNameToPlatformIdsTranslate = @{
"Gearsystem" = @("sega_mastersystem", "sega_gamegear", "sega_sg1000", "coleco_vision");
"Genesis Plus GX" = @("sega_mastersystem", "sega_gamegear", "sega_genesis", "sega_cd");
"Genesis Plus GX Wide" = @("sega_mastersystem", "sega_gamegear", "sega_genesis", "sega_cd");
"nSide (Super Famicom Accuracy)" = @("nintendo_super_nes", "nintendo_gameboy", "nintendo_gameboycolor");
"PicoDrive" = @("sega_mastersystem", "sega_genesis", "sega_cd", "sega_32x");
"SMS Plus GX" = @("sega_mastersystem", "sega_gamegear", "sega_sg1000", "coleco_vision");
}
$raSystemIdToPlatformIdsTranslate = @{
"msx" = @("microsoft_msx", "microsoft_msx2");
"neo_geo_pocket" = @("snk_neogeopocket", "snk_neogeopocket_color");
}
$raSystemNameToPlatformIdTranslate = @{
"3DO" = "3do";
"3DS" = "nintendo_3ds";
"Amiga" = "commodore_amiga";
"Atari 2600" = "atari_2600";
"Atari 5200" = "atari_5200";
"Atari 7800" = "atari_7800";
"Atari ST" = "atari_st";
"C128" = "commodore_64";
"C64" = "commodore_64";
"C64 SuperCPU" = "commodore_64";
"CBM-5x0" = "commodore_cbm5x0";
"CBM-II" = "commodore_cbm2";
"CD" = "nec_turbografx_cd";
"ColecoVision" = "coleco_vision";
"Color" = "bandai_wonderswan_color";
"Commodore Amiga" = "commodore_amiga";
"CPC" = "amstrad_cpc";
"DOS" = "pc_dos";
"DS" = "nintendo_ds";
"Falcon" = "atari_falcon030";
"Game Boy" = "nintendo_gameboy";
"Game Boy Advance" = "nintendo_gameboyadvance";
"Game Boy Color" = "nintendo_gameboycolor";
"GameCube" = "nintendo_gamecube";
"GG" = "sega_gamegear";
"Intellivision" = "mattel_intellivision";
"Jaguar" = "atari_jaguar";
"Lynx" = "atari_lynx";
"Nintendo 64" = "nintendo_64";
"Nintendo DS" = "nintendo_ds";
"Nintendo Entertainment System" = "nintendo_nes";
"PC" = "pc_dos";
"PC Engine" = "nec_turbografx_16";
"PC Engine SuperGrafx" = "nec_supergrafx";
"PC-98" = "nec_pc98";
"PC-FX" = "nec_pcfx";
"PCE-CD" = "nec_turbografx_cd";
"PET" = "commodore_pet";
"PlayStation" = "sony_playstation";
"PLUS" = "commodore_plus4";
"PSP" = "sony_psp";
"Saturn" = "sega_saturn";
"Sega Dreamcast" = "sega_dreamcast";
"Sega Genesis" = "sega_genesis";
"Sega Master System" = "sega_mastersystem";
"Sharp X68000" = "sharp_x68000";
"SNK Neo Geo CD" = "snk_neogeo_cd";
"Sony PlayStation 2" = "sony_playstation2";
"STE" = "atari_st";
"Super Nintendo Entertainment System" = "nintendo_super_nes";
"SuperGrafx" = "nec_supergrafx";
"Supervision" = "watara_supervision";
"SVI" = "microsoft_msx";
"Thomson MO" = "thomson_mo5";
"TO" = "thomson_to7";
"TT" = "atari_st"; # The Atari TT030 is a member of the Atari ST family
"Vectrex" = "vectrex";
"VIC-20" = "commodore_vci20";
"Virtual Boy" = "nintendo_virtualboy";
"Wii" = "nintendo_wii";
"WonderSwan" = "bandai_wonderswan";
"Xbox" = "xbox";
"ZX Spectrum (various)" = "sinclair_zxspectrum";
"ZX81" = "sinclair_zx81";
}
$emuDefinitionTemplate = "Id: retroarch
Name: RetroArch
Website: 'http://www.retroarch.com/'
Profiles:
{0}"
$profileTemplate = ' - Name: {0}
StartupArguments: ''-L ".\cores\{1}.dll" "{{ImagePath}}"''
Platforms: [{2}]
ImageExtensions: [{3}]
ProfileFiles: [''cores\{4}.dll'']
StartupExecutable: ^retroarch\.exe$'
$existingProfileReaddTemplate = ' - Name: {0}
StartupArguments: ''{1}''
Platforms: [{2}]
ImageExtensions: [{3}]
ProfileFiles: [''{4}'']
StartupExecutable: ^retroarch\.exe$'
$existingEmuDefinition = Get-Content $retroArchEmuDefinitionPath -Raw | ConvertFrom-Yaml
$usedProfileNames = @()
$existingProfiles = @{}
foreach ($existingProfile in $existingEmuDefinition.Profiles) {
$existingProfiles[$existingProfile.ProfileFiles[0]] = $existingProfile
$usedProfileNames += $existingProfile.Name
}
$foundCoreNames = @()
$foundPlatformIds = @()
$profiles = @()
$infoPath = Join-Path $RetroArchDir "info"
$infoFiles = Get-ChildItem $infoPath -Filter "*.info"
foreach ($infoFile in $infoFiles)
{
if ($ignoreList.Contains($infoFile.Name))
{
continue
}
$coreInfo = ParseInfoFile $infoFile.FullName
$coreFile = "cores\{0}.dll" -f $infoFile.BaseName
$platformIds = @()
if ($existingProfiles.ContainsKey($coreFile))
{
$coreName = $existingProfiles[$coreFile].Name
$platformIds = $existingProfiles[$coreFile].Platforms
}
else
{
if ($usedProfileNames.Contains($coreInfo.corename))
{
$coreName = "{0} - {1}" -f $coreInfo.corename, $coreInfo.display_name
}
else
{
$coreName = $coreInfo.corename
}
}
if (!($coreInfo.ContainsKey("corename")))
{
Write-Host "$($infoFile.Name) does not contain the core name" -ForegroundColor Yellow # Some cores like anarch_libretro.info don't contain a core name
continue
}
$coreInfoCoreName = $coreInfo.corename
if ($raCoreNameToPlatformIdsTranslate.ContainsKey($coreInfoCoreName))
{
$platformIds = $raCoreNameToPlatformIdsTranslate[$coreInfoCoreName]
}
elseif ($null -ne $coreInfo.systemid -and $raSystemIdToPlatformIdsTranslate.ContainsKey($coreInfo.systemid.Trim()))
{
$platformIds = $raSystemIdToPlatformIdsTranslate[$coreInfo.systemid.Trim()]
}
else
{
if (!($coreInfo.ContainsKey("systemname")))
{
Write-Host "$($infoFile.Name) does not contain systemname" -ForegroundColor Yellow # galaksija_libretro.info
continue
}
$coreInfo.systemname.Split("/", [System.StringSplitOptions]::RemoveEmptyEntries) | ForEach-Object {
$system = $_.Trim()
if (($retroarchArcadeSystems -contains $system) -or ($retroarchMiscSystems -contains $system))
{
Continue
}
if ($raSystemNameToPlatformIdTranslate.ContainsKey($system))
{
$platformId = $raSystemNameToPlatformIdTranslate[$system]
if ($platformIds -notcontains $platformId)
{
$platformIds += $platformId
}
}
else
{
Write-Host "System to platform translate not found. System: $system, CoreName: $($coreInfo.corename), DisplayName: $($coreInfo.display_name)" -ForegroundColor Yellow
}
}
}
if ($null -eq $platformIds -or $platformIds.Count -eq 0)
{
Write-Host "PlatformIds not found. System: $system, CoreName: $($coreInfo.corename), DisplayName: $($coreInfo.display_name)" -ForegroundColor Yellow
continue
}
if ($coreInfo.supported_extensions)
{
$extensions = @()
$coreInfo.supported_extensions.Split("|", [System.StringSplitOptions]::RemoveEmptyEntries) | ForEach-Object {
$extensions += $_
}
if ($extensions -notcontains "zip")
{
$extensions += "zip"
}
if ($extensions -notcontains "7z")
{
$extensions += "7z"
}
$extensions = $extensions | Sort-Object
$extensionsString = [System.String]::Join(", ", $extensions)
}
else
{
Write-Host "Profile did not have extensions. System: $system, CoreName: $($coreInfo.corename), DisplayName: $($coreInfo.display_name)" -ForegroundColor Yellow
continue
}
foreach ($platformId in $platformIds) {
if ($foundPlatformIds -notcontains $platformId)
{
$foundPlatformIds += $platformId
}
}
$platformIds = $platformIds | Sort-Object
$extensions = $extensions | Sort-Object
$platformIdsString = [System.String]::Join(", ", $platformIds)
$profileString = $profileTemplate -f $coreName, $infoFile.BaseName, $platformIdsString, $extensionsString, $infoFile.BaseName
$profiles += $profileString
$foundCoreNames += $coreName
$usedProfileNames += $coreName
}
# Previous profiles need to be kept or existing emulator configuration will break
# Here emulators not generated will be added back
foreach ($existingProfile in $existingEmuDefinition.Profiles) {
if ($foundCoreNames -notcontains $existingProfile.Name)
{
foreach ($platformId in $existingProfile.Platforms) {
if ($foundPlatformIds -notcontains $platformId)
{
$foundPlatformIds += $platformId
}
}
$platformIds = [System.String]::Join(", ", ($existingProfile.Platforms | Sort-Object))
$extensionsString = [System.String]::Join(", ", ($existingProfile.ImageExtensions | Sort-Object))
$profileFilesString = [System.String]::Join(", ", ($existingProfile.ProfileFiles | Sort-Object))
$profileString = $existingProfileReaddTemplate -f $existingProfile.Name, $existingProfile.StartupArguments, $platformIds, $extensionsString, $profileFilesString
$profiles += $profileString
Write-Host "Existing profile $($existingProfile.Name) not found in newly generated definition and was added back from previous definition" -ForegroundColor Yellow
}
}
# Join generated profiles and validated created profile yaml content
$profiles = $profiles | Sort-Object
$profilesString = [System.String]::Join("`n`n", $profiles)
$emuDefinitionContent = $emuDefinitionTemplate -f $profilesString
if ((Get-IsYamlValid $emuDefinitionContent) -eq $false)
{
Write-Host "Newly generated profile definition file is not valid!" -ForegroundColor Red
Set-Clipboard $emuDefinitionContent
return
}
# Add RetroArch to emulators list in Playnite platforms definitions
$platformDefinitionTemplate = '- Name: {0}
{1}'
$newPlatformsDefinitions = @()
$existingPlatformsDefinition = Get-Content $platformsDefinitionPath -Raw | ConvertFrom-Yaml
foreach ($platform in $existingPlatformsDefinition) {
$platformData = @()
$platformData += " Id: {0}" -f $platform.Id
if ($platform.IgdbId)
{
$platformData += "IgdbId: {0}" -f $platform.IgdbId
}
if ($platform.Databases)
{
$platformData += "Databases: [{0}]" -f [System.String]::Join(", ", ($platform.Databases | Sort-Object))
}
$isSupportedByRetroArch = $foundPlatformIds -contains $platform.Id
if ($platform.Emulators)
{
if ($isSupportedByRetroArch -and ($platform.Emulators -notcontains "retroarch"))
{
$platform.Emulators += "retroarch"
$platform.Emulators = $platform.Emulators | Sort-Object
Write-Host "Added retroarch emulator to `"$($platform.Name)`" platform" -ForegroundColor Blue
}
$platformData += "Emulators: [{0}]" -f [System.String]::Join(", ", ($platform.Emulators | Sort-Object))
}
elseif ($isSupportedByRetroArch)
{
$platformData += "Emulators: [{0}]" -f "retroarch"
}
$platformDataString = $platformDefinitionTemplate -f $platform.Name, [System.String]::Join("`n ", $platformData)
$newPlatformsDefinitions += $platformDataString
}
$newPlatformsDefinitionsContent = [System.String]::Join("`n `n", $newPlatformsDefinitions)
# Validate created platforms definition yaml content
if ((Get-IsYamlValid $newPlatformsDefinitionsContent) -eq $false)
{
Write-Host "Newly generated platforms definition file is not valid!" -ForegroundColor Red
Set-Clipboard $newPlatformsDefinitionsContent
return
}
# Save generated yaml files. New lines are replaced to maintain CRLF endings
[System.IO.File]::WriteAllLines($retroArchEmuDefinitionPath, $emuDefinitionContent.Replace("`n","`r`n"), [System.Text.Encoding]::UTF8)
[System.IO.File]::WriteAllLines($platformsDefinitionPath, $newPlatformsDefinitionsContent.Replace("`n","`r`n"), [System.Text.Encoding]::UTF8)
Write-Host "RetroArch emulator and Playnite platforms definitions updated and saved successfully!" -ForegroundColor Green

View File

@ -1,3 +1,5 @@
#Requires -Version 7
param(
[string]$AccessToken
)
@ -11,18 +13,20 @@ $requestHeaders = @{
"Authorization" = "Bearer $AccessToken"
}
$locProgressData = @{}
$locProgress = Invoke-RestMethod -Headers $requestHeaders -Uri "$urlRoot/projects/$playnitePrjId/languages/progress?limit=100"
$locProgressData = New-Object "System.Collections.Specialized.OrderedDictionary"
$locProgress = Invoke-RestMethod -Method Get -Headers $requestHeaders -Uri "$urlRoot/projects/$playnitePrjId/files/30/languages/progress?limit=100" ` -ContentType "application/json"
foreach ($lng in $locProgress.data)
{
$locProgressData.Add($lng.data.languageId, $lng.data.translationProgress);
$locDownloadData = Invoke-RestMethod -Method Post -Headers $requestHeaders -Uri "$urlRoot/projects/$playnitePrjId/translations/builds/files/30" `
-Body "{`"targetLanguageId`":`"$($lng.data.languageId)`"}" -ContentType "application/json"
$locDownload = Invoke-WebRequest -Uri $locDownloadData.data.url
$tempFile = Join-Path $locDir "temp.xaml"
Remove-Item $tempFile -EA 0
$locDownload = Invoke-WebRequest -Uri $locDownloadData.data.url -OutFile $tempFile -PassThru
$locDownload.Headers["Content-Disposition"][0] -match '"(.+)"' | Out-Null
$fileName = $Matches[1]
[System.IO.File]::WriteAllBytes((Join-Path $locDir $fileName), $locDownload.Content)
Move-Item $tempFile (Join-Path $locDir $fileName) -Force
}
$locProgressData | ConvertTo-Json | Out-File (Join-Path $locDir "locstatus.json")

9
doc/.gitignore vendored
View File

@ -1,9 +0,0 @@
###############
# folder #
###############
/**/DROP/
/**/TEMP/
/**/packages/
/**/bin/
/**/obj/
_site

View File

@ -1,7 +0,0 @@
apiRules:
- exclude:
uidRegex: ^System\.Collections\.Concurrent$
type: Namespace
- exclude:
uidRegex: ^Playnite\.SDK\.Converters$
type: Namespace

4
doc/api/.gitignore vendored
View File

@ -1,4 +0,0 @@
###############
# temp file #
###############
*.yml

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +0,0 @@
# Playnite API documentation
SDK can be obtained as [nuget package](https://www.nuget.org/packages/PlayniteSDK/) (recommended) or built from source project `PlayniteSDK`.

View File

@ -1,153 +0,0 @@
### To get automatically notified about SDK changes, you can subscribe to [change tracking issue](https://github.com/JosefNemec/Playnite/issues/1425) on GitHub.
#### 6.2.0
* New
* [Added](https://playnite.link/sdkchangelog/6.1.0-6.2.0/PlayniteSDK_Events_ApplicationEvents.cs.html) selected ROM file and source game action to game starting events.
* [Exposed](https://playnite.link/sdkchangelog/6.1.0-6.2.0/PlayniteSDK_IMainViewAPI.cs.html) selected Desktop view mode in UI API.
* [Added](https://playnite.link/sdkchangelog/6.1.0-6.2.0/PlayniteSDK_IMainViewAPI.cs.html) option to select multiple games.
* [Exposed](https://playnite.link/sdkchangelog/6.1.0-6.2.0/PlayniteSDK_IMainViewAPI.cs.html) list of currently filtered games.
* [Exposed](https://playnite.link/sdkchangelog/6.1.0-6.2.0/PlayniteSDK_IPlayniteSettingsAPI.cs.html) completion status settings.
* [Added](https://playnite.link/sdkchangelog/6.1.0-6.2.0/PlayniteSDK_IWebView.cs.html) option to set user agent for specific web view instance.
* New [model changes](https://playnite.link/sdkchangelog/6.1.0-6.2.0/PlayniteSDK_Models_Emulator.cs.html) related to added option to override built-in emulator arguments.
#### 6.1.0
* New
* `IsMusicMuted` property exposed in settings API.
#### 6.0.0
* **Breaking Changes**
* **Many** breaking changes to the entire SDK. All extensions and themes have to updated to work with Playnite 9. See [Playnite 9 migration guide](tutorials/playnite9migration.md) for more details.
* Removed IronPython support.
* Extensions no longer log into main `playnite.log` log file, but instead log into separate `extensions.log` file.
* Playnite 9 changes how library files are stored on disk. This is not breaking change to the SDK, but some existing extensions modify library files directly (which was never supported) and those will not work anymore.
* New
* PowerShell extensions are now implemented as proper PowerShell modules.
* Playnite now includes built-in add-on browser that can be used to install/update extension. You need to publish your extension to [add-on repository](https://github.com/JosefNemec/PlayniteAddonDatabase) for it to work.
* Ability to inject elements into Sidebar, Top panel and any custom theme that supports specific extension element explicitly.
* Ability to dynamically inject play, install and uninstall actions.
* You can now load extensions from custom directories via `For developers` settings menu.
* Added `Trace` severity log messages. These are not written into log files unless enabled in `For developers` settings menu.
* Import exclusions can be controlled via the SDK.
* Themes can now add [custom mouse cursor](tutorials/themes/various.md#custom-mouse-cursor) and [sound files](tutorials/themes/various.md#changing-audio-files).
#### 5.5.0
* New
* Ability to change progress text when using [ActivateGlobalProgress](xref:Playnite.SDK.IDialogsFactory)
* `CurrentExtensionInstallPath` and `CurrentExtensionDataPath` global variables for script extensions
#### 5.4.0
* New
* [ActivateGlobalProgress](xref:Playnite.SDK.IDialogsFactory) can now report specific progress status.
* [CanExecuteJavascriptInMainFrame](xref:Playnite.SDK.IWebView) property for WebViews.
* Various [data serialization methods](xref:Playnite.SDK.Data.Serialization) (JSON, YAML, TOML)
* [CreateWindow](xref:Playnite.SDK.IDialogsFactory) for creating native Playnite windows with styling.
* [GetCurrentAppWindow](xref:Playnite.SDK.IDialogsFactory) to get currently active Playnite window.
#### 5.3.0
* **Breaking Changes**:
* Playnite will no longer load plugins that reference non-SDK Playnite assemblies. See [this page](tutorials/extensions/plugins.md#referencing-playnite-assemblies) for more information.
* Playnite will no longer install extensions and themes that don't have proper version specified. The version string must a valid [.NET version string](https://docs.microsoft.com/en-us/dotnet/api/system.version)!
* **Now obsolete**:
* These changes do not break compatibility in current version (mentioned methods are still available in SDK), but they will be made breaking in future major Playnite updates.
* Added `Id` to extension and theme [manifests](tutorials/extensions/extensionsManifest.md). This field is currently not mandatory for existing extensions (Playnite 8 will load installed extensions without an ID, but will not install new ones without an ID), but should be provided for better extension installation and update support. Toolbox will not pack new extensions unless `Id` is present.
* The way custom menu items are implemented (for main menu and game menu) has been completely changed (the old system still works temporarily). See [related documentation page](tutorials/extensions/menus.md) for more information.
* [NavigationChanged](xref:Playnite.SDK.IWebView) from IWebView is now obsolete, use new `LoadingChanged` instead.
* New
* Metadata plugins can now provide `Features`, `AgeRating`, `Series`, `Region` and `Platform` data.
* Extensions can now provide [custom menu items](tutorials/extensions/menus.md) for game menus, including nested entries.
* Most useful Playnite settings are now exposed in [IPlayniteSettingsAPI](xref:Playnite.SDK.IPlayniteSettingsAPI).
* [ActivateGlobalProgress](xref:Playnite.SDK.IDialogsFactory) method to show blocking progress dialog.
* [LoadingChanged](xref:Playnite.SDK.IWebView) event for WebViews.
* [EvaluateScriptAsync](xref:Playnite.SDK.IWebView) method to execute JS code in a WebView.
* [GetCookies](xref:Playnite.SDK.IWebView) method to get webview cookies.
* [MarkdownToHtml](xref:Playnite.SDK.Data.Markup.MarkdownToHtml(System.String)) method for converting Markdown markup to HTML.
#### 5.2.0
* **Breaking Changes**:
* [Toolbox](tutorials/toolbox.md) utility has been reworked and accepts different arguments then previously.
* New
* Library plugins can now support extra [capabilities](tutorials/extensions/libraryPlugins.md#capabilities).
* Added [ImportGame](xref:Playnite.SDK.IGameDatabase.ImportGame(Playnite.SDK.Models.GameInfo)) methods to more easily add new games to the library.
* Added [OpenPluginSettings](xref:Playnite.SDK.IMainViewAPI.OpenPluginSettings(System.Guid)) method to open view with extension settings (also accessible via `OpenSettingsView` method inherited from `Plugin` class).
* Added [StartGame](xref:Playnite.SDK.IPlayniteAPI.StartGame(System.Guid)).
* Added [UriHandler](xref:Playnite.SDK.IPlayniteAPI.UriHandler) for registering of custom [URI method actions](tutorials/extensions/uriSupport.md).
* Added option settings when creating offscreen web view (currently only option to disable JavaScript execution).
* Added `OnGameSelected`, `OnApplicationStopped` and `OnLibraryUpdated` events.
* Added `Features` game field and appropriate support for it in metadata plugins.
* [Toolbox](tutorials/toolbox.md) utility can now generate plugins and scripts.
* [Toolbox](tutorials/toolbox.md) utility can pack plugins and scripts into `.pext` file that can be used for easier distribution and installation.
#### 5.1.0
* New
* Added support for creating metadata providers via [plugins](tutorials/extensions/metadataPlugins.md).
* [ChooseImageFile](xref:Playnite.SDK.IDialogsFactory) method for dialogs API. **Only available in Desktop mode.**
* [ChooseItemWithSearch](xref:Playnite.SDK.IDialogsFactory) method for dialogs API. **Only available in Desktop mode.**
#### 5.0.1
* Removed reference to LiteDB package. You can remove it from your plugin project if it's present.
#### 5.0.0
* **Breaking Changes**:
* Extension plugins are no longer created by inheriting plugin interface, but rather extending [Plugin](xref:Playnite.SDK.Plugins.Plugin) and [LibraryPlugin](xref:Playnite.SDK.Plugins.LibraryPlugin) abstract classes.
* [IGameDatabase](xref:Playnite.SDK.IGameDatabase) interface is completely changed and every object collection (Games, Genres, Tags etc.) is now accessible via appropriate `IItemCollection` property.
* [Game](xref:Playnite.SDK.Models.Game) changed dramatically. Fields like genres, tags and others are no longer part of the model itself but just ID pointers to appropriate database objects.
* New
* Extended several API with new methods.
#### 3.0.0
* **Breaking Changes**:
* Removed and added new APIs and API members.
* Game files are no longer stored in single database file. All game and media files are now accessible in their raw form even without user of database API.
#### 2.0.0
* **Breaking Changes**:
* In order to unify terminology used in Playnite's UI and that in SDK, some classes and class members were renamed.
* Extensions (both plugins and scripts) have to provide [extension manifest](tutorials/extensions/extensionsManifest.md) otherwise they won't be loaded.
* Various information about extension (author, version etc.) must be now stored in manifest file.
* Both plugins and scripts have to be stored in the same folder called `Extensions` (rather then in separate `Plugins` or `Scripts` folders).
* Signature for default C# plugins has changed and they now have to implement `IGenericPlugin` interface to be loaded.
* New Plugin types. There are now two types of plugins that can be implemented:
* Generic Plugin: Same as the old plugins.
* [Library Plugin](tutorials/extensions/libraryPlugins.md): Used to add new library providers responsible for automatic game import from various sources.
* All existing supported library importers (Steam, GOG etc.) are now distributed as [library plugins](https://github.com/JosefNemec/Playnite/tree/master/source/Plugins).
* New APIs:
* Static [LogManager](xref:Playnite.SDK.LogManager) for easier log operations.
* [Web Views API](xref:Playnite.SDK.IWebView) for creating web view windows or accessing offscreen browser.
* [Resources API](xref:Playnite.SDK.IPlayniteAPI.Resources) for getting application resources like localized strings.
* [Paths API](xref:Playnite.SDK.IPlayniteAPI.Paths) providing information about Playnite's application paths.
* [Application Info API](xref:Playnite.SDK.IPlayniteAPI.ApplicationInfo) providing information about Playnite.
* New Methods
* GetPluginUserDataPath: Gets path dedicated for plugins to store user data.
* GetPluginConfiguration: Gets plugin configuration if available.
* LoadPluginSettings: Loads plugin settings.
* SavePluginSettings: Saves plugin settings.
* ExpandGameVariables: Expands dynamic game variables in specified game action.
* CreateLogger: Creates new instance of Playnite logger with name of calling class.
#### 1.1.0
* **Breaking Change**: Scripts and Plugins must be place in subfolders rather then directly inside of `Scripts` or `Plugins` folders.
* New: `OnGameStarting` event that will execute before game is started. See [events](tutorials/extensions/events.md) for use from scripts.
* New: [ShowErrorMessage](xref:Playnite.SDK.IDialogsFactory.ShowErrorMessage(System.String,System.String)) method in `IDialogsFactory`

View File

@ -1,70 +0,0 @@
{
"metadata": [
{
"src": [
{
"files": [
"**.csproj"
],
"exclude": [
"**/bin/**",
"**/obj/**",
"_site/**"
],
"src" : "../source/PlayniteSDK/"
}
],
"dest": "api",
"disableGitFeatures": false,
"filter": "SDKfilter.yml"
}
],
"build": {
"content": [
{
"files": [
"api/**.yml",
"api/index.md"
]
},
{
"files": [
"tutorials/**.md",
"tutorials/**/toc.yml",
"manual/**.md",
"manual/**/toc.yml",
"toc.yml",
"*.md"
]
}
],
"resource": [
{
"files": [ "**/images/**" ]
}
],
"overwrite": [
{
"files": [
"apidoc/**.md"
],
"exclude": [
"obj/**",
"_site/**"
]
}
],
"dest": "_site",
"globalMetadataFiles": [],
"fileMetadataFiles": [],
"template": [
"default",
"templates/playnite"
],
"postProcessors": [],
"noLangKeyword": false,
"keepFileLink": false,
"cleanupCacheHistory": false,
"disableGitFeatures": false
}
}

View File

@ -1,20 +0,0 @@
# Playnite SDK documentation
> [!NOTE]
> There's currently very active community around theme/extension development on our [Discord server](https://discord.gg/hSFvmN6). We highly recommend joining if you plan to develop add-ons for Playnite!
### Extensions
To get documentation and tutorials on how to extend Playnite's functionality with scripts and plugins see [extension tutorials](tutorials/extensions/intro.md) page.
### Themes
To get documentation and about custom themes see [themes introduction](tutorials/themes/introduction.md) page.
### API Documentation
Full documentation for SDK interfaces and classes is available on [API Documentation](api/index.md) page.
### Changelog
See [changelog](changelog.md) page for full list of API changes.

View File

@ -1,27 +0,0 @@
Application arguments
=====================
Playnite executable accepts following arguments from command line.
| Argument | Description |
| -- | -- |
| --start <gameId> | Starts game with specified library ID. |
| --nolibupdate | Skips library update on startup. |
| --startdesktop | Forces application to start in Desktop mode. If there's an existing instance already running in Fullscreen mode, it will be switched to Desktop mode. |
| --startfullscreen | Forces application to start in Fullscreen mode. If there's an existing instance already running in Desktop mode, it will be switched to Fullscreen mode. | |
| --forcesoftrender | Forces application to use software render, disabling GPU acceleration. |
| --forcedefaulttheme | Forces application to use default theme. |
| --hidesplashscreen | Won't show startup splash screen. |
| --clearwebcache | Clears web (CEF) cache on startup. |
| --shutdown | Shuts down any existing instances of Playnite. |
| --safestartup | Start playnite in Safe Mode, only loading built-in extensions and using default theme. |
URI commands
---------------------
| Command | Description | Example |
| -- | -- | -- |
| start | Start a game. | playnite://playnite/start/64f78cd1-0b00-4271-a9e1-89abc55f66cc |
| showgame | Show game details for specific game. | playnite://playnite/showgame/64f78cd1-0b00-4271-a9e1-89abc55f66cc |
Extensions can register custom commands via [Playnite SDK](../tutorials/extensions/uriSupport.md).

View File

@ -1,129 +0,0 @@
Emulator support
=====================
General import guide
---------------------
General workflow for importing games is:
- Setup an emulator via Library -> Configure Emulators menu.
- Playnite can automatically import several well known emulators and will set all emulator properties for you. To import an emulator use `Import` button on configuration window.
- See [Emulator support](#emulator-configuration) section for more details about emulator setup.
- Import game image(s) (ROMs) via Add Game -> Emulated Game menu.
- See [Game import support](#game-import-support) section for more details.
- If you want the same directory to be re-scanned on startup (or manually) enable "Save as auto-scan" option. You can later edit saved scanner from emulator configuration window, "Auto-scan configuration" tab.
> [!NOTE]
> It's highly recommended to use automatically imported emulators and built-in profiles for better game import experience. Some built-in emulators (for example RPCS3 and ScummVM) use more advanced import mechanism then just matching file names and you won't be able to utilize it with custom profiles.
> [!NOTE]
> Playnite currently doesn't have built-in support for any arcade emulator. You will have to configure those manually. Built-in support for more well known arcade emulators will be added [in future](https://github.com/JosefNemec/Playnite/issues/2407). If you are having issues with non-arcade emulators, please open GitHub issue (games not being imported or launched properly).
Emulator support
---------------------
Playnite has a support for handling and importing of emulated games. The support is implemented in two ways:
`Built-in support`: Playnite can recognize and import several known [emulators](https://github.com/JosefNemec/Playnite/tree/master/source/Playnite/Emulation/Emulators). This also includes import of emulated based on libretro game database.
If you think that there's an emulator that should be added to built-in list, please [open new issue on GitHub](https://github.com/JosefNemec/Playnite/issues/) for it to be added.
`Custom support`: You can manually configure any emulator that provides a way of launching specific games via command line arguments. Automatic game import might not be as accurate as in case of built-in profiles, since custom emulators only provide scanning based on a file name and file extension.
Emulator configuration
---------------------
Recommend way of adding new emulator is by importing it. If an emulator is recognized as support emulator, it will be show on import dialog with an option to select which emulator profiles to import. Some emulators support multiple profiles, which affect how a game is started and imported.
Alternatively you can add new emulator manually if built-in support doesn't work in a way you prefer, or you can just add custom profile to automatically imported built-in emulator.
### Emulator properties
| Property | Description |
| --- | --- |
| Installation Folder | Emulator's installation folder. Can be passed into profile configurations dynamically via `{EmulatorDir}` variable.
| Emulator specification | Built-in emulator specification used for an emulator. Specifies what built-in profiles can be added to an emulator.
### Profile properties
Profiles handle how game is started and imported.
| Property | Description |
| --- | --- |
| Executable | File path to start an emulator. |
| Arguments | Startup arguments passed to an emulator during startup. |
| Working Directory | Working directory set to an emulator during startup. |
| Supported file types | File extensions separated by `,`. Used to detect ROM files by this profile. If you need to specify empty extension, use `<none>`. |
| Scripts | Profiles can execute custom scripts in the same way as [game or global scripts](gameScripts.md). |
### Startup script
If your profile contains `Startup script` code, Playnite will use that instead of general profile settings to launch an emulator. Emulator startup scripts works in the same way as [game startup scripts](gameScripts.md#startup-script). The only different is that emulator script have some additional variables available:
| Variable | Description |
| :-- | :-- |
| Emulator | [Emulator](xref:Playnite.SDK.Models.Emulator) selected to launch a game. |
| EmulatorProfile | [Emulator profile](xref:Playnite.SDK.Models.EmulatorProfile) selected to launch a game. |
| RomPath | ROM path selected to launch. |
### Custom profile example
Following example show how to configure `snex9x` emulator:
- Installation folder: `c:\some path\to\snes9x\`
- Executable: `{EmulatorDir}\snes9x.exe`
- Arguments: `"{ImagePath}" -fullscreen`
- Supported File Types: `zip, gz, jma, sfc, smc`
> [!NOTE]
> A lot of arcade emulators require ROM file to be passed via command line argument as a file name without complete path or file name without an extension. In that case you can use `{ImageName}` or `{ImageNameNoExt}` [game variables](gameVariables.md), instead of {ImagePath} which contains full path to a ROM file.
Game import support
---------------------
To import a game you need configure a scanner first. How games are imported is controller by an emulator and its selected profile. Built-in emulators/profiles use several different method how to detect a game.
Custom profiles primarily match games by specified file extensions. If you want to increase accuracy of the import, make sure you also assign correct platforms to the profile and that those platforms have [platform specification](libraryManager.md#platform-specification) assigned to them.
Playnite by default groups multi-disc games under one game entry. You can alternatively split or merge these via right-click menu after selecting games on import list. Right-click menu also gives you an ability to change platform and region in bulk.
Auto-scan configurations
---------------------
Scanner configurations can be used to automatically add new games during library import via `Update Game Library` menu. Specific configurations can be excluded from global library update on scanner configurations screen via `Library -> Configure Emulators` menu.
### Exclude patterns
These specify file patterns used during checksum scan. When a file matches specified pattern(s), its checksum won't be calculated and game will be imported based on other ROM properties (mainly file name). This can significantly speed up scanning process but also make import less accurate.
Multiple patterns can be specified by separating the list with comma: `*.chd,*.iso`
> [!NOTE]
> `chd` files are excluded by default because there are currently no records for them in emulation database Playnite uses for game matching.
Launching games
---------------------
If a game is imported via emulation import dialog, Playnite configures game launch via specific emulator (the one used to scan and import games) automatically. If you add a game manually, you can configure launch via an emulator by adding Emulator type [Play action](gameActions.md).
If a game has multiple ROM files assigned to it (on `Installation` tab while editing a game), Playnite will show selection during during game's startup, to specify which ROM should be passed to an emulator.
Troubleshooting
---------------------
If you encounter any issue when using built-in emulator configurations/profiles, please [open new issue on GitHub](https://github.com/JosefNemec/Playnite/issues/) to let us know and we will fix it.
### Emulator doesn't start
Usually occurs when using custom profile if executable path is not properly configured. Make sure that problematic profile points to an existing file.
### Emulator is not being imported
Playnite either doesn't have a profile for the emulator or the emulator has been updated in a way that prevents Playnite from detect it. In both case, please report an issue on GitHub
### Emulator starts, but game is not launched
This is usually caused by wrongly configured profile `Arguments` that are passed to the emulator. Make sure that arguments are configured according to what selected emulator supports (by checking its documentation).
### Game ROMs are not detected
When using custom emulator configurations, Playnite uses `Supported File Types` profile property to scan files ROM files. Make sure you have correct extensions specified.

View File

@ -1,55 +0,0 @@
Game actions
=====================
Introduction
---------------------
Game actions can be use either to start a game or to launch additional executables not related to game startup, for example configuration/mod utilities. Only actions marked as "Play" action are used to start a game, others are available to launch via game menu. If more then one Play action is available, Playnite will show selection dialog on game's startup to specify which action to use to start a game.
`Include library integration play actions` specifies whether integration plugin that imported a specific game, will be asked to handle game startup when the game is being launched.
Play actions can be also provided by plugins, see [game actions](../tutorials/extensions/gameActions.md) plugin page for more details.
Action properties
---------------------
| Property | Description |
| --- | --- |
| Play action | If enabled, Playnite will treat this action as Play action. Offering as an option when starting a game (if more than one option is available and counting play time from a started by this action. |
| Type | Action startup type. |
| Tracking mode | Only available for Play actions (`File` and `URL` types) since it affects how play time detection works. |
| Path | File path (or URL) to start. |
| Arguments | Startup arguments passed to an executable during startup. |
| Working directory | Working directory set to an executable during startup. |
### Action types
| Property | Description |
| --- | --- |
| File | Path is executed as a standard executable file. |
| URL | Path is executed as an URL address. |
| Emulator | Action is started using emulator configuration. |
| Script | Script used to start an application. See [game scripts](gameScripts.md#startup-script) page for more details. |
> [!WARNING]
> Non-play actions that use `Script` startup method will run synchronously on main thead. This means that they will block Playnite's UI until the script is finished running. Therefore make sure you don't use any long running operations in your startup script.
### Emulator settings
| Property | Description |
| --- | --- |
| Emulator | Emulator to launch. |
| Emulator profile | Emulator profile to use to launch a game. Selecting `Choose on startup` will give an option to select a profile |
### Tracking mode
| Property | Description |
| --- | --- |
| Default | Playnite will try to detect and use the best tracking method automatically. |
| Process | Playnite will track a game as running as long as original process or any of its child processes are running. |
| Folder | Playnite will track a game as running as long as some process from `Tracking path` folder is running. |
Troubleshooting
---------------------
In rare cases (depending on an application being started) the application won't start properly unless `Working directory` is not set to application's installation directory. If this happens you need to specify `Working directory` manually to a directory that makes selected application run properly. This is not an issue in Playnite, it's an issue in the started application.

View File

@ -1,164 +0,0 @@
Game scripts
=====================
Introduction
---------------------
Custom PowerShell scripts can be assigned via Playnite's UI to game events. This is similar in a way that extensions support hooking into game events, but doesn't require creation of custom extension and can be assigned on multiple levels:
- Global: executed for every game in a library.
- Emulator: executed for a specific emulator profile on all games using that profile.
- Game: executed for a specific game.
This is not the same as [script extensions](../tutorials/extensions/intro.md) which offer extended functionality and should be used for more complex scenarios.
> [!NOTE]
> PowerShell support requires PowerShell 5.1 to be installed on your machine. If you are Windows 7 user, you need to [install it manually](https://www.microsoft.com/en-us/download/details.aspx?id=54616) (Windows 8 and 10 includes it by default). This also means that PowerShell functionality is restricted to 5.1 version. Playnite currently doesn't support newer PowerShell Core runtime (PowerShell versions 6 and newer).
Execution
---------------------
Scripts are executed in the following order:
global pre -> emulator pre -> game pre -> game post -> emulator post -> global post -> emulator exit -> game exit -> global exit
where:
- pre - before game is started.
- post - after game is started running.
- exit - after game stopped running.
If a game has installation directory set and that directory actually exists, Playnite will set current working directory of a script runtime to that installation directory.
All scripts share the same runtime environment for a single game session. This means that you can share data between them if you declare your variables on global scope, for example `$global:testVar = 2`.
> [!NOTE]
> All scripts are executed synchronously, meaning that Playnite will wait for a script to finish and will block any other execution, including UI since the script runtime runs on main thread.
Startup script is an exception to mentioned execution behavior, see startup script section for more details.
Script variables
---------------------
Playnite provides some built-in global variables that scripts can use to get more information about current game session.
| Variable | Description |
| :-- | :-- |
| PlayniteApi | Instance of [Playnite API](xref:Playnite.SDK.IPlayniteAPI). |
| Game | [Game](xref:Playnite.SDK.Models.Game) library object for current game session. |
| SourceAction | Custom [game action](xref:Playnite.SDK.Models.GameAction) used to start a game. |
| SelectedRomFile | ROM file selected when running a game with multiple ROMs assigned. |
Startup script
---------------------
If you need more complex startup and game tracking procedure other then just starting an executable, or default session tracking doesn't work for a specific game, then you can start and manage game session using a script. This is currently available to emulators (custom profiles) and games.
The script should keep running while you want Playnite to detect the game as running. Once the script finishes with execution, Playnite considers the game to stop running and will record game session length based on how long the script was running (adding that time to overall game play time).
> [!NOTE]
> Startup scripts run in a separate script runtime and thread compared to other game scripts. Therefore you can't share data with other game/global scripts and you can't directly call any code that must be run on main thread (most UI things)!
>
> Breaking exceptions from startup script are not propagated to UI via error message (like for other game/global scripts) and are only logged into Playnite's log file.
### Startup script example
```powershell
$process = [System.Diagnostics.Process]::Start("game.exe")
$process.WaitForExit()
$process.Dispose()
```
### Reacting to tracking cancellation
You can use `$CancelToken.IsCancellationRequested` to detect if user cancelled game session manually from Playnite. When cancellation is initiated, Playnite sets mentioned property to `true` and gives the script 10 seconds to exit gracefully. If the script fails to exit in that time, script's runtime is killed.
```powershell
# WaitForExit() is synchronous check so it can't be used if you want to support session cancellation
$process = [System.Diagnostics.Process]::Start("game.exe")
while ($true)
{
# Check if user cancelled game session
if ($CancelToken.IsCancellationRequested)
{
break
}
# Check if process is still running
if (!(Get-Process -Name "game" -EA 0))
{
break
}
# Sleep for a while to not waste CPU
Start-Sleep -s 1
}
$process.Dispose()
```
### Startup script variables
| Variable | Description |
| :-- | :-- |
| PlayniteApi | Instance of [Playnite API](xref:Playnite.SDK.IPlayniteAPI). |
| Game | [Game](xref:Playnite.SDK.Models.Game) library object for current game session. |
| IsPlayAction | Indicates whether an action was started as play action. |
Examples
---------------------
### Starting additional application(s) before game starts and killing it after game exits.
* Edit game and go to `Scripts` tab
* Change runtime to `PowerShell`
* Set first script to start your application using [Start-Process](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/start-process?view=powershell-5.1) cmdlet
```powershell
Start-Process "c:\somepath\someapp.exe" "-some arguments"
```
* Set second script to kill the application using [Stop-Process]https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/stop-process?view=powershell-5.1) cmdlet
```powershell
Stop-Process -Name "someapp"
```
* If the application requires elevated rights to start then you need to start Playnite as admin too, otherwise the `Stop-Process` will fail due to insufficient privileges.
* If you want to start application minimized and application doesn't have native support for it then add `-WindowStyle` argument.
```powershell
Start-Process "c:\somepath\someapp.exe" "-some arguments" -WindowStyle Minimized
```
Troubleshooting
---------------------
### Application doesn't start
Some applications won't work properly (or even start) when started using working directory outside of their application director. In that case you need to use `-WorkingDirectory` parameter and specify working directory manually.
### Can't shutdown process
You won't be able to use `Stop-Process` on processes that are started with elevated rights. In that case, you need to use WMI to shutdown a process:
```powershell
(Get-WmiObject -Class Win32_Process -Filter "name = 'someapp.exe'").Terminate()
```
### Exceptions related to directory not being found
Paths (and strings in general) in various places in PowerShell are handled not as literal strings, but as strings with wildcard patterns. This has unfortunate issue if specific command doesn't allow you to pass literal string via a specific argument (for example `-LiteralPath`) or has an option to disable wildcard parsing.
This can cause issues if game's installation path contains wildcard pattern characters. For example game installed in `d:\[test] game name\` will cause issues to `Start-Process` cmdlet, because of `[` and `]` pattern characters. This is because Playnite sets script runtime's working directory to game's installation path and Start-Process tries to parse it before launching a program.
Solution is to either use literal path arguments or use different cmdlet or .NET classes directly. For example to start a process:
```powershell
# Instead of:
Start-Process "game.exe"
# call .NET class directly:
[System.Diagnostics.Process]::Start("game.exe")
```
Note: This issue has been fixed in newer versions of PowerShell, but since Playnite has to use older version (5.1) until we switch to newer .NET runtime, you may encounter this issue.

View File

@ -1,28 +0,0 @@
Game variables
=====================
Following is the list of game variables that can be used in various places, specifically in:
- game links
- emulator configuration fields
- game action fields
To use a variable, encapsulate it with curly brackets in a string, for example:
`some string {GameId} test`
|Variable|Description|
| ------------- | ------------- |
|InstallDir|Game installation directory|
|InstallDirName|Name of installation folder
|ImagePath|Game ISO/ROM path if set|
|ImageName|Game ISO/ROM file name|
|ImageNameNoExt|Game ISO/ROM file name without extension|
|PlayniteDir|Playnite's installation directory|
|Name|Game name |
|Platform|Game's platform |
|GameId|Game's ID |
|DatabaseId|Game's database ID |
|PluginId|Game's library plugin ID |
|Version|Game version|
|EmulatorDir|Emulator's installation directory|

View File

@ -1,34 +0,0 @@
Library manager
=====================
Introduction
---------------------
Library manager can be accessed from main menu `Library -> Library manager` sub menu. I can be used to manage various game fields shared between games.
Platforms
---------------------
### Custom images
Icon, Cover and Background images assigned to a platform can be used as a replacement images for games that don't have any of those images assigned. Whether platform images will be used can be controlled via application settings in `Appearance -> Advanced` section via `Missing game * source` options.
### Platform specification
Platform specification fields allow you indicate to Playnite how to treat your specific platform based on internal list of built-in platforms. Setting this to correct value will improve field assignments from various automatic actions like game import or metadata import and will also prevent creation of potential platform duplicates.
If you don't see a platform on the list of platform specifications, please [open new GitHub issue](https://github.com/JosefNemec/Playnite/issues) for the platform to be added.
Regions
---------------------
Similar to platform specifications, you can assign region specification from built-in list of regions to improve automatic game and metadata imports.
Completion statuses
---------------------
Completion statuses view offers additional settings used to configure how Playnite handles specific statuses.
`Default status assigned to newly added games`: specify which status will be assigned to newly imported imported games with no play time recorded yet.
`Status assigned to games played for the first time`: specify which status will be assigned to games played for the first time.

View File

@ -1,17 +0,0 @@
- name: Application arguments
href: cmdlineArguments.md
- name: Game variables
href: gameVariables.md
- name: Game scripts
href: gameScripts.md
- name: Emulator support
href: emulators.md
- name: Game actions
href: gameActions.md
- name: Library manager
href: libraryManager.md

View File

@ -1,17 +0,0 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
<h1 id="{{id}}" data-uid="{{uid}}" class="text-break">{{>partials/title}}</h1>
<div class="markdown level0 summary">{{{summary}}}</div>
<div class="markdown level0 conceptual">{{{conceptual}}}</div>
{{#inClass}}
<h6><strong>{{__global.namespace}}</strong>: {{{namespace.specName.0.value}}}</h6>
{{#remarks}}
<h5 id="{{id}}_remarks"><strong>{{__global.remarks}}</strong></h5>
<div class="markdown level0 remarks">{{{remarks}}}</div>
{{/remarks}}
{{#example.0}}
<h5 id="{{id}}_examples"><strong>{{__global.examples}}</strong></h5>
{{/example.0}}
{{#example}}
{{{.}}}
{{/example}}

View File

@ -1,246 +0,0 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
{{>partials/class.header}}
{{#inheritedMembers.0}}
<div class="inheritance">
<h3>Inherited members</h3>
{{/inheritedMembers.0}}
{{#inheritedMembers}}
<div class="level{{index}}">
{{#definition}}
<xref href="{{definition}}" fullName="{{fullName.0.value}}" name="{{name.0.value}}"/>
{{/definition}}
{{^definition}}
<xref href="{{uid}}" fullName="{{fullName.0.value}}" name="{{name.0.value}}"/>
{{/definition}}
</div>
{{/inheritedMembers}}
{{#inheritedMembers.0}}
</div>
{{/inheritedMembers.0}}
{{#children}}
<h3 id="{{id}}">{{>partials/classSubtitle}}</h3>
{{#children}}
{{^_disableContribution}}
{{#docurl}}
<span class="small pull-right mobile-hide">
<span class="divider">|</span>
<a href="{{docurl}}">{{__global.improveThisDoc}}</a>
</span>{{/docurl}}
{{#sourceurl}}
<span class="small pull-right mobile-hide">
<a href="{{sourceurl}}">{{__global.viewSource}}</a>
</span>{{/sourceurl}}
{{/_disableContribution}}
{{#overload}}
<a id="{{id}}" data-uid="{{uid}}"></a>
{{/overload}}
<h4 id="{{id}}" data-uid="{{uid}}">{{name.0.value}}</h4>
<div class="markdown level1 summary">{{{summary}}}</div>
<div class="markdown level1 conceptual">{{{conceptual}}}</div>
{{#syntax}}
{{#parameters.0}}
<h5 class="parameters">{{__global.parameters}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.name}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
{{/parameters.0}}
{{#parameters}}
<tr>
<td>{{{type.specName.0.value}}}</td>
<td><span class="parametername">{{{id}}}</span></td>
<td>{{{description}}}</td>
</tr>
{{/parameters}}
{{#parameters.0}}
</tbody>
</table>
{{/parameters.0}}
{{#return}}
<h5 class="returns">{{__global.returns}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{{type.specName.0.value}}}</td>
<td>{{{description}}}</td>
</tr>
</tbody>
</table>
{{/return}}
{{#typeParameters.0}}
<h5 class="typeParameters">{{__global.typeParameters}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.name}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
{{/typeParameters.0}}
{{#typeParameters}}
<tr>
<td><span class="parametername">{{{id}}}</span></td>
<td>{{{description}}}</td>
</tr>
{{/typeParameters}}
{{#typeParameters.0}}
</tbody>
</table>
{{/typeParameters.0}}
{{#fieldValue}}
<h5 class="fieldValue">{{__global.fieldValue}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{{type.specName.0.value}}}</td>
<td>{{{description}}}</td>
</tr>
</tbody>
</table>
{{/fieldValue}}
{{#propertyValue}}
<h5 class="propertyValue">{{__global.propertyValue}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{{type.specName.0.value}}}</td>
<td>{{{description}}}</td>
</tr>
</tbody>
</table>
{{/propertyValue}}
{{#eventType}}
<h5 class="eventType">{{__global.eventType}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{{type.specName.0.value}}}</td>
<td>{{{description}}}</td>
</tr>
</tbody>
</table>
{{/eventType}}
{{/syntax}}
{{#overridden}}
<h5 class="overrides">{{__global.overrides}}</h5>
<div><xref uid="{{uid}}" altProperty="fullName" displayProperty="nameWithType"/></div>
{{/overridden}}
{{#remarks}}
<h5 id="{{id}}_remarks">{{__global.remarks}}</h5>
<div class="markdown level1 remarks">{{{remarks}}}</div>
{{/remarks}}
{{#example.0}}
<h5 id="{{id}}_examples">{{__global.examples}}</h5>
{{/example.0}}
{{#example}}
{{{.}}}
{{/example}}
{{#exceptions.0}}
<h5 class="exceptions">{{__global.exceptions}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.condition}}</th>
</tr>
</thead>
<tbody>
{{/exceptions.0}}
{{#exceptions}}
<tr>
<td>{{{type.specName.0.value}}}</td>
<td>{{{description}}}</td>
</tr>
{{/exceptions}}
{{#exceptions.0}}
</tbody>
</table>
{{/exceptions.0}}
{{#seealso.0}}
<h5 id="{{id}}_seealso">{{__global.seealso}}</h5>
<div class="seealso">
{{/seealso.0}}
{{#seealso}}
{{#isCref}}
<div>{{{type.specName.0.value}}}</div>
{{/isCref}}
{{^isCref}}
<div>{{{url}}}</div>
{{/isCref}}
{{/seealso}}
{{#seealso.0}}
</div>
{{/seealso.0}}
{{/children}}
{{/children}}
{{#implements.0}}
<h3 id="implements">{{__global.implements}}</h3>
{{/implements.0}}
{{#implements}}
<div>
{{#definition}}
<xref uid="{{definition}}" altProperty="fullName" displayProperty="nameWithType"/>
{{/definition}}
{{^definition}}
<xref uid="{{uid}}" altProperty="fullName" displayProperty="nameWithType"/>
{{/definition}}
</div>
{{/implements}}
{{#extensionMethods.0}}
<h3 id="extensionmethods">{{__global.extensionMethods}}</h3>
{{/extensionMethods.0}}
{{#extensionMethods}}
<div>
{{#definition}}
<xref uid="{{definition}}" altProperty="fullName" displayProperty="nameWithType"/>
{{/definition}}
{{^definition}}
<xref uid="{{uid}}" altProperty="fullName" displayProperty="nameWithType"/>
{{/definition}}
</div>
{{/extensionMethods}}
{{#seealso.0}}
<h3 id="seealso">{{__global.seealso}}</h3>
<div class="seealso">
{{/seealso.0}}
{{#seealso}}
{{#isCref}}
<div>{{{type.specName.0.value}}}</div>
{{/isCref}}
{{^isCref}}
<div>{{{url}}}</div>
{{/isCref}}
{{/seealso}}
{{#seealso.0}}
</div>
{{/seealso.0}}

View File

@ -1,28 +0,0 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
{{#inConstructor}}
{{__global.constructorsInSubtitle}}
{{/inConstructor}}
{{#inField}}
{{__global.fieldsInSubtitle}}
{{/inField}}
{{#inProperty}}
{{__global.propertiesInSubtitle}}
{{/inProperty}}
{{#inMethod}}
{{__global.methodsInSubtitle}}
{{/inMethod}}
{{#inEvent}}
{{__global.eventsInSubtitle}}
{{/inEvent}}
{{#inOperator}}
{{__global.operatorsInSubtitle}}
{{/inOperator}}
{{#inEii}}
{{__global.eiisInSubtitle}}
{{/inEii}}
{{#inFunction}}
{{__global.functionsInSubtitle}}
{{/inFunction}}
{{#inMember}}
{{__global.membersInSubtitle}}
{{/inMember}}

View File

@ -1,29 +0,0 @@
@media (min-width:992px){.container{width:970px}
}
@media (min-width:1350px){.container{width:1300px}
}
.tabGroup section[role="tabpanel"] > .codeHeader, .tabGroup section[role="tabpanel"] > pre
{
border-radius: 0px;
}
.tabGroup section[role="tabpanel"] > :first-child
{
margin-top: -16px;
}
.tabGroup {
margin-top: 1rem;
margin-bottom: 1rem;
}
.alert-info {
color: #333;
background-color: #d9edf7;
border-color: #bce8f1;
}
article h4 {
border-bottom: 0px;
}

View File

@ -1,7 +0,0 @@
- name: Tutorials
href: tutorials/
- name: Manual
href: manual/
- name: API Documentation
href: api/
homepage: api/index.md

View File

@ -1,113 +0,0 @@
Custom UI Integration
=====================
Introduction
---------------------
Extensions can expose custom UI elements for themes to integrate, this requires support by both an extension and a theme. For theme implementation part, see [this page](../themes/extensionIntegration.md).
Implementation
---------------------
### User Control implementation
1) Add new standard WPF UserControl into your project.
2) Change base class from `UserControl` to `PluginUserControl`
You should end up with something like this:
```xml
<PluginUserControl x:Class="TestPlugin.TestPluginUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
</Grid>
</PluginUserControl>
```
```csharp
public partial class TestPluginUserControl : PluginUserControl
{
public TestPluginUserControl()
{
InitializeComponent();
}
}
```
### Registering custom control
For new control to be recognized by Playnite API and themes call [AddCustomElementSupport](xref:Playnite.SDK.Plugins.Plugin.AddCustomElementSupport(Playnite.SDK.Plugins.AddCustomElementSupportArgs)) method in plugin's constructor.
`AddCustomElementSupportArgs` contains several arguments:
|Property|Description|
|:---|:---|
|ElementList| List of element names supported by the plugin. |
|SourceName| Plugin source name for element name references and settings bindings. |
Following example will allow themes to reference plugin controls by `TestPlugin_TestUserControl1` and `TestPlugin_TestUserControl2` names:
```csharp
AddCustomElementSupport(new AddCustomElementSupportArgs
{
ElementList = new List<string> { "TestUserControl1", "TestUserControl2" },
SourceName = "TestPlugin"
});
```
Lastly, override [GetGameViewControl](xref:Playnite.SDK.Plugins.Plugin.GetGameViewControl(Playnite.SDK.Plugins.GetGameViewControlArgs)) method. The method is called when theme view template is initialized and plugin control should be "injected" into the view.
Example:
```csharp
public override Control GetGameViewControl(GetGameViewControlArgs args)
{
if (args.Name == "TestUserControl")
{
return new TestPluginUserControl();
}
return null;
}
```
### Handling data context
Data of currently bound game object can be accessed via PluginUserControl's `GameContext` property. If you want to react to data context changes, you can override [GameContextChanged](xref:Playnite.SDK.Controls.PluginUserControl.GameContextChanged(Playnite.SDK.Models.Game,Playnite.SDK.Models.Game)) method.
Exposing extension settings
---------------------
You can provide easy way for themes to reference extension settings by calling [AddSettingsSupport](xref:Playnite.SDK.Plugins.Plugin.AddSettingsSupport(Playnite.SDK.Plugins.AddSettingsSupportArgs)) method in plugin's constructor, similarly to how custom element support is done.
`AddSettingsSupport` contains several arguments:
|Property|Description|
|:---|:---|
|SourceName| Plugin source name for element name references and settings bindings. |
|SettingsRoot| Binding root path relative to a plugin object instance. |
`SettingsRoot` must be relative binding path to the plugin class. For example, if your plugin class stores settings in `Settings` property, then SettingsRoot should be set to just "Settings". If you want themes to dynamically react to settings changes, then you need to implement `INotifyPropertyChanged` on your settings object.
Example:
```csharp
AddSettingsSupport(new AddSettingsSupportArgs
{
SourceName = "TestPlugin",
SettingsRoot = $"binding.path.relative.to.plugin.object"
});
```
Themes can then reference settings via `PluginSettings` markup. See [theme integration page](../themes/extensionIntegration.md#extension-settings) for more details.
Theme integration
---------------------
See [theme integration page](../themes/extensionIntegration.md) for more details.
As an extension developer you should provide following information to theme developer:
`Source name`: For both general UI integration and settings integration.
`Element list`: List of element names that you extension exposes and themes can integrate.
`Settings list`: If your extension exposes settings that can be used by themes.
`Addon id`: Addon id used in extension manifest, for theme developers to be able to [detect](../themes/extensionIntegration.md#detecting-if-an-extension-is-installed) if your extension is installed or not.

View File

@ -1,16 +0,0 @@
Script data directory
=====================
Extensions should store any generated data in a designated extension data directory instead of its installation directory, because installation directory gets purged during extension installation or update.
Scripts
---------------------
To get script data directory, use `CurrentExtensionDataPath` global variable.
To get installation directory of currently running script, use `CurrentExtensionInstallPath` global variable. In PowerShell scripts you may also use the standard `$PSScriptRoot` variable.
Plugins
---------------------
To get the directory, call [GetPluginUserDataPath](xref:Playnite.SDK.Plugins.Plugin.GetPluginUserDataPath) method. The method returns full path designated to to a specific plugin. The same directory is used to store plugin [settings](pluginSettings.md).

View File

@ -1,71 +0,0 @@
Reacting to events
=====================
Introduction
---------------------
Playnite's API allows extensions to react to various events, like when a game is started or installed.
Available Events
---------------------
| Name | Event | Passed Arguments |
| --- | --- | --- |
| OnGameStarting | Before game is started. | [OnGameStartingEventArgs](xref:Playnite.SDK.Events.OnGameStartingEventArgs) |
| OnGameStarted | Game started running. | [OnGameStartedEventArgs](xref:Playnite.SDK.Events.OnGameStartedEventArgs) |
| OnGameStopped | Game stopped running. | [OnGameStoppedEventArgs](xref:Playnite.SDK.Events.OnGameStoppedEventArgs) |
| OnGameInstalled | Game is installed. | [OnGameInstalledEventArgs](xref:Playnite.SDK.Events.OnGameInstalledEventArgs) |
| OnGameUninstalled | Game is uninstalled. | [OnGameUninstalledEventArgs](xref:Playnite.SDK.Events.OnGameUninstalledEventArgs) |
| OnGameSelected | Game selection changed. | [OnGameSelectedEventArgs](xref:Playnite.SDK.Events.OnGameSelectedEventArgs) |
| OnApplicationStarted | Playnite was started. | [OnApplicationStartedEventArgs](xref:Playnite.SDK.Events.OnApplicationStartedEventArgs) |
| OnApplicationStopped | Playnite is shutting down. | [OnApplicationStoppedEventArgs](xref:Playnite.SDK.Events.OnApplicationStoppedEventArgs) |
| OnLibraryUpdated | Library was updated. | [OnLibraryUpdatedEventArgs](xref:Playnite.SDK.Events.OnLibraryUpdatedEventArgs) |
Example - Handling start/stop events
---------------------
### Game Starting
Following example writes name of currently playing game into a text file.
# [C#](#tab/csharp)
```csharp
# To have a code executed on a specific event, override selected event method in your plugin.
public override void OnGameStarted(OnGameStartedEventArgs args)
{
logger.Info($"Game started: {args.Game.Name}");
}
```
# [PowerShell](#tab/tabpowershell)
```powershell
# To have a code executed on a specific event, define script function with selected name and export it from your PowerShell extension module.
function OnGameStarted()
{
param($args)
$ags.Game.Name | Out-File "RunningGame.txt"
}
```
***
### Game Stopped
This example writes name of game that stopped running and the time game was running for into a text file.
# [C#](#tab/csharp)
```csharp
public override void OnGameStopped(OnGameStoppedEventArgs args)
{
logger.Info($"{args.Game.Name} was running for {args.ElapsedSeconds} seconds");
}
```
# [PowerShell](#tab/tabpowershell)
```powershell
function OnGameStopped()
{
param($args)
"$($args.Game.Name) was running for $($args.ElapsedSeconds) seconds" | Out-File "StoppedGame.txt"
}
```
***

View File

@ -1,21 +0,0 @@
Working With Dynamic Variables
=====================
Basics
---------------------
Some game fields support user of dynamic variables. For example game action can have working directory pointing to `{InstallDir}`, Playnite then inserts game's installation directory when executing action. Playnite API provides [ExpandGameVariables](xref:Playnite.SDK.IPlayniteAPI.ExpandGameVariables(Playnite.SDK.Models.Game,System.String)) method which resolves these variables from any string.
Full list of variables is available on [here](../../manual/gameVariables.md).
Example
---------------------
Lets say we have a game which has Play action with `Path` set to `{InstallDir}\app.exe` and `InstallDirectory` to `c:\appdir\`. To get full path `c:\appdir\app.exe` use [ExpandGameVariables](xref:Playnite.SDK.IPlayniteAPI.ExpandGameVariables(Playnite.SDK.Models.Game,System.String)) method.
```powershell
$PlayniteApi.ExpandGameVariables($game, $game.PlayTask.Path)
```
> [!NOTE]
> You don't have to check if the string contains any dynamic variables to know whether to use `ExpandGameVariables` or not. If input string doesn't contain any dynamic variables it won't be modified in any way and `ExpandGameVariables` just returns it untouched.

View File

@ -1,52 +0,0 @@
Extensions Manifest
=====================
Extension manifest files are used by Playnite to load extensions and display basic information to user on extension settings dialog. Manifest files are mandatory and extension won't be loaded unless valid manifest file is present inside extension directory under `extension.yaml` file name.
Format
---------------------
Manifest is YAML formatted file with following properties:
| Property | Description |
| -- | -- |
| Id | Unique string identifier for the extension. Must not be shared with any other extension. |
| Name | Extension name. |
| Author | Extension author. |
| Version | Extension version, must be a valid [.NET version string](https://docs.microsoft.com/en-us/dotnet/api/system.version). |
| Module | File name of assembly `*.dll` file for plugins, `*.psm1` or `*.psd1` file for scripts. |
| Type | Extension type, available values are: `Script`, `GenericPlugin`, `GameLibrary`, `MetadataProvider`. |
| Icon | Optional relative file name of extension icon. |
| Links | Optional list of links (extension website, changelog etc.) |
Examples
---------------------
**Example of script extension:**
```yaml
Id: LibraryExporter_Playnite_Script
Name: Library Exporter
Author: Playnite
Version: 1.0
Module: LibraryExporter.psm1
Type: Script
Links:
- Name: Website
Url: https://some.website.nowhere
```
**Example of library plugin:**
```yaml
Id: SomeLibraryPlugin_Playnite_Plugin
Name: Some Library Plugin
Author: Playnite
Version: 1.0
Module: SomeLibraryPlugin.dll
Type: GameLibrary
Icon: pluginicon.png
Links:
- Name: Website
Url: https://some.website.nowhere
```

View File

@ -1,45 +0,0 @@
Game actions
=====================
Introduction
---------------------
Extensions can "inject" game actions dynamically when a game is started rather then assigning them permanently to a game. How this works is that when starting a game, Playnite asks all installed plugins if they know how to handle specific operation for a selected game and if they return controller for that specific action, Playnite will give user an option to use implementation from those plugins.
> [!NOTE]
> Make sure you are returning actions only for games your plugin is able to handle properly. For example by checking if game's source `PluginId` matches yours if you are implementing a controller for a library plugin. You should not be returning any controllers for a game that you can't provide support for.
Play actions
---------------------
Play actions control how a game is started and are also responsible for play time tracking. To implement play action handling, override `GetPlayActions` method from your plugin and return [PlayController](xref:Playnite.SDK.Plugins.PlayController) object implementing game startup functionality.
In you play controller: call `InvokeOnStarted` after the game is started and `InvokeOnStopped` when the game stops running. `InvokeOnStopped` should provide information about last game session, mainly how long the session lasted, for Playnite to record play time properly.
"Automatic" play actions
---------------------
If game startup procedure for your plugin doesn't require any special handling, you can use [AutomaticPlayController](xref:Playnite.SDK.Plugins.AutomaticPlayController) to simplify play action controller implementation. `AutomaticPlayController` mirrors functionality of manual play action configuration you can assign via Playnite UI, it provides the same fields and functionality.
```csharp
public override IEnumerable<PlayController> GetPlayActions(GetPlayActionsArgs args)
{
yield return new AutomaticPlayController(args.Game)
{
Type = GenericPlayActionType.File,
TrackingMode = TrackingMode.Process,
Name = "Notepad",
Path = "notepad.exe"
};
}
```
Install an uninstall actions
---------------------
Similar to how Play controllers are implemented, override `GetInstallActions` and/or `GetUninstallActions` methods. Install controllers should provide [GameInstallationData](xref:Playnite.SDK.Plugins.GameInstallationData) when calling `InvokeOnInstalled` for installation status to be set properly.
Examples
---------------------
You can check [built-in Playnite extensions](https://github.com/JosefNemec/PlayniteExtensions) for various examples of controller implementations.

View File

@ -1,77 +0,0 @@
Generic Plugins
=====================
To implement generic plugin:
* Read the introduction to [extensions](intro.md) and [plugins](plugins.md).
* Create new public class inheriting from [Plugin](xref:Playnite.SDK.Plugins.Plugin) abstract class.
* Add implementation for mandatory abstract members.
Mandatory members
---------------------
| Member | Description |
| -- | -- |
| Id | Unique plugin id. |
Optional members
---------------------
You can implement additional functionality by overriding virtual methods from [Plugin](xref:Playnite.SDK.Plugins.Plugin) base class.
Example plugin
---------------------
```csharp
public class TestPlugin : Plugin
{
private ILogger logger;
public override Guid Id { get; } = Guid.Parse("D51194CD-AA44-47A0-8B89-D1FD544DD9C9");
public TestPlugin(IPlayniteAPI api) : base(api)
{
logger = api.CreateLogger();
}
public override void OnGameInstalled(Game game)
{
// Add code to be executed when game is finished installing.
}
public override void OnGameStarted(Game game)
{
// Add code to be executed when game is started running.
}
public override void OnGameStarting(Game game)
{
// Add code to be executed when game is preparing to be started.
}
public override void OnGameStopped(Game game, long elapsedSeconds)
{
// Add code to be executed when game is preparing to be started.
}
public override void OnGameUninstalled(Game game)
{
// Add code to be executed when game is uninstalled.
}
public override void OnApplicationStarted()
{
// Add code to be execute when Playnite is initialized.
}
public override void OnApplicationStopped()
{
// Add code to be executed when Playnite is shutting down.
}
public override void OnLibraryUpdated()
{
// Add code to be execute when library is updated.
}
}
```

View File

@ -1,83 +0,0 @@
# Introduction to Playnite extensions
Basics
---------------------
Playnite can be extended via extensions implemented via scripts and plugins:
- Scripts: [PowerShell](https://docs.microsoft.com/en-us/powershell/) scripts are supported.
- Plugins: Any .NET Framework compatible language can be used (`C#`, `VB.NET`, `F#` and others).
Extensions fall under several categories of extended functionality that are available based on selected implementation:
| Functionality | Scripts | Plugins |
| -- | :--: | :--: |
| Adding game and main menu entries | • | • |
| Reacting to game events | • | • |
| Adding new UI elements | | • |
| Injecting game actions | | • |
| Library importer | | • |
| Metadata provider | | • |
- `Adding game and main menu entries` - ability to add new executable [menu entries](menus.md) to main menu and game menu.
- `Reacting to game events` - ability to execute code when various [game events](events.md) occur, like when game is started or stopped for example.
- `Adding new UI elements` - ability to add new [UI elements](ui.md) to various views and panels.
- `Injecting game actions` - gives ability to "inject" new Play, Install and Uninstall [game actions](gameActions.md) in real-time.
- `Library importer` - provides automatic import of games from various sources. For example all currently supported external clients (Steam, GOG, Origin etc.) [are implemented](https://github.com/JosefNemec/Playnite/tree/master/source/Plugins) via this extension type.
- `Metadata provider` - provides metadata for games in Playnite. Our default metadata provider, IGDB.com, is also [implemented as a metadata plugin](https://github.com/JosefNemec/Playnite/tree/master/source/Plugins/IGDBMetadata).
> [!WARNING]
> Extension installation and update always replaces the entire extension directory completely. Meaning that any files that are not part of the installation package will be lost during installation process! It is highly recommended to store generated files in a separate extensions data folder. See [Data directories](dataDirectory.md) page to learn more about extension directories.
> [!NOTE]
> There's currently very active community around theme/extension development on our [Discord server](https://discord.gg/hSFvmN6). We highly recommend joining if you plan to develop add-ons for Playnite!
Creating Extensions
---------------------
It's highly recommended to use [Toolbox](../toolbox.md) utility to create new extensions. It will generate base directory structure and all files needed for you.
### 1. Directory structure and location
First create new extension folder inside of Playnite's `Extensions` directory. Location of `Extensions` directory differs based on Playnite's installation type:
- Portable version: `Extensions` folder directly inside of Playnite's installation location.
- Installed version: `%AppData%\Playnite\Extensions` folder.
> [!NOTE]
> You can load extensions from custom directories by adding them as developer plugins in Playnite's `For developers` settings menu.
### 2. Manifest file
Every extension must provide valid [manifest file](extensionsManifest.md) in order to be recognized and loaded by Playnite. Manifest is YAML formatted file called `extension.yaml` that must be stored inside of extension directory.
Resulting folder structure should look something like this:
```
├──Install directory or %AppData%\Playnite
│ └── Extensions
│ └── ExtensionFolder
│ ├── extension.yaml
│ └── scriptFileName.psm1 or pluginFileName.dll
```
See manifest file [documentation page](extensionsManifest.md) for more information about manifest contents.
### 3. Implementing extension
For scripts see [scripting introduction page](scripting.md).
For plugins see [plugins introduction page](plugins.md).
Loading extensions
---------------------
Extensions are loaded automatically by Playnite at every startup (unless extension is disabled via settings menu). Script can be reloaded at runtime via `Tools -> Reload Scripts` menu. Plugins can't be reloaded at runtime.
Distribution
---------------------
Use [Toolbox](../toolbox.md#packing-extensions) utility to package an extension or a theme and distribute `.pext` or `.pthm` file to users.
The best place to share extensions is via [Playnite add-on database](https://github.com/JosefNemec/PlayniteAddonDatabase), submitting an add-on there will make it available in Playnite's built-in add-on browser and will also enable easy add-on installation and updates.
It's also recommended to submit add-on entry to official Playnite forum, specifically [add-on database](https://playnite.link/forum/forum-3.html) sub-forum.

View File

@ -1,151 +0,0 @@
Working with game library
=====================
Introduction
---------------------
Game database API allows you to access and modify game library and its objects (including platforms and emulators). Database API can be accessed via `PlayniteAPI.Database` property, which provides [IDatabaseAPI](xref:Playnite.SDK.IGameDatabaseAPI) interface.
Handling Games
---------------------
### Getting Games
To get list of all games in library use [Database](xref:Playnite.SDK.IPlayniteAPI.Database) property from `IPlayniteAPI` and [Games](xref:Playnite.SDK.IGameDatabase.Games) collection.
# [C#](#tab/csharp)
```csharp
foreach (var game in PlayniteApi.Database.Games)
{
// Do stuff with a game
}
// Get a game with known Id
var game = $PlayniteApi.Database.Games[SomeGuidId];
```
# [PowerShell](#tab/tabpowershell)
```powershell
# Get all games
$games = $PlayniteApi.Database.Games
# Get a game with known Id
$game = $PlayniteApi.Database.Games[$SomeGuidId]
```
***
### Adding New Game
To add a new game create new instance of [Game](xref:Playnite.SDK.Models.Game) class and call `Add` method from [Games](xref:Playnite.SDK.IGameDatabase.Games) collection.
# [C#](#tab/csharp)
```csharp
var newGame = new Game("New Game");
PlayniteApi.Database.Games.Add(newGame);
```
# [PowerShell](#tab/tabpowershell)
```powershell
$newGame = New-Object "Playnite.SDK.Models.Game"
$newGame.Name = "New Game"
$PlayniteApi.Database.Games.Add($newGame)
```
***
### Changing Game Data
Changing properties on a `Game` object doesn't automatically update the game in Playnite's database and changes are lost with application restart. To make permanent changes game object must be updated in database manually using `Update` method from [Games](xref:Playnite.SDK.IGameDatabase.Games) collection.
# [C#](#tab/csharp)
```csharp
var game = PlayniteApi.Database.Games[SomeId];
game.Name = "Changed Name";
PlayniteApi.Database.Games.Update(game);
```
# [PowerShell](#tab/tabpowershell)
```powershell
$game = $PlayniteApi.Database.Games[$SomeId]
$game.Name = "Changed Name"
$PlayniteApi.Database.Games.Update($game)
```
***
### Removing Games
To remove game from database use `Remove` method from [Games](xref:Playnite.SDK.IGameDatabase.Games) collection.
# [C#](#tab/csharp)
```csharp
PlayniteApi.Database.Games.Remove(SomeId);
```
# [PowerShell](#tab/tabpowershell)
```powershell
$PlayniteApi.Database.Games.Remove($SomeId)
```
***
Handling reference fields
---------------------
Some fields are only stored as references in `Game` object and can't be directly updated. For example `Series` field is a reference via `SeriesId` property, you can't directly assign new value to `Series` property (it can be only used to obtain referenced series object).
### Updating references
Every reference field has it's own collection accessible in [Database](xref:Playnite.SDK.IPlayniteAPI.Database) API object. For example all series can be accessed via [Series](xref:Playnite.SDK.IGameDatabase.Series) collection.
If you want to change name of the series then you will need to do it by updating series item from [Series](xref:Playnite.SDK.IGameDatabase.Series) collection. The change will be automatically propagated to all games using that series. All field collections are implemented via [IItemCollection](xref:Playnite.SDK.IItemCollection`1) meaning that the update is done via the same process like updating general game information via `Update` method on the specific collection.
### Adding references
To assign completely new series to a game:
- Add new series into [Series](xref:Playnite.SDK.IGameDatabase.Series) database collection.
- Assign ID of newly added series to the game via `SeriesId` property.
- Call Update on `Games` collection to update new `SeriesId` in database.
Some fields allow you to assign more items to a game. For example you can assign multiple tags to a game. In that case you need to assign [List](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1) of IDs to `TagIds` property.
Handling Files
---------------------
All game related image files are stored in game database itself, with only reference Id being used on the game object itself (with exception of [BackgroundImage](xref:Playnite.SDK.Models.Game.BackgroundImage), which allows use of WEB URL as well). Following examples show how to handle game images using database API.
### Exporting Game Cover
Game cover images are referenced in [CoverImage](xref:Playnite.SDK.Models.Game.CoverImage) property. To save a file first get the file record by calling [GetFullFilePath](xref:Playnite.SDK.IGameDatabaseAPI.GetFullFilePath(System.String)) method. `GetFullFilePath` returns full path to a file on the disk drive.
# [C#](#tab/csharp)
```csharp
var game = PlayniteApi.Database.Games[SomeId];
var coverPath = PlayniteApi.Database.GetFullFilePath(game.CoverImage);
```
# [PowerShell](#tab/tabpowershell)
```powershell
$game = $PlayniteApi.Database.Games[$SomeId]
$coverPath = $PlayniteApi.Database.GetFullFilePath($game.CoverImage)
```
***
### Changing Cover Image
Changing cover image involves several steps. First remove original image by calling [RemoveFile](xref:Playnite.SDK.IGameDatabaseAPI.RemoveFile(System.String)) method. Then add new image file to a database using [AddFile](xref:Playnite.SDK.IGameDatabaseAPI.AddFile(System.String,System.Guid)). And lastly assign Id of new image to a game.
Following example changes cover image of first game in database:
# [C#](#tab/csharp)
```csharp
var game = PlayniteApi.Database.Games[SomeId];
PlayniteApi.Database.RemoveFile(game.CoverImage);
game.CoverImage = PlayniteApi.Database.AddFile(@"c:\file.png", game.Id);
PlayniteApi.Database.Games.Update(game);
```
# [PowerShell](#tab/tabpowershell)
```powershell
$game = $PlayniteApi.Database.Games[SomeId]
$PlayniteApi.Database.RemoveFile($game.CoverImage)
$game.CoverImage = $PlayniteApi.Database.AddFile("c:\file.png", $game.Id)
$PlayniteApi.Database.Games.Update($game)
```
***

View File

@ -1,93 +0,0 @@
Library Plugins
=====================
To implement library plugin:
* Read the introduction to [extensions](intro.md) and [plugins](plugins.md).
* Create new public class inheriting from [LibraryPlugin](xref:Playnite.SDK.Plugins.LibraryPlugin) abstract class.
* Add implementation for mandatory abstract members.
Mandatory members
---------------------
| Member | Description |
| -- | -- |
| Id | Unique plugin id. |
| Name | Library name. |
| GetGames | Return games available in library. |
`GetGames` returns list of [Game](xref:Playnite.SDK.Models.Game) objects and these properties must be set correctly by the plugin in order for game to be imported properly:
| Member | Description |
| -- | -- |
| GameId | Unique identifier used to differentiate games of the same plugin. |
| PluginId | Source Id of the plugin importing game. |
| PlayAction | Game action used to start the game. Only if game is reported as installed via `State` property. |
| InstallDirectory | Installation location. Only if game is reported as installed via `State` property. |
You can implement additional functionality by overriding virtual methods from [LibraryPlugin](xref:Playnite.SDK.Plugins.LibraryPlugin) base class.
Capabilities
---------------------
If you want to provide extra features for specific library integration, like ability to close third party client after the game is close, then implement `Properties` property on your plugin class that represents [LibraryPluginProperties](xref:Playnite.SDK.Plugins.LibraryPluginProperties).
### Supported properties
| Capability | Description |
| -- | -- |
| CanShutdownClient | When supported, library's client object has to implement `Shutdown` method. |
| HasCustomizedGameImport | Specifies that library is in full control over the game import mechanism. In this case the library should implement `ImportGames` method instead of `GetGames`. |
Example plugin
---------------------
```csharp
public class LibraryPlugin : LibraryPlugin
{
public override Guid Id { get; } = Guid.Parse("D625A3B7-1AA4-41CB-9CD7-74448D28E99B");
public override string Name { get; } = "Test Library";
public TestGameLibrary(IPlayniteAPI api) : base (api)
{
Properties = new LibraryPluginProperties
{
CanShutdownClient = true,
HasSettings = true
};
}
public override IEnumerable<GameInfo> GetGames()
{
return new List<GameInfo>()
{
new GameInfo()
{
Name = "Notepad",
GameId = "notepad",
PlayAction = new GameAction()
{
Type = GameActionType.File,
Path = "notepad.exe"
},
IsInstalled = true,
Icon = @"c:\Windows\notepad.exe"
},
new GameInfo()
{
Name = "Calculator",
GameId = "calc",
PlayAction = new GameAction()
{
Type = GameActionType.File,
Path = "calc.exe"
},
IsInstalled = true,
Icon = @"https://playnite.link/applogo.png",
BackgroundImage = @"https://playnite.link/applogo.png"
}
};
}
}
```

View File

@ -1,37 +0,0 @@
Extension localizations
=====================
Info
---------------------
To add support for multiple languages:
- Create `Localization` directory in root of your extension.
- English is considered as base language, put all default strings into `en_US.xaml` file.
- Other languages must be stored in `{locale}.xaml` files. For example `cs_CZ.xaml` for Czech language.
List of currently supported languages can be seen [here](https://github.com/JosefNemec/Playnite/tree/master/source/Playnite/Localization).
Localization files must contain proper `ResourceDictionary` objects, otherwise they won't be loaded. You can see examples of localization files [here](https://github.com/JosefNemec/Playnite/tree/master/source/Playnite/Localization).
> [!WARNING]
> String keys are shared between all extensions so make sure you use unique keys for your extension if there's a possibility of a conflict.
Getting localized strings
---------------------
# [C#](#tab/csharp)
```csharp
var locString = ResourceProvider.GetString("stringkey");
```
# [PowerShell](#tab/tabpowershell)
```powershell
$locString = [Playnite.SDK.ResourceProvider]::GetString("stringkey")
```
***
To reference localized string in XAML view, use `DynamicResource` markup.
```xml
<TextBlock Text="{DynamicResource stringkey}" />
```

View File

@ -1,36 +0,0 @@
Writing to Log Files
=====================
Introduction
---------------------
Playnite provides built-in API for message logging. Messages from extensions are logged into `extensions.log` file that can be found in `%AppData%\Playnite` (for installed version) or in Playnite's installation directory (for portable versions).
> [!NOTE]
> Messages with `Trace` severity are not written into log files unless enabled in `For developers` settings menu.
Scripts
---------------------
To write message into Playnite's log files use `__logger` variable which profiles [ILogger](xref:Playnite.SDK.ILogger) interface.
Plugins
---------------------
Use static `GetLogger` method from [LogManager](xref:Playnite.SDK.LogManager) class, to create logger instance.
Examples
---------------------
# [C#](#tab/csharp)
```csharp
var logger = LogManager.GetLogger();
logger.Info("This is message with Info severity");
```
# [PowerShell](#tab/tabpowershell)
```powershell
$__logger.Info("This is message with Info severity")
```
***

View File

@ -1,118 +0,0 @@
Custom application menus
=====================
Basics
---------------------
You can add new entries into main menu and game menu. Custom menu entries are currently only supported in Desktop mode.
Basics
---------------------
To add new custom menu entries, implement appropriate menu script/plugin functions. Functions should return list of items that will be addded to a menu. Playnite passes [GetGameMenuItemsArgs](xref:Playnite.SDK.Plugins.GetGameMenuItemsArgs) and [GetMainMenuItemsArgs](xref:Playnite.SDK.Plugins.GetMainMenuItemsArgs) objects when the menu function is called.
You can use those argument objects to decide what elements to return. For example, in case of game menu, `GetGameMenuItemsArgs` contains `Games` field listing all currently selected games that are being used as a source for the game menu.
When the function associated with the menu item is invoked, it will be passed an arguments object. For game menu actions, C# extensions will be passed [GameMenuItemActionArgs](xref:Playnite.SDK.Plugins.GameMenuItemActionArgs) and script extensions will be passed [ScriptGameMenuItemActionArgs](xref:Playnite.SDK.Plugins.ScriptGameMenuItemActionArgs). `GameMenuItemActionArgs` has a `Games` property to access the selected list of games. For main menu actions, C# extensions will be passed [MainMenuItemActionArgs](xref:Playnite.SDK.Plugins.MainMenuItemActionArgs) and script extensions will be passed [ScriptMainMenuItemActionArgs](xref:Playnite.SDK.Plugins.ScriptMainMenuItemActionArgs).
> [!NOTE]
> `Get*MenuItems` menu methods are executed each time a menu is opened. For that reason, make sure you are not executing long running code in those methods. It would otherwise result in a noticeable delay when opening the menu.
# [C#](#tab/csharp)
```csharp
// To add new game menu items override GetGameMenuItems
public override List<GameMenuItem> GetGameMenuItems(GetGameMenuItemsArgs args)
{
return new List<GameMenuItem>
{
new GameMenuItem
{
Description = "Name of game menu item",
Action = (args) =>
{
// use args.Games to get list of games attached to the menu source
Console.WriteLine("Invoked from game menu item!");
}
}
};
}
// To add new main menu items override GetMainMenuItems
public override List<MainMenuItem> GetMainMenuItems(GetMainMenuItemsArgs args)
{
return new List<MainMenuItem>
{
new MainMenuItem
{
Description = "Name of main menu item",
Action = (args) => Console.WriteLine("Invoked from main menu item!")
}
};
}
```
# [PowerShell](#tab/tabpowershell)
```powershell
# To add new game menu items implement GetGameMenuItems
function GetGameMenuItems()
{
param($getGameMenuItemsArgs)
$menuItem = New-Object Playnite.SDK.Plugins.ScriptGameMenuItem
$menuItem.Description = "PowerShell game menu item"
$menuItem.FunctionName = "InvokeGameMenuFunction"
return $menuItem
}
# To add new main menu items implement GetMainMenuItems
function GetMainMenuItems()
{
param($getMainMenuItemsArgs)
$menuItem = New-Object Playnite.SDK.Plugins.ScriptMainMenuItem
$menuItem.Description = "PowerShell main menu item"
$menuItem.FunctionName = "InvokeMainMenuFunction"
return $menuItem
}
function InvokeGameMenuFunction()
{
param($scriptGameMenuItemActionArgs)
# use $scriptGameMenuItemActionArgs.Games to get list of games attached to the menu source
}
function InvokeMainMenuFunction()
{
param($scriptMainMenuItemActionArgs)
}
```
***
Sub sections
---------------------
You can add sub sections to menus by assigning `MenuSection` property, sections can be nested. Sub sections are shared between extensions allowing multiple extensions to add items to a single sub section.
To add a menu item under single sub section, assign a string value: `Section name`.
To add nested sections, separate definition with pipes: `Section name|Sub section name`.
To add items under "Extensions" main menu section, add `@` to the beginning of the section definition.
Icons
---------------------
To add an icon to a menu item, assign a value to `Icon` property of menu item. Currently supported values are:
- Full path to an image file.
- Theme relative file path to an image file.
- Key of an application resource.
Separators
---------------------
To add a separator, return new menu item with `Description` field se to `-`.
```csharp
new GameMenuItem { Description = "-" }
```

View File

@ -1,53 +0,0 @@
Metadata Plugins
=====================
To implement metadata plugin:
* Read the introduction to [extensions](intro.md) and [plugins](plugins.md).
* Create new public class inheriting from [MetadataPlugin](xref:Playnite.SDK.Plugins.MetadataPlugin) abstract class.
* Add implementation for mandatory abstract members.
Mandatory members
---------------------
| Member | Description |
| -- | -- |
| Id | Unique plugin id. |
| Name | Provider name. |
| SupportedFields | Returns list of metadata fields this plugin can generally provide. |
| GetMetadataProvider | Returns metadata provider class for specific metadata request. |
OnDemandMetadataProvider
---------------------
[OnDemandMetadataProvider](xref:Playnite.SDK.Plugins.OnDemandMetadataProvider) is an object to be returned from `GetMetadataProvider` method. Playnite uses it to request specific metadata fields based on user's metadata download settings. Override specific `Get*` methods based on what your plugin can provide. The class also contains another implementation of `AvailableFields` property, which should return list available fields for specific request.
`OnDemandMetadataProvider` is `IDisposable` and object is disposed automatically once metadata are processes completely for a single game.
MetadataRequestOptions
---------------------
[MetadataRequestOptions](xref:Playnite.SDK.Plugins.MetadataRequestOptions) is passed into every `GetMetadataProvider` request for each specific game. Most important fields are `IsBackgroundDownload` and `GameData`.
- `IsBackgroundDownload` indicates whether the download is being processed in background. By either automatically started download for newly imported games or manually initiated bulk download. When set to false it indicates that download is for manually initiated request from game edit dialog.
- `GameData` contains game that should be updated we new metadata.
MetadataProperty
---------------------
Some fields like `Genres`, `Tags` and others that are globally stored as static values and shared between games are referenced by metadata sources via `MetadataProperty`. Based on what type is used to reference metadata, Playnite will use different method to assign final data.
Available property types:
| Type | Description |
| --- | --- |
| MetadataNameProperty | Playnite will assign field value based on a name (Playnite 8 behavior). If fields with the same name exists in game library, it's reused. |
| MetadataIdProperty | Playnite will assign field value based on objects database ID. Use if you want to reference specific object already existing in the game library. |
| MetadataSpecProperty | Playnite will assign filed value based on specification identifier. Currently only available for [Platforms](https://github.com/JosefNemec/Playnite/blob/devel/source/Playnite/Emulation/Platforms.yaml) and [Regions](https://github.com/JosefNemec/Playnite/blob/devel/source/Playnite/Emulation/Regions.yaml). Identifier matches based on an ID or a Name. |
Example plugin
---------------------
Playnite's IGDB integration is implemented as a metadata plugin. You can see the source [on GitHub](https://github.com/JosefNemec/Playnite/tree/devel/source/Plugins/IGDBMetadata).

View File

@ -1,172 +0,0 @@
Plugin settings
=====================
Basics
---------------------
Plugins can provide configuration view that end users can use to change plugin's behavior. This includes UI component to display settings objects and input verification methods.
Plugins providing settings have to `HasSettings` plugin property set to `true`.
Implementation
---------------------
Settings support requires that you override methods `GetSettings` and `GetSettingsView` methods. `GetSettings` returns `ISettings` object containing the settings data, while `GetSettingsView` returns WPF `UserControl` used to display that data.
### 1. Settings class
Following example show settings object implementing two custom plugin setting options and sets their default value.
```csharp
public class TestPluginSettings : ISettings
{
public string Option1 { get; set; } = string.Empty;
public bool Option2 { get; set; } = false;
}
```
### 2. Implementing ISettings
Our example class is not complete since we don't have an implementation for all `ISettings` methods. Following example show all methods required for complete `ISettings` implementation.
```csharp
public void BeginEdit()
{
// Code executed when settings view is opened and user starts editing values.
}
public void CancelEdit()
{
// Code executed when user decides to cancel any changes made since BeginEdit was called.
// This method should revert any changes made to Option1 and Option2.
}
public void EndEdit()
{
// Code executed when user decides to confirm changes made since BeginEdit was called.
// This method should save settings made to Option1 and Option2.
}
public bool VerifySettings(out List<string> errors)
{
// Code execute when user decides to confirm changes made since BeginEdit was called.
// Executed before EndEdit is called and EndEdit is not called if false is returned.
// List of errors is presented to user if verification fails.
}
```
### 3. Implementing settings view
Settings view is must be standard WPF UserControl. To add new control into your plugin project:
- Right click on your project, select **Add** -> **New Item...**.
- Select **WPF** from the list of control templates and choose **User Control (WPF)** template.
- Change name of the control to something like `NameOfMyPluginSettingsView.xaml` and save.
- Open `NameOfMyPluginSettingsView.xaml` and implement the view.
Plugin's `ISettings` object is set by Playnite as data context while the view is being created (when user starts editing the settings), so you can directly bind it.
Following example show implementation of text field for our `Option1` value and check box for `Option2`.
```xml
<UserControl x:Class="TestPlugin.TestPluginSettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<TextBlock Text="Description for Option1:" />
<TextBox Text="{Binding Option1}" />
<TextBlock Text="Description for Option2:" />
<CheckBox IsChecked="{Binding Option2}" />
</StackPanel>
</UserControl>
```
### 4. Hooking everything to a plugin class
As stated before, plugin class must override `GetSettings` and `GetSettingsView` methods.
```csharp
public class TestPlugin : Plugin // or LibraryPlugin for library plugins, implementation is the same.
{
public override ISettings GetSettings(bool firstRunSettings)
{
return new TestPluginSettings();
}
public override UserControl GetSettingsView(bool firstRunSettings)
{
return new TestPluginSettingsView();
}
}
```
Saving and loading settings
---------------------
To store your settings permanently you have to implement some logic that will store data into some permanent storage and load them then time your plugin is loaded. You can do this manually or use built-in method that Playnite provides for this purpose.
Following example shows how to load and save values for your plugin.
```csharp
public class TestPluginSettings : ObservableObject, ISettings
{
private TestPlugin plugin;
private string option1 = string.Empty;
private bool option2 = false;
private bool optionThatWontBeSaved = false;
public string Option1 { get => option1; set => SetValue(ref option1, value); }
public bool Option2 { get => option2; set => SetValue(ref option2, value); }
// Playnite serializes settings object to a JSON object and saves it as text file.
// If you want to exclude some property from being saved then use `JsonDontSerialize` ignore attribute.
[DontSerialize]
public bool OptionThatWontBeSaved { get => optionThatWontBeSaved; set => SetValue(ref optionThatWontBeSaved, value); }
// Parameterless constructor must exist if you want to use LoadPluginSettings method.
public TestPluginSettings()
{
}
public TestPluginSettings(TestPlugin plugin)
{
// Injecting your plugin instance is required for Save/Load method because Playnite saves data to a location based on what plugin requested the operation.
this.plugin = plugin;
// Load saved settings.
var savedSettings = plugin.LoadPluginSettings<TestPluginSettings>();
// LoadPluginSettings returns null if not saved data is available.
if (savedSettings != null)
{
Option1 = savedSettings.Option1;
Option2 = savedSettings.Option2;
}
}
// To save settings just call SavePluginSettings when user confirms changes.
public void EndEdit()
{
plugin.SavePluginSettings(this);
}
}
```
Settings workflow
---------------------
When user opens settings window in Playnite, following happens with your plugin:
- Playnite gets `GetSettings` and `GetSettingsView` values from your plugin.
- `Settings` object is set as `DataContext` of `SettingsView` view.
- `BeginEdit` method is called.
- When user decides to cancel editing of settings:
- `CancelEdit` is called.
- When use decides to confirm changes:
- `VerifySettings` is called:
- If `false` is returned Playnite shows verification errors to a user.
- If `true` is returned `EndEdit` is called.

View File

@ -1,94 +0,0 @@
Plugins Introduction
=====================
Basics
---------------------
Plugins can be written in any .NET Framework compatible languages, this includes C#, VB.NET, F# and others, targeting .NET Framework 4.6.
Plugin types
---------------------
There are currently two types of plugins:
- `Generic plugins` Generic plugins offer same extensibility as scripts. You can add new entries to main menu or react to various [game events](events.md).
- `Library plugins`: Add ability to import games automatically as well as methods for metadata download for those games.
- `Metadata plugins`: Add ability to import game metadata.
Creating plugins
---------------------
### Using Toolbox
#### 1. Generate from template
Run [Toolbox](../toolbox.md) with arguments specific to a type of plugin you want to create.
For example, to create new library plugin:
```cmd
Toolbox.exe new LibraryPlugin "SomeLibrary importer" "d:\somefolder"
```
This will generate new C# project, with all of required classes already premade.
#### 2. Implement functionality
Don't forget to implement functionality for template methods and properties that by default return `NotImplementedException` exception.
> [!NOTE]
If you are having issue compiling plugin created from the template, then make sure that nuget dependencies are downloaded and installed properly. You can do that by using "Manage NuGet Packages" menu after right-clicking on plugin solution/project in solution explorer.
### Manually
#### 1. Create plugin project
Start by creating new `Class Library` project targeting `.NET Framework 4.6.2`. Add [Playnite SDK](https://www.nuget.org/packages/PlayniteSDK/) nuget package reference and set reference to not require specific version (right-click on `Playnite.SDK` reference, choose `Properties` and set `Specific Version` to false).
> [!NOTE]
> PlayniteSDK is designed in a way that all versions from one major version branch (for example 1.0, 1.1, 1.2 etc.) are backwards compatible. Therefore plugin written for SDK version 1.0 will also work with Playnite containing all 1.x versions of SDK. When loading plugins Playnite checks all SDK references and won't load plugins referencing incompatible SDK versions.
#### 2. Write a plugin
- `Generic plugins` - see generic plugins [documentation page](genericPlugins.md).
- `Library plugins` - see library plugins [documentation page](libraryPlugins.md).
- `Metadata plugins` - see metadata plugins [documentation page](metadataPlugins.md).
#### 3. Create manifest file
Described in [introduction section](intro.md) to extensions.
Plugin dependencies
---------------------
> [!WARNING]
> If you are using external dependencies (from NuGet for example), make sure that you use the same version that Playnite already references. Current plugin system doesn't allow loading of multiple versions of the same assembly and you may encounter issues if you use different version compared to what Playnite uses.
You can check list of all Playnite's dependencies here:
- [Playnite](https://github.com/JosefNemec/Playnite/blob/master/source/Playnite/packages.config)
- [Playnite.Common](https://github.com/JosefNemec/Playnite/blob/master/source/Playnite.Common/packages.config)
- [Playnite.DesktopApp](https://github.com/JosefNemec/Playnite/blob/master/source/Playnite.DesktopApp/packages.config)
- [Playnite.FullscreenApp](https://github.com/JosefNemec/Playnite/blob/master/source/Playnite.FullscreenApp/packages.config)
Referencing Playnite assemblies
---------------------
> [!WARNING]
> **DO NOT** reference non-SDK Playnite assemblies in your project (`Playnite`, `Playnite.Common` etc.). Playnite will refuse to load plugins that reference those assemblies.
If you want to use functionality/code from non-SDK assemblies, you have several options:
* Open GitHub issues for the functionality to be exposed in the SDK.
* Link the source code to your project (choose "Add as link" when adding a source file into plugin project) and compile it with your plugin assembly.
Plugin settings
---------------------
If you want to give user ability to change plugin behavior, you can do that by implementing appropriate settings overrides from `Plugin` abstract class. Including ability to add fully customizable UI for your configuration that will be accessible in Playnite's settings windows. To add plugin settings support to your plugin follow [Plugin settings guide](pluginSettings.md).
Examples
---------------------
Support for all 3rd part clients in Playnite is implemented fully using plugins so you can use then as a reference when implementing new ones. Source can be found [on GitHub](https://github.com/JosefNemec/Playnite/tree/master/source/Plugins).

View File

@ -1,96 +0,0 @@
Playnite Scripting Introduction
=====================
Basics
---------------------
Playnite can be extended with additional functionality using scripts. [PowerShell](https://docs.microsoft.com/en-us/powershell/) is currently the only supported scripting language.
> [!NOTE]
> PowerShell support requires PowerShell 5.1 to be installed on your machine. If you are Windows 7 user, you need to [install it manually](https://www.microsoft.com/en-us/download/details.aspx?id=54616) (Windows 8 and 10 includes it by default). This also means that PowerShell functionality is restricted to 5.x version. Playnite currently doesn't support newer PowerShell Core runtime (PowerShell versions 6 and newer).
PowerShell extensions are imported as a [PowerShell module](https://docs.microsoft.com/en-us/powershell/scripting/developer/module/how-to-write-a-powershell-script-module?view=powershell-5.1). The extension of the file must be `.psm1` (or `.psd1` if you use a [PowerShell module manifest](https://docs.microsoft.com/en-us/powershell/scripting/developer/module/how-to-write-a-powershell-module-manifest?view=powershell-5.1)).
Any exported functions from your extension must be exported from the module. In a `.psm1` file all functions in the module scope are exported by default, but functions in the global scope (defined like `function global:OnGameStarted()`) will _not_ be correctly exported.
Creating script extensions
---------------------
Run [Toolbox](../toolbox.md) with arguments specific to a type of script you want to create.
To create new PowerShell script extension:
```cmd
Toolbox.exe new PowerShellScript "Some script" "d:\somefolder"
```
Accessing Playnite API
---------------------
Playnite API is available to scripts via `PlayniteAPI` variable. Variable provides [IPlayniteAPI](xref:Playnite.SDK.IPlayniteAPI) methods and interfaces. For example to get list of all games in library use [Database](xref:Playnite.SDK.IPlayniteAPI.Database) property from `IPlayniteAPI` and [Games](xref:Playnite.SDK.IGameDatabase.Games) collection.
```powershell
$PlayniteAPI.Database.Games
```
To display number of games use `Dialogs` property from `PlayniteApi` variable. `Dialogs` provides [IDialogsFactory](xref:Playnite.SDK.IDialogsFactory) interface containing method for interaction with user. `ShowMessage` method will show simple text message to user.
```powershell
$gameCount = $PlayniteApi.Database.Games.Count
$PlayniteApi.Dialogs.ShowMessage($gameCount)
```
Examples
---------------------
Displays number of games in the game library when executing `Show Game Count` menu from `Extensions` menu.
```powershell
function DisplayGameCount()
{
param(
$scriptMainMenuItemActionArgs
)
$gameCount = $PlayniteApi.Database.Games.Count
$PlayniteApi.Dialogs.ShowMessage($gameCount)
}
function GetMainMenuItems()
{
param(
$getMainMenuItemsArgs
)
$menuItem = New-Object Playnite.SDK.Plugins.ScriptMainMenuItem
$menuItem.Description = "Show Game Count"
$menuItem.FunctionName = "DisplayGameCount"
$menuItem.MenuSection = "@"
return $menuItem
}
```
Troubleshooting
---------------------
### Debugging
See [scripting debugging](scriptingDebugging.md) page for more details about how to debug PowerShell code running in Playnite.
### Exceptions related to directory not being found
Paths (and strings in general) in various places in PowerShell are handled not as literal strings, but as strings with wildcard patterns. This has unfortunate issue if specific command doesn't allow you to pass literal string via a specific argument (for example `-LiteralPath`) or has an option to disable wildcard parsing.
This can cause issues if game's installation path contains wildcard pattern characters. For example game installed in `d:\[test] game name\` will cause issues to `Start-Process` cmdlet, because of `[` and `]` pattern characters. This is because Playnite sets script runtime's working directory to game's installation path and Start-Process tries to parse it before launching a program.
Solution is to either use literal path arguments or use different cmdlet or .NET classes directly. For example to start a process:
```powershell
# Instead of:
Start-Process "game.exe"
# call .NET class directly:
[System.Diagnostics.Process]::Start("game.exe")
```
Note: This issue has been fixed in newer versions of PowerShell, but since Playnite has to use older version (5.1) until we switch to newer .NET runtime, you may encounter this issue.

View File

@ -1,27 +0,0 @@
Debugging Scripts
=====================
Debugging PowerShell Scripts with PowerShell ISE
---------------------
1. Open the 64-bit bit version of PowerShell ISE.
2. Enter the PowerShell host process of Playnite:
```powershell
Enter-PSHostProcess -Name Playnite.DesktopApp
```
3. Identify the correct runspace name of your script. It will be the name of the module file. Use the commands `Get-Runspace` or `(Get-Runspace).Name` to list runspaces.
4. Debug the script by attaching to the runspace:
```powershell
Debug-Runspace -Name "LibraryExporter.psm1"
```
5. The debugger will automatically break when code is executed. A tab named "[Remote File] LibraryExporter.psm1 [Read Only]" will appear in PowerShell ISE. To trigger the debugger to break, interact with the extension somehow. For example, click the Playnite menu button to break in `GetMainMenuItems`.
6. Set breakpoints using Debug > Toggle Breakpoint.
7. Continue execution by selecting Debug > Run/Continue.
When the breakpoint is reached, hover over any variable names to see their current value.
Typing into the PowerShell ISE console will evaluate statements in the current context. For example, you can use the `$PlayniteAPI` variable to interactively develop and test code. You may also interactively inspect local variables and their properties.
The Playnite interface will appear frozen while the debugger is paused on a breakpoint.

View File

@ -1,135 +0,0 @@
Interacting with Playnite's UI
=====================
Getting list of selected games
---------------------
To get list of currently selected games use `MainView` from `PlayniteApi` variable. `MainView` provides [IMainViewAPI](xref:Playnite.SDK.IMainViewAPI) interface with [SelectedGames](xref:Playnite.SDK.IMainViewAPI.SelectedGames) property returning list of all selected games.
# [C#](#tab/csharp)
```csharp
var gameCount = PlayniteApi.MainView.SelectedGames.Count;
PlayniteApi.Dialogs.ShowMessage($"Selected {gameCount} games");
```
# [PowerShell](#tab/tabpowershell)
```powershell
$PlayniteApi.MainView.SelectedGames | Select -ExpandProperty Name | Out-File "SelectedGames.txt"
```
***
Custom UI elements
---------------------
See [custom UI integration](customUiIntegration.md) page for more details.
Menus
---------------------
See [menus](menus.md) page for more details.
Dialogs
---------------------
[IDialogsFactory](xref:Playnite.SDK.IDialogsFactory) API can be used to show various dialogs.
# [C#](#tab/csharp)
```csharp
PlayniteApi.Dialogs.ShowMessage("Hello world!");
```
# [PowerShell](#tab/tabpowershell)
```powershell
$PlayniteApi.Dialogs.ShowMessage("Hello world!")
```
***
Sidebar
---------------------
To provide new items to the Sidebar, override `GetSidebarItems` method and return list of [SidebarItem](xref:Playnite.SDK.Plugins.SidebarItem) items.
### Item types
There are two types of Sidebar items set via `Type` property:
- `Button`: Simple activation button.
- `View`: View button that shows custom view when clicked.
To implement `Button` type: set `Type` property of a sidebar item to `Button` and assign action to `Activated` action.
To implement `View` type: set `Type` property of a sidebar item to `View` and assign `Opened` and `Closed` actions. `Opened` is called when user clicks the item and expects UI control to be returned (which is then loaded as a new Playnite view). `Closed` is called when user switches to a different view.
### Progress indicator
Sidebar items can also show progress indicator, use `ProgressValue` and `ProgressMaximum` properties to set a specific progress state. Setting `ProgressValue` to `0` hides the progress bar.
### Example
# [C#](#tab/csharp)
```csharp
public override List<SidebarItem> GetSidebarItems()
{
return new List<SidebarItem>
{
new SidebarItem
{
Title = "Calculator",
// Loads icon from plugin's installation path
Icon = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "icon.png"),
ProgressValue = 40,
Activated = () => Process.Start("calc")
}
};
}
```
# [PowerShell](#tab/tabpowershell)
```powershell
'Not supported in PowerShell extensions.'
```
***
Top panel
---------------------
To provide new items to the Top panel, override `GetTopPanelItems` method and return list of [TopPanelItem](xref:Playnite.SDK.Plugins.TopPanelItem) items.
# [C#](#tab/csharp)
```csharp
public override List<TopPanelItem> GetTopPanelItems()
{
return new List<TopPanelItem>
{
new TopPanelItem
{
Title = "Calculator",
Icon = new TextBlock
{
Text = char.ConvertFromUtf32(0xeaf1),
FontSize = 20,
FontFamily = ResourceProvider.GetResource("FontIcoFont") as FontFamily
},
Activated = () => Process.Start("calc")
}
};
}
```
# [PowerShell](#tab/tabpowershell)
```powershell
'Not supported in PowerShell extensions.'
```
***
Supported icons formats
---------------------
Various objects support icon definitions that doesn't enforce specific format, like Sidebar or Top panel items. Icon is an `object` type and Playnite will interpret as this:
- If `string` is provided, Playnite interprets it in the following order:
- If application resource with the name is found it's used.
- If a file path is found, Playnite will try to load it as an image.
- If partial file path is found:
- Theme file is loaded as an image if found.
- Database file is loaded an an image if found.
- If any other type is found, Playnite assigns that object as icon's content.

View File

@ -1,22 +0,0 @@
Playnite URI support
=====================
Introduction
---------------------
Plugins (scripts are not supported) can register custom methods to be executed when specific `playnite://` URI is opened. This can be done using `RegisterSource` method from [UriHandler](xref:Playnite.SDK.IPlayniteAPI.UriHandler) API.
Example
---------------------
Following example executes method when `playnite://mysource/` URI is opened.
```csharp
PlayniteApi.UriHandler.RegisterSource("mysource", (args) =>
{
// Code to be executed
// Use args.Arguments to access URL arguments
});
```
In this example opening ``playnite://mysource/arg1/arg2` will call registered method and pass array of two arguments ("arg1" and "arg2") to it.

View File

@ -1,97 +0,0 @@
Creating custom windows
=====================
Intro
---------------------
Manually created windows will not inherit Playnite's theme, you need to use [CreateWindow](xref:Playnite.SDK.IDialogsFactory.CreateWindow(Playnite.SDK.WindowCreationOptions)) to create a new window instance. `CreateWindow` returns new instance of WPF Window class.
Examples
---------------------
# [C#](#tab/csharp)
```csharp
var window = PlayniteApi.Dialogs.CreateWindow(new WindowCreationOptions
{
ShowMinimizeButton = false
});
window.Height = 1024;
window.Width = 768;
window.Title = "Some title";
// Set content of a window. Can be loaded from xaml, loaded from UserControl or created from code behind
window.Content =
// Set data context if you want to use MVVM pattern
window.DataContext =
// Set owner if you need to create modal dialog window
window.Owner = PlayniteApi.Dialogs.GetCurrentAppWindow();
window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
// Use Show or ShowDialog to show the window
window.ShowDialog();
```
# [PowerShell](#tab/tabpowershell)
```powershell
$windowCreationOptions = New-Object Playnite.SDK.WindowCreationOptions
$windowCreationOptions.ShowMinimizeButton = $false
$window = $PlayniteApi.Dialogs.CreateWindow($windowCreationOptions);
$window.Height = 768;
$window.Width = 768;
$window.Title = "Some title";
# Set content of a window. Can be loaded from xaml, loaded from UserControl or created from code behind
[xml]$xaml = @"
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}" />
</UserControl.Resources>
<StackPanel Margin="15,0,0,0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="An example button:" Margin="0,0,15,0" VerticalAlignment="Center"/>
<Button x:Name="MyButton" Content="Click me!"/>
</StackPanel>
<TextBlock Text="Currently selected games:" Margin="0,15,0,0"/>
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" Margin="15,0,0,0"
Style="{StaticResource BaseTextBlockStyle}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
<TextBlock Text="Total selected games: "/>
<TextBlock Text="{Binding .Count}"/>
</StackPanel>
</StackPanel>
</UserControl>
"@
$reader = [System.Xml.XmlNodeReader]::new($xaml)
$window.Content = [Windows.Markup.XamlReader]::Load($reader)
# Set data context if you want to use MVVM pattern
$window.DataContext = $PlayniteApi.MainView.SelectedGames
# Attach a click event handler
$button = $window.Content.FindName("MyButton")
$button.Add_Click({
$button.Content = "Clicked"
})
# Set owner if you need to create modal dialog window
$window.Owner = $PlayniteApi.Dialogs.GetCurrentAppWindow();
$window.WindowStartupLocation = "CenterOwner";
# Use Show or ShowDialog to show the window
$window.ShowDialog();
```
***

View File

@ -1,173 +0,0 @@
Playnite 9 add-on migration guide
=====================
Extension load changes
---------------------
### Scripts
**IronPython support has been removed completely, therefore you have to rewrite those to PowerShell.**
PowerShell extensions are now imported as [PowerShell modules](https://docs.microsoft.com/en-us/powershell/scripting/developer/module/how-to-write-a-powershell-script-module?view=powershell-5.1). The extension of the file must be `.psm1` (or `.psd1` if you use a [PowerShell module manifest](https://docs.microsoft.com/en-us/powershell/scripting/developer/module/how-to-write-a-powershell-module-manifest?view=powershell-5.1)).
Any exported functions from your extension must be exported from the module. In a `.psm1` file all functions in the module scope are exported by default, but functions in the global scope (defined like `function global:OnGameStarted()`) will _not_ be correctly exported. Exported functions must accept the *exact* number of arguments that Playnite passes to them.
### Plugins
Generic plugins now have to inherit from [GenericPlugin](xref:Playnite.SDK.Plugins.GenericPlugin) class, not `Plugin` class, otherwise they won't be loaded at all.
Model changes
---------------------
Multiple changes have been made to various data models, properties removed, renamed, added. This primarily affects `Game` and `Emulator` objects.
> [!NOTE]
> Since PowerShell is not statically typed language there's no easy way how to find all model changes you need to fix. Please take care and make sure that you fix and test your code properly, especially if you are writing data into game library, since you could write bad data it if you don't adjust your scripts properly.
File changes:
[M source/PlayniteSDK/BuiltInExtensions.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_BuiltInExtensions.cs.html)
[M source/PlayniteSDK/Collections/ObservableObject.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Collections_ObservableObject.cs.html)
[M source/PlayniteSDK/Data/DataSerialization.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Data_DataSerialization.cs.html)
[M source/PlayniteSDK/Database/IGameDatabase.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Database_IGameDatabase.cs.html)
[M source/PlayniteSDK/Database/IItemCollection.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Database_IItemCollection.cs.html)
[M source/PlayniteSDK/Events/ApplicationEvents.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Events_ApplicationEvents.cs.html)
[M source/PlayniteSDK/Exceptions/ScriptRuntimeException.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Exceptions_ScriptRuntimeException.cs.html)
[M source/PlayniteSDK/ExpandableVariables.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_ExpandableVariables.cs.html)
[M source/PlayniteSDK/Extensions/ListExtensions.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Extensions_ListExtensions.cs.html)
[M source/PlayniteSDK/IDialogsFactory.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_IDialogsFactory.cs.html)
[M source/PlayniteSDK/ILogger.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_ILogger.cs.html)
[M source/PlayniteSDK/IMainViewAPI.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_IMainViewAPI.cs.html)
[M source/PlayniteSDK/IPlayniteAPI.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_IPlayniteAPI.cs.html)
[M source/PlayniteSDK/IPlayniteSettingsAPI.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_IPlayniteSettingsAPI.cs.html)
[M source/PlayniteSDK/IWebView.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_IWebView.cs.html)
[M source/PlayniteSDK/LogManager.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_LogManager.cs.html)
[M source/PlayniteSDK/MetadataProvider.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_MetadataProvider.cs.html)
[M source/PlayniteSDK/Models/AppSoftware.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Models_AppSoftware.cs.html)
[M source/PlayniteSDK/Models/CompletionStatus.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Models_CompletionStatus.cs.html)
[M source/PlayniteSDK/Models/DatabaseObject.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Models_DatabaseObject.cs.html)
[M source/PlayniteSDK/Models/Emulator.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Models_Emulator.cs.html)
[M source/PlayniteSDK/Models/Game.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Models_Game.cs.html)
[M source/PlayniteSDK/Models/GameAction.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Models_GameAction.cs.html)
[M source/PlayniteSDK/Models/PastTimeSegment.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Models_PastTimeSegment.cs.html)
[M source/PlayniteSDK/Models/Platform.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Models_Platform.cs.html)
[M source/PlayniteSDK/Models/Region.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Models_Region.cs.html)
[M source/PlayniteSDK/Plugins/LibraryPlugin.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Plugins_LibraryPlugin.cs.html)
[M source/PlayniteSDK/Plugins/MetadataPlugin.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Plugins_MetadataPlugin.cs.html)
[M source/PlayniteSDK/Plugins/Plugin.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Plugins_Plugin.cs.html)
[M source/PlayniteSDK/Properties/AssemblyInfo.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_Properties_AssemblyInfo.cs.html)
[M source/PlayniteSDK/RelayCommand.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_RelayCommand.cs.html)
[M source/PlayniteSDK/ResourceProvider.cs](https://playnite.link/sdkchangelog/5.5.0-6.0.0/PlayniteSDK_ResourceProvider.cs.html)
Method changes
---------------------
All event and other methods that previously accepted multiple arguments have been consolidated into single argument object. This is true for both plugin and script methods.
Game action controllers
---------------------
Controllers (for installing/uninstalling and starting games) have been reworked. See [related documentation page](../tutorials/extensions/gameActions.md) for more information about how to implement them in Playnite 9.
Metadata plugin changes
---------------------
Metadata sources no longer return data as strings but instead use `MetadataProperty` objects. See [metadata plugin page](extensions/metadataPlugins.md#metadataproperty) for more information.
Other
---------------------
Extensions no longer log into main log file (playnite.log), but use separate file called `extensions.log`.
Themes
---------------------
Use Toolbox utility to update theme files to new version, this is absolutely necessary otherwise Blend will no longer load your theme properly. Note that some styles/views are no longer available, others have been moved or renamed. There are also new styles added to support styling of controls that were previously not exposed to themes (like filter panel dropdowns and search boxes).
Playnite 9 also changes how theme files are loaded, which should solve inheritance issue with static references. For example if you had custom CheckBox style then changes from global CheckBox style would not be applied to inherited style and you had to define the whole inherited style. This is no longer needed and theme global styles should be inherited properly.
File changes:
To see what letters before file change mean check [this page](https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---diff-filterACDMRTUXB82308203).
[M source/Playnite.DesktopApp/Themes/Desktop/Default/Constants.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_Constants.xaml.html)
A source/Playnite.DesktopApp/Themes/Desktop/Default/CustomControls/ComboBoxList.xaml
A source/Playnite.DesktopApp/Themes/Desktop/Default/CustomControls/ExtendedDataGrid.xaml
A source/Playnite.DesktopApp/Themes/Desktop/Default/CustomControls/FilterSelectionBox.xaml
D source/Playnite.DesktopApp/Themes/Desktop/Default/CustomControls/MainMenu.xaml
D source/Playnite.DesktopApp/Themes/Desktop/Default/CustomControls/NullableIntBox.xaml
D source/Playnite.DesktopApp/Themes/Desktop/Default/CustomControls/NumericBox.xaml
A source/Playnite.DesktopApp/Themes/Desktop/Default/CustomControls/NumericBoxes.xaml
A source/Playnite.DesktopApp/Themes/Desktop/Default/CustomControls/PathSelectionBox.xaml
A source/Playnite.DesktopApp/Themes/Desktop/Default/CustomControls/SearchBox.xaml
[M source/Playnite.DesktopApp/Themes/Desktop/Default/CustomControls/SidebarItem.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_CustomControls_SidebarItem.xaml.html)
[M source/Playnite.DesktopApp/Themes/Desktop/Default/CustomControls/SliderEx.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_CustomControls_SliderEx.xaml.html)
A source/Playnite.DesktopApp/Themes/Desktop/Default/CustomControls/TopPanelItem.xaml
D source/Playnite.DesktopApp/Themes/Desktop/Default/CustomControls/ViewSettingsMenu.xaml
[M source/Playnite.DesktopApp/Themes/Desktop/Default/DefaultControls/CheckBox.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_DefaultControls_CheckBox.xaml.html)
A source/Playnite.DesktopApp/Themes/Desktop/Default/DefaultControls/DataGrid.xaml
[M source/Playnite.DesktopApp/Themes/Desktop/Default/DefaultControls/Expander.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_DefaultControls_Expander.xaml.html)
[M source/Playnite.DesktopApp/Themes/Desktop/Default/DefaultControls/ScrollViewer.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_DefaultControls_ScrollViewer.xaml.html)
[M source/Playnite.DesktopApp/Themes/Desktop/Default/DefaultControls/Slider.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_DefaultControls_Slider.xaml.html)
[M source/Playnite.DesktopApp/Themes/Desktop/Default/DefaultControls/TabControl.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_DefaultControls_TabControl.xaml.html)
[M source/Playnite.DesktopApp/Themes/Desktop/Default/DefaultControls/Thumb.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_DefaultControls_Thumb.xaml.html)
A source/Playnite.DesktopApp/Themes/Desktop/Default/DerivedStyles/GridViewGroupStyle.xaml
A source/Playnite.DesktopApp/Themes/Desktop/Default/DerivedStyles/ListViewGroupStyle.xaml
[M source/Playnite.DesktopApp/Themes/Desktop/Default/DerivedStyles/PlayButton.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_DerivedStyles_PlayButton.xaml.html)
[M source/Playnite.DesktopApp/Themes/Desktop/Default/DerivedStyles/PropertyItemButton.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_DerivedStyles_PropertyItemButton.xaml.html)
[M source/Playnite.DesktopApp/Themes/Desktop/Default/Media.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_Media.xaml.html)
[M source/Playnite.DesktopApp/Themes/Desktop/Default/Views/DetailsViewGameOverview.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_Views_DetailsViewGameOverview.xaml.html)
D source/Playnite.DesktopApp/Themes/Desktop/Default/Views/FilterPanel.xaml
A source/Playnite.DesktopApp/Themes/Desktop/Default/Views/FilterPanelView.xaml
[M source/Playnite.DesktopApp/Themes/Desktop/Default/Views/GridViewGameOverview.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_Views_GridViewGameOverview.xaml.html)
[M source/Playnite.DesktopApp/Themes/Desktop/Default/Views/Library.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_Views_Library.xaml.html)
[M source/Playnite.DesktopApp/Themes/Desktop/Default/Views/LibraryDetailsView.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_Views_LibraryDetailsView.xaml.html)
[M source/Playnite.DesktopApp/Themes/Desktop/Default/Views/LibraryGridView.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_Views_LibraryGridView.xaml.html)
D source/Playnite.DesktopApp/Themes/Desktop/Default/Views/MainPanel.xaml
[M source/Playnite.DesktopApp/Themes/Desktop/Default/Views/Sidebar.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.DesktopApp_Themes_Desktop_Default_Views_Sidebar.xaml.html)
A source/Playnite.DesktopApp/Themes/Desktop/Default/Views/TopPanel.xaml
D source/Playnite.DesktopApp/Themes/Desktop/DefaultRed/Constants.xaml
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Constants.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_Constants.xaml.html)
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/CustomControls/FilterDbItemtSelection.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_CustomControls_FilterDbItemtSelection.xaml.html)
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/CustomControls/FilterEnumListSelection.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_CustomControls_FilterEnumListSelection.xaml.html)
A source/Playnite.FullscreenApp/Themes/Fullscreen/Default/CustomControls/FilterPresetSelector.xaml
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/CustomControls/FilterStringListSelection.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_CustomControls_FilterStringListSelection.xaml.html)
D source/Playnite.FullscreenApp/Themes/Fullscreen/Default/CustomControls/WindowBase.xaml
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DefaultControls/Button.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_DefaultControls_Button.xaml.html)
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DefaultControls/CheckBox.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_DefaultControls_CheckBox.xaml.html)
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DefaultControls/ComboBox.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_DefaultControls_ComboBox.xaml.html)
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DefaultControls/ScrollViewer.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_DefaultControls_ScrollViewer.xaml.html)
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DefaultControls/Slider.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_DefaultControls_Slider.xaml.html)
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DefaultControls/TextBox.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_DefaultControls_TextBox.xaml.html)
A source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DefaultControls/ToggleButton.xaml
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DefaultControls/ToolTip.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_DefaultControls_ToolTip.xaml.html)
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DerivedStyles/ButtonBottomMenu.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_DerivedStyles_ButtonBottomMenu.xaml.html)
D source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DerivedStyles/ButtonFilterNagivation.xaml
D source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DerivedStyles/ButtonMainMenu.xaml
D source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DerivedStyles/ButtonMessageBox.xaml
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DerivedStyles/ButtonTopMenu.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_DerivedStyles_ButtonTopMenu.xaml.html)
D source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DerivedStyles/ButtonVirtualKeyboard.xaml
D source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DerivedStyles/CheckBoxSettings.xaml
D source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DerivedStyles/ListGameItem.xaml
A source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DerivedStyles/ListGameItemStyle.xaml
A source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DerivedStyles/ListGameItemTemplate.xaml
D source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DerivedStyles/MainWindowStyle.xaml
D source/Playnite.FullscreenApp/Themes/Fullscreen/Default/DerivedStyles/ToggleButtonTopFilter.xaml
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Images/ButtonPrompts/PlayStation/PlayStation.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_Images_ButtonPrompts_PlayStation_PlayStation.xaml.html)
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Images/ButtonPrompts/Xbox/Xbox.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_Images_ButtonPrompts_Xbox_Xbox.xaml.html)
A source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/ActionSelection.xaml
D source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/Filters.xaml
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/FiltersAdditional.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_Views_FiltersAdditional.xaml.html)
A source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/FiltersView.xaml
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/GameDetails.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_Views_GameDetails.xaml.html)
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/GameMenu.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_Views_GameMenu.xaml.html)
A source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/GameStatus.xaml
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/Main.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_Views_Main.xaml.html)
[M source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/MainMenu.xaml](https://playnite.link/themechangelog/1.9.0-2.0.0/Playnite.FullscreenApp_Themes_Fullscreen_Default_Views_MainMenu.xaml.html)
A source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/MessageBox.xaml
D source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/Notifications.xaml
A source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/NotificationsMenu.xaml
D source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/SettingsMenu.xaml
A source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/SettingsMenus.xaml
A source/Playnite.FullscreenApp/Themes/Fullscreen/Default/Views/TextInput.xaml
D source/Playnite.FullscreenApp/Themes/Fullscreen/DefaultLime/Constants.xaml

View File

@ -1,70 +0,0 @@
# Distributing Themes
Introduction
---------------------
You should only distribute files that your theme changes compared to the original source theme. It's because of the way theme loading is implemented in Playnite. Playnite is capable of loading only modified files while keeping everything else from original theme. This is to make sure that when change is made to original files, those changes are also applied to custom themes as well (unless custom theme provides their own version of that file).
This is done for a reason that theme files can contain functional elements (like buttons), that add or remove functionality and this makes sure that new functionality is also available in custom themes if possible.
If you distribute all files with your theme (even those you didn't modify) and update is made to Playnite that adds new functionality via theme files, your theme users won't be able to use that new functionality until you update the theme.
Packaging themes
---------------------
To package theme, run [Toolbox](../toolbox.md) utility with following arguments:
```cmd
Toolbox.exe pack <ThemeDirectoryPath> <TargetFolder>
```
For example...
```cmd
Toolbox.exe pack "c:\playnite\Themes\Desktop\Default\TestingTheme" "c:\somedir"
```
...will create `c:\somedir\SuperClearModern.pthm` theme file you can distribute to users.
`<ThemeDirectoryPath>` is full path to folder where you are developing the theme.
Uploading themes
---------------------
The best place to share themes is via [Playnite add-on database](https://github.com/JosefNemec/PlayniteAddonDatabase), submitting a theme there will make it available in Playnite's built-in add-on browser and will also enable easy theme installation and updates.
It's also recommended to submit theme entry to official Playnite forum, specifically [add-on database](https://playnite.link/forum/forum-3.html) sub-forum.
Updating themes
---------------------
You will need to update themes from time to time to make sure they work with new Playnite versions properly. You can follow changes to theme files by subscribing to [change tracking GitHub issue](https://github.com/JosefNemec/Playnite/issues/1259).
> [!WARNING]
> Keeping your theme update is essential if you want theme users to take advantage of newly added Playnite features and fixes.
Updates are necessary in these two cases:
* Theme API is updated with breaking changes (major version number changes, for example from `1.0.0` to `2.0.0`).
* Playnite will not load themes that are not made for supported API version.
* Minor updates will not break theme loading. For example Theme made for version `1.0.0` will still load in Playnite with API version `1.5.0`.
* New functionality is added to Playnite that requires update in theme file.
* This usually means that your theme will still work (unless update means breaking change to Theme API), but users won't be able to make use of new features until the theme is updated.
You generally don't need to update your theme if you didn't modify any files mentioned in the changelog for a specific version and you are packaging your theme using Toolbox utility.
Blend made themes
---------------------
`Toolbox` utility can be used to automatically update theme files if you are developing themes in Blend.
To update existing theme run Toolbox with following arguments:
```cmd
Toolbox.exe update "<ThemeDirectoryPath>"
```
`<ThemeDirectoryPath>` is full path to folder where you are developing the theme.
Toolbox will try to update all files to latest version, but if you modified files that were also modified in the latest API change, you will need to update those files manually. You will get the list of all files requiring manual update after the update process is finished.

View File

@ -1,47 +0,0 @@
Integrating extension elements
=====================
Introduction
---------------------
If an extension use Playnite SDK to officially expose its custom UI elements, then you can use following markups to more easily integrate those elements. This requires proper support for specific extension, it's not something that's generally enabled by default on all extensions. You should contact extension developer for support in case you have issue integrating specific element.
Integrating elements
---------------------
To actually use plugin control in a view, add `ContentControl` with its name set in `<SourceName>_<ElementName>` format:
- `SourceName` is plugin's source name.
- `ElementName` is a specific element name you want to integrate.
Both of these should be provided by an extension developer.
For example, to include `TestUserControl1` control from `TestPlugin` source:
```xml
<ContentControl x:Name="TestPlugin_TestUserControl1" />
```
Detecting if an extension is installed
---------------------
You can use `PluginStatus` markup to add conditions based on if a plugin is installed or not.
```xml
<SomeElement Property="{PluginStatus Plugin=AddonId, Status=Installed}" />
```
`PluginStatus` automatically converts to `Visibility` value if used on Visibility property, it's not needed to use converter in that case. In other cases it return's `bool` value, `true` if a plugin is installed.
`AddonId` should be provided by extension's developer.
Extension settings
---------------------
If an extension provides support for themes to use its settings, then you can use `PluginSettings` markup to reference them:
```xml
<TextBlock Text="{PluginSettings Plugin=<SourceName>, Path=CustomOption}" />
```
where `SourceName` is the plugin source name and `CustomOption` is the name of a specific settings property (or path in case you want to reference nested properties).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 546 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -1,17 +0,0 @@
# Installing themes
Using .pthm file
---------------------
If theme developer distributes the theme as `.pthm` file then just drag and drop the file to Playnite's main window while it's running in Desktop mode. You will be prompted with installation dialog and after installation is complete you can change to new theme via Settings menu.
Manual installation
---------------------
### Standard Playnite installation
Copy theme folder into `%AppData%\Playnite\Themes\Desktop|Fullscreen` directory.
### Portable Playnite installation
Copy theme folder into `\Themes\Desktop|Fullscreen` folder inside Playnite's installation directory.

View File

@ -1,71 +0,0 @@
# Introduction to Themes
General information
---------------------
Playnite's user interface is implemented using Windows Presentation Framework (WPF) and UI definition is done using [XAML](https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/xaml-overview-wpf) files. Custom themes in Playnite are implemented using [standard template and styling](https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/styling-and-templating) support that WPF provides, therefore any tutorial that applies to styling in WPF also applies to Playnite.
Fullscreen and Desktop modes
---------------------
Playnite offers two separate modes of operation. Standard `Desktop` mode designed for keyboard and mouse and `Fullscreen` mode designed to be controlled with gamepad. These two modes are implemented completely separately and therefore themes are also completely separate.
Learning resources
---------------------
Since Playnite themes are essentially just set of [template and style](https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/styling-and-templating) files, general editing rules and tutorials that apply to WPF also apply to Playnite.
Recommended WPF resources:
* https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/xaml-overview-wpf
* https://www.wpftutorial.net/GettingStarted.html
* https://www.tutorialspoint.com/wpf/
> [!NOTE]
> There's currently very active community around theme/extension development on our [Discord server](https://discord.gg/hSFvmN6). We highly recommend joining if you plan to develop add-ons for Playnite!
Creating Playnite themes
---------------------
> [!WARNING]
> Do not edit built-in default themes. Always create new copy of theme files (ideally using Toolbox utility) are edit those. Broken edits to default theme files could lead to Playnite not being able to start anymore.
> [!WARNING]
> Please read the documentation carefully, especially section about [distribution and theme updates](distributionAndUpdates.md). Not updating your theme regularly could cause issues to theme users, for example they might not be able to use newly added features. Or they might not be able to load the theme at all in newer version of Playnite, in the worst case scenario.
There are generally two approaches to theme creation in Playnite.
1. **[Manually editing](manualEditing.md)** XAML files using any text editor.
2. **[Using Blend/Visual Studio](usingBlend.md)** designer.
Option #1 doesn't require installation of any additional applications and themes can be generally created even using Notepad. However this approach has major disadvantages:
* You don't get live preview of changes your are making.
* You have to restart Playnite every time a change is made to theme files.
* There's not autocompletion or error checking for XAML syntax.
Option #2 requires installation of [Visual Studio IDE](https://visualstudio.microsoft.com/), Community edition is free to download and includes [Blend](https://docs.microsoft.com/en-us/visualstudio/designers/creating-a-ui-by-using-blend-for-visual-studio?view=vs-2019) editor. This approach takes some time to set up, but offers all advantages that manual editing lacks, like live preview, autocompletion of XAML properties, visual editor etc.
**Using Blend editor is recommended option.**
> [!WARNING]
> Theme installation and update always replaces the entire theme directory completely. Meaning that any files that are not part of the installation package will be lost during installation process! If your theme includes some custom functionality that requires user to replace/add files to theme's directory, make sure they know that they will loose those changes after an update!
Integrating with plugins
---------------------
Plugins can provide custom UI elements that can be integration into a theme. See [extension integration page](extensionIntegration.md) for more details.
Theme files and directories
---------------------
This section explains contents and purpose of specific theme files.
| Directory/File | Description |
| -- | -- |
| DefaultControls | Styles for standard (built-in WPF) controls like button, checkbox etc. |
| DerivedStyles | Styles for standard (built-in WPF) controls like button, checkbox etc., that are used in specific cases. For example Play button, list item for Grid view etc. |
| CustomControls | Styles for custom Playnite controls. |
| Views | Styles for library views and panels. |
| Common.xaml | Base styles that are inherited by other styles from the theme. |
| Constants.xaml | Colors, brushes, sizes and other constants used by styles form the theme. |
| Media.xaml | Various icons, texts and image specifications used by styles form the theme. |

View File

@ -1,23 +0,0 @@
# Theme manifest file
General information
---------------------
Every theme has to have manifest file name `theme.yaml`. This file is used by Playnite for several things including loading the theme and theme will not be usable in Playnite if manifest file is missing. The file should be in theme's root directory.
Available fields
---------------------
| Field | Description |
| -- | -- |
| Id | Unique string identifier for the theme. Must not be shared with any other theme. |
| Name | Theme's name that will be displayed during installation and on theme selection dialogs. |
| Author | Name of theme's author. |
| Version | Extension version, must be a valid [.NET version string](https://docs.microsoft.com/en-us/dotnet/api/system.version). |
| Mode | Specifies whether the theme is for Desktop of Fullscreen mode. |
| ThemeApiVersion | Theme API version required for theme to work. |
| Links | Optional list of links (extension website, changelog etc.) |
> [!WARNING]
> Fields `Mode` and `ThemeApiVersion` are automatically generated and shouldn't be changed by hand, unless you are updating the theme to support newer versions of Playnite.

View File

@ -1,28 +0,0 @@
# Creating themes manually
Basics
---------------------
This method is generally not recommended and we recommend using [Blend](usingBlend.md) instead. However for smaller changes this is a usable method.
Creating theme
---------------------
* Create empty folder inside of `Themes` directory (and `Fullscreen` or `Desktop` subdirectory).
* Create theme [manifest file](manifestFile.md).
* Set proper `Mode` and `ThemeApiVersion` fields. `ThemeApiVersion` of currently installed Playnite version can be found by opening `About Playnite` menu from Desktop mode.
* Copy original theme file you want to edit (xaml, image etc.) to the new folder (make sure you keep the directory structure).
* Make changes to copied file using any text editor.
Testing changes
---------------------
To test theme in Playnite itself, just start Playnite and change theme selection in the application settings. No additional steps should be needed for Playnite to load the theme as long as theme manifest is present.
Packaging theme for distribution
---------------------
See [Distribution and Updates](distributionAndUpdates.md) page for more details.
> [!WARNING]
> Please pay special attention to section about updating themes to make sure your custom theme always works with the latest Playnite version.

View File

@ -1,112 +0,0 @@
# Creating themes using Blend editor
Installing Blend
---------------------
Blend is part of [Visual Studio IDE](https://visualstudio.microsoft.com/), which is available for free with Community edition. Visual Studio comes with lot of components you might not be interested in, for theme development you only need `.NET Desktop development` workload.
> [!NOTE]
> Couple people reported that live preview doesn't work properly in Visual Studio 2022, therefore 2019 or 2017 version is recommended.
Creating new theme
---------------------
[Open command prompt](https://www.windows-commandline.com/how-to-open-command-prompt/) and [navigate](https://www.windows-commandline.com/command-prompt-change-directory/) to Playnite's installation folder. To create new theme you need to run `Toolbox.exe` utility with these arguments:
```cmd
Toolbox.exe new desktoptheme|fullscreentheme <ThemeName>
```
For example to create new desktop theme with "Super Clear Modern" name:
```cmd
Toolbox.exe new desktoptheme "Super Clear Modern"
```
This will create new theme folder with all files needed for theme to be edited in Blend. If theme creation is successful then Explorer window will open with your new theme folder. DO NOT move theme's directory, designer in Blend will not work properly unless the theme is opened from the location where Toolbox created it!
> [!NOTE]
> There might be issues with above examples if you installed Playnite into folder where write access is not enabled by default unless you have elevated privileges (folders like `c:\Program Files`). In that case you will need to run command prompt and Blend with admin privileges. However better approach would be to use different install location.
Editing theme
---------------------
To edit theme in Blend open `Theme.sln` file from theme's directory.
> [!NOTE]
> Just opening `.sln` file will usually open Visual Studio instead of Blend. While you can use Visual Studio to edit the theme as well, it lacks many features that make editing easier, like live preview for templates and styles. To open `.sln` files in Blend, right-click on the file, select `Open with` and choose `Blend for Visual Studio` option.
> [!WARNING]
> Due to way Playnite resolves paths to theme files (like images), it is necessary to open theme sln file via the file itself. If you open Blend first and then use it to open the theme sln, some parts of live preview might not work properly. This will be fixed in future Playnite updates.
As a first thing after creating new theme, open `theme.yaml` file and change manifest fields if you need to (you will probably need to change Author at least). For more information about available manifest fields see [manifest file page](manifestFile.md).
Files
---------------------
Themes consist of several `.xaml` files. Each view, panel or specific control usually has their own xaml file. Commonly used resources like colors and brushes that affect all controls are generally defined in `Constants.xaml`.
Live preview
---------------------
To open live preview (design view):
#### 1) Open appropriate style (xaml) file
Not all files can be previewed in design view, some only contain constants like colors, brushes etc. `Constants.xaml` is best example of this. If you want to see preview for these resources, open resources window (View -> Resources window) and expand appropriate file.
#### 2) Open design view panel
Toggle design view using `Design` tab button. It is highly recommended to keep XAML text view open as well since it's faster for making changes. To have both views open you can split the editor using buttons on bottom right part of the editor (offering both horizontal and vertical split.
![image](images/designSwitch.png)
#### 3) Select style to preview
Since single xaml file can contain multiple styles for multiple views/controls, you need to select style you want to preview first. To do so select line in a text editor starting with with `<Style TargetType=...`.
#### 4) Activate preview
On design panel select `Style` dropdown, then `Edit Template` and lastly `Edit Current`. This will load preview for style you selected in previous step.
![image](images/templateEdit.png)
#### 5) Enjoy
Now a preview for the specific view/control should be visible. If the view doesn't seem to display all resources properly (for example missing or incorrect colors and brushes are used), see troubleshooting section.
![image](images/designExample.png)
Troubleshooting
---------------------
### Fonts, colors and other resources are not applied
Opening style's design view for the first sometimes doesn't properly load referenced resources (like fonts, colors etc). This is a Blend issue and can be fixed easily by editing some part of the style, which will force the design view to reload. Switching to a different file tab and back also resolves this sometimes.
### Updating ThemeFile markup doesn't update in a preview
Specifically declare `RelativePath` property if this happens:
```xml
<Image Source="{ThemeFile RelativePath='Images/applogo.png'}" />
```
...instead of just:
```xml
<Image Source="{ThemeFile 'Images/applogo.png'}" />
```
### Design view just doesn't work
This happens if theme is not opened from correct directory. As mentioned above, theme's .sln file must be opened from the directory that Toolbox created it in. Moving to a different directory will cause issues!
Testing changes
---------------------
To test theme in Playnite itself, just start Playnite and change theme selection in the application settings. No additional steps should be needed for Playnite to load the theme.
Packaging theme for distribution
---------------------
See [Distribution and Updates](distributionAndUpdates.md) page for more details.
> [!WARNING]
> Please pay special attention to section about updating themes to make sure your custom theme always works with the latest Playnite version.

View File

@ -1,90 +0,0 @@
Referencing theme files
---------------------
If you need to reference a file that's part of you theme (for example an image), then you need to use `ThemeFile` markup extension.
For example creating image that uses `applogo.png` file stored in `Images` subfolder would be done this way:
```xml
<Image Source="{ThemeFile 'Images/applogo.png'}" />
```
If you need to reference theme files based on game property, use `ThemeFileBinding` markup extension.
For example to bind to an image based on game's platform name:
```xml
<Image Source="{ThemeFileBinding Game.Platform.Name, PathFormat='Platforms/{0}.jpg'}" />
```
Adding video to a theme
---------------------
Use [MediaElement](https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.mediaelement?view=netframework-4.8) element ([supported formats](https://docs.microsoft.com/en-us/previous-versions/windows/silverlight/dotnet-windows-silverlight/cc189080(v=vs.95)?redirectedfrom=MSDN)) to add a video to a xaml file. Video files by default don't repeat, to automatically repeat playback use `MediaElementBehaviors.Repeat` behavior.
Following example adds video file `video.mp4` stored in `Videos` theme subfolder and plays it on repeat:
```xml
<MediaElement Source="{ThemeFile 'Videos/video.mp4'}" MediaElementBehaviors.Repeat="True" />
```
What all these PART_ element names
---------------------
You may have seen something like this in theme files:
```xml
<CheckBox x:Name="PART_ToggleFilter" />
```
This notifies theme engine about what kind of checkbox it is and how to hookup functionality for it. If the name is changed or removed then the element will loose all functionality and you will need to set it up in theme file itself via `Binding` markups. You can see PART specifications in appropriate backend file for each control/view (for example [this file](https://github.com/JosefNemec/Playnite/blob/master/source/Playnite.DesktopApp/Controls/Views/GameOverview.cs) for GameOverview view).
This however doesn't mean that you can only include information backed by PART definition in your themes...
Custom mouse cursor
---------------------
Custom mouse cursors are only supported in `.cur` and `.ani` formats. To assign custom cursor to a theme, put `cursor.cur` or `cursor.ani` file into theme directory root (next to `theme.yaml` file).
Changing audio files
---------------------
All audio files must be stored in `audio` sub-directory and have **44.1 kHz** sampling rate!
You can currently change several audio samples in Fullscreen themes:
| Type | File name | Supported formats |
| :--- | :--- | :--- |
| Navigation sound | navigation | `.wav`, `.mp3` |
| Activation sound | activation | `.wav`, `.mp3` |
| Background sound/music | background | `.wma`, `.mp3` |
Adding additional information to views
---------------------
Not every information, that is available to theme, is always displayed on screen and you may want to display it in your custom theme or completely change how the original information is displayed using PART system. For example `GameDetails.xaml` view from Fullscreen mode theme only shows some game information.
You can display additional information by adding extra elements (TextBoxes, Images etc.) and binding source data to it. When using Blend you can easily see what information is available on particular view by starting typing `Binding` markup, the list of available fields should show up like this:
![image](images/bindingData.png)
If it doesn't then you can invoke it via `CTRL-Space` shortcut after typing `Binding`.
Useful data binding docs:
* https://www.wpf-tutorial.com/data-binding/introduction/
* https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/data-binding-wpf
Color definitions
---------------------
You may be wondering why are some colors defined with just 6 digits like `#112233` and other with 8 digits like `#BB112233`. WPF uses RGB system to define color values where each color is defined by values ranging from `00` to `FF` (using [hex](https://simple.wikipedia.org/wiki/Hexadecimal_numeral_system) digits): `#RRGGBB`. However you can also define alpha transparency using additional two digits to specify transparency intensity: `#AARRGGBB`. Where `00` is fully transparent and `FF` is fully opaque.
Using custom controls and 3rd party assemblies
---------------------
The way Playnite currently loads theme files doesn't natively support use of 3rd party assemblies unless they are manually placed in application folder, meaning they can't be distributed inside [pthm](distributionAndUpdates.md) files.
Using custom fonts
---------------------
Limitations of using 3rd party assemblies also apply to use of custom fonts. Currently recommended option is to install desired font in Windows font storage and then use it as any other built-in Windows font in your XAML files.

View File

@ -1,64 +0,0 @@
- name: Extensions
items:
- name: Introduction
href: extensions/intro.md
- name: Scripts
href: extensions/scripting.md
- name: Plugins
href: extensions/plugins.md
- name: Library Plugins
href: extensions/libraryPlugins.md
- name: Metadata Plugins
href: extensions/metadataPlugins.md
- name: Data directories
href: extensions/dataDirectory.md
- name: Logging
href: extensions/logging.md
- name: Plugin settings
href: extensions/pluginSettings.md
- name: Working with game library
href: extensions/library.md
- name: Events
href: extensions/events.md
- name: UI Interaction
href: extensions/ui.md
- name: Custom UI Integration
href: extensions/customUiIntegration.md
- name: Menu items
href: extensions/menus.md
- name: Game actions
href: extensions/gameActions.md
- name: Custom windows
href: extensions/windows.md
- name: Game variables
href: extensions/expandingVariables.md
- name: Playnite URI support
href: extensions/uriSupport.md
- name: Debugging scripts
href: extensions/scriptingDebugging.md
- name: String localizations
href: extensions/localizations.md
- name: Manifest file
href: extensions/extensionsManifest.md
- name: Themes
items:
- name: Introduction
href: themes/introduction.md
- name: Using Blend
href: themes/usingBlend.md
- name: Manual editing
href: themes/manualEditing.md
- name: Distribution and updates
href: themes/distributionAndUpdates.md
- name: Various
href: themes/various.md
- name: Installing themes
href: themes/installing.md
- name: Manifest file
href: themes/manifestFile.md
- name: Extension integrations
href: themes/extensionIntegration.md
- name: Toolbox utility
href: toolbox.md

View File

@ -1,88 +0,0 @@
# Extension Toolbox utility
Introduction
---------------------
Toolbox is Playnite utility that can be used for various tasks, mainly for creating extensions and themes. Toolbox is distributed with every Playnite installation and can be found in Playnite's installation directory.
Creating new extensions
---------------------
### Themes
```cmd
Toolbox.exe new <themetype> <themename>
```
`<themetype>` available options:
- **DesktopTheme**
- **FullscreenTheme**
`<themename>` - name of the theme.
#### Example
```cmd
Toolbox.exe new desktoptheme "New Desktop Theme"
```
### Scripts
```cmd
Toolbox.exe new <scripttype> <scriptname> <targetfolder>
```
`<scripttype>` available options:
- **PowerShellScript**
`<scriptname>` - name of the new script extension.
`<targetfolder>` - folder to create script in.
#### Example
```cmd
Toolbox.exe new PowerShellScript "Testing Script" "d:\somefolder"
```
### Plugins
```cmd
Toolbox.exe new <plugintype> <pluginname> <targetfolder>
```
`<plugintype>` available options:
- **GenericPlugin**
- **MetadataPlugin**
- **LibraryPlugin**
`<pluginname>` - name of the new plugin extension.
`<targetfolder>` - folder to create plugin in.
#### Example
```cmd
Toolbox.exe new MetadataPlugin "GameDatabase metadata provider" "d:\somefolder"
```
Packing extensions
---------------------
```cmd
Toolbox.exe pack <extensionfolder> <targetfolder>
```
`<extensionfolder>` - extension directory (theme, script or plugin) to pack (in case of plugins it has to be folder with built binaries).
`<targetfolder>` - target directory where to save packed file.
#### Example
```cmd
Toolbox.exe pack "C:\Playnite\Themes\Fullscreen\TestingFullscreen" "c:\somefolder"
```
... will create `c:\somefolder\TestingFullscreen.pthm` package.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
references/SDL2.dll Normal file

Binary file not shown.

BIN
references/SDL2_mixer.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,12 +1,14 @@
using Playnite.DesktopApp.ViewModels;
using Playnite.SDK;
using Playnite.SDK.Models;
using Playnite.SDK.Plugins;
using Playnite.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Threading;
namespace Playnite.DesktopApp.API
{
@ -19,20 +21,49 @@ namespace Playnite.DesktopApp.API
{
get
{
if (mainModel.SelectedGames == null && mainModel.SelectedGame != null)
return UIDispatcher.Invoke(() =>
{
return new List<Game>() { mainModel.SelectedGame.Game };
}
else
{
return mainModel.SelectedGames?.Select(a => a.Game).ToList();
}
if (mainModel.SelectedGames == null && mainModel.SelectedGame != null)
{
return new List<Game>() { mainModel.SelectedGame.Game };
}
else
{
return mainModel.SelectedGames?.Select(a => a.Game).ToList();
}
});
}
}
public DesktopView ActiveDesktopView => (DesktopView)mainModel.AppSettings.ViewSettings.GamesViewType;
public DesktopView ActiveDesktopView
{
get => mainModel.AppSettings.ViewSettings.GamesViewType;
set => mainModel.AppSettings.ViewSettings.GamesViewType = value;
}
public List<Game> FilteredGames => mainModel.GamesView.CollectionView.Cast<GamesCollectionViewEntry>().Select(a => a.Game).Distinct().ToList();
public FullscreenView ActiveFullscreenView { get; } = FullscreenView.List;
public SortOrder SortOrder
{
get => mainModel.AppSettings.ViewSettings.SortingOrder;
set => mainModel.AppSettings.ViewSettings.SortingOrder = value;
}
public SortOrderDirection SortOrderDirection
{
get => mainModel.AppSettings.ViewSettings.SortingOrderDirection;
set => mainModel.AppSettings.ViewSettings.SortingOrderDirection = value;
}
public GroupableField Grouping
{
get => mainModel.AppSettings.ViewSettings.GroupingOrder;
set => mainModel.AppSettings.ViewSettings.GroupingOrder = value;
}
public List<Game> FilteredGames => UIDispatcher.Invoke(() => mainModel.GamesView.CollectionView.Cast<GamesCollectionViewEntry>().Select(a => a.Game).Distinct().ToList());
public Dispatcher UIDispatcher => PlayniteApplication.CurrentNative.Dispatcher;
public MainViewAPI(DesktopAppViewModel mainModel)
{
@ -66,5 +97,68 @@ namespace Playnite.DesktopApp.API
{
mainModel.SelectGames(gameIds);
}
public void ApplyFilterPreset(Guid filterId)
{
mainModel.ApplyFilterPreset(filterId);
}
public void ApplyFilterPreset(FilterPreset preset)
{
mainModel.ActiveFilterPreset = preset;
}
public Guid GetActiveFilterPreset()
{
return mainModel.AppSettings.SelectedFilterPreset;
}
public FilterPresetSettings GetCurrentFilterSettings()
{
return mainModel.AppSettings.FilterSettings.AsPresetSettings();
}
public void OpenSearch(string searchTerm)
{
mainModel.OpenSearch(searchTerm);
}
public void OpenSearch(SearchContext context, string searchTerm)
{
mainModel.OpenSearch(context, searchTerm);
}
public bool? OpenEditDialog(Guid gameId)
{
var game = mainModel.Database.Games.Get(gameId);
if (game is null)
return null;
return mainModel.GamesEditor.EditGame(game);
}
public bool? OpenEditDialog(List<Guid> gameIds)
{
var games = mainModel.Database.Games.Get(gameIds);
if (!games.HasItems())
return null;
return mainModel.GamesEditor.EditGames(games);
}
public List<FilterPreset> GetSortedFilterPresets()
{
return mainModel.SortedFilterPresets.ToList();
}
public List<FilterPreset> GetSortedFilterFullscreenPresets()
{
return mainModel.SortedFilterFullscreenPresets.ToList();
}
public void ToggleFullscreenView()
{
throw new NotSupportedInDesktopException();
}
}
}

View File

@ -6,12 +6,17 @@
<appSettings file="Common.config">
</appSettings>
<runtime>
<enforceFIPSPolicy enabled="false" />
<loadFromRemoteSources enabled="True" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -12,10 +12,11 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Playnite;component/Localization/LocSource.xaml"/>
<ResourceDictionary Source="GlobalResources.xaml" />
<ResourceDictionary Source="ControlGalleryView.xaml" />
<ResourceDictionary Source="Themes/Desktop/Default/Constants.xaml" />
<ResourceDictionary Source="Themes/Desktop/Default/Common.xaml" />
<ResourceDictionary Source="Themes/Desktop/Default/Media.xaml" />
<!--Default Controls-->
<ResourceDictionary Source="Themes/Desktop/Default/DefaultControls/Border.xaml" />
<ResourceDictionary Source="Themes/Desktop/Default/DefaultControls/TextBlock.xaml" />
@ -66,6 +67,7 @@
<ResourceDictionary Source="Themes/Desktop/Default/CustomControls/SearchBox.xaml" />
<ResourceDictionary Source="Themes/Desktop/Default/CustomControls/TopPanelItem.xaml" />
<ResourceDictionary Source="Themes/Desktop/Default/CustomControls/PathSelectionBox.xaml" />
<ResourceDictionary Source="Themes/Desktop/Default/CustomControls/HotKeyBox.xaml" />
<!--Derived Styles-->
<ResourceDictionary Source="Themes/Desktop/Default/DerivedStyles/TextBlockGameScore.xaml" />
@ -102,6 +104,7 @@
<ResourceDictionary Source="Themes/Desktop/Default/Views/LibraryListView.xaml" />
<ResourceDictionary Source="Themes/Desktop/Default/Views/Library.xaml" />
<ResourceDictionary Source="Themes/Desktop/Default/Views/MainWindow.xaml" />
<ResourceDictionary Source="Themes/Desktop/Default/Views/SearchView.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>

View File

@ -0,0 +1,182 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:pctrls="clr-namespace:Playnite.DesktopApp.Controls"
mc:Ignorable="d">
<Style x:Key="ControlGalleryContentStyle" TargetType="{x:Type ContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContentControl}">
<DockPanel Background="{DynamicResource WindowBackgourndBrush}"
d:DesignWidth="800" d:DesignHeight="700">
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem Header="_New" />
<MenuItem Header="Open" IsEnabled="False" />
<MenuItem Header="Save" IsChecked="True" IsCheckable="True"/>
<Separator />
<MenuItem Header="Exit">
<MenuItem Header="Test" />
<MenuItem Header="Test2" />
</MenuItem>
</MenuItem>
<MenuItem Header="Test" IsEnabled="False">
<MenuItem Header="_New" />
</MenuItem>
<MenuItem Header="Test2" >
<MenuItem Header="New" />
</MenuItem>
</Menu>
<TabControl TabStripPlacement="Top">
<TabItem Header="Test">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Margin="10" Grid.Column="0">
<StackPanel Orientation="Horizontal">
<Button Content="Button" HorizontalAlignment="Left" Margin="5">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="Test1" />
<Separator />
<MenuItem Header="Test2">
<MenuItem Header="Test1" />
</MenuItem>
</ContextMenu>
</Button.ContextMenu>
</Button>
<RepeatButton Content="RepeatButton" HorizontalAlignment="Left" Margin="5"
ToolTip="Testing tooltip for a button"/>
<ToggleButton Content="ToggleButton"
HorizontalAlignment="Left" Margin="5" />
</StackPanel>
<UniformGrid Columns="2">
<CheckBox Content="TestCheckbox" IsChecked="True" HorizontalAlignment="Left" IsThreeState="True" Margin="5"/>
<TextBlock VerticalAlignment="Center">
<Hyperlink>
Hyperlink Click here
</Hyperlink>
</TextBlock>
</UniformGrid>
<UniformGrid Columns="2">
<ComboBox IsEditable="True" Text="Test2" Margin="5"
HorizontalAlignment="Stretch"/>
<ComboBox SelectedIndex="1" Margin="5"
HorizontalAlignment="Stretch">
<ComboBoxItem Content="Test1"/>
<ComboBoxItem Content="Test2"/>
<ComboBoxItem Content="Test3"/>
<ComboBoxItem Content="Test1"/>
<ComboBoxItem Content="Test2"/>
<ComboBoxItem Content="Test3"/>
<ComboBoxItem Content="Test1"/>
<ComboBoxItem Content="Test2"/>
<ComboBoxItem Content="Test3"/>
<ComboBoxItem Content="Test1"/>
<ComboBoxItem Content="Test2"/>
<ComboBoxItem Content="Test3"/>
<ComboBoxItem Content="Test1"/>
<ComboBoxItem Content="Test2"/>
<ComboBoxItem Content="Test3"/>
<ComboBoxItem Content="Test1"/>
<ComboBoxItem Content="Test2"/>
<ComboBoxItem Content="Test3"/>
<ComboBoxItem Content="Test3"/>
<ComboBoxItem Content="Test1"/>
<ComboBoxItem Content="Test2"/>
<ComboBoxItem Content="Test3"/>
<ComboBoxItem Content="Test1"/>
<ComboBoxItem Content="Test2"/>
<ComboBoxItem Content="Test3"/>
<ComboBoxItem Content="Test3"/>
<ComboBoxItem Content="Test1"/>
</ComboBox>
</UniformGrid>
<TextBlock Text="Test text just test text" Margin="5"/>
<TextBox Text="Test text just test text" Margin="5" />
<TextBox Height="50" TextWrapping="Wrap" AcceptsReturn="True" Text="This TextBox will allow the user to enter multiple lines of text. When the RETURN key is pressed,
or when typed text reaches the edge of the text box, a new line is automatically inserted." VerticalScrollBarVisibility="Auto" Margin="5"/>
<PasswordBox Password="test" Margin="5"/>
<Expander Header="TestExpander" IsExpanded="True" Margin="5">
<ListView Height="100"
Name="listview"
SelectedIndex="1" Margin="5">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
<GridViewColumn Header="Mail" Width="150" DisplayMemberBinding="{Binding Mail}" />
</GridView>
</ListView.View>
<ListViewItem Content="Tea"></ListViewItem>
<ListViewItem Content="Test"></ListViewItem>
</ListView>
</Expander>
<ListBox SelectedIndex="1" Margin="5" Height="100">
<ListBoxItem Content="ListItem 1" />
<ListBoxItem Content="ListItem 2" />
<ListBoxItem Content="ListItem 3" />
<ListBoxItem Content="ListItem 1" />
<ListBoxItem Content="ListItem 2" />
<ListBoxItem Content="ListItem 3" />
<ListBoxItem Content="ListItem 1" />
<ListBoxItem Content="ListItem 2" />
<ListBoxItem Content="ListItem 3" />
</ListBox>
</StackPanel>
<StackPanel Grid.Column="1">
<pctrls:NullIntNumericBox Margin="5" />
<pctrls:LongNumericBox Margin="5" />
<pctrls:SearchBox Margin="5" />
<pctrls:FilterSelectionBox Margin="5" />
<pctrls:DdItemListSelectionBox Margin="5" />
<GroupBox Header="Test Groubox" Margin="5">
<StackPanel>
<ProgressBar Value="30" Margin="5" Width="342" Height="20" />
<RadioButton Content="RadioButton1" IsChecked="True" GroupName="test" Margin="5"/>
<RadioButton Content="RadioButton2" GroupName="test" Margin="5" />
</StackPanel>
</GroupBox>
<TreeView Margin="5">
<TreeViewItem Header="Level 1" IsExpanded="True">
<TreeViewItem Header="Level 2.1" IsSelected="True" />
<TreeViewItem Header="Level 2.2" IsExpanded="True" >
<TreeViewItem Header="Level 3.1" />
<TreeViewItem Header="Level 3.2" />
</TreeViewItem>
<TreeViewItem Header="Level 2.2" IsExpanded="False" >
<TreeViewItem Header="Level 3.1" />
<TreeViewItem Header="Level 3.2" />
</TreeViewItem>
</TreeViewItem>
</TreeView>
<ScrollViewer Width="100" Height="100"
HorizontalScrollBarVisibility="Auto" Margin="5">
<Viewbox Width="200" Height="200">
<TextBlock Text="R" />
</Viewbox>
</ScrollViewer>
</StackPanel>
</Grid>
</TabItem>
<TabItem Header="Test2">
</TabItem>
</TabControl>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@ -27,7 +27,7 @@
<Grid Margin="5">
<DockPanel Visibility="{Binding IsUpdateListLoading, Converter={StaticResource InvertedBooleanToVisibilityConverter}}">
<StackPanel DockPanel.Dock="Bottom" HorizontalAlignment="Right">
<StackPanel DockPanel.Dock="Bottom" HorizontalAlignment="Left">
<Button Content="{DynamicResource LOCAddonUpdateAddons}" Margin="0,5,0,0"
Visibility="{Binding IsUpdateAvailable, Converter={StaticResource BooleanToVisibilityConverter}}"
Command="{Binding UpdateAddonsCommand}"/>

View File

@ -54,8 +54,12 @@
</DockPanel>
<ListBox ItemsSource="{Binding OnlineAddonList}"
SelectedItem="{Binding SelectedOnlineAddon}"
Name="ListOnlineAddons" Grid.Column="0" Grid.Row="1"
ScrollViewer.CanContentScroll="False"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.ScrollUnit="Pixel"
ScrollViewer.CanContentScroll="True"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
@ -76,7 +80,7 @@
<ScrollViewer Grid.Column="2" Grid.Row="1" Margin="15,0,5,0"
HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<StackPanel DataContext="{Binding SelectedItem, ElementName=ListOnlineAddons}"
<StackPanel DataContext="{Binding SelectedOnlineAddon}"
Visibility="{Binding SelectedItem, ElementName=ListOnlineAddons, Converter={StaticResource NullToVisibilityConverter}}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{DynamicResource LOCExtensionCreatedBy}" />
@ -84,12 +88,12 @@
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
<TextBlock Text="Version:" />
<TextBlock Text="{DynamicResource LOCExtensionVersion}" />
<TextBlock Text="{Binding LatestPackage.Version}" FontWeight="Bold" Margin="5,0,0,0" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
<TextBlock Text="Updated:" />
<TextBlock Text="{DynamicResource LOCExtensionUpdated}" />
<TextBlock Text="{Binding LatestPackage.ReleaseDate, Converter={StaticResource NullableDateToStringConverter}}" FontWeight="Bold" Margin="5,0,0,0" />
</StackPanel>
@ -106,22 +110,28 @@
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button HorizontalAlignment="Left" Margin="0,15,0,0"
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
<Button Margin="0,0,10,0"
Command="{Binding Data.InstallAddonCommand, Source={StaticResource RootDataContext}}"
CommandParameter="{Binding}"
Visibility="{Binding IsQueuedForInstall, Converter={StaticResource InvertedBooleanToVisibilityConverter}}">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Content" Value="{DynamicResource LOCAddonInstall}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsInstalled}" Value="True">
<Setter Property="Content" Value="{DynamicResource LOCAddonAlreadyInstalled}" />
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
IsEnabled="{Binding IsQueuedForInstall, Converter={StaticResource NegateConverter}}">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Content" Value="{DynamicResource LOCAddonInstall}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsInstalled}" Value="True">
<Setter Property="Content" Value="{DynamicResource LOCAddonReinstall}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<ComboBox MinWidth="100"
ItemsSource="{Binding Data.AvailablePackages, Source={StaticResource RootDataContext}}"
SelectedValue="{Binding Data.SelectedInstallPackage, Source={StaticResource RootDataContext}}"
DisplayMemberPath="Version" />
</StackPanel>
<TextBlock Text="{DynamicResource LOCAddonQueuedForInstall}"
Margin="0,10,0,0" TextWrapping="Wrap"

View File

@ -113,7 +113,7 @@
<TextBlock Margin="5,10,0,10" DockPanel.Dock="Bottom">
<Hyperlink Command="{x:Static pcmd:GlobalCommands.NavigateUrlCommand}"
CommandParameter="https://playnite.link/docs/{AppBranch}/tutorials/extensions/intro.html">
CommandParameter="{}{DocsRootUrl}/tutorials/extensions/intro.html">
<Run Text="{DynamicResource LOCSettingsCreateExtensions}" />
</Hyperlink>
</TextBlock>

View File

@ -95,7 +95,7 @@
<TextBlock Margin="5,10,0,10" DockPanel.Dock="Bottom">
<Hyperlink Command="{x:Static pcmd:GlobalCommands.NavigateUrlCommand}"
CommandParameter="https://playnite.link/docs/{AppBranch}/tutorials/themes/introduction.html">
CommandParameter="{}{DocsRootUrl}/tutorials/themes/introduction.html">
<Run Text="{DynamicResource LOCSettingsCreateThemes}" />
</Hyperlink>
</TextBlock>

View File

@ -174,6 +174,34 @@ namespace Playnite.DesktopApp.Controls
}
UpdateTextStatus();
if (Template.FindName("Popup", this) is Popup popup)
{
popup.Opened += (_, __) =>
{
if (ShowSearchBox && TextSearchBox != null)
{
TextSearchBox.IsFocused = true;
}
};
popup.Closed += (_, __) =>
{
if (ShowSearchBox && TextSearchBox != null)
{
TextSearchBox.IsFocused = false;
TextSearchBox.Text = string.Empty;
}
};
popup.PreviewKeyUp += (_, keyArgs) =>
{
if (keyArgs.Key == Key.Escape)
{
popup.IsOpen = false;
}
};
}
}
public override void ClearButtonAction(RoutedEventArgs e)

Some files were not shown because too many files have changed in this diff Show More