Skip to content
This repository has been archived by the owner on Mar 3, 2023. It is now read-only.

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
erri120 committed Aug 17, 2020
1 parent 98c15dd commit 18c4a7e
Show file tree
Hide file tree
Showing 7 changed files with 219 additions and 57 deletions.
24 changes: 15 additions & 9 deletions ScreenshotPlugin/Hotkey/GlobalHotkeyService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@
using System.Windows.Forms;
using System.Windows.Input;
using Extensions.Common;
using JetBrains.Annotations;
using Newtonsoft.Json;
using Playnite.SDK;

namespace ScreenshotPlugin.Hotkey
namespace ScreenshotPlugin
{
//partially from https://tyrrrz.me/blog/wndproc-in-wpf

public static partial class PInvoke
public static partial class NativeFunctions
{
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
public static extern ushort GlobalAddAtom(string lpString);
Expand Down Expand Up @@ -131,8 +132,10 @@ public GlobalHotkeyService(ILogger logger)
_logger = logger;
}

public void RegisterHotkey(Hotkey hotkey)
public void RegisterHotkey([CanBeNull] Hotkey hotkey)
{
if (hotkey == null) return;

if (hotkey.Status == HotkeyStatus.Registered)
{
_logger.Warn($"Hotkey {hotkey.DebugString()} is already registered!");
Expand All @@ -149,7 +152,7 @@ public void RegisterHotkey(Hotkey hotkey)
if (hotkey.ID == 0)
{
var guid = Guid.NewGuid().ToString("N");
hotkey.ID = PInvoke.GlobalAddAtom(guid);
hotkey.ID = NativeFunctions.GlobalAddAtom(guid);

if (hotkey.ID == 0)
{
Expand All @@ -160,9 +163,9 @@ public void RegisterHotkey(Hotkey hotkey)
}

var vk = KeyInterop.VirtualKeyFromKey(hotkey.KeyCode);
if (!PInvoke.RegisterHotKey(_sponge.Handle, hotkey.ID, hotkey.KeyModifiers, vk))
if (!NativeFunctions.RegisterHotKey(_sponge.Handle, hotkey.ID, hotkey.KeyModifiers, vk))
{
PInvoke.GlobalDeleteAtom(hotkey.ID);
NativeFunctions.GlobalDeleteAtom(hotkey.ID);
hotkey.ID = 0;
hotkey.Status = HotkeyStatus.Failed;
_logger.Error($"Could not register hotkey {hotkey.DebugString()}");
Expand All @@ -174,21 +177,24 @@ public void RegisterHotkey(Hotkey hotkey)
_logger.Info($"Registered hotkey {hotkey.DebugString()}");
}

public void UnregisterHotkey(Hotkey hotkey)
public void UnregisterHotkey([CanBeNull] Hotkey hotkey)
{
if (hotkey == null) return;

if (hotkey.ID == 0)
{
hotkey.Status = HotkeyStatus.Failed;
_logger.Error($"Unable to unregister hotkey {hotkey.DebugString()}, ID is 0!");
return;
}

if (PInvoke.UnregisterHotKey(_sponge.Handle, hotkey.ID))
if (NativeFunctions.UnregisterHotKey(_sponge.Handle, hotkey.ID))
{
PInvoke.GlobalDeleteAtom(hotkey.ID);
NativeFunctions.GlobalDeleteAtom(hotkey.ID);
hotkey.ID = 0;
hotkey.Status = HotkeyStatus.NotConfigured;
_logger.Info($"Unregistered hotkey {hotkey.DebugString()}");
_hotkeys.Remove(hotkey);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion ScreenshotPlugin/Hotkey/SpongeWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
using System;
using System.Windows.Forms;

namespace ScreenshotPlugin.Hotkey
namespace ScreenshotPlugin
{
public sealed class SpongeWindow : NativeWindow
{
Expand Down
13 changes: 6 additions & 7 deletions ScreenshotPlugin/HotkeySelectionControl.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
using System.Text;
using System.Windows;
using System.Windows;
using System.Windows.Input;

namespace ScreenshotPlugin
{
public partial class HotkeySelectionControl
{
public static readonly DependencyProperty HotkeyProperty =
DependencyProperty.Register(nameof(Hotkey), typeof(Hotkey.Hotkey),
DependencyProperty.Register(nameof(Hotkey), typeof(Hotkey),
typeof(HotkeySelectionControl),
new FrameworkPropertyMetadata(default(Hotkey.Hotkey),
new FrameworkPropertyMetadata(default(Hotkey),
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

public Hotkey.Hotkey Hotkey
public Hotkey Hotkey
{
get => (Hotkey.Hotkey) GetValue(HotkeyProperty);
get => (Hotkey) GetValue(HotkeyProperty);
set => SetValue(HotkeyProperty, value);
}

Expand Down Expand Up @@ -65,7 +64,7 @@ private void HotkeyTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
}

// Update the value
Hotkey = new Hotkey.Hotkey
Hotkey = new Hotkey
{
KeyCode = key,
KeyModifiers = modifiers
Expand Down
102 changes: 99 additions & 3 deletions ScreenshotPlugin/ScreenshotExtensionPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,16 @@
// */

using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Controls;
using JetBrains.Annotations;
using Playnite.SDK;
using Playnite.SDK.Models;
using Playnite.SDK.Plugins;
using ScreenshotPlugin.Hotkey;
using ScreenshotPlugin.ShareX;

namespace ScreenshotPlugin
{
Expand All @@ -40,16 +45,107 @@ public ScreenshotExtensionPlugin(IPlayniteAPI playniteAPI) : base(playniteAPI)
_logger = playniteAPI.CreateLogger();
_globalHotkeyService = new GlobalHotkeyService(_logger);
_settings = new ScreenshotPluginSettings(this);

_globalHotkeyService.HotkeyPress += GlobalHotkeyServiceOnHotkeyPress;
}

public override void OnApplicationStarted()
[CanBeNull]
private Game _currentlyRunningGame;

private void GlobalHotkeyServiceOnHotkeyPress(Hotkey hotkey)
{
try
{
Bitmap bitmap;
var screenshot = new Screenshot();
string region;

if (hotkey == _settings.CaptureFullscreenHotkey)
{
bitmap = screenshot.CaptureFullscreen();
region = "fullscreen";
} else if (hotkey == _settings.CaptureActiveMonitorHotkey)
{
bitmap = screenshot.CaptureActiveMonitor();
region = "active monitor";
} else if (hotkey == _settings.CaptureActiveWindowHotkey)
{
bitmap = screenshot.CaptureActiveWindow();
region = "active window";
}
else
{
_logger.Error($"Unknown hotkey: {hotkey.DebugString()}");
return;
}

if (bitmap == null)
{
_logger.Error($"Unable to capture {region} with hotkey {hotkey.DebugString()}");
return;
}

var fileName = DateTime.Now.ToString("yyyy-MM-ddThh-mm-ss");
var folder = _currentlyRunningGame == null
? _settings.ScreenshotsPath
: Path.Combine(_settings.ScreenshotsPath, _currentlyRunningGame.GameId);

if (!Directory.Exists(folder))
Directory.CreateDirectory(folder);

var path = Path.Combine(folder, fileName + ".png");

bitmap.Save(path, ImageFormat.Png);
//bitmap.Dispose();

_playniteAPI.Notifications.Add(new NotificationMessage(fileName, $"Saved new screenshot to {path}", NotificationType.Info,
() =>
{
try
{
Process.Start(path);
}
catch (Exception)
{
//ignored
}
}));
}
catch (Exception e)
{
_logger.Error(e, $"Exception while handling hotkey {hotkey.DebugString()}\n");
}
}

public override void OnGameStarted(Game game)
{
_currentlyRunningGame = game;
}

public override void OnApplicationStopped()
public override void OnGameStopped(Game game, long ellapsedSeconds)
{
_currentlyRunningGame = null;
}

public override void OnApplicationStarted()
{
UpdateHotkeys(null, _settings);
}

public void UpdateHotkeys([CanBeNull] ScreenshotPluginSettings before, ScreenshotPluginSettings after)
{
if (before != null)
{
_globalHotkeyService.UnregisterHotkey(before.CaptureFullscreenHotkey);
_globalHotkeyService.UnregisterHotkey(before.CaptureActiveMonitorHotkey);
_globalHotkeyService.UnregisterHotkey(before.CaptureActiveWindowHotkey);
}

_globalHotkeyService.RegisterHotkey(after.CaptureFullscreenHotkey);
_globalHotkeyService.RegisterHotkey(after.CaptureActiveMonitorHotkey);
_globalHotkeyService.RegisterHotkey(after.CaptureActiveWindowHotkey);
}

public override ISettings GetSettings(bool firstRunSettings)
{
return _settings;
Expand Down
76 changes: 64 additions & 12 deletions ScreenshotPlugin/ScreenshotPluginSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,45 +16,70 @@
// */

using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using Extensions.Common;
using JetBrains.Annotations;
using Newtonsoft.Json;
using Playnite.SDK;
using ScreenshotPlugin.Hotkey;

namespace ScreenshotPlugin
{
public class ScreenshotPluginSettings : ISettings
{
private readonly ScreenshotExtensionPlugin _plugin;

public bool NoGameScreenshots { get; set; }
public string FullscreenScreenshotsPath { get; set; }
public Hotkey.Hotkey FullscreenWPFHotkey { get; set; }
public Hotkey.Hotkey ActiveWindowWPFHotkey { get; set; }
//public bool SaveToGame { get; set; }
//public bool SaveToFolder { get; set; }
public string ScreenshotsPath { get; set; }
public Hotkey CaptureActiveMonitorHotkey { get; set; }
public Hotkey CaptureActiveWindowHotkey { get; set; }
public Hotkey CaptureFullscreenHotkey { get; set; }

[UsedImplicitly]
public ScreenshotPluginSettings() { }

public ScreenshotPluginSettings(ScreenshotExtensionPlugin plugin)
{
_plugin = plugin;

var savedSettings = plugin.LoadPluginSettings<ScreenshotPluginSettings>();

if (savedSettings == null) return;
NoGameScreenshots = savedSettings.NoGameScreenshots;
FullscreenScreenshotsPath = savedSettings.FullscreenScreenshotsPath;
FullscreenWPFHotkey = savedSettings.FullscreenWPFHotkey;
ActiveWindowWPFHotkey = savedSettings.ActiveWindowWPFHotkey;
if (savedSettings != null)
{
//SaveToGame = savedSettings.SaveToGame;
//SaveToFolder = savedSettings.SaveToFolder;
ScreenshotsPath = savedSettings.ScreenshotsPath;
CaptureActiveMonitorHotkey = savedSettings.CaptureActiveMonitorHotkey;
CaptureActiveWindowHotkey = savedSettings.CaptureActiveWindowHotkey;
CaptureFullscreenHotkey = savedSettings.CaptureFullscreenHotkey;
}

if (ScreenshotsPath.IsEmpty())
{
ScreenshotsPath = Path.Combine(_plugin.PlayniteApi.Paths.ExtensionsDataPath, _plugin.Id.ToString());
}
}

private ScreenshotPluginSettings _before;

public void BeginEdit()
{
_before = new ScreenshotPluginSettings
{
CaptureActiveWindowHotkey = CaptureActiveWindowHotkey,
CaptureActiveMonitorHotkey = CaptureActiveMonitorHotkey,
CaptureFullscreenHotkey = CaptureFullscreenHotkey
};
}

public void EndEdit()
{
_plugin.SavePluginSettings(this);
_plugin.UpdateHotkeys(_before, this);

if (!Directory.Exists(ScreenshotsPath))
Directory.CreateDirectory(ScreenshotsPath);
}

public void CancelEdit()
Expand All @@ -64,7 +89,34 @@ public void CancelEdit()
public bool VerifySettings(out List<string> errors)
{
errors = new List<string>();
return true;

/*if (SaveToFolder && ScreenshotsPath.IsEmpty())
{
errors.Add("Screenshots Folder Path must not be empty if you want to save the screenshots to a folder!");
}*/

if (ScreenshotsPath.IsEmpty())
{
errors.Add("Screenshots Folder Path must not be empty!");
}

var hotkeys = new HashSet<Hotkey>(new HotkeyComparer());
if (!hotkeys.Add(CaptureFullscreenHotkey))
{
errors.Add("Duplicate hotkeys are not allowed!");
}

if (!hotkeys.Add(CaptureActiveMonitorHotkey))
{
errors.Add("Duplicate hotkeys are not allowed!");
}

if (!hotkeys.Add(CaptureActiveWindowHotkey))
{
errors.Add("Duplicate hotkeys are not allowed!");
}

return errors.Count <= 0;
}
}
}
18 changes: 11 additions & 7 deletions ScreenshotPlugin/ScreenshotSettingsView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
d:DataContext="{d:DesignInstance local:ScreenshotPluginSettings}"
d:DesignHeight="450" d:DesignWidth="800">
<StackPanel Margin="16 16">
<CheckBox IsChecked="{Binding NoGameScreenshots}" Margin="0 8" x:Name="NoGameScreenshots">Take Screenshots without playing a game</CheckBox>
<Label Margin="0 8 0 2" Target="{Binding ElementName=NoGameScreenshotsPath}">Screenshots Folder Path for non-game screenshots</Label>
<TextBox Text="{Binding FullscreenScreenshotsPath}" ToolTip="Screenshots taken while not running a game while be saved to this location. Only needed if the checkbox above is ticked." x:Name="NoGameScreenshotsPath"/>
<Label Margin="0 8 0 2" Target="{Binding ElementName=FullscreenHotkey}">Entire Screen Screenshot Hotkey</Label>
<local:HotkeySelectionControl x:Name="FullscreenHotkey" Hotkey="{Binding FullscreenWPFHotkey}"/>
<Label Margin="0 8 0 2" Target="{Binding ElementName=ActiveWindowHotkey}">Active Window Screenshot Hotkey</Label>
<local:HotkeySelectionControl x:Name="ActiveWindowHotkey" Hotkey="{Binding ActiveWindowWPFHotkey}"/>
<Label Margin="0 8 0 2" Target="{Binding ElementName=ScreenshotsPathTextBox}">Screenshots Folder Path</Label>
<TextBox x:Name="ScreenshotsPathTextBox" Text="{Binding ScreenshotsPath}"/>

<Label Margin="0 8 0 2" Target="{Binding ElementName=FullscreenHotkeyControl}">Capture Fullscreen Hotkey</Label>
<local:HotkeySelectionControl x:Name="FullscreenHotkeyControl" Hotkey="{Binding CaptureFullscreenHotkey}"/>

<Label Margin="0 8 0 2" Target="{Binding ElementName=ActiveMonitorHotkeyControl}">Capture active Monitor Hotkey</Label>
<local:HotkeySelectionControl x:Name="ActiveMonitorHotkeyControl" Hotkey="{Binding CaptureActiveMonitorHotkey}"/>

<Label Margin="0 8 0 2" Target="{Binding ElementName=ActiveWindowHotkeyControl}">Capture active Window Hotkey</Label>
<local:HotkeySelectionControl x:Name="ActiveWindowHotkeyControl" Hotkey="{Binding CaptureActiveWindowHotkey}"/>
</StackPanel>
</UserControl>
Loading

0 comments on commit 18c4a7e

Please sign in to comment.