Compare commits

...

20 Commits

Author SHA1 Message Date
d55e3c556d Update 2025-09-09 21:22:19 +02:00
fb3ab6ae77 Update 2025-08-30 20:52:13 +02:00
3b02e5c13d fix(config): adjust thumbnail snap grid and hotkey settings for improved usability 2025-08-30 00:22:44 +02:00
ad575c88d2 refactor(MainForm): validate hotkey input on leave event 2025-08-30 00:16:55 +02:00
708c1f3df6 Update 2025-08-30 00:16:55 +02:00
4f4bbd4b3d Update settings 2025-08-30 00:16:55 +02:00
328e77aa2f fix(MainForm.cs): update snap grid to be 1/4 of thumbnail size 2025-08-30 00:16:55 +02:00
b469d4a4f4 refactor(MainFormPresenter.cs): change hotkey registration from Send to Publish for better event handling 2025-08-30 00:16:55 +02:00
43496480f5 Add bin directory
For config
2025-08-30 00:16:55 +02:00
a9cdb69e0f feat(hotkeys): add hotkey configuration for toggling tracking and single process 2025-08-30 00:16:55 +02:00
dbee1a03d3 feat(Eve-O-Preview): add hotkey to toggle all thumbnails and update target framework 2025-08-30 00:16:55 +02:00
368e5e88c1 fix(ThumbnailManager.cs): set default location change notification delay to 0 to improve responsiveness 2025-08-29 22:52:15 +02:00
dfed1f4d69 refactor(MainForm.Designer.cs): remove redundant margin declarations and simplify font definitions 2025-08-29 22:47:51 +02:00
fe0a22b2bc fix(MainForm): adjust thumbnail snap range minimum to 0 and add maximum to prevent issues 2025-08-29 22:45:23 +02:00
4e461e1c9c refactor(ThumbnailManager.cs): use configured snap range for thumbnail view alignment 2025-08-29 22:43:50 +02:00
e53b9712ca feat(Eve-O-Preview): add aspect ratio maintenance for thumbnail size 2025-08-29 22:40:31 +02:00
7f5ab131af Fuck with the UI a bit 2025-08-29 22:34:11 +02:00
00eb9eb2de feat(configuration): add thumbnail snap range setting 2025-08-29 22:32:05 +02:00
a975fbf03d feat(MainForm): auto-set thumbnail size to match picked region 2025-08-29 22:23:06 +02:00
418ae9352d Make region selector shower instead of whole screen ) 2025-08-29 22:19:21 +02:00
109 changed files with 7591 additions and 6448 deletions

3
.clang-format Normal file
View File

@@ -0,0 +1,3 @@
BasedOnStyle: Google
IndentWidth: 4
ColumnLimit: 120

5
.gitignore vendored
View File

@@ -1,4 +1,3 @@
bin/
obj/ obj/
publish/ publish/
tools/ tools/
@@ -9,3 +8,7 @@ src/*/.vs/
*.DotSettings *.DotSettings
build/Fody* build/Fody*
*.vs/ *.vs/
*.dll
*.exe
*.log
*.pdb

View File

@@ -0,0 +1,100 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v6.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v6.0": {
"EVE-O-Preview/1.0.0": {
"dependencies": {
"LightInject": "7.0.1",
"MediatR": "9.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.NET.ILLink.Analyzers": "7.0.100-1.23211.1",
"Microsoft.NET.ILLink.Tasks": "7.0.100-1.23211.1",
"Newtonsoft.Json": "13.0.3"
},
"runtime": {
"EVE-O-Preview.dll": {}
}
},
"LightInject/7.0.1": {
"runtime": {
"lib/netstandard2.0/LightInject.dll": {
"assemblyVersion": "7.0.1.0",
"fileVersion": "7.0.1.0"
}
}
},
"MediatR/9.0.0": {
"runtime": {
"lib/netstandard2.1/MediatR.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.0.0"
}
}
},
"Microsoft.CSharp/4.7.0": {},
"Microsoft.NET.ILLink.Analyzers/7.0.100-1.23211.1": {},
"Microsoft.NET.ILLink.Tasks/7.0.100-1.23211.1": {},
"Newtonsoft.Json/13.0.3": {
"runtime": {
"lib/net6.0/Newtonsoft.Json.dll": {
"assemblyVersion": "13.0.0.0",
"fileVersion": "13.0.3.27908"
}
}
}
}
},
"libraries": {
"EVE-O-Preview/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"LightInject/7.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-aw4ayG2Pe68i+85ws8zYk7MPCKjEd4DeBoTqVvmjA2cfpYYNnw+v0E5T3PKdriKaxdKF+eUzlnxWWZnYK/gx4w==",
"path": "lightinject/7.0.1",
"hashPath": "lightinject.7.0.1.nupkg.sha512"
},
"MediatR/9.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-8b3UYNxegHVYcJMG2zH8wn+YqxLvXG+eMfj0cMCq/jTW72p6O3PCKMkrIv0mqyxdW7bA4gblsocw7n+/9Akg5g==",
"path": "mediatr/9.0.0",
"hashPath": "mediatr.9.0.0.nupkg.sha512"
},
"Microsoft.CSharp/4.7.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA==",
"path": "microsoft.csharp/4.7.0",
"hashPath": "microsoft.csharp.4.7.0.nupkg.sha512"
},
"Microsoft.NET.ILLink.Analyzers/7.0.100-1.23211.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-0GvbEgDGcUQA9KuWcQU1WwYHXt1tBzNr1Nls/M57rM7NA/AndFwCaCEoJpJkmxRY7xLlPDBnmGp8h5+FNqUngg==",
"path": "microsoft.net.illink.analyzers/7.0.100-1.23211.1",
"hashPath": "microsoft.net.illink.analyzers.7.0.100-1.23211.1.nupkg.sha512"
},
"Microsoft.NET.ILLink.Tasks/7.0.100-1.23211.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-tvG8XZYLjT0o3WicCyKBZysVWo1jC9HdCFmNRmddx3WbAz0UCsd0qKZqpiEo99VLA8Re+FzWK51OcRldQPbt2Q==",
"path": "microsoft.net.illink.tasks/7.0.100-1.23211.1",
"hashPath": "microsoft.net.illink.tasks.7.0.100-1.23211.1.nupkg.sha512"
},
"Newtonsoft.Json/13.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==",
"path": "newtonsoft.json/13.0.3",
"hashPath": "newtonsoft.json.13.0.3.nupkg.sha512"
}
}
}

View File

@@ -0,0 +1,128 @@
{
"ConfigVersion": 1,
"CycleGroup1ForwardHotkeys": [
"F14",
"Control+F14"
],
"CycleGroup1BackwardHotkeys": [
"F13",
"Control+F13"
],
"CycleGroup1ClientsOrder": {
"EVE - Example DPS Toon 1": 1,
"EVE - Example DPS Toon 2": 2,
"EVE - Example DPS Toon 3": 3
},
"CycleGroup2ForwardHotkeys": [
"F16",
"Control+F16"
],
"CycleGroup2BackwardHotkeys": [
"F15",
"Control+F15"
],
"CycleGroup2ClientsOrder": {
"EVE - Example Logi Toon 1": 1,
"EVE - Example Scout Toon 2": 2,
"EVE - Example Tackle Toon 3": 3
},
"CycleGroup3ForwardHotkeys": [
""
],
"CycleGroup3BackwardHotkeys": [
""
],
"CycleGroup3ClientsOrder": {
"EVE - cycle group 3": 1
},
"CycleGroup4ForwardHotkeys": [
""
],
"CycleGroup4BackwardHotkeys": [
""
],
"CycleGroup4ClientsOrder": {
"EVE - cycle group 4": 1
},
"CycleGroup5ForwardHotkeys": [
""
],
"CycleGroup5BackwardHotkeys": [
""
],
"CycleGroup5ClientsOrder": {
"EVE - cycle group 5": 1
},
"PerClientActiveClientHighlightColor": {
"EVE - Example Toon 1": "Red",
"EVE - Example Toon 2": "Green"
},
"PerClientThumbnailSize": {
"EVE - Example Toon 1": "200, 200",
"EVE - Example Toon 2": "200, 200"
},
"PerClientThumbnailRegion": {},
"PerClientZoomAnchor": {
"EVE - Example Toon 1": 1,
"EVE - Example Toon 2": 7
},
"MinimizeToTray": false,
"ThumbnailRefreshPeriod": 500,
"ThumbnailResizeTimeoutPeriod": 500,
"WineCompatibilityMode": false,
"ThumbnailsOpacity": 0.5,
"EnableClientLayoutTracking": false,
"HideActiveClientThumbnail": false,
"HideLoginClientThumbnail": false,
"MinimizeInactiveClients": false,
"WindowsAnimationStyle": 1,
"ShowThumbnailsAlwaysOnTop": true,
"EnablePerClientThumbnailLayouts": false,
"HideThumbnailsOnLostFocus": false,
"HideThumbnailsDelay": 2,
"ThumbnailSize": "408, 177",
"ThumbnailMaximumSize": "960, 540",
"ThumbnailMinimumSize": "192, 108",
"EnableThumbnailSnap": true,
"ThumbnailSnapRange": 20,
"EnableThumbnailZoom": false,
"ThumbnailZoomFactor": 2,
"ThumbnailZoomAnchor": 0,
"OverlayLabelAnchor": 0,
"ShowThumbnailOverlays": true,
"ShowThumbnailFrames": false,
"LockThumbnailLocation": false,
"ThumbnailSnapToGrid": true,
"ThumbnailSnapToGridSizeX": 102,
"ThumbnailSnapToGridSizeY": 44,
"EnableActiveClientHighlight": false,
"ActiveClientHighlightColor": "GreenYellow",
"OverlayLabelColor": "Orange",
"OverlayLabelSize": 10,
"EnableThumbnailRegionSnipping": true,
"DefaultThumbnailRegion": "1187, 1252, 398, 174",
"CurrentProfile": "Default",
"AvailableProfiles": [
"Default"
],
"IconName": "IconOriginal",
"ActiveClientHighlightThickness": 3,
"LoginThumbnailLocation": "5, 5",
"ToggleTrackingHotkey": "Alt+F16",
"ToggleSingleProcessHotkey": "Control+F16",
"ToggleAllThumbnailsHotkey": "Alt+F12",
"ThumbnailsManuallyHidden": false,
"PerClientLayout": {},
"FlatLayout": {
"EVE - Sn v1 cosunoo (2)": "1938, 1100",
"EVE - Primorium (1)": "1530, 1100",
"EVE - PhatPhuckDave (3)": "1122, 1100"
},
"ClientLayout": {},
"ClientHotkey": {},
"DisableThumbnail": {},
"PriorityClients": [],
"ExecutablesToPreview": [
"exefile"
]
}

View File

@@ -0,0 +1,18 @@
{
"runtimeOptions": {
"tfm": "net6.0",
"frameworks": [
{
"name": "Microsoft.NETCore.App",
"version": "6.0.0"
},
{
"name": "Microsoft.WindowsDesktop.App",
"version": "6.0.0"
}
],
"configProperties": {
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false
}
}
}

View File

@@ -0,0 +1,91 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v8.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v8.0": {
"EVE-O-Preview/1.0.0": {
"dependencies": {
"LightInject": "7.0.1",
"MediatR": "9.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.NET.ILLink.Tasks": "8.0.18",
"Newtonsoft.Json": "13.0.3"
},
"runtime": {
"EVE-O-Preview.dll": {}
}
},
"LightInject/7.0.1": {
"runtime": {
"lib/net8.0/LightInject.dll": {
"assemblyVersion": "7.0.1.0",
"fileVersion": "7.0.1.0"
}
}
},
"MediatR/9.0.0": {
"runtime": {
"lib/netstandard2.1/MediatR.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.0.0"
}
}
},
"Microsoft.CSharp/4.7.0": {},
"Microsoft.NET.ILLink.Tasks/8.0.18": {},
"Newtonsoft.Json/13.0.3": {
"runtime": {
"lib/net6.0/Newtonsoft.Json.dll": {
"assemblyVersion": "13.0.0.0",
"fileVersion": "13.0.3.27908"
}
}
}
}
},
"libraries": {
"EVE-O-Preview/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"LightInject/7.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-aw4ayG2Pe68i+85ws8zYk7MPCKjEd4DeBoTqVvmjA2cfpYYNnw+v0E5T3PKdriKaxdKF+eUzlnxWWZnYK/gx4w==",
"path": "lightinject/7.0.1",
"hashPath": "lightinject.7.0.1.nupkg.sha512"
},
"MediatR/9.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-8b3UYNxegHVYcJMG2zH8wn+YqxLvXG+eMfj0cMCq/jTW72p6O3PCKMkrIv0mqyxdW7bA4gblsocw7n+/9Akg5g==",
"path": "mediatr/9.0.0",
"hashPath": "mediatr.9.0.0.nupkg.sha512"
},
"Microsoft.CSharp/4.7.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA==",
"path": "microsoft.csharp/4.7.0",
"hashPath": "microsoft.csharp.4.7.0.nupkg.sha512"
},
"Microsoft.NET.ILLink.Tasks/8.0.18": {
"type": "package",
"serviceable": true,
"sha512": "sha512-OiXqr2YIBEV9dsAWEtasK470ALyJ0VxJ9k4MotOxlWV6HeEgrJKYMW4HHj1OCCXvqE0/A25wEKPkpfiBARgDZA==",
"path": "microsoft.net.illink.tasks/8.0.18",
"hashPath": "microsoft.net.illink.tasks.8.0.18.nupkg.sha512"
},
"Newtonsoft.Json/13.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==",
"path": "newtonsoft.json/13.0.3",
"hashPath": "newtonsoft.json.13.0.3.nupkg.sha512"
}
}
}

View File

@@ -0,0 +1,137 @@
{
"ConfigVersion": 1,
"CycleGroup1ForwardHotkeys": [
"F14",
"Control+F14"
],
"CycleGroup1BackwardHotkeys": [
"F13",
"Control+F13"
],
"CycleGroup1ClientsOrder": {
"EVE - Example DPS Toon 1": 1,
"EVE - Example DPS Toon 2": 2,
"EVE - Example DPS Toon 3": 3
},
"CycleGroup2ForwardHotkeys": [
"F16",
"Control+F16"
],
"CycleGroup2BackwardHotkeys": [
"F15",
"Control+F15"
],
"CycleGroup2ClientsOrder": {
"EVE - Example Logi Toon 1": 1,
"EVE - Example Scout Toon 2": 2,
"EVE - Example Tackle Toon 3": 3
},
"CycleGroup3ForwardHotkeys": [
""
],
"CycleGroup3BackwardHotkeys": [
""
],
"CycleGroup3ClientsOrder": {
"EVE - cycle group 3": 1
},
"CycleGroup4ForwardHotkeys": [
""
],
"CycleGroup4BackwardHotkeys": [
""
],
"CycleGroup4ClientsOrder": {
"EVE - cycle group 4": 1
},
"CycleGroup5ForwardHotkeys": [
""
],
"CycleGroup5BackwardHotkeys": [
""
],
"CycleGroup5ClientsOrder": {
"EVE - cycle group 5": 1
},
"PerClientActiveClientHighlightColor": {
"EVE - Example Toon 1": "Red",
"EVE - Example Toon 2": "Green"
},
"PerClientThumbnailSize": {
"EVE - Example Toon 1": "200, 200",
"EVE - Example Toon 2": "200, 200"
},
"PerClientThumbnailRegion": {},
"PerClientZoomAnchor": {
"EVE - Example Toon 1": 1,
"EVE - Example Toon 2": 7
},
"MinimizeToTray": true,
"ThumbnailRefreshPeriod": 500,
"ThumbnailResizeTimeoutPeriod": 500,
"WineCompatibilityMode": false,
"ThumbnailsOpacity": 1.0,
"EnableClientLayoutTracking": false,
"HideActiveClientThumbnail": false,
"HideLoginClientThumbnail": false,
"MinimizeInactiveClients": false,
"WindowsAnimationStyle": 1,
"ShowThumbnailsAlwaysOnTop": true,
"EnablePerClientThumbnailLayouts": false,
"HideThumbnailsOnLostFocus": false,
"HideThumbnailsDelay": 2,
"ThumbnailSize": "451, 238",
"ThumbnailMaximumSize": "960, 540",
"ThumbnailMinimumSize": "192, 108",
"EnableThumbnailSnap": true,
"ThumbnailSnapRange": 150,
"EnableThumbnailZoom": false,
"ThumbnailZoomFactor": 2,
"ThumbnailZoomAnchor": 0,
"OverlayLabelAnchor": 0,
"ShowThumbnailOverlays": true,
"ShowThumbnailFrames": false,
"LockThumbnailLocation": false,
"ThumbnailSnapToGrid": true,
"ThumbnailSnapToGridSizeX": 112,
"ThumbnailSnapToGridSizeY": 59,
"EnableActiveClientHighlight": true,
"ActiveClientHighlightColor": "GreenYellow",
"OverlayLabelColor": "Orange",
"OverlayLabelSize": 10,
"EnableThumbnailRegionSnipping": true,
"DefaultThumbnailRegion": "1664, 188, 451, 238",
"CurrentProfile": "Default",
"AvailableProfiles": [
"Default"
],
"IconName": "IconOriginal",
"ActiveClientHighlightThickness": 3,
"LoginThumbnailLocation": "5, 5",
"ToggleTrackingHotkey": "Alt+F16",
"ToggleSingleProcessHotkey": "Control+F16",
"ToggleAllThumbnailsHotkey": "Shift+Alt+Oem3",
"ThumbnailsManuallyHidden": false,
"PerClientLayout": {},
"FlatLayout": {
"EVE - Sn v1 cosunoo (2)": "1995, 1058",
"EVE - Primorium (1)": "240, 645",
"EVE - PhatPhuckDave (3)": "224, -2",
"EVE - Primorium (3)": "146, 285",
"EVE - PhatPhuckDave (2)": "146, 57",
"EVE - Sn v1 cosunoo (1)": "154, 472",
"EVE - Sn v1 cosunoo (3)": "292, 517",
"EVE - Primorium (2)": "224, 236",
"EVE - PhatPhuckDave (1)": "292, 57",
"EVE - Secundamen (1)": "224, 474"
},
"ClientLayout": {},
"ClientHotkey": {},
"DisableThumbnail": {
"EVE - PhatPhuckDave (1)": false
},
"PriorityClients": [],
"ExecutablesToPreview": [
"exefile"
]
}

View File

@@ -0,0 +1,20 @@
{
"runtimeOptions": {
"tfm": "net8.0",
"frameworks": [
{
"name": "Microsoft.NETCore.App",
"version": "8.0.0"
},
{
"name": "Microsoft.WindowsDesktop.App",
"version": "8.0.0"
}
],
"configProperties": {
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": true,
"CSWINRT_USE_WINDOWS_UI_XAML_PROJECTIONS": false
}
}
}

View File

@@ -1,8 +1,5 @@
using System.Windows; using System.Windows;
namespace EveOMock namespace EveOMock {
{ public partial class App : Application {}
public partial class App : Application
{
}
} }

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net6.0-windows</TargetFramework>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<RootNamespace>EveOMock</RootNamespace> <RootNamespace>EveOMock</RootNamespace>
<AssemblyName>ExeFile</AssemblyName> <AssemblyName>ExeFile</AssemblyName>

View File

@@ -2,16 +2,14 @@
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
namespace EveOMock namespace EveOMock {
{ public partial class MainWindow : Window {
public partial class MainWindow : Window public MainWindow() {
{ InitializeComponent();
public MainWindow() Random random = new Random();
{ this.Title += random.Next().ToString("X");
InitializeComponent(); this.grid.Background = new SolidColorBrush(
Random random = new Random(); Color.FromArgb(255, (byte)random.Next(0, 255), (byte)random.Next(0, 255), (byte)random.Next(0, 255)));
this.Title += random.Next().ToString("X"); }
this.grid.Background = new SolidColorBrush(Color.FromArgb(255, (byte)random.Next(0, 255), (byte)random.Next(0, 255), (byte)random.Next(0, 255))); }
}
}
} }

View File

@@ -3,26 +3,25 @@ using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
[assembly: AssemblyTitle("EVE Online mock executable for the EVE-O-Preview project")] [assembly:AssemblyTitle("EVE Online mock executable for the EVE-O-Preview project")]
[assembly: AssemblyDescription("")] [assembly:AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly:AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly:AssemblyCompany("")]
[assembly: AssemblyProduct("EVE-O Mock")] [assembly:AssemblyProduct("EVE-O Mock")]
[assembly: AssemblyTrademark("")] [assembly:AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly:AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly:ComVisible(false)]
[assembly: ThemeInfo( [assembly:ThemeInfo(ResourceDictionaryLocation.None, // where theme specific resource dictionaries are located
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located //(used if a resource is not found in the page,
//(used if a resource is not found in the page, // or application resource dictionaries)
// or application resource dictionaries) ResourceDictionaryLocation.SourceAssembly // where the generic resource dictionary is located
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located //(used if a resource is not found in the page,
//(used if a resource is not found in the page, // app, or any theme specific resource dictionaries)
// app, or any theme specific resource dictionaries) )]
)]
[assembly: AssemblyVersion("1.0.0.0")] [assembly:AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly:AssemblyFileVersion("1.0.0.0")]
[assembly: CLSCompliant(true)] [assembly:CLSCompliant(true)]

View File

@@ -10,8 +10,7 @@
namespace EveOMock.Properties { namespace EveOMock.Properties {
using System; using System;
/// <summary> /// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc. /// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary> /// </summary>
@@ -19,45 +18,44 @@ namespace EveOMock.Properties {
// class via a tool like ResGen or Visual Studio. // class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen // To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project. // with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder",
"17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources { internal class Resources {
private static global::System.Resources.ResourceManager resourceMan; private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture; private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance",
internal Resources() { "CA1811:AvoidUncalledPrivateCode")]
} internal Resources() {}
/// <summary> /// <summary>
/// Returns the cached ResourceManager instance used by this class. /// Returns the cached ResourceManager instance used by this class.
/// </summary> /// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] [global::System.ComponentModel.EditorBrowsableAttribute(
global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager { internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EveOMock.Properties.Resources", typeof(Resources).Assembly); global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(
"EveOMock.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
} }
} }
/// <summary> /// <summary>
/// Overrides the current thread's CurrentUICulture property for all /// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class. /// resource lookups using this strongly typed resource class.
/// </summary> /// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] [global::System.ComponentModel.EditorBrowsableAttribute(
global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture { internal static global::System.Globalization.CultureInfo Culture {
get { get { return resourceCulture; }
return resourceCulture; set { resourceCulture = value; }
}
set {
resourceCulture = value;
}
} }
} }
} }

View File

@@ -9,18 +9,16 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace EveOMock.Properties { namespace EveOMock.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute(
"Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance =
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default { public static Settings Default {
get { get { return defaultInstance; }
return defaultInstance;
}
} }
} }
} }

View File

@@ -1,7 +1,5 @@
namespace PreviewToy namespace PreviewToy {
{ partial class AboutBox {
partial class AboutBox
{
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
/// </summary> /// </summary>
@@ -10,23 +8,20 @@
/// <summary> /// <summary>
/// Clean up any resources being used. /// Clean up any resources being used.
/// </summary> /// </summary>
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing) {
{ if (disposing && (components != null)) {
if (disposing && (components != null))
{
components.Dispose(); components.Dispose();
} }
base.Dispose(disposing); base.Dispose(disposing);
} }
#region Windows Form Designer generated code #region Windows Form Designer generated code
/// <summary> /// <summary>
/// Required method for Designer support - do not modify /// Required method for Designer support - do not modify
/// the contents of this method with the code editor. /// the contents of this method with the code editor.
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent() {
{
this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
this.logoPictureBox = new System.Windows.Forms.PictureBox(); this.logoPictureBox = new System.Windows.Forms.PictureBox();
this.labelProductName = new System.Windows.Forms.Label(); this.labelProductName = new System.Windows.Forms.Label();
@@ -38,12 +33,14 @@
this.tableLayoutPanel.SuspendLayout(); this.tableLayoutPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit();
this.SuspendLayout(); this.SuspendLayout();
// //
// tableLayoutPanel // tableLayoutPanel
// //
this.tableLayoutPanel.ColumnCount = 2; this.tableLayoutPanel.ColumnCount = 2;
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F)); this.tableLayoutPanel.ColumnStyles.Add(
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 67F)); new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F));
this.tableLayoutPanel.ColumnStyles.Add(
new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 67F));
this.tableLayoutPanel.Controls.Add(this.logoPictureBox, 0, 0); this.tableLayoutPanel.Controls.Add(this.logoPictureBox, 0, 0);
this.tableLayoutPanel.Controls.Add(this.labelProductName, 1, 0); this.tableLayoutPanel.Controls.Add(this.labelProductName, 1, 0);
this.tableLayoutPanel.Controls.Add(this.labelVersion, 1, 1); this.tableLayoutPanel.Controls.Add(this.labelVersion, 1, 1);
@@ -55,17 +52,23 @@
this.tableLayoutPanel.Location = new System.Drawing.Point(9, 9); this.tableLayoutPanel.Location = new System.Drawing.Point(9, 9);
this.tableLayoutPanel.Name = "tableLayoutPanel"; this.tableLayoutPanel.Name = "tableLayoutPanel";
this.tableLayoutPanel.RowCount = 6; this.tableLayoutPanel.RowCount = 6;
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); this.tableLayoutPanel.RowStyles.Add(
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); this.tableLayoutPanel.RowStyles.Add(
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); this.tableLayoutPanel.RowStyles.Add(
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.RowStyles.Add(
new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.RowStyles.Add(
new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel.RowStyles.Add(
new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.Size = new System.Drawing.Size(534, 490); this.tableLayoutPanel.Size = new System.Drawing.Size(534, 490);
this.tableLayoutPanel.TabIndex = 0; this.tableLayoutPanel.TabIndex = 0;
// //
// logoPictureBox // logoPictureBox
// //
this.logoPictureBox.Dock = System.Windows.Forms.DockStyle.Fill; this.logoPictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.logoPictureBox.Image = global::PreviewToy.Properties.Resources.Eve_online; this.logoPictureBox.Image = global::PreviewToy.Properties.Resources.Eve_online;
this.logoPictureBox.Location = new System.Drawing.Point(3, 3); this.logoPictureBox.Location = new System.Drawing.Point(3, 3);
@@ -75,9 +78,9 @@
this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.logoPictureBox.TabIndex = 12; this.logoPictureBox.TabIndex = 12;
this.logoPictureBox.TabStop = false; this.logoPictureBox.TabStop = false;
// //
// labelProductName // labelProductName
// //
this.labelProductName.Dock = System.Windows.Forms.DockStyle.Fill; this.labelProductName.Dock = System.Windows.Forms.DockStyle.Fill;
this.labelProductName.Location = new System.Drawing.Point(182, 0); this.labelProductName.Location = new System.Drawing.Point(182, 0);
this.labelProductName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); this.labelProductName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
@@ -87,9 +90,9 @@
this.labelProductName.TabIndex = 19; this.labelProductName.TabIndex = 19;
this.labelProductName.Text = "Product Name"; this.labelProductName.Text = "Product Name";
this.labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; this.labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
// //
// labelVersion // labelVersion
// //
this.labelVersion.Dock = System.Windows.Forms.DockStyle.Fill; this.labelVersion.Dock = System.Windows.Forms.DockStyle.Fill;
this.labelVersion.Location = new System.Drawing.Point(182, 49); this.labelVersion.Location = new System.Drawing.Point(182, 49);
this.labelVersion.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); this.labelVersion.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
@@ -99,9 +102,9 @@
this.labelVersion.TabIndex = 0; this.labelVersion.TabIndex = 0;
this.labelVersion.Text = "Version"; this.labelVersion.Text = "Version";
this.labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; this.labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
// //
// labelCopyright // labelCopyright
// //
this.labelCopyright.Dock = System.Windows.Forms.DockStyle.Fill; this.labelCopyright.Dock = System.Windows.Forms.DockStyle.Fill;
this.labelCopyright.Location = new System.Drawing.Point(182, 98); this.labelCopyright.Location = new System.Drawing.Point(182, 98);
this.labelCopyright.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); this.labelCopyright.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
@@ -112,10 +115,11 @@
this.labelCopyright.TabStop = true; this.labelCopyright.TabStop = true;
this.labelCopyright.Text = "Copyright"; this.labelCopyright.Text = "Copyright";
this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.labelCopyright.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.labelCopyright_LinkClicked); this.labelCopyright.LinkClicked +=
// new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.labelCopyright_LinkClicked);
//
// labelCompanyName // labelCompanyName
// //
this.labelCompanyName.Dock = System.Windows.Forms.DockStyle.Fill; this.labelCompanyName.Dock = System.Windows.Forms.DockStyle.Fill;
this.labelCompanyName.Location = new System.Drawing.Point(182, 147); this.labelCompanyName.Location = new System.Drawing.Point(182, 147);
this.labelCompanyName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); this.labelCompanyName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
@@ -126,32 +130,36 @@
this.labelCompanyName.TabStop = true; this.labelCompanyName.TabStop = true;
this.labelCompanyName.Text = "Company Name"; this.labelCompanyName.Text = "Company Name";
this.labelCompanyName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; this.labelCompanyName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.labelCompanyName.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.labelCompanyName_LinkClicked); this.labelCompanyName.LinkClicked +=
// new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.labelCompanyName_LinkClicked);
//
// okButton // okButton
// //
this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)(
(System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.okButton.Location = new System.Drawing.Point(456, 464); this.okButton.Location = new System.Drawing.Point(456, 464);
this.okButton.Name = "okButton"; this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(75, 23); this.okButton.Size = new System.Drawing.Size(75, 23);
this.okButton.TabIndex = 24; this.okButton.TabIndex = 24;
this.okButton.Text = "&OK"; this.okButton.Text = "&OK";
// //
// richTextBoxDescription // richTextBoxDescription
// //
this.richTextBoxDescription.BackColor = System.Drawing.SystemColors.Control; this.richTextBoxDescription.BackColor = System.Drawing.SystemColors.Control;
this.richTextBoxDescription.Dock = System.Windows.Forms.DockStyle.Fill; this.richTextBoxDescription.Dock = System.Windows.Forms.DockStyle.Fill;
this.richTextBoxDescription.Font = new System.Drawing.Font("Microsoft Sans Serif", 6F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.richTextBoxDescription.Font =
new System.Drawing.Font("Microsoft Sans Serif", 6F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.richTextBoxDescription.Location = new System.Drawing.Point(179, 199); this.richTextBoxDescription.Location = new System.Drawing.Point(179, 199);
this.richTextBoxDescription.Name = "richTextBoxDescription"; this.richTextBoxDescription.Name = "richTextBoxDescription";
this.richTextBoxDescription.ReadOnly = true; this.richTextBoxDescription.ReadOnly = true;
this.richTextBoxDescription.Size = new System.Drawing.Size(352, 239); this.richTextBoxDescription.Size = new System.Drawing.Size(352, 239);
this.richTextBoxDescription.TabIndex = 25; this.richTextBoxDescription.TabIndex = 25;
this.richTextBoxDescription.Text = "Description"; this.richTextBoxDescription.Text = "Description";
// //
// AboutBox // AboutBox
// //
this.AcceptButton = this.okButton; this.AcceptButton = this.okButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
@@ -169,10 +177,9 @@
this.tableLayoutPanel.ResumeLayout(false); this.tableLayoutPanel.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit();
this.ResumeLayout(false); this.ResumeLayout(false);
} }
#endregion #endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
private System.Windows.Forms.PictureBox logoPictureBox; private System.Windows.Forms.PictureBox logoPictureBox;

View File

@@ -7,12 +7,9 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Windows.Forms; using System.Windows.Forms;
namespace PreviewToy namespace PreviewToy {
{ partial class AboutBox : Form {
partial class AboutBox : Form public AboutBox() {
{
public AboutBox()
{
InitializeComponent(); InitializeComponent();
this.Text = String.Format("About {0}", AssemblyTitle); this.Text = String.Format("About {0}", AssemblyTitle);
this.labelProductName.Text = AssemblyProduct; this.labelProductName.Text = AssemblyProduct;
@@ -20,7 +17,7 @@ namespace PreviewToy
this.labelCopyright.Text = AssemblyCopyright; this.labelCopyright.Text = AssemblyCopyright;
this.labelCompanyName.Text = AssemblyCompany; this.labelCompanyName.Text = AssemblyCompany;
this.richTextBoxDescription.Rtf = this.richTextBoxDescription.Rtf =
@"{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Arial;}{\f1\fnil\fcharset0 Calibri;}{\f2\fnil\fcharset2 Symbol;}} @"{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Arial;}{\f1\fnil\fcharset0 Calibri;}{\f2\fnil\fcharset2 Symbol;}}
{\*\generator Riched20 6.3.9600}\viewkind4\uc1 {\*\generator Riched20 6.3.9600}\viewkind4\uc1
\pard\sa200\sl276\slmult1\qc\b\fs28\lang9 EVE-O Preview\par \pard\sa200\sl276\slmult1\qc\b\fs28\lang9 EVE-O Preview\par
@@ -40,34 +37,29 @@ namespace PreviewToy
}"; }";
} }
//StinkRay // StinkRay
private void labelCopyright_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) private void labelCopyright_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
{
string url = "https://forums.eveonline.com/default.aspx?g=posts&t=246157"; string url = "https://forums.eveonline.com/default.aspx?g=posts&t=246157";
ProcessStartInfo sInfo = new ProcessStartInfo(new Uri(url).AbsoluteUri); ProcessStartInfo sInfo = new ProcessStartInfo(new Uri(url).AbsoluteUri);
Process.Start(sInfo); Process.Start(sInfo);
} }
//New Thread // New Thread
private void labelCompanyName_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) private void labelCompanyName_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
{
string url = "https://forums.eveonline.com/default.aspx?g=posts&m=5264866"; string url = "https://forums.eveonline.com/default.aspx?g=posts&m=5264866";
ProcessStartInfo sInfo = new ProcessStartInfo(new Uri(url).AbsoluteUri); ProcessStartInfo sInfo = new ProcessStartInfo(new Uri(url).AbsoluteUri);
Process.Start(sInfo); Process.Start(sInfo);
} }
#region Assembly Attribute Accessors #region Assembly Attribute Accessors
public string AssemblyTitle public string AssemblyTitle {
{ get {
get object[] attributes =
{ Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false); if (attributes.Length > 0) {
if (attributes.Length > 0)
{
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0]; AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
if (titleAttribute.Title != "") if (titleAttribute.Title != "") {
{
return titleAttribute.Title; return titleAttribute.Title;
} }
} }
@@ -75,65 +67,53 @@ namespace PreviewToy
} }
} }
public string AssemblyVersion public string AssemblyVersion {
{ get { return Assembly.GetExecutingAssembly().GetName().Version.ToString(); }
get
{
return Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
} }
public string AssemblyDescription public string AssemblyDescription {
{ get {
get object[] attributes =
{ Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false); if (attributes.Length == 0) {
if (attributes.Length == 0)
{
return ""; return "";
} }
return ((AssemblyDescriptionAttribute)attributes[0]).Description; return ((AssemblyDescriptionAttribute)attributes[0]).Description;
} }
} }
public string AssemblyProduct public string AssemblyProduct {
{ get {
get object[] attributes =
{ Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false); if (attributes.Length == 0) {
if (attributes.Length == 0)
{
return ""; return "";
} }
return ((AssemblyProductAttribute)attributes[0]).Product; return ((AssemblyProductAttribute)attributes[0]).Product;
} }
} }
public string AssemblyCopyright public string AssemblyCopyright {
{ get {
get object[] attributes =
{ Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); if (attributes.Length == 0) {
if (attributes.Length == 0)
{
return ""; return "";
} }
return ((AssemblyCopyrightAttribute)attributes[0]).Copyright; return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
} }
} }
public string AssemblyCompany public string AssemblyCompany {
{ get {
get object[] attributes =
{ Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false); if (attributes.Length == 0) {
if (attributes.Length == 0)
{
return ""; return "";
} }
return ((AssemblyCompanyAttribute)attributes[0]).Company; return ((AssemblyCompanyAttribute)attributes[0]).Company;
} }
} }
#endregion #endregion
} }
} }

View File

@@ -1,69 +1,57 @@
namespace EveOPreview namespace EveOPreview {
{ public class ApplicationController : IApplicationController {
public class ApplicationController : IApplicationController private readonly IIocContainer _container;
{
private readonly IIocContainer _container;
public ApplicationController(IIocContainer container) public ApplicationController(IIocContainer container) {
{ this._container = container;
this._container = container; this._container.RegisterInstance<IApplicationController>(this);
this._container.RegisterInstance<IApplicationController>(this); }
}
public IApplicationController RegisterView<TView, TImplementation>() public IApplicationController RegisterView<TView, TImplementation>()
where TView : IView where TView : IView
where TImplementation : class, TView where TImplementation : class, TView {
{ this._container.Register<TView, TImplementation>();
this._container.Register<TView, TImplementation>(); return this;
return this; }
}
public IApplicationController RegisterInstance<TArgument>(TArgument instance) public IApplicationController RegisterInstance<TArgument>(TArgument instance) {
{ this._container.RegisterInstance(instance);
this._container.RegisterInstance(instance); return this;
return this; }
}
public IApplicationController RegisterService<TService, TImplementation>() public IApplicationController RegisterService<TService, TImplementation>()
where TImplementation : class, TService where TImplementation : class, TService {
{ this._container.Register<TService, TImplementation>();
this._container.Register<TService, TImplementation>(); return this;
return this; }
}
public void Run<TPresenter>() public void Run<TPresenter>()
where TPresenter : class, IPresenter where TPresenter : class, IPresenter {
{ if (!this._container.IsRegistered<TPresenter>()) {
if (!this._container.IsRegistered<TPresenter>()) this._container.Register<TPresenter>();
{ }
this._container.Register<TPresenter>();
}
TPresenter presenter = this._container.Resolve<TPresenter>(); TPresenter presenter = this._container.Resolve<TPresenter>();
presenter.Run(); presenter.Run();
} }
public void Run<TPresenter, TParameter>(TParameter args) public void Run<TPresenter, TParameter>(TParameter args)
where TPresenter : class, IPresenter<TParameter> where TPresenter : class, IPresenter<TParameter> {
{ if (!this._container.IsRegistered<TPresenter>()) {
if (!this._container.IsRegistered<TPresenter>()) this._container.Register<TPresenter>();
{ }
this._container.Register<TPresenter>();
}
TPresenter presenter = this._container.Resolve<TPresenter>(); TPresenter presenter = this._container.Resolve<TPresenter>();
presenter.Run(args); presenter.Run(args);
} }
public TService Create<TService>() public TService Create<TService>()
where TService : class where TService : class {
{ if (!this._container.IsRegistered<TService>()) {
if (!this._container.IsRegistered<TService>()) this._container.Register<TService>();
{ }
this._container.Register<TService>();
}
return this._container.Resolve<TService>(); return this._container.Resolve<TService>();
} }
} }
} }

View File

@@ -3,53 +3,45 @@ using System.IO;
using System.Threading; using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
namespace EveOPreview namespace EveOPreview {
{ // A really very primitive exception handler stuff here
// A really very primitive exception handler stuff here // No IoC, no fancy DI containers - just a plain exception stacktrace dump
// No IoC, no fancy DI containers - just a plain exception stacktrace dump // If this code is called then something was gone really bad
// If this code is called then something was gone really bad // so even the DI infrastructure might be dead already.
// so even the DI infrastructure might be dead already. // So this dumb and non elegant approach is used
// So this dumb and non elegant approach is used sealed class ExceptionHandler {
sealed class ExceptionHandler private const string EXCEPTION_DUMP_FILE_NAME = "EVE-O-Preview.log";
{ private const string EXCEPTION_MESSAGE =
private const string EXCEPTION_DUMP_FILE_NAME = "EVE-O-Preview.log"; "EVE-O-Preview has encountered a problem and needs to close. Additional information has been saved in the crash log file.";
private const string EXCEPTION_MESSAGE = "EVE-O-Preview has encountered a problem and needs to close. Additional information has been saved in the crash log file.";
public void SetupExceptionHandlers() public void SetupExceptionHandlers() {
{ if (System.Diagnostics.Debugger.IsAttached) {
if (System.Diagnostics.Debugger.IsAttached) return;
{ }
return;
}
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += delegate (Object sender, ThreadExceptionEventArgs e) Application.ThreadException += delegate(Object sender, ThreadExceptionEventArgs e) {
{ this.ExceptionEventHandler(e.Exception);
this.ExceptionEventHandler(e.Exception); };
};
AppDomain.CurrentDomain.UnhandledException += delegate (Object sender, UnhandledExceptionEventArgs e) AppDomain.CurrentDomain.UnhandledException += delegate(Object sender, UnhandledExceptionEventArgs e) {
{ this.ExceptionEventHandler(e.ExceptionObject as Exception);
this.ExceptionEventHandler(e.ExceptionObject as Exception); };
}; }
}
private void ExceptionEventHandler(Exception exception) private void ExceptionEventHandler(Exception exception) {
{ try {
try String exceptionMessage = exception.ToString();
{ File.WriteAllText(ExceptionHandler.EXCEPTION_DUMP_FILE_NAME, exceptionMessage);
String exceptionMessage = exception.ToString();
File.WriteAllText(ExceptionHandler.EXCEPTION_DUMP_FILE_NAME, exceptionMessage);
MessageBox.Show(ExceptionHandler.EXCEPTION_MESSAGE, @"EVE-O-Preview", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(ExceptionHandler.EXCEPTION_MESSAGE, @"EVE-O-Preview", MessageBoxButtons.OK,
} MessageBoxIcon.Error);
catch } catch {
{ // We are in unstable state now so even this operation might fail
// We are in unstable state now so even this operation might fail // Still we actually don't care anymore - anyway the application has been cashed
// Still we actually don't care anymore - anyway the application has been cashed }
}
System.Environment.Exit(1); System.Environment.Exit(1);
} }
} }
} }

View File

@@ -1,26 +1,22 @@
namespace EveOPreview namespace EveOPreview {
{ /// <summary>
/// <summary> /// Application controller
/// Application controller /// </summary>
/// </summary> public interface IApplicationController {
public interface IApplicationController IApplicationController RegisterView<TView, TPresenter>()
{ where TPresenter : class, TView
IApplicationController RegisterView<TView, TPresenter>() where TView : IView;
where TPresenter : class, TView
where TView : IView;
IApplicationController RegisterInstance<T>(T instance); IApplicationController RegisterInstance<T>(T instance);
IApplicationController RegisterService<TService, TImplementation>() IApplicationController RegisterService<TService, TImplementation>()
where TImplementation : class, TService; where TImplementation : class, TService;
void Run<TPresenter>() void Run<TPresenter>()
where TPresenter : class, IPresenter; where TPresenter : class, IPresenter;
void Run<TPresenter, TArgument>(TArgument args) void Run<TPresenter, TArgument>(TArgument args)
where TPresenter : class, IPresenter<TArgument>; where TPresenter : class, IPresenter<TArgument>;
TService Create<TService>() TService Create<TService>()
where TService : class; where TService : class; } }
}
}

View File

@@ -3,24 +3,10 @@ using System.Collections.Generic;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
namespace EveOPreview namespace EveOPreview {
{ /// <summary>
/// <summary> /// Generic interface for an Inversion Of Control container
/// Generic interface for an Inversion Of Control container /// </summary>
/// </summary> public interface IIocContainer {
public interface IIocContainer void Register<TService, TImplementation>()
{ where TImplementation : TService; void Register(Type serviceType, Assembly container); void Register<TService>(); void Register<TService>(Expression<Func<TService>> factory); void Register<TService, TArgument>(Expression<Func<TArgument, TService>> factory); void RegisterInstance<TService>(TService instance); TService Resolve<TService>(); IEnumerable<TService> ResolveAll<TService>(); object Resolve(Type serviceType); IEnumerable<object> ResolveAll(Type serviceType); bool IsRegistered<TService>(); } }
void Register<TService, TImplementation>()
where TImplementation : TService;
void Register(Type serviceType, Assembly container);
void Register<TService>();
void Register<TService>(Expression<Func<TService>> factory);
void Register<TService, TArgument>(Expression<Func<TArgument, TService>> factory);
void RegisterInstance<TService>(TService instance);
TService Resolve<TService>();
IEnumerable<TService> ResolveAll<TService>();
object Resolve(Type serviceType);
IEnumerable<object> ResolveAll(Type serviceType);
bool IsRegistered<TService>();
}
}

View File

@@ -1,7 +1,5 @@
namespace EveOPreview namespace EveOPreview {
{ public interface IPresenter {
public interface IPresenter void Run();
{ }
void Run();
}
} }

View File

@@ -1,7 +1,5 @@
namespace EveOPreview namespace EveOPreview {
{ public interface IPresenter<in TArgument> {
public interface IPresenter<in TArgument> void Run(TArgument args);
{ }
void Run(TArgument args);
}
} }

View File

@@ -1,12 +1,10 @@
namespace EveOPreview namespace EveOPreview {
{ /// <summary>
/// <summary> /// Properties and methods that are common for all views
/// Properties and methods that are common for all views /// </summary>
/// </summary> public interface IView {
public interface IView void Show();
{ void Hide();
void Show(); void Close();
void Hide(); }
void Close();
}
} }

View File

@@ -4,96 +4,76 @@ using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
using LightInject; using LightInject;
namespace EveOPreview namespace EveOPreview {
{ // Adapts LighInject to the generic IoC interface
// Adapts LighInject to the generic IoC interface sealed class LightInjectContainer : IIocContainer {
sealed class LightInjectContainer : IIocContainer private readonly ServiceContainer _container;
{
private readonly ServiceContainer _container;
public LightInjectContainer() public LightInjectContainer() {
{ this._container = new ServiceContainer(ContainerOptions.Default);
this._container = new ServiceContainer(ContainerOptions.Default); }
}
public bool IsRegistered<TService>() public bool IsRegistered<TService>() {
{ return this._container.CanGetInstance(typeof(TService), "");
return this._container.CanGetInstance(typeof(TService), ""); }
}
public void Register(Type serviceType, Assembly container) public void Register(Type serviceType, Assembly container) {
{ if (!serviceType.IsInterface) {
if (!serviceType.IsInterface) this._container.Register(serviceType, new PerContainerLifetime());
{ return;
this._container.Register(serviceType, new PerContainerLifetime()); }
return;
}
if (serviceType.IsInterface && serviceType.IsGenericType) if (serviceType.IsInterface && serviceType.IsGenericType) {
{ this._container.RegisterAssembly(
this._container.RegisterAssembly(container, (st, it) => st.IsConstructedGenericType && st.GetGenericTypeDefinition() == serviceType); container, (st, it) => st.IsConstructedGenericType && st.GetGenericTypeDefinition() == serviceType);
} } else {
else foreach (TypeInfo implementationType in container.DefinedTypes) {
{ if (!implementationType.IsClass || implementationType.IsAbstract) {
foreach (TypeInfo implementationType in container.DefinedTypes) continue;
{ }
if (!implementationType.IsClass || implementationType.IsAbstract)
{
continue;
}
if (serviceType.IsAssignableFrom(implementationType)) if (serviceType.IsAssignableFrom(implementationType)) {
{ this._container.Register(serviceType, implementationType, new PerContainerLifetime());
this._container.Register(serviceType, implementationType, new PerContainerLifetime()); }
} }
} }
} }
}
public void Register<TService>() public void Register<TService>() {
{ this.Register(typeof(TService), typeof(TService).Assembly);
this.Register(typeof(TService), typeof(TService).Assembly); }
}
public void Register<TService, TImplementation>() public void Register<TService, TImplementation>()
where TImplementation : TService where TImplementation : TService {
{ this._container.Register<TService, TImplementation>();
this._container.Register<TService, TImplementation>(); }
}
public void Register<TService>(Expression<Func<TService>> factory) public void Register<TService>(Expression<Func<TService>> factory) {
{ this._container.Register(f => factory);
this._container.Register(f => factory); }
}
public void Register<TService, TArgument>(Expression<Func<TArgument, TService>> factory) public void Register<TService, TArgument>(Expression<Func<TArgument, TService>> factory) {
{ this._container.Register(f => factory);
this._container.Register(f => factory); }
}
public void RegisterInstance<TService>(TService instance) public void RegisterInstance<TService>(TService instance) {
{ this._container.RegisterInstance(instance);
this._container.RegisterInstance(instance); }
}
public TService Resolve<TService>() public TService Resolve<TService>() {
{ return this._container.GetInstance<TService>();
return this._container.GetInstance<TService>(); }
}
public IEnumerable<TService> ResolveAll<TService>() public IEnumerable<TService> ResolveAll<TService>() {
{ return this._container.GetAllInstances<TService>();
return this._container.GetAllInstances<TService>(); }
}
public object Resolve(Type serviceType) public object Resolve(Type serviceType) {
{ return this._container.GetInstance(serviceType);
return this._container.GetInstance(serviceType); }
}
public IEnumerable<object> ResolveAll(Type serviceType) public IEnumerable<object> ResolveAll(Type serviceType) {
{ return this._container.GetAllInstances(serviceType);
return this._container.GetAllInstances(serviceType); }
} }
}
} }

View File

@@ -1,22 +1,18 @@
namespace EveOPreview namespace EveOPreview {
{ public abstract class Presenter<TView> : IPresenter
public abstract class Presenter<TView> : IPresenter where TView : IView {
where TView : IView // Properties are used instead of fields so the code remains CLS compliant
{ // 'protected readonly' fields would result in non-CLS compliant code
// Properties are used instead of fields so the code remains CLS compliant protected TView View { get; private set; }
// 'protected readonly' fields would result in non-CLS compliant code protected IApplicationController Controller { get; private set; }
protected TView View { get; private set; }
protected IApplicationController Controller { get; private set; }
protected Presenter(IApplicationController controller, TView view) protected Presenter(IApplicationController controller, TView view) {
{ this.Controller = controller;
this.Controller = controller; this.View = view;
this.View = view; }
}
public void Run() public void Run() {
{ this.View.Show();
this.View.Show(); }
} }
}
} }

View File

@@ -1,19 +1,16 @@
namespace EveOPreview namespace EveOPreview {
{ public abstract class Presenter<TView, TArgument> : IPresenter<TArgument>
public abstract class Presenter<TView, TArgument> : IPresenter<TArgument> where TView : IView {
where TView : IView // Properties are used instead of fields so the code remains CLS compliant
{ // 'protected readonly' fields would result in non-CLS compliant code
// Properties are used instead of fields so the code remains CLS compliant protected TView View { get; private set; }
// 'protected readonly' fields would result in non-CLS compliant code protected IApplicationController Controller { get; private set; }
protected TView View { get; private set; }
protected IApplicationController Controller { get; private set; }
protected Presenter(IApplicationController controller, TView view) protected Presenter(IApplicationController controller, TView view) {
{ this.Controller = controller;
this.Controller = controller; this.View = view;
this.View = view; }
}
public abstract void Run(TArgument args); public abstract void Run(TArgument args);
} }
} }

View File

@@ -1,13 +1,10 @@
namespace EveOPreview.Configuration.Implementation namespace EveOPreview.Configuration.Implementation {
{ class AppConfig : IAppConfig {
class AppConfig : IAppConfig public AppConfig() {
{ // Default values
public AppConfig() this.ConfigFileName = null;
{ }
// Default values
this.ConfigFileName = null;
}
public string ConfigFileName { get; set; } public string ConfigFileName { get; set; }
} }
} }

View File

@@ -1,63 +1,52 @@
using System.IO; using System.IO;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace EveOPreview.Configuration.Implementation namespace EveOPreview.Configuration.Implementation {
{ class ConfigurationStorage : IConfigurationStorage {
class ConfigurationStorage : IConfigurationStorage private const string CONFIGURATION_FILE_NAME = "EVE-O-Preview.json";
{
private const string CONFIGURATION_FILE_NAME = "EVE-O-Preview.json";
private readonly IAppConfig _appConfig; private readonly IAppConfig _appConfig;
private readonly IThumbnailConfiguration _thumbnailConfiguration; private readonly IThumbnailConfiguration _thumbnailConfiguration;
public ConfigurationStorage(IAppConfig appConfig, IThumbnailConfiguration thumbnailConfiguration) public ConfigurationStorage(IAppConfig appConfig, IThumbnailConfiguration thumbnailConfiguration) {
{ this._appConfig = appConfig;
this._appConfig = appConfig; this._thumbnailConfiguration = thumbnailConfiguration;
this._thumbnailConfiguration = thumbnailConfiguration; }
}
public void Load() public void Load() {
{ string filename = this.GetConfigFileName();
string filename = this.GetConfigFileName();
if (!File.Exists(filename)) if (!File.Exists(filename)) {
{ return;
return; }
}
string rawData = File.ReadAllText(filename); string rawData = File.ReadAllText(filename);
JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings() JsonSerializerSettings jsonSerializerSettings =
{ new JsonSerializerSettings() { ObjectCreationHandling = ObjectCreationHandling.Replace };
ObjectCreationHandling = ObjectCreationHandling.Replace
};
// StageHotkeyArraysToAvoidDuplicates(rawData); // StageHotkeyArraysToAvoidDuplicates(rawData);
JsonConvert.PopulateObject(rawData, this._thumbnailConfiguration, jsonSerializerSettings); JsonConvert.PopulateObject(rawData, this._thumbnailConfiguration, jsonSerializerSettings);
// Validate data after loading it // Validate data after loading it
this._thumbnailConfiguration.ApplyRestrictions(); this._thumbnailConfiguration.ApplyRestrictions();
} }
public void Save() public void Save() {
{ string rawData = JsonConvert.SerializeObject(this._thumbnailConfiguration, Formatting.Indented);
string rawData = JsonConvert.SerializeObject(this._thumbnailConfiguration, Formatting.Indented); string filename = this.GetConfigFileName();
string filename = this.GetConfigFileName();
try try {
{ File.WriteAllText(filename, rawData);
File.WriteAllText(filename, rawData); } catch (IOException) {
} // Ignore error if for some reason the updated config cannot be written down
catch (IOException) }
{ }
// Ignore error if for some reason the updated config cannot be written down
}
}
private string GetConfigFileName() private string GetConfigFileName() {
{ return string.IsNullOrEmpty(this._appConfig.ConfigFileName) ? ConfigurationStorage.CONFIGURATION_FILE_NAME
return string.IsNullOrEmpty(this._appConfig.ConfigFileName) ? ConfigurationStorage.CONFIGURATION_FILE_NAME : this._appConfig.ConfigFileName; : this._appConfig.ConfigFileName;
} }
} }
} }

View File

@@ -5,438 +5,531 @@ using System.Linq;
using System.Windows.Forms; using System.Windows.Forms;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace EveOPreview.Configuration.Implementation namespace EveOPreview.Configuration.Implementation {
{ sealed class ThumbnailConfiguration : IThumbnailConfiguration {
sealed class ThumbnailConfiguration : IThumbnailConfiguration #region Private fields
{ private bool _enablePerClientThumbnailLayouts;
#region Private fields private bool _enableClientLayoutTracking;
private bool _enablePerClientThumbnailLayouts; #endregion
private bool _enableClientLayoutTracking;
#endregion
public ThumbnailConfiguration() public ThumbnailConfiguration() {
{ this.ConfigVersion = 1;
this.ConfigVersion = 1;
this.CycleGroup1ForwardHotkeys = new List<string> { "F14", "Control+F14" }; this.CycleGroup1ForwardHotkeys = new List<string> { "F14", "Control+F14" };
this.CycleGroup1BackwardHotkeys = new List<string> { "F13", "Control+F13" }; this.CycleGroup1BackwardHotkeys = new List<string> { "F13", "Control+F13" };
this.CycleGroup1ClientsOrder = new Dictionary<string, int> this.CycleGroup1ClientsOrder = new Dictionary<string, int> {
{ { "EVE - Example DPS Toon 1", 1 }, { "EVE - Example DPS Toon 2", 2 }, { "EVE - Example DPS Toon 3", 3 }
{ "EVE - Example DPS Toon 1", 1 }, };
{ "EVE - Example DPS Toon 2", 2 },
{ "EVE - Example DPS Toon 3", 3 }
};
this.CycleGroup2ForwardHotkeys = new List<string> { "F16", "Control+F16" }; this.CycleGroup2ForwardHotkeys = new List<string> { "F16", "Control+F16" };
this.CycleGroup2BackwardHotkeys = new List<string> { "F15", "Control+F15" }; this.CycleGroup2BackwardHotkeys = new List<string> { "F15", "Control+F15" };
this.CycleGroup2ClientsOrder = new Dictionary<string, int> this.CycleGroup2ClientsOrder = new Dictionary<string, int> { { "EVE - Example Logi Toon 1", 1 },
{ { "EVE - Example Scout Toon 2", 2 },
{ "EVE - Example Logi Toon 1", 1 }, { "EVE - Example Tackle Toon 3", 3 } };
{ "EVE - Example Scout Toon 2", 2 },
{ "EVE - Example Tackle Toon 3", 3 }
};
this.CycleGroup3ForwardHotkeys = new List<string> { "" }; this.CycleGroup3ForwardHotkeys = new List<string> { "" };
this.CycleGroup3BackwardHotkeys = new List<string> { "" }; this.CycleGroup3BackwardHotkeys = new List<string> { "" };
this.CycleGroup3ClientsOrder = new Dictionary<string, int> this.CycleGroup3ClientsOrder = new Dictionary<string, int> {
{ { "EVE - cycle group 3", 1 },
{ "EVE - cycle group 3", 1 }, };
}; this.CycleGroup4ForwardHotkeys = new List<string> { "" };
this.CycleGroup4ForwardHotkeys = new List<string> { "" }; this.CycleGroup4BackwardHotkeys = new List<string> { "" };
this.CycleGroup4BackwardHotkeys = new List<string> { "" }; this.CycleGroup4ClientsOrder = new Dictionary<string, int> {
this.CycleGroup4ClientsOrder = new Dictionary<string, int> { "EVE - cycle group 4", 1 },
{ };
{ "EVE - cycle group 4", 1 }, this.CycleGroup5ForwardHotkeys = new List<string> { "" };
}; this.CycleGroup5BackwardHotkeys = new List<string> { "" };
this.CycleGroup5ForwardHotkeys = new List<string> { "" }; this.CycleGroup5ClientsOrder = new Dictionary<string, int> {
this.CycleGroup5BackwardHotkeys = new List<string> { "" }; { "EVE - cycle group 5", 1 },
this.CycleGroup5ClientsOrder = new Dictionary<string, int> };
{
{ "EVE - cycle group 5", 1 },
};
this.PerClientActiveClientHighlightColor = new Dictionary<string, Color> this.PerClientActiveClientHighlightColor =
{ new Dictionary<string, Color> { { "EVE - Example Toon 1", Color.Red },
{"EVE - Example Toon 1", Color.Red}, { "EVE - Example Toon 2", Color.Green } };
{"EVE - Example Toon 2", Color.Green}
};
this.PerClientThumbnailSize = new Dictionary<string, Size> this.PerClientThumbnailSize =
{ new Dictionary<string, Size> { { "EVE - Example Toon 1", new Size(200, 200) },
{"EVE - Example Toon 1", new Size(200, 200)}, { "EVE - Example Toon 2", new Size(200, 200) } };
{"EVE - Example Toon 2", new Size(200, 200)}
};
this.PerClientZoomAnchor = new Dictionary<string, ZoomAnchor> this.PerClientThumbnailRegion = new Dictionary<string, Rectangle>();
{
{"EVE - Example Toon 1", ZoomAnchor.N },
{"EVE - Example Toon 2", ZoomAnchor.S}
};
this.PerClientLayout = new Dictionary<string, Dictionary<string, Point>>(); this.PerClientZoomAnchor = new Dictionary<string, ZoomAnchor> { { "EVE - Example Toon 1", ZoomAnchor.N },
this.FlatLayout = new Dictionary<string, Point>(); { "EVE - Example Toon 2", ZoomAnchor.S } };
this.ClientLayout = new Dictionary<string, ClientLayout>();
this.ClientHotkey = new Dictionary<string, string>();
this.DisableThumbnail = new Dictionary<string, bool>();
this.PriorityClients = new List<string>();
this.ExecutablesToPreview = new List<string> { "exefile" }; this.PerClientLayout = new Dictionary<string, Dictionary<string, Point>>();
this.FlatLayout = new Dictionary<string, Point>();
this.ClientLayout = new Dictionary<string, ClientLayout>();
this.ClientHotkey = new Dictionary<string, string>();
this.DisableThumbnail = new Dictionary<string, bool>();
this.PriorityClients = new List<string>();
this.MinimizeToTray = false; this.ExecutablesToPreview = new List<string> { "exefile" };
this.ThumbnailRefreshPeriod = 500;
this.ThumbnailResizeTimeoutPeriod = 500; this.MinimizeToTray = false;
this.ThumbnailRefreshPeriod = 500;
this.ThumbnailResizeTimeoutPeriod = 500;
#if LINUX #if LINUX
this.EnableWineCompatibilityMode = true; this.EnableWineCompatibilityMode = true;
#else #else
this.EnableWineCompatibilityMode = false; this.EnableWineCompatibilityMode = false;
#endif #endif
this.ThumbnailOpacity = 0.5; this.ThumbnailOpacity = 0.5;
this.EnableClientLayoutTracking = false; this.EnableClientLayoutTracking = false;
this.HideActiveClientThumbnail = false; this.HideActiveClientThumbnail = false;
this.HideLoginClientThumbnail = false; this.HideLoginClientThumbnail = false;
this.MinimizeInactiveClients = false; this.MinimizeInactiveClients = false;
this.WindowsAnimationStyle = AnimationStyle.NoAnimation; this.WindowsAnimationStyle = AnimationStyle.NoAnimation;
this.ShowThumbnailsAlwaysOnTop = true; this.ShowThumbnailsAlwaysOnTop = true;
this.EnablePerClientThumbnailLayouts = false; this.EnablePerClientThumbnailLayouts = false;
this.HideThumbnailsOnLostFocus = false; this.HideThumbnailsOnLostFocus = false;
this.HideThumbnailsDelay = 2; // 2 thumbnails refresh cycles (1.0 sec) this.HideThumbnailsDelay = 2; // 2 thumbnails refresh cycles (1.0 sec)
this.ThumbnailSize = new Size(384, 216); this.ThumbnailSize = new Size(384, 216);
this.ThumbnailMinimumSize = new Size(192, 108); this.ThumbnailMinimumSize = new Size(192, 108);
this.ThumbnailMaximumSize = new Size(960, 540); this.ThumbnailMaximumSize = new Size(960, 540);
this.EnableThumbnailSnap = true; this.EnableThumbnailSnap = true;
this.ThumbnailSnapRange = 20;
this.ThumbnailZoomEnabled = false; this.ThumbnailZoomEnabled = false;
this.ThumbnailZoomFactor = 2; this.ThumbnailZoomFactor = 2;
this.ThumbnailZoomAnchor = ZoomAnchor.NW; this.ThumbnailZoomAnchor = ZoomAnchor.NW;
this.OverlayLabelAnchor = ZoomAnchor.NW; this.OverlayLabelAnchor = ZoomAnchor.NW;
this.ShowThumbnailOverlays = true; this.ShowThumbnailOverlays = true;
this.ShowThumbnailFrames = false; this.ShowThumbnailFrames = false;
this.LockThumbnailLocation = false; this.LockThumbnailLocation = false;
this.ThumbnailSnapToGrid = true; this.ThumbnailSnapToGrid = true;
this.ThumbnailSnapToGridSizeX = 100; this.ThumbnailSnapToGridSizeX = 100;
this.ThumbnailSnapToGridSizeY = 50; this.ThumbnailSnapToGridSizeY = 50;
this.EnableActiveClientHighlight = false; this.EnableActiveClientHighlight = false;
this.ActiveClientHighlightColor = Color.GreenYellow; this.ActiveClientHighlightColor = Color.GreenYellow;
this.ActiveClientHighlightThickness = 3; this.ActiveClientHighlightThickness = 3;
this.OverlayLabelColor = Color.Orange; this.OverlayLabelColor = Color.Orange;
this.OverlayLabelSize = 10; this.OverlayLabelSize = 10;
this.IconName = ""; this.EnableThumbnailRegionSnipping = false;
this.DefaultThumbnailRegion = new Rectangle(0, 0, 384, 216);
this.LoginThumbnailLocation = new Point(5, 5); this.CurrentProfile = "Default";
} this.AvailableProfiles = new List<string> { "Default" };
this.IconName = "";
[JsonProperty("ConfigVersion")] this.LoginThumbnailLocation = new Point(5, 5);
public int ConfigVersion { get; set; } this.ToggleTrackingHotkey = "Alt+F16";
this.ToggleSingleProcessHotkey = "Control+F16";
this.ToggleAllThumbnailsHotkey = "Alt+F12";
this.ThumbnailsManuallyHidden = false;
}
[JsonProperty("CycleGroup1ForwardHotkeys")] [JsonProperty("ConfigVersion")]
public List<string> CycleGroup1ForwardHotkeys { get; set; } public int ConfigVersion { get; set; }
[JsonProperty("CycleGroup1BackwardHotkeys")] [JsonProperty("CycleGroup1ForwardHotkeys")]
public List<string> CycleGroup1BackwardHotkeys { get; set; } public List<string> CycleGroup1ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup1ClientsOrder")] [JsonProperty("CycleGroup1BackwardHotkeys")]
public Dictionary<string, int> CycleGroup1ClientsOrder { get; set; } public List<string> CycleGroup1BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup2ForwardHotkeys")] [JsonProperty("CycleGroup1ClientsOrder")]
public List<string> CycleGroup2ForwardHotkeys { get; set; } public Dictionary<string, int> CycleGroup1ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup2BackwardHotkeys")] [JsonProperty("CycleGroup2ForwardHotkeys")]
public List<string> CycleGroup2BackwardHotkeys { get; set; } public List<string> CycleGroup2ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup2ClientsOrder")] [JsonProperty("CycleGroup2BackwardHotkeys")]
public Dictionary<string, int> CycleGroup2ClientsOrder { get; set; } public List<string> CycleGroup2BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup3ForwardHotkeys")] [JsonProperty("CycleGroup2ClientsOrder")]
public List<string> CycleGroup3ForwardHotkeys { get; set; } public Dictionary<string, int> CycleGroup2ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup3BackwardHotkeys")] [JsonProperty("CycleGroup3ForwardHotkeys")]
public List<string> CycleGroup3BackwardHotkeys { get; set; } public List<string> CycleGroup3ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup3ClientsOrder")] [JsonProperty("CycleGroup3BackwardHotkeys")]
public Dictionary<string, int> CycleGroup3ClientsOrder { get; set; } public List<string> CycleGroup3BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup4ForwardHotkeys")] [JsonProperty("CycleGroup3ClientsOrder")]
public List<string> CycleGroup4ForwardHotkeys { get; set; } public Dictionary<string, int> CycleGroup3ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup4BackwardHotkeys")] [JsonProperty("CycleGroup4ForwardHotkeys")]
public List<string> CycleGroup4BackwardHotkeys { get; set; } public List<string> CycleGroup4ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup4ClientsOrder")] [JsonProperty("CycleGroup4BackwardHotkeys")]
public Dictionary<string, int> CycleGroup4ClientsOrder { get; set; } public List<string> CycleGroup4BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup5ForwardHotkeys")] [JsonProperty("CycleGroup4ClientsOrder")]
public List<string> CycleGroup5ForwardHotkeys { get; set; } public Dictionary<string, int> CycleGroup4ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup5BackwardHotkeys")] [JsonProperty("CycleGroup5ForwardHotkeys")]
public List<string> CycleGroup5BackwardHotkeys { get; set; } public List<string> CycleGroup5ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup5ClientsOrder")] [JsonProperty("CycleGroup5BackwardHotkeys")]
public Dictionary<string, int> CycleGroup5ClientsOrder { get; set; } public List<string> CycleGroup5BackwardHotkeys {
get; set;
}
[JsonProperty("PerClientActiveClientHighlightColor")] [JsonProperty("CycleGroup5ClientsOrder")]
public Dictionary<string, Color> PerClientActiveClientHighlightColor { get; set; } public Dictionary<string, int> CycleGroup5ClientsOrder {
get; set;
}
[JsonProperty("PerClientThumbnailSize")] [JsonProperty("PerClientActiveClientHighlightColor")]
public Dictionary<string, Size> PerClientThumbnailSize { get; set; } public Dictionary<string, Color> PerClientActiveClientHighlightColor {
get; set;
}
[JsonProperty("PerClientZoomAnchor")] [JsonProperty("PerClientThumbnailSize")]
public Dictionary<string, ZoomAnchor> PerClientZoomAnchor{ get; set; } public Dictionary<string, Size> PerClientThumbnailSize {
public bool MinimizeToTray { get; set; } get; set;
public int ThumbnailRefreshPeriod { get; set; } }
public int ThumbnailResizeTimeoutPeriod { get; set; }
[JsonProperty("WineCompatibilityMode")] [JsonProperty("PerClientThumbnailRegion")]
public bool EnableWineCompatibilityMode { get; set; } public Dictionary<string, Rectangle> PerClientThumbnailRegion {
get; set;
}
[JsonProperty("ThumbnailsOpacity")] [JsonProperty("PerClientZoomAnchor")]
public double ThumbnailOpacity { get; set; } public Dictionary<string, ZoomAnchor> PerClientZoomAnchor {
get; set;
}
public bool MinimizeToTray { get; set; }
public int ThumbnailRefreshPeriod { get; set; }
public int ThumbnailResizeTimeoutPeriod { get; set; }
public bool EnableClientLayoutTracking [JsonProperty("WineCompatibilityMode")]
{ public bool EnableWineCompatibilityMode {
get => this._enableClientLayoutTracking; get; set;
set }
{
if (!value)
{
this.ClientLayout.Clear();
}
this._enableClientLayoutTracking = value; [JsonProperty("ThumbnailsOpacity")]
} public double ThumbnailOpacity {
} get; set;
}
public bool HideActiveClientThumbnail { get; set; } public bool EnableClientLayoutTracking {
public bool HideLoginClientThumbnail { get; set; } get => this._enableClientLayoutTracking;
public bool MinimizeInactiveClients { get; set; } set {
public AnimationStyle WindowsAnimationStyle { get; set; } if (!value) {
public bool ShowThumbnailsAlwaysOnTop { get; set; } this.ClientLayout.Clear();
}
public bool EnablePerClientThumbnailLayouts this._enableClientLayoutTracking = value;
{ }
get => this._enablePerClientThumbnailLayouts; }
set
{
if (!value)
{
this.PerClientLayout.Clear();
}
this._enablePerClientThumbnailLayouts = value; public bool HideActiveClientThumbnail { get; set; }
} public bool HideLoginClientThumbnail { get; set; }
} public bool MinimizeInactiveClients { get; set; }
public AnimationStyle WindowsAnimationStyle { get; set; }
public bool ShowThumbnailsAlwaysOnTop { get; set; }
public bool HideThumbnailsOnLostFocus { get; set; } public bool EnablePerClientThumbnailLayouts {
public int HideThumbnailsDelay { get; set; } get => this._enablePerClientThumbnailLayouts;
set {
if (!value) {
this.PerClientLayout.Clear();
}
public Size ThumbnailSize { get; set; } this._enablePerClientThumbnailLayouts = value;
public Size ThumbnailMaximumSize { get; set; } }
public Size ThumbnailMinimumSize { get; set; } }
public bool EnableThumbnailSnap { get; set; } public bool HideThumbnailsOnLostFocus { get; set; }
public int HideThumbnailsDelay { get; set; }
[JsonProperty("EnableThumbnailZoom")] public Size ThumbnailSize { get; set; }
public bool ThumbnailZoomEnabled { get; set; } public Size ThumbnailMaximumSize { get; set; }
public int ThumbnailZoomFactor { get; set; } public Size ThumbnailMinimumSize { get; set; }
public ZoomAnchor ThumbnailZoomAnchor { get; set; }
public ZoomAnchor OverlayLabelAnchor { get; set; }
public bool ShowThumbnailOverlays { get; set; } public bool EnableThumbnailSnap { get; set; }
public bool ShowThumbnailFrames { get; set; } public int ThumbnailSnapRange { get; set; }
public bool LockThumbnailLocation { get; set; }
public bool ThumbnailSnapToGrid { get; set; }
public int ThumbnailSnapToGridSizeX { get; set; }
public int ThumbnailSnapToGridSizeY { get; set; }
public bool EnableActiveClientHighlight { get; set; } [JsonProperty("EnableThumbnailZoom")]
public bool ThumbnailZoomEnabled {
get; set;
}
public int ThumbnailZoomFactor { get; set; }
public ZoomAnchor ThumbnailZoomAnchor { get; set; }
public ZoomAnchor OverlayLabelAnchor { get; set; }
public Color ActiveClientHighlightColor { get; set; } public bool ShowThumbnailOverlays { get; set; }
public Color OverlayLabelColor { get; set; } public bool ShowThumbnailFrames { get; set; }
public int OverlayLabelSize { get; set; } public bool LockThumbnailLocation { get; set; }
[JsonProperty("IconName")] public bool ThumbnailSnapToGrid { get; set; }
public string IconName { get; set; } public int ThumbnailSnapToGridSizeX { get; set; }
public int ThumbnailSnapToGridSizeY { get; set; }
public int ActiveClientHighlightThickness { get; set; } public bool EnableActiveClientHighlight { get; set; }
[JsonProperty("LoginThumbnailLocation")] public Color ActiveClientHighlightColor { get; set; }
public Point LoginThumbnailLocation { get; set; } public Color OverlayLabelColor { get; set; }
public int OverlayLabelSize { get; set; }
[JsonProperty("ToggleTrackingHotkey")] public bool EnableThumbnailRegionSnipping { get; set; }
public string ToggleTrackingHotkey { get; set; } public Rectangle DefaultThumbnailRegion { get; set; }
[JsonProperty] public string CurrentProfile { get; set; }
private Dictionary<string, Dictionary<string, Point>> PerClientLayout { get; set; } public List<string> AvailableProfiles { get; set; }
[JsonProperty] [JsonProperty("IconName")]
private Dictionary<string, Point> FlatLayout { get; set; } public string IconName {
[JsonProperty] get; set;
private Dictionary<string, ClientLayout> ClientLayout { get; set; } }
[JsonProperty]
private Dictionary<string, string> ClientHotkey { get; set; }
[JsonProperty]
private Dictionary<string, bool> DisableThumbnail { get; set; }
[JsonProperty]
private List<string> PriorityClients { get; set; }
[JsonProperty]
public List<string> ExecutablesToPreview { get; set; }
public Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation) public int ActiveClientHighlightThickness { get; set; }
{
Point location;
// What this code does: [JsonProperty("LoginThumbnailLocation")]
// If Per-Client layouts are enabled public Point LoginThumbnailLocation {
// and client name is known get; set;
// and there is a separate thumbnails layout for this client }
// and this layout contains an entry for the current client
// then return that entry
// otherwise try to get client layout from the flat all-clients layout
// If there is no layout too then use the default one
if (this.EnablePerClientThumbnailLayouts && !string.IsNullOrEmpty(activeClient))
{
Dictionary<string, Point> layoutSource;
if (this.PerClientLayout.TryGetValue(activeClient, out layoutSource) && layoutSource.TryGetValue(currentClient, out location))
{
return location;
}
}
return this.FlatLayout.TryGetValue(currentClient, out location) ? location : defaultLocation; [JsonProperty("ToggleTrackingHotkey")]
} public string ToggleTrackingHotkey {
get; set;
}
public Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize) [JsonProperty("ToggleSingleProcessHotkey")]
{ public string ToggleSingleProcessHotkey {
Size sizeOfThumbnail; get; set;
return this.PerClientThumbnailSize.TryGetValue(currentClient, out sizeOfThumbnail) ? sizeOfThumbnail : defaultSize; }
}
public ZoomAnchor GetZoomAnchor(string currentClient, ZoomAnchor defaultZoomAnchor)
{
ZoomAnchor zoomAnchor;
return this.PerClientZoomAnchor.TryGetValue(currentClient, out zoomAnchor) ? zoomAnchor : defaultZoomAnchor;
}
public void SetThumbnailLocation(string currentClient, string activeClient, Point location) [JsonProperty("ToggleAllThumbnailsHotkey")]
{ public string ToggleAllThumbnailsHotkey {
Dictionary<string, Point> layoutSource; get; set;
}
if (this.EnablePerClientThumbnailLayouts) [JsonProperty("ThumbnailsManuallyHidden")]
{ public bool ThumbnailsManuallyHidden {
if (string.IsNullOrEmpty(activeClient)) get; set;
{ }
return;
}
if (!this.PerClientLayout.TryGetValue(activeClient, out layoutSource)) [JsonProperty]
{ private Dictionary<string, Dictionary<string, Point>> PerClientLayout {
layoutSource = new Dictionary<string, Point>(); get; set;
this.PerClientLayout[activeClient] = layoutSource; }
} [JsonProperty]
} private Dictionary<string, Point> FlatLayout {
else get; set;
{ }
layoutSource = this.FlatLayout; [JsonProperty]
} private Dictionary<string, ClientLayout> ClientLayout {
get; set;
}
[JsonProperty]
private Dictionary<string, string> ClientHotkey {
get; set;
}
[JsonProperty]
private Dictionary<string, bool> DisableThumbnail {
get; set;
}
[JsonProperty]
private List<string> PriorityClients {
get; set;
}
[JsonProperty]
public List<string> ExecutablesToPreview {
get; set;
}
layoutSource[currentClient] = location; public Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation) {
} Point location;
public ClientLayout GetClientLayout(string currentClient) // What this code does:
{ // If Per-Client layouts are enabled
ClientLayout layout; // and client name is known
this.ClientLayout.TryGetValue(currentClient, out layout); // and there is a separate thumbnails layout for this client
// and this layout contains an entry for the current client
// then return that entry
// otherwise try to get client layout from the flat all-clients layout
// If there is no layout too then use the default one
if (this.EnablePerClientThumbnailLayouts && !string.IsNullOrEmpty(activeClient)) {
Dictionary<string, Point> layoutSource;
if (this.PerClientLayout.TryGetValue(activeClient, out layoutSource) &&
layoutSource.TryGetValue(currentClient, out location)) {
return location;
}
}
return layout; return this.FlatLayout.TryGetValue(currentClient, out location) ? location : defaultLocation;
} }
public void SetClientLayout(string currentClient, ClientLayout layout) public Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize) {
{ Size sizeOfThumbnail;
this.ClientLayout[currentClient] = layout; return this.PerClientThumbnailSize.TryGetValue(currentClient, out sizeOfThumbnail) ? sizeOfThumbnail
} : defaultSize;
}
public Keys GetClientHotkey(string currentClient) public Rectangle GetThumbnailRegion(string currentClient, Rectangle defaultRegion) {
{ Rectangle region;
string hotkey; return this.PerClientThumbnailRegion.TryGetValue(currentClient, out region) ? region : defaultRegion;
if (this.ClientHotkey.TryGetValue(currentClient, out hotkey)) }
{
// Protect from incorrect values
object rawValue = (new KeysConverter()).ConvertFromInvariantString(hotkey);
return rawValue != null ? (Keys)rawValue : Keys.None;
}
return Keys.None; public ZoomAnchor GetZoomAnchor(string currentClient, ZoomAnchor defaultZoomAnchor) {
} ZoomAnchor zoomAnchor;
return this.PerClientZoomAnchor.TryGetValue(currentClient, out zoomAnchor) ? zoomAnchor : defaultZoomAnchor;
}
public void SetClientHotkey(string currentClient, Keys hotkey) public void SetThumbnailLocation(string currentClient, string activeClient, Point location) {
{ Dictionary<string, Point> layoutSource;
this.ClientHotkey[currentClient] = (new KeysConverter()).ConvertToInvariantString(hotkey);
}
public Keys StringToKey(string hotkey) if (this.EnablePerClientThumbnailLayouts) {
{ if (string.IsNullOrEmpty(activeClient)) {
object rawValue = (new KeysConverter()).ConvertFromInvariantString(hotkey); return;
return rawValue != null ? (Keys)rawValue : Keys.None; }
}
public bool IsPriorityClient(string currentClient) if (!this.PerClientLayout.TryGetValue(activeClient, out layoutSource)) {
{ layoutSource = new Dictionary<string, Point>();
return this.PriorityClients.Contains(currentClient); this.PerClientLayout[activeClient] = layoutSource;
} }
public bool IsExecutableToPreview(string processName) } else {
{ layoutSource = this.FlatLayout;
return this.ExecutablesToPreview.Any(s => s.Equals(processName, StringComparison.OrdinalIgnoreCase)); }
}
public bool IsThumbnailDisabled(string currentClient) layoutSource[currentClient] = location;
{ }
return this.DisableThumbnail.TryGetValue(currentClient, out bool isDisabled) && isDisabled;
}
public void ToggleThumbnail(string currentClient, bool isDisabled) public void SetThumbnailRegion(string currentClient, Rectangle region) {
{ this.PerClientThumbnailRegion[currentClient] = region;
this.DisableThumbnail[currentClient] = isDisabled; }
}
/// <summary> public void SaveProfile(string profileName) {
/// Applies restrictions to different parameters of the config if (!this.AvailableProfiles.Contains(profileName)) {
/// </summary> this.AvailableProfiles.Add(profileName);
public void ApplyRestrictions() }
{ this.CurrentProfile = profileName;
}
public void LoadProfile(string profileName) {
if (this.AvailableProfiles.Contains(profileName)) {
this.CurrentProfile = profileName;
}
}
public void DeleteProfile(string profileName) {
if (profileName != "Default" && this.AvailableProfiles.Contains(profileName)) {
this.AvailableProfiles.Remove(profileName);
if (this.CurrentProfile == profileName) {
this.CurrentProfile = "Default";
}
}
}
public ClientLayout GetClientLayout(string currentClient) {
ClientLayout layout;
this.ClientLayout.TryGetValue(currentClient, out layout);
return layout;
}
public void SetClientLayout(string currentClient, ClientLayout layout) {
this.ClientLayout[currentClient] = layout;
}
public Keys GetClientHotkey(string currentClient) {
string hotkey;
if (this.ClientHotkey.TryGetValue(currentClient, out hotkey)) {
// Protect from incorrect values
object rawValue = (new KeysConverter()).ConvertFromInvariantString(hotkey);
return rawValue != null ? (Keys)rawValue : Keys.None;
}
return Keys.None;
}
public void SetClientHotkey(string currentClient, Keys hotkey) {
this.ClientHotkey[currentClient] = (new KeysConverter()).ConvertToInvariantString(hotkey);
}
public Keys StringToKey(string hotkey) {
object rawValue = (new KeysConverter()).ConvertFromInvariantString(hotkey);
return rawValue != null ? (Keys)rawValue : Keys.None;
}
public bool IsPriorityClient(string currentClient) {
return this.PriorityClients.Contains(currentClient);
}
public bool IsExecutableToPreview(string processName) {
return this.ExecutablesToPreview.Any(s => s.Equals(processName, StringComparison.OrdinalIgnoreCase));
}
public bool IsThumbnailDisabled(string currentClient) {
return this.DisableThumbnail.TryGetValue(currentClient, out bool isDisabled) && isDisabled;
}
public void ToggleThumbnail(string currentClient, bool isDisabled) {
this.DisableThumbnail[currentClient] = isDisabled;
}
/// <summary>
/// Applies restrictions to different parameters of the config
/// </summary>
public void ApplyRestrictions() {
#if LINUX #if LINUX
this.ThumbnailRefreshPeriod = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailRefreshPeriod, 10, 1000); this.ThumbnailRefreshPeriod =
ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailRefreshPeriod, 10, 1000);
#else #else
this.ThumbnailRefreshPeriod = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailRefreshPeriod, 300, 1000); this.ThumbnailRefreshPeriod =
ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailRefreshPeriod, 300, 1000);
#endif #endif
this.ThumbnailResizeTimeoutPeriod = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailResizeTimeoutPeriod, 200, 5000); this.ThumbnailResizeTimeoutPeriod =
this.ThumbnailSize = new Size(ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailSize.Width, this.ThumbnailMinimumSize.Width, this.ThumbnailMaximumSize.Width), ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailResizeTimeoutPeriod, 200, 5000);
ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailSize.Height, this.ThumbnailMinimumSize.Height, this.ThumbnailMaximumSize.Height)); this.ThumbnailSize = new Size(
this.ThumbnailOpacity = ThumbnailConfiguration.ApplyRestrictions((int)(this.ThumbnailOpacity * 100.00), 20, 100) / 100.00; ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailSize.Width, this.ThumbnailMinimumSize.Width,
this.ThumbnailZoomFactor = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailZoomFactor, 2, 10); this.ThumbnailMaximumSize.Width),
this.ActiveClientHighlightThickness = ThumbnailConfiguration.ApplyRestrictions(this.ActiveClientHighlightThickness, 1, 6); ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailSize.Height, this.ThumbnailMinimumSize.Height,
} this.ThumbnailMaximumSize.Height));
this.ThumbnailOpacity =
ThumbnailConfiguration.ApplyRestrictions((int)(this.ThumbnailOpacity * 100.00), 20, 100) / 100.00;
this.ThumbnailZoomFactor = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailZoomFactor, 2, 10);
this.ActiveClientHighlightThickness =
ThumbnailConfiguration.ApplyRestrictions(this.ActiveClientHighlightThickness, 1, 6);
}
private static int ApplyRestrictions(int value, int minimum, int maximum) private static int ApplyRestrictions(int value, int minimum, int maximum) {
{ if (value <= minimum) {
if (value <= minimum) return minimum;
{ }
return minimum;
}
if (value >= maximum) if (value >= maximum) {
{ return maximum;
return maximum; }
}
return value; return value;
} }
} }
} }

View File

@@ -1,8 +1,3 @@
namespace EveOPreview.Configuration namespace EveOPreview.Configuration {
{ public enum AnimationStyle { OriginalAnimation, NoAnimation }
public enum AnimationStyle
{
OriginalAnimation,
NoAnimation
}
} }

View File

@@ -1,28 +1,23 @@
namespace EveOPreview.Configuration namespace EveOPreview.Configuration {
{ public class ClientLayout {
public class ClientLayout public ClientLayout() {}
{
public ClientLayout()
{
}
public ClientLayout(int x, int y, int width, int height, bool maximized) public ClientLayout(int x, int y, int width, int height, bool maximized) {
{ this.X = x;
this.X = x; this.Y = y;
this.Y = y; this.Width = width;
this.Width = width; this.Height = height;
this.Height = height; this.IsMaximized = maximized;
this.IsMaximized = maximized; }
}
public int X { get; set; } public int X { get; set; }
public int Y { get; set; } public int Y { get; set; }
public int Width { get; set; } public int Width { get; set; }
public int Height { get; set; } public int Height { get; set; }
public bool IsMaximized { get; set; } public bool IsMaximized { get; set; }
} }
} }

View File

@@ -1,10 +1,8 @@
namespace EveOPreview.Configuration namespace EveOPreview.Configuration {
{ /// <summary>
/// <summary> /// Application configuration
/// Application configuration /// </summary>
/// </summary> public interface IAppConfig {
public interface IAppConfig string ConfigFileName { get; set; }
{ }
string ConfigFileName { get; set; }
}
} }

View File

@@ -1,8 +1,6 @@
namespace EveOPreview.Configuration namespace EveOPreview.Configuration {
{ public interface IConfigurationStorage {
public interface IConfigurationStorage void Load();
{ void Save();
void Load(); }
void Save();
}
} }

View File

@@ -2,100 +2,115 @@
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
namespace EveOPreview.Configuration namespace EveOPreview.Configuration {
{ public interface IThumbnailConfiguration {
public interface IThumbnailConfiguration List<string> CycleGroup1ForwardHotkeys { get; set; }
{ List<string> CycleGroup1BackwardHotkeys { get; set; }
List<string> CycleGroup1ForwardHotkeys { get; set; } Dictionary<string, int> CycleGroup1ClientsOrder { get; set; }
List<string> CycleGroup1BackwardHotkeys { get; set; }
Dictionary<string, int> CycleGroup1ClientsOrder { get; set; }
List<string> CycleGroup2ForwardHotkeys { get; set; } List<string> CycleGroup2ForwardHotkeys { get; set; }
List<string> CycleGroup2BackwardHotkeys { get; set; } List<string> CycleGroup2BackwardHotkeys { get; set; }
Dictionary<string, int> CycleGroup2ClientsOrder { get; set; } Dictionary<string, int> CycleGroup2ClientsOrder { get; set; }
List<string> CycleGroup3ForwardHotkeys { get; set; } List<string> CycleGroup3ForwardHotkeys { get; set; }
List<string> CycleGroup3BackwardHotkeys { get; set; } List<string> CycleGroup3BackwardHotkeys { get; set; }
Dictionary<string, int> CycleGroup3ClientsOrder { get; set; } Dictionary<string, int> CycleGroup3ClientsOrder { get; set; }
List<string> CycleGroup4ForwardHotkeys { get; set; } List<string> CycleGroup4ForwardHotkeys { get; set; }
List<string> CycleGroup4BackwardHotkeys { get; set; } List<string> CycleGroup4BackwardHotkeys { get; set; }
Dictionary<string, int> CycleGroup4ClientsOrder { get; set; } Dictionary<string, int> CycleGroup4ClientsOrder { get; set; }
List<string> CycleGroup5ForwardHotkeys { get; set; } List<string> CycleGroup5ForwardHotkeys { get; set; }
List<string> CycleGroup5BackwardHotkeys { get; set; } List<string> CycleGroup5BackwardHotkeys { get; set; }
Dictionary<string, int> CycleGroup5ClientsOrder { get; set; } Dictionary<string, int> CycleGroup5ClientsOrder { get; set; }
string ToggleTrackingHotkey { get; set; } string ToggleTrackingHotkey { get; set; }
string ToggleSingleProcessHotkey { get; set; }
string ToggleAllThumbnailsHotkey { get; set; }
bool ThumbnailsManuallyHidden { get; set; }
Dictionary<string, Color> PerClientActiveClientHighlightColor { get; set; } Dictionary<string, Color> PerClientActiveClientHighlightColor { get; set; }
Dictionary<string, Size> PerClientThumbnailSize { get; set; } Dictionary<string, Size> PerClientThumbnailSize { get; set; }
Dictionary<string, Rectangle> PerClientThumbnailRegion { get; set; }
bool MinimizeToTray { get; set; } bool MinimizeToTray { get; set; }
int ThumbnailRefreshPeriod { get; set; } int ThumbnailRefreshPeriod { get; set; }
int ThumbnailResizeTimeoutPeriod { get; set; } int ThumbnailResizeTimeoutPeriod { get; set; }
bool EnableWineCompatibilityMode { get; set; } bool EnableWineCompatibilityMode { get; set; }
double ThumbnailOpacity { get; set; } double ThumbnailOpacity { get; set; }
bool EnableClientLayoutTracking { get; set; } bool EnableClientLayoutTracking { get; set; }
bool HideActiveClientThumbnail { get; set; } bool HideActiveClientThumbnail { get; set; }
bool HideLoginClientThumbnail { get; set; } bool HideLoginClientThumbnail { get; set; }
bool MinimizeInactiveClients { get; set; } bool MinimizeInactiveClients { get; set; }
AnimationStyle WindowsAnimationStyle { get; set; } AnimationStyle WindowsAnimationStyle { get; set; }
bool ShowThumbnailsAlwaysOnTop { get; set; } bool ShowThumbnailsAlwaysOnTop { get; set; }
bool EnablePerClientThumbnailLayouts { get; set; } bool EnablePerClientThumbnailLayouts { get; set; }
bool HideThumbnailsOnLostFocus { get; set; } bool HideThumbnailsOnLostFocus { get; set; }
int HideThumbnailsDelay { get; set; } int HideThumbnailsDelay { get; set; }
Size ThumbnailSize { get; set; } Size ThumbnailSize { get; set; }
Size ThumbnailMinimumSize { get; set; } Size ThumbnailMinimumSize { get; set; }
Size ThumbnailMaximumSize { get; set; } Size ThumbnailMaximumSize { get; set; }
bool EnableThumbnailSnap { get; set; } bool EnableThumbnailSnap { get; set; }
int ThumbnailSnapRange { get; set; }
bool ThumbnailZoomEnabled { get; set; } bool ThumbnailZoomEnabled { get; set; }
int ThumbnailZoomFactor { get; set; } int ThumbnailZoomFactor { get; set; }
ZoomAnchor ThumbnailZoomAnchor { get; set; } ZoomAnchor ThumbnailZoomAnchor { get; set; }
ZoomAnchor OverlayLabelAnchor { get; set; } ZoomAnchor OverlayLabelAnchor { get; set; }
bool ShowThumbnailOverlays { get; set; } bool ShowThumbnailOverlays { get; set; }
bool ShowThumbnailFrames { get; set; } bool ShowThumbnailFrames { get; set; }
bool LockThumbnailLocation { get; set; } bool LockThumbnailLocation { get; set; }
bool ThumbnailSnapToGrid { get; set; } bool ThumbnailSnapToGrid { get; set; }
int ThumbnailSnapToGridSizeX { get; set; } int ThumbnailSnapToGridSizeX { get; set; }
int ThumbnailSnapToGridSizeY { get; set; } int ThumbnailSnapToGridSizeY { get; set; }
bool EnableActiveClientHighlight { get; set; } bool EnableActiveClientHighlight { get; set; }
Color ActiveClientHighlightColor { get; set; } Color ActiveClientHighlightColor { get; set; }
int ActiveClientHighlightThickness { get; set; } int ActiveClientHighlightThickness { get; set; }
Color OverlayLabelColor { get; set; } Color OverlayLabelColor { get; set; }
int OverlayLabelSize { get; set; } int OverlayLabelSize { get; set; }
string IconName { get; set; } bool EnableThumbnailRegionSnipping { get; set; }
Rectangle DefaultThumbnailRegion { get; set; }
Point LoginThumbnailLocation { get; set; } string CurrentProfile { get; set; }
List<string> AvailableProfiles { get; set; }
Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation); string IconName { get; set; }
Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize);
ZoomAnchor GetZoomAnchor(string currentClient, ZoomAnchor defaultZoomAnchor);
void SetThumbnailLocation(string currentClient, string activeClient, Point location);
ClientLayout GetClientLayout(string currentClient); Point LoginThumbnailLocation { get; set; }
void SetClientLayout(string currentClient, ClientLayout layout);
Keys GetClientHotkey(string currentClient); Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation);
void SetClientHotkey(string currentClient, Keys hotkey); Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize);
Keys StringToKey(string hotkey); ZoomAnchor GetZoomAnchor(string currentClient, ZoomAnchor defaultZoomAnchor);
Rectangle GetThumbnailRegion(string currentClient, Rectangle defaultRegion);
void SetThumbnailLocation(string currentClient, string activeClient, Point location);
void SetThumbnailRegion(string currentClient, Rectangle region);
bool IsPriorityClient(string currentClient); void SaveProfile(string profileName);
bool IsExecutableToPreview(string processName); void LoadProfile(string profileName);
List<string> ExecutablesToPreview { get; set; } void DeleteProfile(string profileName);
bool IsThumbnailDisabled(string currentClient); ClientLayout GetClientLayout(string currentClient);
void ToggleThumbnail(string currentClient, bool isDisabled); void SetClientLayout(string currentClient, ClientLayout layout);
void ApplyRestrictions(); Keys GetClientHotkey(string currentClient);
} void SetClientHotkey(string currentClient, Keys hotkey);
Keys StringToKey(string hotkey);
bool IsPriorityClient(string currentClient);
bool IsExecutableToPreview(string processName);
List<string> ExecutablesToPreview { get; set; }
bool IsThumbnailDisabled(string currentClient);
void ToggleThumbnail(string currentClient, bool isDisabled);
void ApplyRestrictions();
}
} }

View File

@@ -1,15 +1,3 @@
namespace EveOPreview.Configuration namespace EveOPreview.Configuration {
{ public enum ZoomAnchor { NW, N, NE, W, C, E, SW, S, SE }
public enum ZoomAnchor
{
NW,
N,
NE,
W,
C,
E,
SW,
S,
SE
}
} }

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<DefineConstants Condition="'$(EVEOTarget)'=='Linux'">LINUX</DefineConstants> <DefineConstants Condition="'$(EVEOTarget)'=='Linux'">LINUX</DefineConstants>
<TargetFramework>net8.0-windows8.0</TargetFramework> <TargetFramework>net8.0-windows8.0</TargetFramework>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<PublishSingleFile>true</PublishSingleFile> <PublishSingleFile>true</PublishSingleFile>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract> <IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>

View File

@@ -2,131 +2,114 @@ using System;
using System.Windows.Forms; using System.Windows.Forms;
using System.ComponentModel; using System.ComponentModel;
namespace EveOPreview.UI.Hotkeys namespace EveOPreview.UI.Hotkeys {
{ class HotkeyHandler : IMessageFilter, IDisposable {
class HotkeyHandler : IMessageFilter, IDisposable private static int _currentId;
{ private const int MAX_ID = 0xBFFF;
private static int _currentId;
private const int MAX_ID = 0xBFFF;
#region Private fields #region Private fields
private readonly int _hotkeyId; private readonly int _hotkeyId;
private readonly IntPtr _hotkeyTarget; private readonly IntPtr _hotkeyTarget;
#endregion #endregion
public HotkeyHandler(IntPtr target, Keys hotkey) public HotkeyHandler(IntPtr target, Keys hotkey) {
{ this._hotkeyId = HotkeyHandler._currentId;
this._hotkeyId = HotkeyHandler._currentId; HotkeyHandler._currentId = (HotkeyHandler._currentId + 1) & HotkeyHandler.MAX_ID;
HotkeyHandler._currentId = (HotkeyHandler._currentId + 1) & HotkeyHandler.MAX_ID;
this._hotkeyTarget = target; this._hotkeyTarget = target;
// Assign properties // Assign properties
this.IsRegistered = false; this.IsRegistered = false;
this.KeyCode = hotkey; this.KeyCode = hotkey;
} }
public void Dispose() public void Dispose() {
{ this.Unregister();
this.Unregister(); GC.SuppressFinalize(this);
GC.SuppressFinalize(this); }
}
~HotkeyHandler() ~HotkeyHandler() {
{ // Unregister the hotkey if necessary
// Unregister the hotkey if necessary this.Unregister();
this.Unregister(); }
}
public bool IsRegistered { get; private set; } public bool IsRegistered { get; private set; }
public Keys KeyCode { get; private set; } public Keys KeyCode { get; private set; }
public event HandledEventHandler Pressed; public event HandledEventHandler Pressed;
public bool CanRegister() public bool CanRegister() {
{ // Attempt to register
// Attempt to register if (this.Register()) {
if (this.Register()) // Unregister and say we managed it
{ this.Unregister();
// Unregister and say we managed it return true;
this.Unregister(); }
return true;
}
return false; return false;
} }
public bool Register() public bool Register() {
{ // Check that we have not registered
// Check that we have not registered if (this.IsRegistered) {
if (this.IsRegistered) return false;
{ }
return false;
}
if (this.KeyCode == Keys.None) if (this.KeyCode == Keys.None) {
{ return false;
return false; }
}
// Remove all modifiers from the 'main' hotkey // Remove all modifiers from the 'main' hotkey
uint key = (uint)this.KeyCode & (~(uint)Keys.Alt) & (~(uint)Keys.Control) & (~(uint)Keys.Shift); uint key = (uint)this.KeyCode & (~(uint)Keys.Alt) & (~(uint)Keys.Control) & (~(uint)Keys.Shift);
// Get unmanaged version of the modifiers code // Get unmanaged version of the modifiers code
uint modifiers = (this.KeyCode.HasFlag(Keys.Alt) ? HotkeyHandlerNativeMethods.MOD_ALT : 0) uint modifiers = (this.KeyCode.HasFlag(Keys.Alt) ? HotkeyHandlerNativeMethods.MOD_ALT : 0) |
| (this.KeyCode.HasFlag(Keys.Control) ? HotkeyHandlerNativeMethods.MOD_CONTROL : 0) (this.KeyCode.HasFlag(Keys.Control) ? HotkeyHandlerNativeMethods.MOD_CONTROL : 0) |
| (this.KeyCode.HasFlag(Keys.Shift) ? HotkeyHandlerNativeMethods.MOD_SHIFT : 0); (this.KeyCode.HasFlag(Keys.Shift) ? HotkeyHandlerNativeMethods.MOD_SHIFT : 0);
// Register the hotkey // Register the hotkey
if (!HotkeyHandlerNativeMethods.RegisterHotKey(this._hotkeyTarget, this._hotkeyId, modifiers, key)) if (!HotkeyHandlerNativeMethods.RegisterHotKey(this._hotkeyTarget, this._hotkeyId, modifiers, key)) {
{ return false;
return false; }
}
Application.AddMessageFilter(this); Application.AddMessageFilter(this);
this.IsRegistered = true; this.IsRegistered = true;
// We successfully registered // We successfully registered
return true; return true;
} }
public void Unregister() public void Unregister() {
{ // Check that we have registered
// Check that we have registered if (!this.IsRegistered) {
if (!this.IsRegistered) return;
{ }
return;
}
this.IsRegistered = false; this.IsRegistered = false;
Application.RemoveMessageFilter(this); Application.RemoveMessageFilter(this);
// Clean up after ourselves // Clean up after ourselves
HotkeyHandlerNativeMethods.UnregisterHotKey(this._hotkeyTarget, this._hotkeyId); HotkeyHandlerNativeMethods.UnregisterHotKey(this._hotkeyTarget, this._hotkeyId);
} }
#region IMessageFilter #region IMessageFilter
public bool PreFilterMessage(ref Message message) public bool PreFilterMessage(ref Message message) {
{ return this.IsRegistered && (message.Msg == HotkeyHandlerNativeMethods.WM_HOTKEY) &&
return this.IsRegistered (message.WParam.ToInt32() == this._hotkeyId) && this.OnPressed();
&& (message.Msg == HotkeyHandlerNativeMethods.WM_HOTKEY) }
&& (message.WParam.ToInt32() == this._hotkeyId) #endregion
&& this.OnPressed();
}
#endregion
private bool OnPressed() private bool OnPressed() {
{ // Fire the event if we can
// Fire the event if we can HandledEventArgs handledEventArgs = new HandledEventArgs(false);
HandledEventArgs handledEventArgs = new HandledEventArgs(false); this.Pressed?.Invoke(this, handledEventArgs);
this.Pressed?.Invoke(this, handledEventArgs);
// Return whether we handled the event or not // Return whether we handled the event or not
return handledEventArgs.Handled; return handledEventArgs.Handled;
} }
} }
} }

View File

@@ -1,23 +1,21 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace EveOPreview.UI.Hotkeys namespace EveOPreview.UI.Hotkeys {
{ static class HotkeyHandlerNativeMethods {
static class HotkeyHandlerNativeMethods [DllImport("user32.dll")]
{ public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id); public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
public const uint WM_HOTKEY = 0x0312; public const uint WM_HOTKEY = 0x0312;
public const uint MOD_ALT = 0x1; public const uint MOD_ALT = 0x1;
public const uint MOD_CONTROL = 0x2; public const uint MOD_CONTROL = 0x2;
public const uint MOD_SHIFT = 0x4; public const uint MOD_SHIFT = 0x4;
public const uint MOD_WIN = 0x8; public const uint MOD_WIN = 0x8;
public const uint ERROR_HOTKEY_ALREADY_REGISTERED = 1409; public const uint ERROR_HOTKEY_ALREADY_REGISTERED = 1409;
} }
} }

View File

@@ -4,22 +4,18 @@ using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages; using EveOPreview.Mediator.Messages;
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Handlers.Configuration namespace EveOPreview.Mediator.Handlers.Configuration {
{ sealed class SaveConfigurationHandler : IRequestHandler<SaveConfiguration> {
sealed class SaveConfigurationHandler : IRequestHandler<SaveConfiguration> private readonly IConfigurationStorage _storage;
{
private readonly IConfigurationStorage _storage;
public SaveConfigurationHandler(IConfigurationStorage storage) public SaveConfigurationHandler(IConfigurationStorage storage) {
{ this._storage = storage;
this._storage = storage; }
}
public Task<Unit> Handle(SaveConfiguration message, CancellationToken cancellationToken) public Task<Unit> Handle(SaveConfiguration message, CancellationToken cancellationToken) {
{ this._storage.Save();
this._storage.Save();
return Unit.Task; return Unit.Task;
} }
} }
} }

View File

@@ -0,0 +1,20 @@
using System.Threading;
using System.Threading.Tasks;
using EveOPreview.Mediator.Messages;
using EveOPreview.Services;
using MediatR;
namespace EveOPreview.Mediator.Handlers.Services {
public sealed class ReRegisterHotkeysHandler : INotificationHandler<ReRegisterHotkeys> {
private readonly IThumbnailManager _thumbnailManager;
public ReRegisterHotkeysHandler(IThumbnailManager thumbnailManager) {
this._thumbnailManager = thumbnailManager;
}
public Task Handle(ReRegisterHotkeys notification, CancellationToken cancellationToken) {
this._thumbnailManager.ReRegisterHotkeys();
return Task.CompletedTask;
}
}
}

View File

@@ -4,29 +4,24 @@ using EveOPreview.Mediator.Messages;
using EveOPreview.Services; using EveOPreview.Services;
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Handlers.Services namespace EveOPreview.Mediator.Handlers.Services {
{ sealed class StartStopServiceHandler : IRequestHandler<StartService>, IRequestHandler<StopService> {
sealed class StartStopServiceHandler : IRequestHandler<StartService>, IRequestHandler<StopService> private readonly IThumbnailManager _manager;
{
private readonly IThumbnailManager _manager;
public StartStopServiceHandler(IThumbnailManager manager) public StartStopServiceHandler(IThumbnailManager manager) {
{ this._manager = manager;
this._manager = manager; }
}
public Task<Unit> Handle(StartService message, CancellationToken cancellationToken) public Task<Unit> Handle(StartService message, CancellationToken cancellationToken) {
{ this._manager.Start();
this._manager.Start();
return Unit.Task; return Unit.Task;
} }
public Task<Unit> Handle(StopService message, CancellationToken cancellationToken) public Task<Unit> Handle(StopService message, CancellationToken cancellationToken) {
{ this._manager.Stop();
this._manager.Stop();
return Unit.Task; return Unit.Task;
} }
} }
} }

View File

@@ -4,22 +4,18 @@ using EveOPreview.Mediator.Messages;
using EveOPreview.Presenters; using EveOPreview.Presenters;
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Handlers.Thumbnails namespace EveOPreview.Mediator.Handlers.Thumbnails {
{ sealed class ThumbnailActiveSizeUpdatedHandler : INotificationHandler<ThumbnailActiveSizeUpdated> {
sealed class ThumbnailActiveSizeUpdatedHandler : INotificationHandler<ThumbnailActiveSizeUpdated> private readonly IMainFormPresenter _presenter;
{
private readonly IMainFormPresenter _presenter;
public ThumbnailActiveSizeUpdatedHandler(MainFormPresenter presenter) public ThumbnailActiveSizeUpdatedHandler(MainFormPresenter presenter) {
{ this._presenter = presenter;
this._presenter = presenter; }
}
public Task Handle(ThumbnailActiveSizeUpdated notification, CancellationToken cancellationToken) public Task Handle(ThumbnailActiveSizeUpdated notification, CancellationToken cancellationToken) {
{ this._presenter.UpdateThumbnailSize(notification.Value);
this._presenter.UpdateThumbnailSize(notification.Value);
return Task.CompletedTask; return Task.CompletedTask;
} }
} }
} }

View File

@@ -4,22 +4,18 @@ using EveOPreview.Mediator.Messages;
using EveOPreview.Services; using EveOPreview.Services;
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Handlers.Thumbnails namespace EveOPreview.Mediator.Handlers.Thumbnails {
{ sealed class ThumbnailConfiguredSizeUpdatedHandler : INotificationHandler<ThumbnailConfiguredSizeUpdated> {
sealed class ThumbnailConfiguredSizeUpdatedHandler : INotificationHandler<ThumbnailConfiguredSizeUpdated> private readonly IThumbnailManager _manager;
{
private readonly IThumbnailManager _manager;
public ThumbnailConfiguredSizeUpdatedHandler(IThumbnailManager manager) public ThumbnailConfiguredSizeUpdatedHandler(IThumbnailManager manager) {
{ this._manager = manager;
this._manager = manager; }
}
public Task Handle(ThumbnailConfiguredSizeUpdated notification, CancellationToken cancellationToken) public Task Handle(ThumbnailConfiguredSizeUpdated notification, CancellationToken cancellationToken) {
{ this._manager.UpdateThumbnailsSize();
this._manager.UpdateThumbnailsSize();
return Task.CompletedTask; return Task.CompletedTask;
} }
} }
} }

View File

@@ -4,22 +4,18 @@ using EveOPreview.Mediator.Messages;
using EveOPreview.Services; using EveOPreview.Services;
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Handlers.Thumbnails namespace EveOPreview.Mediator.Handlers.Thumbnails {
{ sealed class ThumbnailFrameSettingsUpdatedHandler : INotificationHandler<ThumbnailFrameSettingsUpdated> {
sealed class ThumbnailFrameSettingsUpdatedHandler : INotificationHandler<ThumbnailFrameSettingsUpdated> private readonly IThumbnailManager _manager;
{
private readonly IThumbnailManager _manager;
public ThumbnailFrameSettingsUpdatedHandler(IThumbnailManager manager) public ThumbnailFrameSettingsUpdatedHandler(IThumbnailManager manager) {
{ this._manager = manager;
this._manager = manager; }
}
public Task Handle(ThumbnailFrameSettingsUpdated notification, CancellationToken cancellationToken) public Task Handle(ThumbnailFrameSettingsUpdated notification, CancellationToken cancellationToken) {
{ this._manager.UpdateThumbnailFrames();
this._manager.UpdateThumbnailFrames();
return Task.CompletedTask; return Task.CompletedTask;
} }
} }
} }

View File

@@ -4,32 +4,26 @@ using EveOPreview.Mediator.Messages;
using EveOPreview.Presenters; using EveOPreview.Presenters;
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Handlers.Thumbnails namespace EveOPreview.Mediator.Handlers.Thumbnails {
{ sealed class ThumbnailListUpdatedHandler : INotificationHandler<ThumbnailListUpdated> {
sealed class ThumbnailListUpdatedHandler : INotificationHandler<ThumbnailListUpdated> #region Private fields
{ private readonly IMainFormPresenter _presenter;
#region Private fields #endregion
private readonly IMainFormPresenter _presenter;
#endregion
public ThumbnailListUpdatedHandler(MainFormPresenter presenter) public ThumbnailListUpdatedHandler(MainFormPresenter presenter) {
{ this._presenter = presenter;
this._presenter = presenter; }
}
public Task Handle(ThumbnailListUpdated notification, CancellationToken cancellationToken) public Task Handle(ThumbnailListUpdated notification, CancellationToken cancellationToken) {
{ if (notification.Added.Count > 0) {
if (notification.Added.Count > 0) this._presenter.AddThumbnails(notification.Added);
{ }
this._presenter.AddThumbnails(notification.Added);
}
if (notification.Removed.Count > 0) if (notification.Removed.Count > 0) {
{ this._presenter.RemoveThumbnails(notification.Removed);
this._presenter.RemoveThumbnails(notification.Removed); }
}
return Task.CompletedTask;
return Task.CompletedTask; }
} }
}
} }

View File

@@ -4,24 +4,21 @@ using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages; using EveOPreview.Mediator.Messages;
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Handlers.Thumbnails namespace EveOPreview.Mediator.Handlers.Thumbnails {
{ sealed class ThumbnailLocationUpdatedHandler : INotificationHandler<ThumbnailLocationUpdated> {
sealed class ThumbnailLocationUpdatedHandler : INotificationHandler<ThumbnailLocationUpdated> private readonly IMediator _mediator;
{ private readonly IThumbnailConfiguration _configuration;
private readonly IMediator _mediator;
private readonly IThumbnailConfiguration _configuration;
public ThumbnailLocationUpdatedHandler(IMediator mediator, IThumbnailConfiguration configuration) public ThumbnailLocationUpdatedHandler(IMediator mediator, IThumbnailConfiguration configuration) {
{ this._mediator = mediator;
this._mediator = mediator; this._configuration = configuration;
this._configuration = configuration; }
}
public Task Handle(ThumbnailLocationUpdated notification, CancellationToken cancellationToken) public Task Handle(ThumbnailLocationUpdated notification, CancellationToken cancellationToken) {
{ this._configuration.SetThumbnailLocation(notification.ThumbnailName, notification.ActiveClientName,
this._configuration.SetThumbnailLocation(notification.ThumbnailName, notification.ActiveClientName, notification.Location); notification.Location);
return this._mediator.Send(new SaveConfiguration(), cancellationToken); return this._mediator.Send(new SaveConfiguration(), cancellationToken);
} }
} }
} }

View File

@@ -0,0 +1,20 @@
using System.Threading;
using System.Threading.Tasks;
using EveOPreview.Mediator.Messages;
using EveOPreview.Services;
using MediatR;
namespace EveOPreview.Mediator.Handlers.Thumbnails {
public class ThumbnailRegionSettingsUpdatedHandler : INotificationHandler<ThumbnailRegionSettingsUpdated> {
private readonly IThumbnailManager _thumbnailManager;
public ThumbnailRegionSettingsUpdatedHandler(IThumbnailManager thumbnailManager) {
this._thumbnailManager = thumbnailManager;
}
public Task Handle(ThumbnailRegionSettingsUpdated notification, CancellationToken cancellationToken) {
this._thumbnailManager.UpdateThumbnailRegionSettings();
return Task.CompletedTask;
}
}
}

View File

@@ -1,14 +1,11 @@
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Messages namespace EveOPreview.Mediator.Messages {
{ abstract class NotificationBase<TValue> : INotification {
abstract class NotificationBase<TValue> : INotification protected NotificationBase(TValue value) {
{ this.Value = value;
protected NotificationBase(TValue value) }
{
this.Value = value;
}
public TValue Value { get; } public TValue Value { get; }
} }
} }

View File

@@ -1,8 +1,5 @@
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Messages namespace EveOPreview.Mediator.Messages {
{ sealed class SaveConfiguration : IRequest {}
sealed class SaveConfiguration : IRequest
{
}
} }

View File

@@ -0,0 +1,5 @@
using MediatR;
namespace EveOPreview.Mediator.Messages {
public sealed class ReRegisterHotkeys : INotification {}
}

View File

@@ -1,8 +1,5 @@
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Messages namespace EveOPreview.Mediator.Messages {
{ sealed class StartService : IRequest {}
sealed class StartService : IRequest
{
}
} }

View File

@@ -1,8 +1,5 @@
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Messages namespace EveOPreview.Mediator.Messages {
{ sealed class StopService : IRequest {}
sealed class StopService : IRequest
{
}
} }

View File

@@ -1,12 +1,7 @@
using System.Drawing; using System.Drawing;
namespace EveOPreview.Mediator.Messages namespace EveOPreview.Mediator.Messages {
{ sealed class ThumbnailActiveSizeUpdated : NotificationBase<Size> {
sealed class ThumbnailActiveSizeUpdated : NotificationBase<Size> public ThumbnailActiveSizeUpdated(Size size) : base(size) {}
{ }
public ThumbnailActiveSizeUpdated(Size size)
: base(size)
{
}
}
} }

View File

@@ -1,8 +1,5 @@
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Messages namespace EveOPreview.Mediator.Messages {
{ sealed class ThumbnailConfiguredSizeUpdated : INotification {}
sealed class ThumbnailConfiguredSizeUpdated : INotification
{
}
} }

View File

@@ -1,8 +1,5 @@
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Messages namespace EveOPreview.Mediator.Messages {
{ sealed class ThumbnailFrameSettingsUpdated : INotification {}
sealed class ThumbnailFrameSettingsUpdated : INotification
{
}
} }

View File

@@ -1,17 +1,14 @@
using System.Collections.Generic; using System.Collections.Generic;
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Messages namespace EveOPreview.Mediator.Messages {
{ sealed class ThumbnailListUpdated : INotification {
sealed class ThumbnailListUpdated : INotification public ThumbnailListUpdated(IList<string> addedThumbnails, IList<string> removedThumbnails) {
{ this.Added = addedThumbnails;
public ThumbnailListUpdated(IList<string> addedThumbnails, IList<string> removedThumbnails) this.Removed = removedThumbnails;
{ }
this.Added = addedThumbnails;
this.Removed = removedThumbnails;
}
public IList<string> Added { get; } public IList<string> Added { get; }
public IList<string> Removed { get; } public IList<string> Removed { get; }
} }
} }

View File

@@ -1,21 +1,18 @@
using System.Drawing; using System.Drawing;
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Messages namespace EveOPreview.Mediator.Messages {
{ sealed class ThumbnailLocationUpdated : INotification {
sealed class ThumbnailLocationUpdated : INotification public ThumbnailLocationUpdated(string thumbnailName, string activeClientName, Point location) {
{ this.ThumbnailName = thumbnailName;
public ThumbnailLocationUpdated(string thumbnailName, string activeClientName, Point location) this.ActiveClientName = activeClientName;
{ this.Location = location;
this.ThumbnailName = thumbnailName; }
this.ActiveClientName = activeClientName;
this.Location = location;
}
public string ThumbnailName { get; } public string ThumbnailName { get; }
public string ActiveClientName { get; } public string ActiveClientName { get; }
public Point Location { get; } public Point Location { get; }
} }
} }

View File

@@ -0,0 +1,5 @@
using MediatR;
namespace EveOPreview.Mediator.Messages {
public sealed class ThumbnailRegionSettingsUpdated : INotification {}
}

View File

@@ -4,280 +4,287 @@ using System.Diagnostics;
using System.Drawing; using System.Drawing;
using EveOPreview.Configuration; using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages; using EveOPreview.Mediator.Messages;
using EveOPreview.View; using EveOPreview.View;
using MediatR; using MediatR;
namespace EveOPreview.Presenters namespace EveOPreview.Presenters {
{ public class MainFormPresenter : Presenter<IMainFormView>, IMainFormPresenter {
public class MainFormPresenter : Presenter<IMainFormView>, IMainFormPresenter #region Private constants
{ private const string FORUM_URL = @"https://forum.eveonline.com/t/4202";
#region Private constants #endregion
private const string FORUM_URL = @"https://forum.eveonline.com/t/4202";
#endregion
#region Private fields #region Private fields
private readonly IMediator _mediator; private readonly IMediator _mediator;
private readonly IThumbnailConfiguration _configuration; private readonly IThumbnailConfiguration _configuration;
private readonly IConfigurationStorage _configurationStorage; private readonly IConfigurationStorage _configurationStorage;
private readonly IDictionary<string, IThumbnailDescription> _descriptionsCache; private readonly IDictionary<string, IThumbnailDescription> _descriptionsCache;
private bool _suppressSizeNotifications; private bool _suppressSizeNotifications;
private bool _exitApplication; private bool _exitApplication;
#endregion #endregion
public MainFormPresenter(IApplicationController controller, IMainFormView view, IMediator mediator, IThumbnailConfiguration configuration, IConfigurationStorage configurationStorage) public MainFormPresenter(IApplicationController controller, IMainFormView view, IMediator mediator,
: base(controller, view) IThumbnailConfiguration configuration, IConfigurationStorage configurationStorage)
{ : base(controller, view) {
this._mediator = mediator; this._mediator = mediator;
this._configuration = configuration; this._configuration = configuration;
this._configurationStorage = configurationStorage; this._configurationStorage = configurationStorage;
this._descriptionsCache = new Dictionary<string, IThumbnailDescription>(); this._descriptionsCache = new Dictionary<string, IThumbnailDescription>();
this._suppressSizeNotifications = false; this._suppressSizeNotifications = false;
this._exitApplication = false; this._exitApplication = false;
this.View.FormActivated = this.Activate; this.View.FormActivated = this.Activate;
this.View.FormMinimized = this.Minimize; this.View.FormMinimized = this.Minimize;
this.View.FormCloseRequested = this.Close; this.View.FormCloseRequested = this.Close;
this.View.ApplicationSettingsChanged = this.SaveApplicationSettings; this.View.ApplicationSettingsChanged = this.SaveApplicationSettings;
this.View.ThumbnailsSizeChanged = this.UpdateThumbnailsSize; this.View.ThumbnailsSizeChanged = this.UpdateThumbnailsSize;
this.View.ThumbnailStateChanged = this.UpdateThumbnailState; this.View.ThumbnailStateChanged = this.UpdateThumbnailState;
this.View.DocumentationLinkActivated = this.OpenDocumentationLink; this.View.DocumentationLinkActivated = this.OpenDocumentationLink;
this.View.ApplicationExitRequested = this.ExitApplication; this.View.ApplicationExitRequested = this.ExitApplication;
this.View.IconName = this._configuration.IconName; this.View.IconName = this._configuration.IconName;
} }
private void Activate() private void Activate() {
{ this._suppressSizeNotifications = true;
this._suppressSizeNotifications = true; this.LoadApplicationSettings();
this.LoadApplicationSettings(); this.View.SetDocumentationUrl(MainFormPresenter.FORUM_URL);
this.View.SetDocumentationUrl(MainFormPresenter.FORUM_URL); this.View.SetVersionInfo(this.GetApplicationVersion());
this.View.SetVersionInfo(this.GetApplicationVersion()); if (this._configuration.MinimizeToTray) {
if (this._configuration.MinimizeToTray) this.View.Minimize();
{ }
this.View.Minimize();
}
this._mediator.Send(new StartService()); this._mediator.Send(new StartService());
this._suppressSizeNotifications = false; this._suppressSizeNotifications = false;
} }
private void Minimize() private void Minimize() {
{ if (!this._configuration.MinimizeToTray) {
if (!this._configuration.MinimizeToTray) return;
{ }
return;
}
this.View.Hide(); this.View.Hide();
} }
private void Close(ViewCloseRequest request) private void Close(ViewCloseRequest request) {
{ if (this._exitApplication || !this.View.MinimizeToTray) {
if (this._exitApplication || !this.View.MinimizeToTray) this._mediator.Send(new StopService()).Wait();
{
this._mediator.Send(new StopService()).Wait();
this._configurationStorage.Save(); this._configurationStorage.Save();
request.Allow = true; request.Allow = true;
return; return;
} }
request.Allow = false; request.Allow = false;
this.View.Minimize(); this.View.Minimize();
} }
private async void UpdateThumbnailsSize() private async void UpdateThumbnailsSize() {
{ if (!this._suppressSizeNotifications) {
if (!this._suppressSizeNotifications) this.SaveApplicationSettings();
{ await this._mediator.Publish(new ThumbnailConfiguredSizeUpdated());
this.SaveApplicationSettings(); }
await this._mediator.Publish(new ThumbnailConfiguredSizeUpdated()); }
}
}
private void LoadApplicationSettings() private void LoadApplicationSettings() {
{ this._configurationStorage.Load();
this._configurationStorage.Load();
this.View.MinimizeToTray = this._configuration.MinimizeToTray; this.View.MinimizeToTray = this._configuration.MinimizeToTray;
this.View.ThumbnailOpacity = this._configuration.ThumbnailOpacity; this.View.ThumbnailOpacity = this._configuration.ThumbnailOpacity;
this.View.EnableClientLayoutTracking = this._configuration.EnableClientLayoutTracking; this.View.EnableClientLayoutTracking = this._configuration.EnableClientLayoutTracking;
this.View.HideActiveClientThumbnail = this._configuration.HideActiveClientThumbnail; this.View.HideActiveClientThumbnail = this._configuration.HideActiveClientThumbnail;
this.View.MinimizeInactiveClients = this._configuration.MinimizeInactiveClients; this.View.MinimizeInactiveClients = this._configuration.MinimizeInactiveClients;
this.View.WindowsAnimationStyle = ViewAnimationStyleConverter.Convert(this._configuration.WindowsAnimationStyle); this.View.WindowsAnimationStyle =
this.View.ShowThumbnailsAlwaysOnTop = this._configuration.ShowThumbnailsAlwaysOnTop; ViewAnimationStyleConverter.Convert(this._configuration.WindowsAnimationStyle);
this.View.HideThumbnailsOnLostFocus = this._configuration.HideThumbnailsOnLostFocus; this.View.ShowThumbnailsAlwaysOnTop = this._configuration.ShowThumbnailsAlwaysOnTop;
this.View.EnablePerClientThumbnailLayouts = this._configuration.EnablePerClientThumbnailLayouts; this.View.HideThumbnailsOnLostFocus = this._configuration.HideThumbnailsOnLostFocus;
this.View.EnablePerClientThumbnailLayouts = this._configuration.EnablePerClientThumbnailLayouts;
this.View.SetThumbnailSizeLimitations(this._configuration.ThumbnailMinimumSize, this._configuration.ThumbnailMaximumSize); this.View.SetThumbnailSizeLimitations(this._configuration.ThumbnailMinimumSize,
this.View.ThumbnailSize = this._configuration.ThumbnailSize; this._configuration.ThumbnailMaximumSize);
this.View.ThumbnailSize = this._configuration.ThumbnailSize;
this.View.EnableThumbnailZoom = this._configuration.ThumbnailZoomEnabled; this.View.EnableThumbnailZoom = this._configuration.ThumbnailZoomEnabled;
this.View.ThumbnailZoomFactor = this._configuration.ThumbnailZoomFactor; this.View.ThumbnailZoomFactor = this._configuration.ThumbnailZoomFactor;
this.View.ThumbnailZoomAnchor = ViewZoomAnchorConverter.Convert(this._configuration.ThumbnailZoomAnchor); this.View.ThumbnailZoomAnchor = ViewZoomAnchorConverter.Convert(this._configuration.ThumbnailZoomAnchor);
this.View.OverlayLabelAnchor = ViewZoomAnchorConverter.Convert(this._configuration.OverlayLabelAnchor); this.View.OverlayLabelAnchor = ViewZoomAnchorConverter.Convert(this._configuration.OverlayLabelAnchor);
this.View.ShowThumbnailOverlays = this._configuration.ShowThumbnailOverlays; this.View.ShowThumbnailOverlays = this._configuration.ShowThumbnailOverlays;
this.View.ShowThumbnailFrames = this._configuration.ShowThumbnailFrames; this.View.ShowThumbnailFrames = this._configuration.ShowThumbnailFrames;
this.View.LockThumbnailLocation = this._configuration.LockThumbnailLocation; this.View.LockThumbnailLocation = this._configuration.LockThumbnailLocation;
this.View.ThumbnailSnapToGrid = this._configuration.ThumbnailSnapToGrid; this.View.ThumbnailSnapToGrid = this._configuration.ThumbnailSnapToGrid;
this.View.ThumbnailSnapToGridSizeX = this._configuration.ThumbnailSnapToGridSizeX; this.View.ThumbnailSnapToGridSizeX = this._configuration.ThumbnailSnapToGridSizeX;
this.View.ThumbnailSnapToGridSizeY = this._configuration.ThumbnailSnapToGridSizeY; this.View.ThumbnailSnapToGridSizeY = this._configuration.ThumbnailSnapToGridSizeY;
this.View.EnableActiveClientHighlight = this._configuration.EnableActiveClientHighlight; this.View.ThumbnailSnapRange = this._configuration.ThumbnailSnapRange;
this.View.ActiveClientHighlightColor = this._configuration.ActiveClientHighlightColor; this.View.EnableActiveClientHighlight = this._configuration.EnableActiveClientHighlight;
this.View.ActiveClientHighlightColor = this._configuration.ActiveClientHighlightColor;
this.View.OverlayLabelColor = this._configuration.OverlayLabelColor; this.View.OverlayLabelColor = this._configuration.OverlayLabelColor;
this.View.OverlayLabelSize = this._configuration.OverlayLabelSize; this.View.OverlayLabelSize = this._configuration.OverlayLabelSize;
this.View.IconName = this._configuration.IconName; this.View.EnableThumbnailRegionSnipping = this._configuration.EnableThumbnailRegionSnipping;
} this.View.DefaultThumbnailRegion = this._configuration.DefaultThumbnailRegion;
private async void SaveApplicationSettings() this.View.AvailableProfiles = this._configuration.AvailableProfiles;
{ this.View.CurrentProfile = this._configuration.CurrentProfile;
this._configuration.MinimizeToTray = this.View.MinimizeToTray;
this._configuration.ThumbnailOpacity = (float)this.View.ThumbnailOpacity; this.View.ToggleTrackingHotkey = this._configuration.ToggleTrackingHotkey;
this.View.ToggleSingleProcessHotkey = this._configuration.ToggleSingleProcessHotkey;
this.View.ToggleAllThumbnailsHotkey = this._configuration.ToggleAllThumbnailsHotkey;
this._configuration.EnableClientLayoutTracking = this.View.EnableClientLayoutTracking; this.View.IconName = this._configuration.IconName;
this._configuration.HideActiveClientThumbnail = this.View.HideActiveClientThumbnail; }
this._configuration.MinimizeInactiveClients = this.View.MinimizeInactiveClients;
this._configuration.WindowsAnimationStyle = ViewAnimationStyleConverter.Convert(this.View.WindowsAnimationStyle); private async void SaveApplicationSettings() {
this._configuration.MinimizeToTray = this.View.MinimizeToTray;
this._configuration.ThumbnailOpacity = (float)this.View.ThumbnailOpacity;
this._configuration.EnableClientLayoutTracking = this.View.EnableClientLayoutTracking;
this._configuration.HideActiveClientThumbnail = this.View.HideActiveClientThumbnail;
this._configuration.MinimizeInactiveClients = this.View.MinimizeInactiveClients;
this._configuration.WindowsAnimationStyle =
ViewAnimationStyleConverter.Convert(this.View.WindowsAnimationStyle);
this._configuration.ShowThumbnailsAlwaysOnTop = this.View.ShowThumbnailsAlwaysOnTop; this._configuration.ShowThumbnailsAlwaysOnTop = this.View.ShowThumbnailsAlwaysOnTop;
this._configuration.HideThumbnailsOnLostFocus = this.View.HideThumbnailsOnLostFocus; this._configuration.HideThumbnailsOnLostFocus = this.View.HideThumbnailsOnLostFocus;
this._configuration.EnablePerClientThumbnailLayouts = this.View.EnablePerClientThumbnailLayouts; this._configuration.EnablePerClientThumbnailLayouts = this.View.EnablePerClientThumbnailLayouts;
this._configuration.ThumbnailSize = this.View.ThumbnailSize; this._configuration.ThumbnailSize = this.View.ThumbnailSize;
this._configuration.ThumbnailZoomEnabled = this.View.EnableThumbnailZoom; this._configuration.ThumbnailZoomEnabled = this.View.EnableThumbnailZoom;
this._configuration.ThumbnailZoomFactor = this.View.ThumbnailZoomFactor; this._configuration.ThumbnailZoomFactor = this.View.ThumbnailZoomFactor;
this._configuration.ThumbnailZoomAnchor = ViewZoomAnchorConverter.Convert(this.View.ThumbnailZoomAnchor); this._configuration.ThumbnailZoomAnchor = ViewZoomAnchorConverter.Convert(this.View.ThumbnailZoomAnchor);
this._configuration.OverlayLabelAnchor = ViewZoomAnchorConverter.Convert(this.View.OverlayLabelAnchor); this._configuration.OverlayLabelAnchor = ViewZoomAnchorConverter.Convert(this.View.OverlayLabelAnchor);
this._configuration.ShowThumbnailOverlays = this.View.ShowThumbnailOverlays; this._configuration.ShowThumbnailOverlays = this.View.ShowThumbnailOverlays;
if (this._configuration.ShowThumbnailFrames != this.View.ShowThumbnailFrames) if (this._configuration.ShowThumbnailFrames != this.View.ShowThumbnailFrames) {
{ this._configuration.ShowThumbnailFrames = this.View.ShowThumbnailFrames;
this._configuration.ShowThumbnailFrames = this.View.ShowThumbnailFrames; await this._mediator.Publish(new ThumbnailFrameSettingsUpdated());
await this._mediator.Publish(new ThumbnailFrameSettingsUpdated()); }
}
this._configuration.LockThumbnailLocation = this.View.LockThumbnailLocation; this._configuration.LockThumbnailLocation = this.View.LockThumbnailLocation;
this._configuration.ThumbnailSnapToGrid = this.View.ThumbnailSnapToGrid; this._configuration.ThumbnailSnapToGrid = this.View.ThumbnailSnapToGrid;
this._configuration.ThumbnailSnapToGridSizeX = this.View.ThumbnailSnapToGridSizeX; this._configuration.ThumbnailSnapToGridSizeX = this.View.ThumbnailSnapToGridSizeX;
this._configuration.ThumbnailSnapToGridSizeY = this.View.ThumbnailSnapToGridSizeY; this._configuration.ThumbnailSnapToGridSizeY = this.View.ThumbnailSnapToGridSizeY;
this._configuration.ThumbnailSnapRange = this.View.ThumbnailSnapRange;
this._configuration.EnableActiveClientHighlight = this.View.EnableActiveClientHighlight; this._configuration.EnableActiveClientHighlight = this.View.EnableActiveClientHighlight;
this._configuration.ActiveClientHighlightColor = this.View.ActiveClientHighlightColor; this._configuration.ActiveClientHighlightColor = this.View.ActiveClientHighlightColor;
this._configuration.OverlayLabelColor = this.View.OverlayLabelColor; this._configuration.OverlayLabelColor = this.View.OverlayLabelColor;
this._configuration.OverlayLabelSize = this.View.OverlayLabelSize; this._configuration.OverlayLabelSize = this.View.OverlayLabelSize;
this._configuration.IconName = this.View.IconName; this._configuration.EnableThumbnailRegionSnipping = this.View.EnableThumbnailRegionSnipping;
this._configuration.DefaultThumbnailRegion = this.View.DefaultThumbnailRegion;
this._configurationStorage.Save(); this._configuration.AvailableProfiles = this.View.AvailableProfiles;
this._configuration.CurrentProfile = this.View.CurrentProfile;
this.View.RefreshZoomSettings(); this._configuration.ToggleTrackingHotkey = this.View.ToggleTrackingHotkey;
this._configuration.ToggleSingleProcessHotkey = this.View.ToggleSingleProcessHotkey;
this._configuration.ToggleAllThumbnailsHotkey = this.View.ToggleAllThumbnailsHotkey;
await this._mediator.Send(new SaveConfiguration()); // Re-register hotkeys if they changed
} await this._mediator.Publish(new ReRegisterHotkeys());
// Publish region settings update if they changed
if (this._configuration.EnableThumbnailRegionSnipping != this.View.EnableThumbnailRegionSnipping ||
this._configuration.DefaultThumbnailRegion != this.View.DefaultThumbnailRegion) {
await this._mediator.Publish(new ThumbnailRegionSettingsUpdated());
}
public void AddThumbnails(IList<string> thumbnailTitles) this._configuration.IconName = this.View.IconName;
{
IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count);
lock (this._descriptionsCache) this._configurationStorage.Save();
{
foreach (string title in thumbnailTitles)
{
IThumbnailDescription description = this.CreateThumbnailDescription(title);
this._descriptionsCache[title] = description;
descriptions.Add(description); this.View.RefreshZoomSettings();
}
}
this.View.AddThumbnails(descriptions); await this._mediator.Send(new SaveConfiguration());
} }
public void RemoveThumbnails(IList<string> thumbnailTitles) public void AddThumbnails(IList<string> thumbnailTitles) {
{ IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count);
IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count);
lock (this._descriptionsCache) lock (this._descriptionsCache) {
{ foreach (string title in thumbnailTitles) {
foreach (string title in thumbnailTitles) IThumbnailDescription description = this.CreateThumbnailDescription(title);
{ this._descriptionsCache[title] = description;
if (!this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description))
{
continue;
}
this._descriptionsCache.Remove(title); descriptions.Add(description);
descriptions.Add(description); }
} }
}
this.View.RemoveThumbnails(descriptions); this.View.AddThumbnails(descriptions);
} }
private IThumbnailDescription CreateThumbnailDescription(string title) public void RemoveThumbnails(IList<string> thumbnailTitles) {
{ IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count);
bool isDisabled = this._configuration.IsThumbnailDisabled(title);
return new ThumbnailDescription(title, isDisabled);
}
private async void UpdateThumbnailState(String title) lock (this._descriptionsCache) {
{ foreach (string title in thumbnailTitles) {
if (this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description)) if (!this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description)) {
{ continue;
this._configuration.ToggleThumbnail(title, description.IsDisabled); }
}
await this._mediator.Send(new SaveConfiguration()); this._descriptionsCache.Remove(title);
} descriptions.Add(description);
}
}
public void UpdateThumbnailSize(Size size) this.View.RemoveThumbnails(descriptions);
{ }
this._suppressSizeNotifications = true;
this.View.ThumbnailSize = size;
this._suppressSizeNotifications = false;
}
private void OpenDocumentationLink() private IThumbnailDescription CreateThumbnailDescription(string title) {
{ bool isDisabled = this._configuration.IsThumbnailDisabled(title);
// funtimes return new ThumbnailDescription(title, isDisabled);
// https://brockallen.com/2016/09/24/process-start-for-urls-on-net-core/ }
// https://github.com/dotnet/runtime/issues/17938
// TODO Move out to a separate service / presenter / message handler private async void UpdateThumbnailState(String title) {
if (this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description)) {
this._configuration.ToggleThumbnail(title, description.IsDisabled);
}
await this._mediator.Send(new SaveConfiguration());
}
public void UpdateThumbnailSize(Size size) {
this._suppressSizeNotifications = true;
this.View.ThumbnailSize = size;
this._suppressSizeNotifications = false;
}
private void OpenDocumentationLink() {
// funtimes
// https://brockallen.com/2016/09/24/process-start-for-urls-on-net-core/
// https://github.com/dotnet/runtime/issues/17938
// TODO Move out to a separate service / presenter / message handler
#if LINUX #if LINUX
Process.Start("xdg-open", new Uri(MainFormPresenter.FORUM_URL).AbsoluteUri); Process.Start("xdg-open", new Uri(MainFormPresenter.FORUM_URL).AbsoluteUri);
#else #else
ProcessStartInfo processStartInfo = new ProcessStartInfo(new Uri(MainFormPresenter.FORUM_URL).AbsoluteUri); ProcessStartInfo processStartInfo = new ProcessStartInfo(new Uri(MainFormPresenter.FORUM_URL).AbsoluteUri);
processStartInfo.UseShellExecute = true; processStartInfo.UseShellExecute = true;
Process.Start(processStartInfo); Process.Start(processStartInfo);
#endif #endif
} }
private string GetApplicationVersion() private string GetApplicationVersion() {
{ Version version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version;
Version version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version; string target = "Windows";
string target = "Windows";
#if LINUX #if LINUX
target = "Linux"; target = "Linux";
#endif #endif
return $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision} {target}"; return $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision} {target}";
} }
private void ExitApplication() private void ExitApplication() {
{ this._exitApplication = true;
this._exitApplication = true; this.View.Close();
this.View.Close(); }
} }
}
} }

View File

@@ -1,19 +1,15 @@
using EveOPreview.Configuration; using EveOPreview.Configuration;
namespace EveOPreview.View namespace EveOPreview.View {
{ static class ViewAnimationStyleConverter {
static class ViewAnimationStyleConverter public static AnimationStyle Convert(ViewAnimationStyle value) {
{ // Cheat based on fact that the order and byte values of both enums are the same
public static AnimationStyle Convert(ViewAnimationStyle value) return (AnimationStyle)((int)value);
{ }
// Cheat based on fact that the order and byte values of both enums are the same
return (AnimationStyle)((int)value);
}
public static ViewAnimationStyle Convert(AnimationStyle value) public static ViewAnimationStyle Convert(AnimationStyle value) {
{ // Cheat based on fact that the order and byte values of both enums are the same
// Cheat based on fact that the order and byte values of both enums are the same return (ViewAnimationStyle)((int)value);
return (ViewAnimationStyle)((int)value); }
} }
}
} }

View File

@@ -1,19 +1,15 @@
using EveOPreview.Configuration; using EveOPreview.Configuration;
namespace EveOPreview.View namespace EveOPreview.View {
{ static class ViewZoomAnchorConverter {
static class ViewZoomAnchorConverter public static ZoomAnchor Convert(ViewZoomAnchor value) {
{ // Cheat based on fact that the order and byte values of both enums are the same
public static ZoomAnchor Convert(ViewZoomAnchor value) return (ZoomAnchor)((int)value);
{ }
// Cheat based on fact that the order and byte values of both enums are the same
return (ZoomAnchor)((int)value);
}
public static ViewZoomAnchor Convert(ZoomAnchor value) public static ViewZoomAnchor Convert(ZoomAnchor value) {
{ // Cheat based on fact that the order and byte values of both enums are the same
// Cheat based on fact that the order and byte values of both enums are the same return (ViewZoomAnchor)((int)value);
return (ViewZoomAnchor)((int)value); }
} }
}
} }

View File

@@ -1,13 +1,11 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
namespace EveOPreview.Presenters namespace EveOPreview.Presenters {
{ interface IMainFormPresenter {
interface IMainFormPresenter void AddThumbnails(IList<string> thumbnailTitles);
{ void RemoveThumbnails(IList<string> thumbnailTitles);
void AddThumbnails(IList<string> thumbnailTitles);
void RemoveThumbnails(IList<string> thumbnailTitles);
void UpdateThumbnailSize(Size size); void UpdateThumbnailSize(Size size);
} }
} }

View File

@@ -1,12 +1,9 @@
namespace EveOPreview.View namespace EveOPreview.View {
{ public class ViewCloseRequest {
public class ViewCloseRequest public ViewCloseRequest() {
{ this.Allow = true;
public ViewCloseRequest() }
{
this.Allow = true;
}
public bool Allow { get; set; } public bool Allow { get; set; }
} }
} }

View File

@@ -7,108 +7,96 @@ using EveOPreview.Services;
using EveOPreview.View; using EveOPreview.View;
using MediatR; using MediatR;
namespace EveOPreview namespace EveOPreview {
{ static class Program {
static class Program private static string MUTEX_NAME = "EVE-O-Preview Single Instance Mutex";
{
private static string MUTEX_NAME = "EVE-O-Preview Single Instance Mutex";
private static Mutex _singleInstanceMutex; private static Mutex _singleInstanceMutex;
/// <summary>The main entry point for the application.</summary> /// <summary>The main entry point for the application.</summary>
[STAThread] [STAThread]
static void Main() static void Main() {
{ // The very usual Mutex-based single-instance screening
// The very usual Mutex-based single-instance screening // 'token' variable is used to store reference to the instance Mutex
// 'token' variable is used to store reference to the instance Mutex // during the app lifetime
// during the app lifetime Program._singleInstanceMutex = Program.GetInstanceToken();
Program._singleInstanceMutex = Program.GetInstanceToken();
// If it was not possible to acquire the app token then another app instance is already running // If it was not possible to acquire the app token then another app instance is already running
// Nothing to do here // Nothing to do here
if (Program._singleInstanceMutex == null) if (Program._singleInstanceMutex == null) {
{ return;
return; }
}
ExceptionHandler handler = new ExceptionHandler(); ExceptionHandler handler = new ExceptionHandler();
handler.SetupExceptionHandlers(); handler.SetupExceptionHandlers();
IApplicationController controller = Program.InitializeApplicationController(); IApplicationController controller = Program.InitializeApplicationController();
Program.InitializeWinForms(); Program.InitializeWinForms();
controller.Run<MainFormPresenter>(); controller.Run<MainFormPresenter>();
} }
private static Mutex GetInstanceToken() private static Mutex GetInstanceToken() {
{ // The code might look overcomplicated here for a single Mutex operation
// The code might look overcomplicated here for a single Mutex operation // Yet we had already experienced a Windows-level issue
// Yet we had already experienced a Windows-level issue // where .NET finalizer thread was literally paralyzed by
// where .NET finalizer thread was literally paralyzed by // a failed Mutex operation. That did lead to weird OutOfMemory
// a failed Mutex operation. That did lead to weird OutOfMemory // exceptions later
// exceptions later try {
try Mutex.OpenExisting(Program.MUTEX_NAME);
{ // if that didn't fail then another instance is already running
Mutex.OpenExisting(Program.MUTEX_NAME); return null;
// if that didn't fail then another instance is already running } catch (UnauthorizedAccessException) {
return null; return null;
} } catch (Exception) {
catch (UnauthorizedAccessException) Mutex token = new Mutex(true, Program.MUTEX_NAME, out var result);
{ return result ? token : null;
return null; }
} }
catch (Exception)
{
Mutex token = new Mutex(true, Program.MUTEX_NAME, out var result);
return result ? token : null;
}
}
private static void InitializeWinForms() private static void InitializeWinForms() {
{ Application.EnableVisualStyles();
Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false);
Application.SetCompatibleTextRenderingDefault(false);
#if WINDOWS #if WINDOWS
Application.SetHighDpiMode(HighDpiMode.PerMonitorV2); Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);
#endif #endif
} }
private static IApplicationController InitializeApplicationController() private static IApplicationController InitializeApplicationController() {
{ IIocContainer container = new LightInjectContainer();
IIocContainer container = new LightInjectContainer();
// Singleton registration is used for services // Singleton registration is used for services
// Low-level services // Low-level services
container.Register<IWindowManager>(); container.Register<IWindowManager>();
container.Register<IProcessMonitor>(); container.Register<IProcessMonitor>();
// MediatR // MediatR
container.Register<IMediator, MediatR.Mediator>(); container.Register<IMediator, MediatR.Mediator>();
container.RegisterInstance<ServiceFactory>(t => container.Resolve(t)); container.RegisterInstance<ServiceFactory>(t => container.Resolve(t));
container.Register(typeof(INotificationHandler<>), typeof(Program).Assembly); container.Register(typeof(INotificationHandler<>), typeof(Program).Assembly);
container.Register(typeof(IRequestHandler<>), typeof(Program).Assembly); container.Register(typeof(IRequestHandler<>), typeof(Program).Assembly);
container.Register(typeof(IRequestHandler<,>), typeof(Program).Assembly); container.Register(typeof(IRequestHandler<, >), typeof(Program).Assembly);
// Configuration services // Configuration services
container.Register<IConfigurationStorage>(); container.Register<IConfigurationStorage>();
container.Register<IAppConfig>(); container.Register<IAppConfig>();
container.Register<IThumbnailConfiguration>(); container.Register<IThumbnailConfiguration>();
// Application services // Application services
container.Register<IThumbnailManager>(); container.Register<IThumbnailManager>();
container.Register<IThumbnailViewFactory>(); container.Register<IThumbnailViewFactory>();
container.Register<IThumbnailDescription>(); container.Register<IThumbnailDescription>();
IApplicationController controller = new ApplicationController(container); IApplicationController controller = new ApplicationController(container);
// UI classes // UI classes
controller.RegisterView<StaticThumbnailView, StaticThumbnailView>(); controller.RegisterView<StaticThumbnailView, StaticThumbnailView>();
controller.RegisterView<LiveThumbnailView, LiveThumbnailView>(); controller.RegisterView<LiveThumbnailView, LiveThumbnailView>();
controller.RegisterView<IMainFormView, MainForm>(); controller.RegisterView<IMainFormView, MainForm>();
controller.RegisterInstance(new ApplicationContext()); controller.RegisterInstance(new ApplicationContext());
return controller; return controller;
} }
} }
} }

View File

@@ -10,8 +10,7 @@
namespace EveOPreview.Properties { namespace EveOPreview.Properties {
using System; using System;
/// <summary> /// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc. /// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary> /// </summary>
@@ -19,45 +18,44 @@ namespace EveOPreview.Properties {
// class via a tool like ResGen or Visual Studio. // class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen // To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project. // with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder",
"17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources { internal class Resources {
private static global::System.Resources.ResourceManager resourceMan; private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture; private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance",
internal Resources() { "CA1811:AvoidUncalledPrivateCode")]
} internal Resources() {}
/// <summary> /// <summary>
/// Returns the cached ResourceManager instance used by this class. /// Returns the cached ResourceManager instance used by this class.
/// </summary> /// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] [global::System.ComponentModel.EditorBrowsableAttribute(
global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager { internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EveOPreview.Properties.Resources", typeof(Resources).Assembly); global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(
"EveOPreview.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
} }
} }
/// <summary> /// <summary>
/// Overrides the current thread's CurrentUICulture property for all /// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class. /// resource lookups using this strongly typed resource class.
/// </summary> /// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] [global::System.ComponentModel.EditorBrowsableAttribute(
global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture { internal static global::System.Globalization.CultureInfo Culture {
get { get { return resourceCulture; }
return resourceCulture; set { resourceCulture = value; }
}
set {
resourceCulture = value;
}
} }
} }
} }

View File

@@ -2,102 +2,86 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using EveOPreview.Services.Interop; using EveOPreview.Services.Interop;
namespace EveOPreview.Services.Implementation namespace EveOPreview.Services.Implementation {
{ class DwmThumbnail : IDwmThumbnail {
class DwmThumbnail : IDwmThumbnail #region Private fields
{ private readonly IWindowManager _windowManager;
#region Private fields private IntPtr _handle;
private readonly IWindowManager _windowManager; private DWM_THUMBNAIL_PROPERTIES _properties;
private IntPtr _handle; #endregion
private DWM_THUMBNAIL_PROPERTIES _properties;
#endregion
public DwmThumbnail(IWindowManager windowManager) public DwmThumbnail(IWindowManager windowManager) {
{ this._windowManager = windowManager;
this._windowManager = windowManager; this._handle = IntPtr.Zero;
this._handle = IntPtr.Zero; }
}
public void Register(IntPtr destination, IntPtr source) public void Register(IntPtr destination, IntPtr source) {
{ this._properties = new DWM_THUMBNAIL_PROPERTIES();
this._properties = new DWM_THUMBNAIL_PROPERTIES(); this._properties.dwFlags = DWM_TNP_CONSTANTS.DWM_TNP_VISIBLE + DWM_TNP_CONSTANTS.DWM_TNP_OPACITY +
this._properties.dwFlags = DWM_TNP_CONSTANTS.DWM_TNP_VISIBLE DWM_TNP_CONSTANTS.DWM_TNP_RECTDESTINATION +
+ DWM_TNP_CONSTANTS.DWM_TNP_OPACITY DWM_TNP_CONSTANTS.DWM_TNP_SOURCECLIENTAREAONLY;
+ DWM_TNP_CONSTANTS.DWM_TNP_RECTDESTINATION this._properties.opacity = 255;
+ DWM_TNP_CONSTANTS.DWM_TNP_SOURCECLIENTAREAONLY; this._properties.fVisible = true;
this._properties.opacity = 255; this._properties.fSourceClientAreaOnly = true;
this._properties.fVisible = true; this._properties.rcSource = new RECT(0, 0, 0, 0); // Initialize with empty source rect
this._properties.fSourceClientAreaOnly = true;
if (!this._windowManager.IsCompositionEnabled) if (!this._windowManager.IsCompositionEnabled) {
{ return;
return; }
}
try try {
{ this._handle = DwmNativeMethods.DwmRegisterThumbnail(destination, source);
this._handle = DwmNativeMethods.DwmRegisterThumbnail(destination, source); } catch (ArgumentException) {
} // This exception is raised if the source client is already closed
catch (ArgumentException) // Can happen on a really slow CPU's that the window is still being
{ // listed in the process list yet it already cannot be used as
// This exception is raised if the source client is already closed // a thumbnail source
// Can happen on a really slow CPU's that the window is still being this._handle = IntPtr.Zero;
// listed in the process list yet it already cannot be used as } catch (COMException) {
// a thumbnail source // This exception is raised if DWM is suddenly not available
this._handle = IntPtr.Zero; // (f.e. when switching between Windows user accounts)
} this._handle = IntPtr.Zero;
catch (COMException) }
{ }
// This exception is raised if DWM is suddenly not available
// (f.e. when switching between Windows user accounts)
this._handle = IntPtr.Zero;
}
}
public void Unregister() public void Unregister() {
{ if ((!this._windowManager.IsCompositionEnabled) || (this._handle == IntPtr.Zero)) {
if ((!this._windowManager.IsCompositionEnabled) || (this._handle == IntPtr.Zero)) return;
{ }
return;
}
try try {
{ DwmNativeMethods.DwmUnregisterThumbnail(this._handle);
DwmNativeMethods.DwmUnregisterThumbnail(this._handle); } catch (ArgumentException) {
} } catch (COMException) {
catch (ArgumentException) // This exception is raised when DWM is not available for some reason
{ }
} }
catch (COMException)
{
// This exception is raised when DWM is not available for some reason
}
}
public void Move(int left, int top, int right, int bottom) public void Move(int left, int top, int right, int bottom) {
{ this._properties.rcDestination = new RECT(left, top, right, bottom);
this._properties.rcDestination = new RECT(left, top, right, bottom); }
}
public void Update() public void SetSourceRegion(int left, int top, int right, int bottom) {
{ this._properties.rcSource = new RECT(left, top, right, bottom);
if ((!this._windowManager.IsCompositionEnabled) || (this._handle == IntPtr.Zero)) this._properties.dwFlags |= DWM_TNP_CONSTANTS.DWM_TNP_RECTSOURCE;
{ }
return;
}
try public void ClearSourceRegion() {
{ this._properties.dwFlags &= ~DWM_TNP_CONSTANTS.DWM_TNP_RECTSOURCE;
DwmNativeMethods.DwmUpdateThumbnailProperties(this._handle, this._properties); }
}
catch (ArgumentException) public void Update() {
{ if ((!this._windowManager.IsCompositionEnabled) || (this._handle == IntPtr.Zero)) {
// This exception will be thrown if the EVE client disappears while this method is running return;
} }
catch (COMException)
{ try {
// This exception is raised when DWM is not available for some reason DwmNativeMethods.DwmUpdateThumbnailProperties(this._handle, this._properties);
} } catch (ArgumentException) {
} // This exception will be thrown if the EVE client disappears while this method is running
} } catch (COMException) {
// This exception is raised when DWM is not available for some reason
}
}
}
} }

View File

@@ -1,16 +1,13 @@
using System; using System;
namespace EveOPreview.Services.Implementation namespace EveOPreview.Services.Implementation {
{ sealed class ProcessInfo : IProcessInfo {
sealed class ProcessInfo : IProcessInfo public ProcessInfo(IntPtr handle, string title) {
{ this.Handle = handle;
public ProcessInfo(IntPtr handle, string title) this.Title = title;
{ }
this.Handle = handle;
this.Title = title;
}
public IntPtr Handle { get; } public IntPtr Handle { get; }
public string Title { get; } public string Title { get; }
} }
} }

View File

@@ -4,172 +4,148 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
namespace EveOPreview.Services.Implementation namespace EveOPreview.Services.Implementation {
{ sealed class ProcessMonitor : IProcessMonitor {
sealed class ProcessMonitor : IProcessMonitor #region Private constants
{ private const string DEFAULT_PROCESS_NAME = "Uwow-64";
#region Private constants private const string CURRENT_PROCESS_NAME = "EVE-O Preview";
private const string DEFAULT_PROCESS_NAME = "Uwow-64"; #endregion
private const string CURRENT_PROCESS_NAME = "EVE-O Preview";
#endregion
#region Private fields #region Private fields
private readonly IDictionary<IntPtr, string> _processCache; private readonly IDictionary<IntPtr, string> _processCache;
private IProcessInfo _currentProcessInfo; private IProcessInfo _currentProcessInfo;
private readonly IThumbnailConfiguration _configuration; private readonly IThumbnailConfiguration _configuration;
private readonly HashSet<int> _trackedPids; // Change to HashSet for multiple PIDs private readonly HashSet<int> _trackedPids; // Change to HashSet for multiple PIDs
#endregion #endregion
public ProcessMonitor(IThumbnailConfiguration configuration) public ProcessMonitor(IThumbnailConfiguration configuration) {
{ this._processCache = new Dictionary<IntPtr, string>(512);
this._processCache = new Dictionary<IntPtr, string>(512); this._configuration = configuration;
this._configuration = configuration; this._trackedPids = new HashSet<int>(); // Initialize empty set
this._trackedPids = new HashSet<int>(); // Initialize empty set
// This field cannot be initialized properly in constructor // This field cannot be initialized properly in constructor
// At the moment this code is executed the main application window is not yet initialized // At the moment this code is executed the main application window is not yet initialized
this._currentProcessInfo = new ProcessInfo(IntPtr.Zero, ""); this._currentProcessInfo = new ProcessInfo(IntPtr.Zero, "");
} }
private bool IsMonitoredProcess(string processName, int processId) private bool IsMonitoredProcess(string processName, int processId) {
{ // If we're tracking this specific PID, include it
// If we're tracking this specific PID, include it if (_trackedPids.Contains(processId)) {
if (_trackedPids.Contains(processId)) return true;
{ }
return true;
}
// Also include any processes that match executable tracking // Also include any processes that match executable tracking
return _configuration.IsExecutableToPreview(processName); return _configuration.IsExecutableToPreview(processName);
} }
private IProcessInfo GetCurrentProcessInfo() private IProcessInfo GetCurrentProcessInfo() {
{ var currentProcess = Process.GetCurrentProcess();
var currentProcess = Process.GetCurrentProcess(); return new ProcessInfo(currentProcess.MainWindowHandle, currentProcess.MainWindowTitle);
return new ProcessInfo(currentProcess.MainWindowHandle, currentProcess.MainWindowTitle); }
}
public IProcessInfo GetMainProcess() public IProcessInfo GetMainProcess() {
{ if (this._currentProcessInfo.Handle == IntPtr.Zero) {
if (this._currentProcessInfo.Handle == IntPtr.Zero) var processInfo = this.GetCurrentProcessInfo();
{
var processInfo = this.GetCurrentProcessInfo();
// Are we initialized yet? // Are we initialized yet?
if (processInfo.Title != "") if (processInfo.Title != "") {
{ this._currentProcessInfo = processInfo;
this._currentProcessInfo = processInfo; }
} }
}
return this._currentProcessInfo; return this._currentProcessInfo;
} }
public ICollection<IProcessInfo> GetAllProcesses() public ICollection<IProcessInfo> GetAllProcesses() {
{ ICollection<IProcessInfo> result = new List<IProcessInfo>(this._processCache.Count);
ICollection<IProcessInfo> result = new List<IProcessInfo>(this._processCache.Count);
// TODO Lock list here just in case // TODO Lock list here just in case
foreach (KeyValuePair<IntPtr, string> entry in this._processCache) foreach (KeyValuePair<IntPtr, string> entry in this._processCache) {
{ result.Add(new ProcessInfo(entry.Key, entry.Value));
result.Add(new ProcessInfo(entry.Key, entry.Value)); }
}
return result; return result;
} }
public void GetUpdatedProcesses(out ICollection<IProcessInfo> addedProcesses, out ICollection<IProcessInfo> updatedProcesses, out ICollection<IProcessInfo> removedProcesses) public void GetUpdatedProcesses(out ICollection<IProcessInfo> addedProcesses,
{ out ICollection<IProcessInfo> updatedProcesses,
addedProcesses = new List<IProcessInfo>(16); out ICollection<IProcessInfo> removedProcesses) {
updatedProcesses = new List<IProcessInfo>(16); addedProcesses = new List<IProcessInfo>(16);
removedProcesses = new List<IProcessInfo>(16); updatedProcesses = new List<IProcessInfo>(16);
removedProcesses = new List<IProcessInfo>(16);
IList<IntPtr> knownProcesses = new List<IntPtr>(this._processCache.Keys); IList<IntPtr> knownProcesses = new List<IntPtr>(this._processCache.Keys);
foreach (Process process in Process.GetProcesses()) foreach (Process process in Process.GetProcesses()) {
{ string processName = process.ProcessName;
string processName = process.ProcessName; int processId = process.Id;
int processId = process.Id;
if (!this.IsMonitoredProcess(processName, processId)) if (!this.IsMonitoredProcess(processName, processId)) {
{ continue;
continue; }
}
IntPtr mainWindowHandle = process.MainWindowHandle; IntPtr mainWindowHandle = process.MainWindowHandle;
if (mainWindowHandle == IntPtr.Zero) if (mainWindowHandle == IntPtr.Zero) {
{ continue; // No need to monitor non-visual processes
continue; // No need to monitor non-visual processes }
}
// Get all processes with same name and sort by PID // Get all processes with same name and sort by PID
var sameNameProcesses = Process.GetProcessesByName(processName) var sameNameProcesses = Process.GetProcessesByName(processName)
.Where(p => p.MainWindowHandle != IntPtr.Zero) .Where(p => p.MainWindowHandle != IntPtr.Zero)
.OrderBy(p => p.Id) .OrderBy(p => p.Id)
.ToList(); .ToList();
// Find index of current process in sorted list // Find index of current process in sorted list
int index = sameNameProcesses.FindIndex(p => p.Id == process.Id); int index = sameNameProcesses.FindIndex(p => p.Id == process.Id);
string mainWindowTitle = $"{process.MainWindowTitle} ({index + 1})"; string mainWindowTitle = $"{process.MainWindowTitle} ({index + 1})";
this._processCache.TryGetValue(mainWindowHandle, out string cachedTitle); this._processCache.TryGetValue(mainWindowHandle, out string cachedTitle);
if (cachedTitle == null) if (cachedTitle == null) {
{ // This is a new process in the list
// This is a new process in the list this._processCache.Add(mainWindowHandle, mainWindowTitle);
this._processCache.Add(mainWindowHandle, mainWindowTitle); addedProcesses.Add(new ProcessInfo(mainWindowHandle, mainWindowTitle));
addedProcesses.Add(new ProcessInfo(mainWindowHandle, mainWindowTitle)); } else {
} // This is an already known process
else if (cachedTitle != mainWindowTitle) {
{ this._processCache[mainWindowHandle] = mainWindowTitle;
// This is an already known process updatedProcesses.Add(new ProcessInfo(mainWindowHandle, mainWindowTitle));
if (cachedTitle != mainWindowTitle) }
{ }
this._processCache[mainWindowHandle] = mainWindowTitle;
updatedProcesses.Add(new ProcessInfo(mainWindowHandle, mainWindowTitle));
}
}
knownProcesses.Remove(mainWindowHandle); knownProcesses.Remove(mainWindowHandle);
} }
foreach (IntPtr index in knownProcesses) foreach (IntPtr index in knownProcesses) {
{ string title = this._processCache[index];
string title = this._processCache[index]; removedProcesses.Add(new ProcessInfo(index, title));
removedProcesses.Add(new ProcessInfo(index, title)); this._processCache.Remove(index);
this._processCache.Remove(index); }
} }
}
// Update to handle multiple PIDs // Update to handle multiple PIDs
public void SetTrackedPid(int pid) public void SetTrackedPid(int pid) {
{ if (pid == 0) // Special case: 0 means stop tracking all
if (pid == 0) // Special case: 0 means stop tracking all {
{ this._trackedPids.Clear();
this._trackedPids.Clear(); return;
return; }
}
if (this._trackedPids.Contains(pid)) if (this._trackedPids.Contains(pid)) {
{ this._trackedPids.Remove(pid); // Toggle off if already tracking
this._trackedPids.Remove(pid); // Toggle off if already tracking } else {
} this._trackedPids.Add(pid); // Toggle on if not tracking
else }
{ }
this._trackedPids.Add(pid); // Toggle on if not tracking
}
}
// Update to return currently tracked PID (for compatibility) // Update to return currently tracked PID (for compatibility)
public int GetTrackedPid() public int GetTrackedPid() {
{ // Return the first tracked PID, or 0 if none
// Return the first tracked PID, or 0 if none return this._trackedPids.FirstOrDefault();
return this._trackedPids.FirstOrDefault(); }
}
// Add method to get all tracked PIDs if needed // Add method to get all tracked PIDs if needed
public IReadOnlyCollection<int> GetTrackedPids() public IReadOnlyCollection<int> GetTrackedPids() {
{ return this._trackedPids;
return this._trackedPids; }
} }
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -5,321 +5,278 @@ using System.Runtime.InteropServices;
using EveOPreview.Configuration; using EveOPreview.Configuration;
using EveOPreview.Services.Interop; using EveOPreview.Services.Interop;
namespace EveOPreview.Services.Implementation namespace EveOPreview.Services.Implementation {
{ public class WindowManager : IWindowManager {
public class WindowManager : IWindowManager #region Private constants
{ private const int WINDOW_SIZE_THRESHOLD = 300;
#region Private constants private const int NO_ANIMATION = 0;
private const int WINDOW_SIZE_THRESHOLD = 300; #endregion
private const int NO_ANIMATION = 0;
#endregion
#region Private fields #region Private fields
private readonly bool _enableWineCompatabilityMode; private readonly bool _enableWineCompatabilityMode;
private string _bashLocation; private string _bashLocation;
private string _wmctrlLocation; private string _wmctrlLocation;
private const string EXCEPTION_DUMP_FILE_NAME = "EVE-O-Preview.log"; private const string EXCEPTION_DUMP_FILE_NAME = "EVE-O-Preview.log";
#endregion #endregion
public WindowManager(IThumbnailConfiguration configuration) {
public WindowManager(IThumbnailConfiguration configuration)
{
#if LINUX #if LINUX
this._enableWineCompatabilityMode = configuration.EnableWineCompatibilityMode; this._enableWineCompatabilityMode = configuration.EnableWineCompatibilityMode;
this._bashLocation = FindLinuxBinLocation("bash"); this._bashLocation = FindLinuxBinLocation("bash");
this._wmctrlLocation = FindLinuxBinLocation("wmctrl"); this._wmctrlLocation = FindLinuxBinLocation("wmctrl");
#endif #endif
// Composition is always enabled for Windows 8+ // Composition is always enabled for Windows 8+
this.IsCompositionEnabled = this.IsCompositionEnabled =
((Environment.OSVersion.Version.Major == 6) && (Environment.OSVersion.Version.Minor >= 2)) // Win 8 and Win 8.1 ((Environment.OSVersion.Version.Major == 6) &&
|| (Environment.OSVersion.Version.Major >= 10) // Win 10 (Environment.OSVersion.Version.Minor >= 2)) // Win 8 and Win 8.1
|| DwmNativeMethods.DwmIsCompositionEnabled(); // In case of Win 7 an API call is requiredWin 7 || (Environment.OSVersion.Version.Major >= 10) // Win 10
_animationParam.cbSize = (System.UInt32)Marshal.SizeOf(typeof(ANIMATIONINFO)); || DwmNativeMethods.DwmIsCompositionEnabled(); // In case of Win 7 an API call is requiredWin 7
} _animationParam.cbSize = (System.UInt32)Marshal.SizeOf(typeof(ANIMATIONINFO));
}
#if LINUX #if LINUX
private string FindLinuxBinLocation(string command) private string FindLinuxBinLocation(string command) {
{ // Check common paths for command
// Check common paths for command string[] paths = { "/run/host/usr/bin", "/bin", "/usr/bin" };
string[] paths = { "/run/host/usr/bin", "/bin", "/usr/bin" }; foreach (var path in paths) {
foreach (var path in paths) string locationToCheck = $"{path}/{command}";
{ if (System.IO.File.Exists(locationToCheck)) {
string locationToCheck = $"{path}/{command}"; string binLocation = System.IO.Path.GetDirectoryName(locationToCheck);
if (System.IO.File.Exists(locationToCheck)) string binLocationUnixStyle = binLocation.Replace("\\", "/");
{
string binLocation = System.IO.Path.GetDirectoryName(locationToCheck);
string binLocationUnixStyle = binLocation.Replace("\\", "/");
return binLocationUnixStyle; return binLocationUnixStyle;
} }
} }
WriteToLog($"[{DateTime.Now}] Error: {command} not found in expected locations."); WriteToLog($"[{DateTime.Now}] Error: {command} not found in expected locations.");
return null; return null;
} }
#endif #endif
private void WriteToLog(string message) private void WriteToLog(string message) {
{ try {
try System.IO.File.AppendAllText(EXCEPTION_DUMP_FILE_NAME, message + Environment.NewLine);
{ } catch (Exception ex) {
System.IO.File.AppendAllText(EXCEPTION_DUMP_FILE_NAME, message + Environment.NewLine); Console.WriteLine($"Failed to write to log file: {ex.Message}");
} }
catch (Exception ex) }
{
Console.WriteLine($"Failed to write to log file: {ex.Message}");
}
}
private int? _currentAnimationSetting = null; private int? _currentAnimationSetting = null;
private ANIMATIONINFO _animationParam = new ANIMATIONINFO(); private ANIMATIONINFO _animationParam = new ANIMATIONINFO();
public bool IsCompositionEnabled { get; } public bool IsCompositionEnabled { get; }
public IntPtr GetForegroundWindowHandle() public IntPtr GetForegroundWindowHandle() {
{ return User32NativeMethods.GetForegroundWindow();
return User32NativeMethods.GetForegroundWindow(); }
}
private void TurnOffAnimation() private void TurnOffAnimation() {
{ var currentAnimationSetup = User32NativeMethods.SystemParametersInfo(
var currentAnimationSetup = User32NativeMethods.SystemParametersInfo(User32NativeMethods.SPI_GETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)), ref _animationParam, 0); User32NativeMethods.SPI_GETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)),
if (_currentAnimationSetting == null) ref _animationParam, 0);
{ if (_currentAnimationSetting == null) {
// Store the current Animation Setting // Store the current Animation Setting
_currentAnimationSetting = _animationParam.iMinAnimate; _currentAnimationSetting = _animationParam.iMinAnimate;
} }
if (currentAnimationSetup != NO_ANIMATION) if (currentAnimationSetup != NO_ANIMATION) {
{ // Turn off Animation
// Turn off Animation _animationParam.iMinAnimate = NO_ANIMATION;
_animationParam.iMinAnimate = NO_ANIMATION; var animationOffReturn = User32NativeMethods.SystemParametersInfo(
var animationOffReturn = User32NativeMethods.SystemParametersInfo(User32NativeMethods.SPI_SETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)), ref _animationParam, 0); User32NativeMethods.SPI_SETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)),
} ref _animationParam, 0);
} }
}
private void RestoreAnimation() private void RestoreAnimation() {
{ var currentAnimationSetup = User32NativeMethods.SystemParametersInfo(
var currentAnimationSetup = User32NativeMethods.SystemParametersInfo(User32NativeMethods.SPI_GETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)), ref _animationParam, 0); User32NativeMethods.SPI_GETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)),
// Restore current Animation Settings ref _animationParam, 0);
if (_animationParam.iMinAnimate != (int)_currentAnimationSetting) // Restore current Animation Settings
{ if (_animationParam.iMinAnimate != (int)_currentAnimationSetting) {
_animationParam.iMinAnimate = (int)_currentAnimationSetting; _animationParam.iMinAnimate = (int)_currentAnimationSetting;
var animationResetReturn = User32NativeMethods.SystemParametersInfo(User32NativeMethods.SPI_SETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)), ref _animationParam, 0); var animationResetReturn = User32NativeMethods.SystemParametersInfo(
} User32NativeMethods.SPI_SETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)),
} ref _animationParam, 0);
}
}
// if building for LINUX the window handling is slightly different // if building for LINUX the window handling is slightly different
#if LINUX #if LINUX
private void WindowsActivateWindow(IntPtr handle) private void WindowsActivateWindow(IntPtr handle) {
{ User32NativeMethods.SetForegroundWindow(handle);
User32NativeMethods.SetForegroundWindow(handle); User32NativeMethods.SetFocus(handle);
User32NativeMethods.SetFocus(handle);
int style = User32NativeMethods.GetWindowLong(handle, InteropConstants.GWL_STYLE); int style = User32NativeMethods.GetWindowLong(handle, InteropConstants.GWL_STYLE);
if ((style & InteropConstants.WS_MINIMIZE) == InteropConstants.WS_MINIMIZE) if ((style & InteropConstants.WS_MINIMIZE) == InteropConstants.WS_MINIMIZE) {
{ User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_RESTORE);
User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_RESTORE); }
} }
}
private void WineActivateWindow(string windowName) private void WineActivateWindow(string windowName) {
{ // On Wine it is not possible to manipulate windows directly.
// On Wine it is not possible to manipulate windows directly. // They are managed by native Window Manager
// They are managed by native Window Manager // So a separate command-line utility is used
// So a separate command-line utility is used if (string.IsNullOrEmpty(windowName)) {
if (string.IsNullOrEmpty(windowName)) return;
{ }
return;
}
string cmd = ""; string cmd = "";
try try {
{
// If we are in a flatpak, then use flatpak-spawn to run wmctrl outside the sandbox // If we are in a flatpak, then use flatpak-spawn to run wmctrl outside the sandbox
if (Environment.GetEnvironmentVariable("container") == "flatpak") if (Environment.GetEnvironmentVariable("container") == "flatpak") {
{
cmd = $"-c \"flatpak-spawn --host wmctrl -a \"\"" + windowName + "\"\"\""; cmd = $"-c \"flatpak-spawn --host wmctrl -a \"\"" + windowName + "\"\"\"";
} } else {
else
{
cmd = $"-c \"{this._wmctrlLocation}/wmctrl -a \"\"" + windowName + "\"\"\""; cmd = $"-c \"{this._wmctrlLocation}/wmctrl -a \"\"" + windowName + "\"\"\"";
} }
// Configure and start the process // Configure and start the process
var processStartInfo = new System.Diagnostics.ProcessStartInfo var processStartInfo =
{ new System.Diagnostics.ProcessStartInfo { FileName = $"{this._bashLocation}/bash", Arguments = cmd,
FileName = $"{this._bashLocation}/bash", UseShellExecute = false, CreateNoWindow = false };
Arguments = cmd,
UseShellExecute = false,
CreateNoWindow = false
};
using (var process = System.Diagnostics.Process.Start(processStartInfo)) using (var process = System.Diagnostics.Process.Start(processStartInfo)) {
{ process.WaitForExit();
process.WaitForExit(); }
} } catch (Exception ex) {
} WriteToLog($"[{DateTime.Now}] executing wmctrl - Exception: {ex.Message}");
catch (Exception ex)
{
WriteToLog($"[{DateTime.Now}] executing wmctrl - Exception: {ex.Message}");
}
}
public void ActivateWindow(IntPtr handle, string windowName)
{
if (this._enableWineCompatabilityMode)
{
this.WineActivateWindow(windowName);
} }
else }
{
public void ActivateWindow(IntPtr handle, string windowName) {
if (this._enableWineCompatabilityMode) {
this.WineActivateWindow(windowName);
} else {
this.WindowsActivateWindow(handle); this.WindowsActivateWindow(handle);
} }
} }
public void MinimizeWindow(IntPtr handle, bool enableAnimation) public void MinimizeWindow(IntPtr handle, bool enableAnimation) {
{ if (enableAnimation) {
if (enableAnimation) User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND, InteropConstants.SC_MINIMIZE,
{ 0);
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND, InteropConstants.SC_MINIMIZE, 0); } else {
} WINDOWPLACEMENT param = new WINDOWPLACEMENT();
else param.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
{ User32NativeMethods.GetWindowPlacement(handle, ref param);
WINDOWPLACEMENT param = new WINDOWPLACEMENT(); param.showCmd = WINDOWPLACEMENT.SW_MINIMIZE;
param.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT)); User32NativeMethods.SetWindowPlacement(handle, ref param);
User32NativeMethods.GetWindowPlacement(handle, ref param); }
param.showCmd = WINDOWPLACEMENT.SW_MINIMIZE; }
User32NativeMethods.SetWindowPlacement(handle, ref param);
}
}
#endif #endif
#if WINDOWS #if WINDOWS
public void ActivateWindow(IntPtr handle, AnimationStyle animation) public void ActivateWindow(IntPtr handle, AnimationStyle animation) {
{ User32NativeMethods.SetForegroundWindow(handle);
User32NativeMethods.SetForegroundWindow(handle); User32NativeMethods.SetFocus(handle);
User32NativeMethods.SetFocus(handle);
int style = User32NativeMethods.GetWindowLong(handle, InteropConstants.GWL_STYLE); int style = User32NativeMethods.GetWindowLong(handle, InteropConstants.GWL_STYLE);
if ((style & InteropConstants.WS_MINIMIZE) == InteropConstants.WS_MINIMIZE) if ((style & InteropConstants.WS_MINIMIZE) == InteropConstants.WS_MINIMIZE) {
{ switch (animation) {
switch (animation) case AnimationStyle.OriginalAnimation:
{ User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_RESTORE);
case AnimationStyle.OriginalAnimation: break;
User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_RESTORE); case AnimationStyle.NoAnimation:
break; TurnOffAnimation();
case AnimationStyle.NoAnimation: User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_RESTORE);
TurnOffAnimation(); RestoreAnimation();
User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_RESTORE); break;
RestoreAnimation(); }
break; }
}
}
}
public void MinimizeWindow(IntPtr handle, AnimationStyle animation, bool enableAnimation)
{
if (enableAnimation)
{
switch (animation)
{
case AnimationStyle.OriginalAnimation:
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND, InteropConstants.SC_MINIMIZE, 0);
break;
case AnimationStyle.NoAnimation:
TurnOffAnimation();
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND, InteropConstants.SC_MINIMIZE, 0);
RestoreAnimation();
break;
}
}
else
{
switch (animation)
{
case AnimationStyle.OriginalAnimation:
WINDOWPLACEMENT param = new WINDOWPLACEMENT();
param.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
User32NativeMethods.GetWindowPlacement(handle, ref param);
param.showCmd = WINDOWPLACEMENT.SW_MINIMIZE;
User32NativeMethods.SetWindowPlacement(handle, ref param);
break;
case AnimationStyle.NoAnimation:
TurnOffAnimation();
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND, InteropConstants.SC_MINIMIZE, 0);
RestoreAnimation();
break;
}
}
}
#endif
public void MoveWindow(IntPtr handle, int left, int top, int width, int height)
{
User32NativeMethods.MoveWindow(handle, left, top, width, height, true);
}
public void MaximizeWindow(IntPtr handle)
{
User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_SHOWMAXIMIZED);
} }
public (int Left, int Top, int Right, int Bottom) GetWindowPosition(IntPtr handle) public void MinimizeWindow(IntPtr handle, AnimationStyle animation, bool enableAnimation) {
{ if (enableAnimation) {
User32NativeMethods.GetWindowRect(handle, out RECT windowRectangle); switch (animation) {
case AnimationStyle.OriginalAnimation:
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND,
InteropConstants.SC_MINIMIZE, 0);
break;
case AnimationStyle.NoAnimation:
TurnOffAnimation();
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND,
InteropConstants.SC_MINIMIZE, 0);
RestoreAnimation();
break;
}
} else {
switch (animation) {
case AnimationStyle.OriginalAnimation:
WINDOWPLACEMENT param = new WINDOWPLACEMENT();
param.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
User32NativeMethods.GetWindowPlacement(handle, ref param);
param.showCmd = WINDOWPLACEMENT.SW_MINIMIZE;
User32NativeMethods.SetWindowPlacement(handle, ref param);
break;
case AnimationStyle.NoAnimation:
TurnOffAnimation();
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND,
InteropConstants.SC_MINIMIZE, 0);
RestoreAnimation();
break;
}
}
}
#endif
return (windowRectangle.Left, windowRectangle.Top, windowRectangle.Right, windowRectangle.Bottom); public void MoveWindow(IntPtr handle, int left, int top, int width, int height) {
} User32NativeMethods.MoveWindow(handle, left, top, width, height, true);
}
public bool IsWindowMaximized(IntPtr handle) public void MaximizeWindow(IntPtr handle) {
{ User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_SHOWMAXIMIZED);
return User32NativeMethods.IsZoomed(handle); }
}
public bool IsWindowMinimized(IntPtr handle) public (int Left, int Top, int Right, int Bottom) GetWindowPosition(IntPtr handle) {
{ User32NativeMethods.GetWindowRect(handle, out RECT windowRectangle);
return User32NativeMethods.IsIconic(handle);
}
public IDwmThumbnail GetLiveThumbnail(IntPtr destination, IntPtr source) return (windowRectangle.Left, windowRectangle.Top, windowRectangle.Right, windowRectangle.Bottom);
{ }
IDwmThumbnail thumbnail = new DwmThumbnail(this);
thumbnail.Register(destination, source);
return thumbnail; public bool IsWindowMaximized(IntPtr handle) {
} return User32NativeMethods.IsZoomed(handle);
}
public Image GetStaticThumbnail(IntPtr source) public bool IsWindowMinimized(IntPtr handle) {
{ return User32NativeMethods.IsIconic(handle);
var sourceContext = User32NativeMethods.GetDC(source); }
User32NativeMethods.GetClientRect(source, out RECT windowRect); public IDwmThumbnail GetLiveThumbnail(IntPtr destination, IntPtr source) {
IDwmThumbnail thumbnail = new DwmThumbnail(this);
thumbnail.Register(destination, source);
var width = windowRect.Right - windowRect.Left; return thumbnail;
var height = windowRect.Bottom - windowRect.Top; }
// Check if there is anything to make thumbnail of public Image GetStaticThumbnail(IntPtr source) {
if ((width < WINDOW_SIZE_THRESHOLD) || (height < WINDOW_SIZE_THRESHOLD)) var sourceContext = User32NativeMethods.GetDC(source);
{
return null;
}
var destContext = Gdi32NativeMethods.CreateCompatibleDC(sourceContext); User32NativeMethods.GetClientRect(source, out RECT windowRect);
var bitmap = Gdi32NativeMethods.CreateCompatibleBitmap(sourceContext, width, height);
var oldBitmap = Gdi32NativeMethods.SelectObject(destContext, bitmap); var width = windowRect.Right - windowRect.Left;
Gdi32NativeMethods.BitBlt(destContext, 0, 0, width, height, sourceContext, 0, 0, Gdi32NativeMethods.SRCCOPY); var height = windowRect.Bottom - windowRect.Top;
Gdi32NativeMethods.SelectObject(destContext, oldBitmap);
Gdi32NativeMethods.DeleteDC(destContext);
User32NativeMethods.ReleaseDC(source, sourceContext);
Image image = Image.FromHbitmap(bitmap); // Check if there is anything to make thumbnail of
Gdi32NativeMethods.DeleteObject(bitmap); if ((width < WINDOW_SIZE_THRESHOLD) || (height < WINDOW_SIZE_THRESHOLD)) {
return null;
}
return image; var destContext = Gdi32NativeMethods.CreateCompatibleDC(sourceContext);
} var bitmap = Gdi32NativeMethods.CreateCompatibleBitmap(sourceContext, width, height);
}
var oldBitmap = Gdi32NativeMethods.SelectObject(destContext, bitmap);
Gdi32NativeMethods.BitBlt(destContext, 0, 0, width, height, sourceContext, 0, 0,
Gdi32NativeMethods.SRCCOPY);
Gdi32NativeMethods.SelectObject(destContext, oldBitmap);
Gdi32NativeMethods.DeleteDC(destContext);
User32NativeMethods.ReleaseDC(source, sourceContext);
Image image = Image.FromHbitmap(bitmap);
Gdi32NativeMethods.DeleteObject(bitmap);
return image;
}
}
} }

View File

@@ -1,13 +1,13 @@
using System; using System;
namespace EveOPreview.Services namespace EveOPreview.Services {
{ public interface IDwmThumbnail {
public interface IDwmThumbnail void Register(IntPtr destination, IntPtr source);
{ void Unregister();
void Register(IntPtr destination, IntPtr source);
void Unregister();
void Move(int left, int top, int right, int bottom); void Move(int left, int top, int right, int bottom);
void Update(); void SetSourceRegion(int left, int top, int right, int bottom);
} void ClearSourceRegion();
void Update();
}
} }

View File

@@ -1,10 +1,8 @@
using System; using System;
namespace EveOPreview.Services namespace EveOPreview.Services {
{ public interface IProcessInfo {
public interface IProcessInfo IntPtr Handle { get; }
{ string Title { get; }
IntPtr Handle { get; } }
string Title { get; }
}
} }

View File

@@ -1,13 +1,13 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace EveOPreview.Services namespace EveOPreview.Services {
{ public interface IProcessMonitor {
public interface IProcessMonitor IProcessInfo GetMainProcess();
{ ICollection<IProcessInfo> GetAllProcesses();
IProcessInfo GetMainProcess(); void GetUpdatedProcesses(out ICollection<IProcessInfo> addedProcesses,
ICollection<IProcessInfo> GetAllProcesses(); out ICollection<IProcessInfo> updatedProcesses,
void GetUpdatedProcesses(out ICollection<IProcessInfo> addedProcesses, out ICollection<IProcessInfo> updatedProcesses, out ICollection<IProcessInfo> removedProcesses); out ICollection<IProcessInfo> removedProcesses);
int GetTrackedPid(); int GetTrackedPid();
void SetTrackedPid(int pid); void SetTrackedPid(int pid);
} }
} }

View File

@@ -1,17 +1,17 @@
using EveOPreview.View; using EveOPreview.View;
namespace EveOPreview.Services namespace EveOPreview.Services {
{ public interface IThumbnailManager {
public interface IThumbnailManager void Start();
{ void Stop();
void Start();
void Stop();
void UpdateThumbnailsSize(); void UpdateThumbnailsSize();
void UpdateThumbnailFrames(); void UpdateThumbnailFrames();
void UpdateThumbnailRegionSettings();
void ReRegisterHotkeys();
IThumbnailView GetClientByTitle(string title); IThumbnailView GetClientByTitle(string title);
IThumbnailView GetClientByPointer(System.IntPtr ptr); IThumbnailView GetClientByPointer(System.IntPtr ptr);
IThumbnailView GetActiveClient(); IThumbnailView GetActiveClient();
} }
} }

View File

@@ -2,25 +2,23 @@
using System; using System;
using System.Drawing; using System.Drawing;
namespace EveOPreview.Services namespace EveOPreview.Services {
{ public interface IWindowManager {
public interface IWindowManager bool IsCompositionEnabled { get; }
{
bool IsCompositionEnabled { get; }
IntPtr GetForegroundWindowHandle(); IntPtr GetForegroundWindowHandle();
#if LINUX #if LINUX
void ActivateWindow(IntPtr handle, string windowName); void ActivateWindow(IntPtr handle, string windowName);
#else #else
void ActivateWindow(IntPtr handle, AnimationStyle animation); void ActivateWindow(IntPtr handle, AnimationStyle animation);
#endif #endif
void MinimizeWindow(IntPtr handle, AnimationStyle animation, bool enableAnimation); void MinimizeWindow(IntPtr handle, AnimationStyle animation, bool enableAnimation);
void MoveWindow(IntPtr handle, int left, int top, int width, int height); void MoveWindow(IntPtr handle, int left, int top, int width, int height);
void MaximizeWindow(IntPtr handle); void MaximizeWindow(IntPtr handle);
(int Left, int Top, int Right, int Bottom) GetWindowPosition(IntPtr handle); (int Left, int Top, int Right, int Bottom) GetWindowPosition(IntPtr handle);
bool IsWindowMaximized(IntPtr handle); bool IsWindowMaximized(IntPtr handle);
bool IsWindowMinimized(IntPtr handle); bool IsWindowMinimized(IntPtr handle);
IDwmThumbnail GetLiveThumbnail(IntPtr destination, IntPtr source); IDwmThumbnail GetLiveThumbnail(IntPtr destination, IntPtr source);
Image GetStaticThumbnail(IntPtr source); Image GetStaticThumbnail(IntPtr source);
} }
} }

View File

@@ -1,83 +1,81 @@
using System; using System;
namespace EveOPreview.Services namespace EveOPreview.Services {
{ public static class InteropConstants {
public static class InteropConstants public const int GWL_ID = (-12);
{ public const int GWL_STYLE = (-16);
public const int GWL_ID = (-12); public const int GWL_EXSTYLE = (-20);
public const int GWL_STYLE = (-16);
public const int GWL_EXSTYLE = (-20);
// Window Styles // Window Styles
public const UInt32 WS_OVERLAPPED = 0; public const UInt32 WS_OVERLAPPED = 0;
public const UInt32 WS_POPUP = 0x80000000; public const UInt32 WS_POPUP = 0x80000000;
public const UInt32 WS_CHILD = 0x40000000; public const UInt32 WS_CHILD = 0x40000000;
public const UInt32 WS_MINIMIZE = 0x20000000; public const UInt32 WS_MINIMIZE = 0x20000000;
public const UInt32 WS_VISIBLE = 0x10000000; public const UInt32 WS_VISIBLE = 0x10000000;
public const UInt32 WS_DISABLED = 0x8000000; public const UInt32 WS_DISABLED = 0x8000000;
public const UInt32 WS_CLIPSIBLINGS = 0x4000000; public const UInt32 WS_CLIPSIBLINGS = 0x4000000;
public const UInt32 WS_CLIPCHILDREN = 0x2000000; public const UInt32 WS_CLIPCHILDREN = 0x2000000;
public const UInt32 WS_MAXIMIZE = 0x1000000; public const UInt32 WS_MAXIMIZE = 0x1000000;
public const UInt32 WS_CAPTION = 0xC00000; // WS_BORDER or WS_DLGFRAME public const UInt32 WS_CAPTION = 0xC00000; // WS_BORDER or WS_DLGFRAME
public const UInt32 WS_BORDER = 0x800000; public const UInt32 WS_BORDER = 0x800000;
public const UInt32 WS_DLGFRAME = 0x400000; public const UInt32 WS_DLGFRAME = 0x400000;
public const UInt32 WS_VSCROLL = 0x200000; public const UInt32 WS_VSCROLL = 0x200000;
public const UInt32 WS_HSCROLL = 0x100000; public const UInt32 WS_HSCROLL = 0x100000;
public const UInt32 WS_SYSMENU = 0x80000; public const UInt32 WS_SYSMENU = 0x80000;
public const UInt32 WS_THICKFRAME = 0x40000; public const UInt32 WS_THICKFRAME = 0x40000;
public const UInt32 WS_GROUP = 0x20000; public const UInt32 WS_GROUP = 0x20000;
public const UInt32 WS_TABSTOP = 0x10000; public const UInt32 WS_TABSTOP = 0x10000;
public const UInt32 WS_MINIMIZEBOX = 0x20000; public const UInt32 WS_MINIMIZEBOX = 0x20000;
public const UInt32 WS_MAXIMIZEBOX = 0x10000; public const UInt32 WS_MAXIMIZEBOX = 0x10000;
public const UInt32 WS_TILED = WS_OVERLAPPED; public const UInt32 WS_TILED = WS_OVERLAPPED;
public const UInt32 WS_ICONIC = WS_MINIMIZE; public const UInt32 WS_ICONIC = WS_MINIMIZE;
public const UInt32 WS_SIZEBOX = WS_THICKFRAME; public const UInt32 WS_SIZEBOX = WS_THICKFRAME;
// Extended Window Styles // Extended Window Styles
public const UInt32 WS_EX_DLGMODALFRAME = 0x0001; public const UInt32 WS_EX_DLGMODALFRAME = 0x0001;
public const UInt32 WS_EX_NOPARENTNOTIFY = 0x0004; public const UInt32 WS_EX_NOPARENTNOTIFY = 0x0004;
public const UInt32 WS_EX_TOPMOST = 0x0008; public const UInt32 WS_EX_TOPMOST = 0x0008;
public const UInt32 WS_EX_ACCEPTFILES = 0x0010; public const UInt32 WS_EX_ACCEPTFILES = 0x0010;
public const UInt32 WS_EX_TRANSPARENT = 0x0020; public const UInt32 WS_EX_TRANSPARENT = 0x0020;
public const UInt32 WS_EX_MDICHILD = 0x0040; public const UInt32 WS_EX_MDICHILD = 0x0040;
public const UInt32 WS_EX_TOOLWINDOW = 0x0080; public const UInt32 WS_EX_TOOLWINDOW = 0x0080;
public const UInt32 WS_EX_WINDOWEDGE = 0x0100; public const UInt32 WS_EX_WINDOWEDGE = 0x0100;
public const UInt32 WS_EX_CLIENTEDGE = 0x0200; public const UInt32 WS_EX_CLIENTEDGE = 0x0200;
public const UInt32 WS_EX_CONTEXTHELP = 0x0400; public const UInt32 WS_EX_CONTEXTHELP = 0x0400;
public const UInt32 WS_EX_RIGHT = 0x1000; public const UInt32 WS_EX_RIGHT = 0x1000;
public const UInt32 WS_EX_LEFT = 0x0000; public const UInt32 WS_EX_LEFT = 0x0000;
public const UInt32 WS_EX_RTLREADING = 0x2000; public const UInt32 WS_EX_RTLREADING = 0x2000;
public const UInt32 WS_EX_LTRREADING = 0x0000; public const UInt32 WS_EX_LTRREADING = 0x0000;
public const UInt32 WS_EX_LEFTSCROLLBAR = 0x4000; public const UInt32 WS_EX_LEFTSCROLLBAR = 0x4000;
public const UInt32 WS_EX_RIGHTSCROLLBAR = 0x0000; public const UInt32 WS_EX_RIGHTSCROLLBAR = 0x0000;
public const UInt32 WS_EX_CONTROLPARENT = 0x10000; public const UInt32 WS_EX_CONTROLPARENT = 0x10000;
public const UInt32 WS_EX_STATICEDGE = 0x20000; public const UInt32 WS_EX_STATICEDGE = 0x20000;
public const UInt32 WS_EX_APPWINDOW = 0x40000; public const UInt32 WS_EX_APPWINDOW = 0x40000;
public const UInt32 WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE); public const UInt32 WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE);
public const UInt32 WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST); public const UInt32 WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST);
public const UInt32 WS_EX_LAYERED = 0x00080000; public const UInt32 WS_EX_LAYERED = 0x00080000;
public const UInt32 WS_EX_NOINHERITLAYOUT = 0x00100000; // Disable inheritance of mirroring by children public const UInt32 WS_EX_NOINHERITLAYOUT = 0x00100000; // Disable inheritance of mirroring by children
public const UInt32 WS_EX_LAYOUTRTL = 0x00400000; // Right to left mirroring public const UInt32 WS_EX_LAYOUTRTL = 0x00400000; // Right to left mirroring
public const UInt32 WS_EX_COMPOSITED = 0x02000000; public const UInt32 WS_EX_COMPOSITED = 0x02000000;
public const UInt32 WS_EX_NOACTIVATE = 0x08000000; public const UInt32 WS_EX_NOACTIVATE = 0x08000000;
public const int WM_SIZE = 5; public const int WM_SIZE = 5;
public const int WM_SYSCOMMAND = 0x0112; public const int WM_SYSCOMMAND = 0x0112;
public const int SC_MINIMIZE = 0xf020; public const int SC_MINIMIZE = 0xf020;
public const int SIZE_RESTORED = 0; public const int SIZE_RESTORED = 0;
public const int SIZE_MINIMIZED = 1; public const int SIZE_MINIMIZED = 1;
public const int SIZE_MAXIMIZED = 2; public const int SIZE_MAXIMIZED = 2;
public const int SIZE_MAXSHOW = 3; public const int SIZE_MAXSHOW = 3;
public const int SIZE_MAXHIDE = 4; public const int SIZE_MAXHIDE = 4;
public const int WM_NCLBUTTONDOWN = 0xA1; public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HTCAPTION = 0x2; public const int HTCAPTION = 0x2;
public const int SW_SHOWNORMAL = 1; public const int SW_SHOWNORMAL = 1;
public const int SW_SHOWMINIMIZED = 2; public const int SW_SHOWMINIMIZED = 2;
public const int SW_SHOWMAXIMIZED = 3; public const int SW_SHOWMAXIMIZED = 3;
public const int SW_RESTORE = 9; public const int SW_RESTORE = 9;
} }
} }

View File

@@ -1,12 +1,10 @@
using MediatR; using MediatR;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{
// Definition for Window Placement Structure // Definition for Window Placement Structure
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
struct ANIMATIONINFO struct ANIMATIONINFO {
{
public uint cbSize; public uint cbSize;
public int iMinAnimate; public int iMinAnimate;
} }

View File

@@ -1,20 +1,18 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{ [StructLayout(LayoutKind.Sequential)]
[StructLayout(LayoutKind.Sequential)] class DWM_BLURBEHIND {
class DWM_BLURBEHIND public uint dwFlags;
{ [MarshalAs(UnmanagedType.Bool)]
public uint dwFlags; public bool fEnable;
[MarshalAs(UnmanagedType.Bool)] public IntPtr hRegionBlur;
public bool fEnable; [MarshalAs(UnmanagedType.Bool)]
public IntPtr hRegionBlur; public bool fTransitionOnMaximized;
[MarshalAs(UnmanagedType.Bool)]
public bool fTransitionOnMaximized;
public const uint DWM_BB_ENABLE = 0x00000001; public const uint DWM_BB_ENABLE = 0x00000001;
public const uint DWM_BB_BLURREGION = 0x00000002; public const uint DWM_BB_BLURREGION = 0x00000002;
public const uint DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004; public const uint DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004;
} }
} }

View File

@@ -1,17 +1,15 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{ [StructLayout(LayoutKind.Sequential)]
[StructLayout(LayoutKind.Sequential)] class DWM_THUMBNAIL_PROPERTIES {
class DWM_THUMBNAIL_PROPERTIES public uint dwFlags;
{ public RECT rcDestination;
public uint dwFlags; public RECT rcSource;
public RECT rcDestination; public byte opacity;
public RECT rcSource; [MarshalAs(UnmanagedType.Bool)]
public byte opacity; public bool fVisible;
[MarshalAs(UnmanagedType.Bool)] [MarshalAs(UnmanagedType.Bool)]
public bool fVisible; public bool fSourceClientAreaOnly;
[MarshalAs(UnmanagedType.Bool)] }
public bool fSourceClientAreaOnly;
}
} }

View File

@@ -1,11 +1,9 @@
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{ static class DWM_TNP_CONSTANTS {
static class DWM_TNP_CONSTANTS public const uint DWM_TNP_RECTDESTINATION = 0x00000001;
{ public const uint DWM_TNP_RECTSOURCE = 0x00000002;
public const uint DWM_TNP_RECTDESTINATION = 0x00000001; public const uint DWM_TNP_OPACITY = 0x00000004;
public const uint DWM_TNP_RECTSOURCE = 0x00000002; public const uint DWM_TNP_VISIBLE = 0x00000008;
public const uint DWM_TNP_OPACITY = 0x00000004; public const uint DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010;
public const uint DWM_TNP_VISIBLE = 0x00000008; }
public const uint DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010;
}
} }

View File

@@ -2,37 +2,34 @@ using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Drawing; using System.Drawing;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{ static class DwmNativeMethods {
static class DwmNativeMethods [DllImport("dwmapi.dll", PreserveSig = false)]
{ public static extern void DwmEnableBlurBehindWindow(IntPtr hWnd, DWM_BLURBEHIND pBlurBehind);
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmEnableBlurBehindWindow(IntPtr hWnd, DWM_BLURBEHIND pBlurBehind);
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, MARGINS pMargins); public static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, MARGINS pMargins);
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
public static extern bool DwmIsCompositionEnabled(); public static extern bool DwmIsCompositionEnabled();
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmGetColorizationColor( public static extern void DwmGetColorizationColor(out int pcrColorization,
out int pcrColorization, [MarshalAs(UnmanagedType.Bool)] out bool pfOpaqueBlend);
[MarshalAs(UnmanagedType.Bool)]out bool pfOpaqueBlend);
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmEnableComposition(bool bEnable); public static extern void DwmEnableComposition(bool bEnable);
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
public static extern IntPtr DwmRegisterThumbnail(IntPtr dest, IntPtr source); public static extern IntPtr DwmRegisterThumbnail(IntPtr dest, IntPtr source);
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmUnregisterThumbnail(IntPtr hThumbnail); public static extern void DwmUnregisterThumbnail(IntPtr hThumbnail);
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmUpdateThumbnailProperties(IntPtr hThumbnail, DWM_THUMBNAIL_PROPERTIES props); public static extern void DwmUpdateThumbnailProperties(IntPtr hThumbnail, DWM_THUMBNAIL_PROPERTIES props);
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmQueryThumbnailSourceSize(IntPtr hThumbnail, out Size size); public static extern void DwmQueryThumbnailSourceSize(IntPtr hThumbnail, out Size size);
} }
} }

View File

@@ -1,28 +1,27 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{ static class Gdi32NativeMethods {
static class Gdi32NativeMethods public const int SRCCOPY = 13369376;
{
public const int SRCCOPY = 13369376;
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc); public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
public static extern bool DeleteDC(IntPtr hdc); public static extern bool DeleteDC(IntPtr hdc);
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int width, int height); public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int width, int height);
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject); public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject);
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject); public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjectSource, int nXSrc, int nYSrc, int dwRop); public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight,
} IntPtr hObjectSource, int nXSrc, int nYSrc, int dwRop);
}
} }

View File

@@ -1,21 +1,18 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{ [StructLayout(LayoutKind.Sequential)]
[StructLayout(LayoutKind.Sequential)] class MARGINS {
class MARGINS public int cxLeftWidth;
{ public int cxRightWidth;
public int cxLeftWidth; public int cyTopHeight;
public int cxRightWidth; public int cyBottomHeight;
public int cyTopHeight;
public int cyBottomHeight;
public MARGINS(int left, int top, int right, int bottom) public MARGINS(int left, int top, int right, int bottom) {
{ cxLeftWidth = left;
cxLeftWidth = left; cyTopHeight = top;
cyTopHeight = top; cxRightWidth = right;
cxRightWidth = right; cyBottomHeight = bottom;
cyBottomHeight = bottom; }
} }
}
} }

View File

@@ -1,21 +1,18 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{ [StructLayout(LayoutKind.Sequential)]
[StructLayout(LayoutKind.Sequential)] struct RECT {
struct RECT public int Left;
{ public int Top;
public int Left; public int Right;
public int Top; public int Bottom;
public int Right;
public int Bottom;
public RECT(int left, int top, int right, int bottom) public RECT(int left, int top, int right, int bottom) {
{ this.Left = left;
this.Left = left; this.Top = top;
this.Top = top; this.Right = right;
this.Right = right; this.Bottom = bottom;
this.Bottom = bottom; }
} }
}
} }

View File

@@ -1,70 +1,69 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{ static class User32NativeMethods {
static class User32NativeMethods public const uint SPI_SETANIMATION = 0x0049;
{ public const uint SPI_GETANIMATION = 0x0048;
public const uint SPI_SETANIMATION = 0x0049;
public const uint SPI_GETANIMATION = 0x0048;
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow(); public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr window); public static extern bool SetForegroundWindow(IntPtr window);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern void SetFocus(IntPtr window); public static extern void SetFocus(IntPtr window);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern void EnableWindow(IntPtr window, bool isEnabled); public static extern void EnableWindow(IntPtr window, bool isEnabled);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("User32.dll")] [DllImport("User32.dll")]
public static extern bool ReleaseCapture(); public static extern bool ReleaseCapture();
[DllImport("User32.dll")] [DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImport("user32.dll", SetLastError = true)] [DllImport("user32.dll", SetLastError = true)]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex); public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern int GetWindowRect(IntPtr hWnd, out RECT rect); public static extern int GetWindowRect(IntPtr hWnd, out RECT rect);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool GetClientRect(IntPtr hWnd, out RECT rect); public static extern bool GetClientRect(IntPtr hWnd, out RECT rect);
[DllImport("user32.dll", SetLastError = true)] [DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)] [return:MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl); public static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
[DllImport("user32.dll")] [DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)] [return:MarshalAs(UnmanagedType.Bool)]
public static extern bool IsIconic(IntPtr hWnd); public static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool IsZoomed(IntPtr hWnd); public static extern bool IsZoomed(IntPtr hWnd);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd); public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr hWnd); public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hdc); public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hdc);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern long SystemParametersInfo(long uAction, int lpvParam, ref ANIMATIONINFO uParam, int fuWinIni); public static extern long SystemParametersInfo(long uAction, int lpvParam, ref ANIMATIONINFO uParam,
} int fuWinIni);
}
} }

View File

@@ -1,30 +1,28 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{ // Definition for Window Placement Structure
//Definition for Window Placement Structure [StructLayout(LayoutKind.Sequential)]
[StructLayout(LayoutKind.Sequential)] struct WINDOWPLACEMENT {
struct WINDOWPLACEMENT public int length;
{ public int flags;
public int length; public int showCmd;
public int flags; public System.Drawing.Point ptMinPosition;
public int showCmd; public System.Drawing.Point ptMaxPosition;
public System.Drawing.Point ptMinPosition; public System.Drawing.Rectangle rcNormalPosition;
public System.Drawing.Point ptMaxPosition;
public System.Drawing.Rectangle rcNormalPosition;
//Definitions For Different Window Placement Constants // Definitions For Different Window Placement Constants
public const int SW_HIDE = 0; public const int SW_HIDE = 0;
public const int SW_SHOWNORMAL = 1; public const int SW_SHOWNORMAL = 1;
public const int SW_NORMAL = 1; public const int SW_NORMAL = 1;
public const int SW_SHOWMINIMIZED = 2; public const int SW_SHOWMINIMIZED = 2;
public const int SW_SHOWMAXIMIZED = 3; public const int SW_SHOWMAXIMIZED = 3;
public const int SW_MAXIMIZE = 3; public const int SW_MAXIMIZE = 3;
public const int SW_SHOWNOACTIVATE = 4; public const int SW_SHOWNOACTIVATE = 4;
public const int SW_SHOW = 5; public const int SW_SHOW = 5;
public const int SW_MINIMIZE = 6; public const int SW_MINIMIZE = 6;
public const int SW_SHOWMINNOACTIVE = 7; public const int SW_SHOWMINNOACTIVE = 7;
public const int SW_SHOWNA = 8; public const int SW_SHOWNA = 8;
public const int SW_RESTORE = 9; public const int SW_RESTORE = 9;
} }
} }

View File

@@ -0,0 +1,71 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace EveOPreview.View.Implementation {
public partial class InputDialog : Form {
private TextBox _inputTextBox;
private Button _okButton;
private Button _cancelButton;
private Label _promptLabel;
public string InputText => _inputTextBox.Text;
public InputDialog(string title, string prompt) {
InitializeComponent();
this.Text = title;
_promptLabel.Text = prompt;
}
private void InitializeComponent() {
this._promptLabel = new Label();
this._inputTextBox = new TextBox();
this._okButton = new Button();
this._cancelButton = new Button();
this.SuspendLayout();
// Form
this.AcceptButton = this._okButton;
this.CancelButton = this._cancelButton;
this.ClientSize = new Size(300, 120);
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.StartPosition = FormStartPosition.CenterParent;
// Prompt Label
this._promptLabel.AutoSize = true;
this._promptLabel.Location = new Point(12, 15);
this._promptLabel.Size = new Size(35, 15);
this._promptLabel.Text = "Prompt:";
// Input TextBox
this._inputTextBox.Location = new Point(12, 35);
this._inputTextBox.Size = new Size(270, 23);
this._inputTextBox.TabIndex = 0;
// OK Button
this._okButton.DialogResult = DialogResult.OK;
this._okButton.Location = new Point(120, 70);
this._okButton.Size = new Size(75, 23);
this._okButton.TabIndex = 1;
this._okButton.Text = "OK";
// Cancel Button
this._cancelButton.DialogResult = DialogResult.Cancel;
this._cancelButton.Location = new Point(210, 70);
this._cancelButton.Size = new Size(75, 23);
this._cancelButton.TabIndex = 2;
this._cancelButton.Text = "Cancel";
// Controls
this.Controls.Add(this._promptLabel);
this.Controls.Add(this._inputTextBox);
this.Controls.Add(this._okButton);
this.Controls.Add(this._cancelButton);
this.ResumeLayout(false);
this.PerformLayout();
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -3,61 +3,76 @@ using System.Drawing;
using EveOPreview.Configuration; using EveOPreview.Configuration;
using EveOPreview.Services; using EveOPreview.Services;
namespace EveOPreview.View namespace EveOPreview.View {
{ sealed class LiveThumbnailView : ThumbnailView {
sealed class LiveThumbnailView : ThumbnailView #region Private fields
{ private IDwmThumbnail _thumbnail;
#region Private fields private Point _startLocation;
private IDwmThumbnail _thumbnail; private Point _endLocation;
private Point _startLocation; private IThumbnailConfiguration _config;
private Point _endLocation; #endregion
private IThumbnailConfiguration _config;
#endregion
public LiveThumbnailView(IWindowManager windowManager, IThumbnailConfiguration config, IThumbnailManager thumbnailManager) public LiveThumbnailView(IWindowManager windowManager, IThumbnailConfiguration config,
: base(windowManager, config, thumbnailManager) IThumbnailManager thumbnailManager)
{ : base(windowManager, config, thumbnailManager) {
this._startLocation = new Point(0, 0); this._startLocation = new Point(0, 0);
this._endLocation = new Point(this.ClientSize); this._endLocation = new Point(this.ClientSize);
this._config = config; this._config = config;
} }
protected override void RefreshThumbnail(bool forceRefresh) protected override void RefreshThumbnail(bool forceRefresh) {
{ // To prevent flickering the old broken thumbnail is removed AFTER the new shiny one is created
// To prevent flickering the old broken thumbnail is removed AFTER the new shiny one is created IDwmThumbnail obsoleteThumbnail = forceRefresh ? this._thumbnail : null;
IDwmThumbnail obsoleteThumbnail = forceRefresh ? this._thumbnail : null;
if ((this._thumbnail == null) || forceRefresh) if ((this._thumbnail == null) || forceRefresh) {
{ this.RegisterThumbnail();
this.RegisterThumbnail(); }
}
obsoleteThumbnail?.Unregister(); obsoleteThumbnail?.Unregister();
} }
protected override void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop, int highlightWidthRight, int highlightWidthBottom, int highlightWidthLeft) protected override void ApplyRegionSettings() {
{ if (this._thumbnail == null)
var left = 0 + highlightWidthLeft; return;
var top = 0 + highlightWidthTop;
var right = baseWidth - highlightWidthRight;
var bottom = baseHeight - highlightWidthBottom;
if ((this._startLocation.X == left) && (this._startLocation.Y == top) && (this._endLocation.X == right) && (this._endLocation.Y == bottom)) if (this._config.EnableThumbnailRegionSnipping) {
{ var region = this._config.GetThumbnailRegion(this.Title, this._config.DefaultThumbnailRegion);
return; // No update required if (region.Width > 0 && region.Height > 0) {
} this._thumbnail.SetSourceRegion(region.Left, region.Top, region.Right, region.Bottom);
this._startLocation = new Point(left, top); } else {
this._endLocation = new Point(right, bottom); this._thumbnail.ClearSourceRegion();
}
} else {
this._thumbnail.ClearSourceRegion();
}
this._thumbnail.Move(left, top, right, bottom); this._thumbnail.Update();
this._thumbnail.Update(); }
}
private void RegisterThumbnail() protected override void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop,
{ int highlightWidthRight, int highlightWidthBottom,
this._thumbnail = this.WindowManager.GetLiveThumbnail(this.Handle, this.Id); int highlightWidthLeft) {
this._thumbnail.Move(this._startLocation.X, this._startLocation.Y, this._endLocation.X, this._endLocation.Y); var left = 0 + highlightWidthLeft;
this._thumbnail.Update(); var top = 0 + highlightWidthTop;
} var right = baseWidth - highlightWidthRight;
} var bottom = baseHeight - highlightWidthBottom;
if ((this._startLocation.X == left) && (this._startLocation.Y == top) && (this._endLocation.X == right) &&
(this._endLocation.Y == bottom)) {
return; // No update required
}
this._startLocation = new Point(left, top);
this._endLocation = new Point(right, bottom);
this._thumbnail.Move(left, top, right, bottom);
this._thumbnail.Update();
}
private void RegisterThumbnail() {
this._thumbnail = this.WindowManager.GetLiveThumbnail(this.Handle, this.Id);
this._thumbnail.Move(this._startLocation.X, this._startLocation.Y, this._endLocation.X,
this._endLocation.Y);
this._thumbnail.Update();
}
}
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
@@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->
@@ -117,85 +117,84 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <metadata name="RestoreWindowMenuItem.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<data name="RestoreWindowMenuItem.GenerateMember" type="System.Boolean, mscorlib">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="ExitMenuItem.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="ExitMenuItem.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="TitleMenuItem.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="TitleMenuItem.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="SeparatorMenuItem.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="SeparatorMenuItem.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="ContentTabControl.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="ContentTabControl.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="GeneralTabPage.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="GeneralTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="GeneralSettingsPanel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="GeneralSettingsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="label4.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="label4.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="ThumbnailTabPage.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="ThumbnailTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="ThumbnailSettingsPanel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="ThumbnailSettingsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="HeigthLabel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="HeigthLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="WidthLabel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="WidthLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="OpacityLabel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="OpacityLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="ZoomSettingsPanel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="ZoomSettingsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="ZoomFactorLabel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="ZoomFactorLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="ZoomAnchorLabel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="ZoomAnchorLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="OverlayTabPage.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="OverlayTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="OverlaySettingsPanel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="OverlaySettingsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="ClientsTabPage.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="ClientsTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="ClientsPanel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="ClientsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="ThumbnailsListLabel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="ThumbnailsListLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="AboutTabPage.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="AboutTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="AboutPanel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="AboutPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="CreditMaintLabel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="CreditMaintLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="DocumentationLinkLabel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="DocumentationLinkLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="DescriptionLabel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="DescriptionLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<data name="DescriptionLabel.Text" xml:space="preserve"> <data name="DescriptionLabel.Text" xml:space="preserve">
<value>An advanced task switcher for EVE Online clients. <value>An advanced task switcher for EVE Online clients.
@@ -206,16 +205,16 @@ The program does NOT
• interact with EVE Online except of; • interact with EVE Online except of;
- resizing or bringing it to the foreground</value> - resizing or bringing it to the foreground</value>
</data> </data>
<data name="NameLabel.GenerateMember" type="System.Boolean, mscorlib"> <metadata name="NameLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</data> </metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <metadata name="NotifyIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<data name="NotifyIcon.TrayLocation" type="System.Drawing.Point, System.Drawing">
<value>17, 17</value> <value>17, 17</value>
</data> </metadata>
<data name="TrayMenu.TrayLocation" type="System.Drawing.Point, System.Drawing"> <metadata name="TrayMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>123, 17</value> <value>123, 17</value>
</data> </metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="NotifyIcon.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="NotifyIcon.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
AAABAAQAEBAAAAEAIABoBAAARgAAACAgAAABACAAqBAAAK4EAAAwMAAAAQAgAKglAABWFQAAQEAAAAEA AAABAAQAEBAAAAEAIABoBAAARgAAACAgAAABACAAqBAAAK4EAAAwMAAAAQAgAKglAABWFQAAQEAAAAEA
@@ -754,9 +753,9 @@ The program does NOT
Af//4AAAAAAH///wAAAAAA////gAAAAAH////gAAAAB/////AAAAAP/////AAAAD/////+AAAAf//w== Af//4AAAAAAH///wAAAAAA////gAAAAAH////gAAAAB/////AAAAAP/////AAAAD/////+AAAAf//w==
</value> </value>
</data> </data>
<data name="$this.TrayHeight" type="System.Int32, mscorlib"> <metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>36</value> <value>36</value>
</data> </metadata>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
AAABAAQAEBAAAAEAIABoBAAARgAAACAgAAABACAAqBAAAK4EAAAwMAAAAQAgAKglAABWFQAAQEAAAAEA AAABAAQAEBAAAAEAIABoBAAARgAAACAgAAABACAAqBAAAK4EAAAwMAAAAQAgAKglAABWFQAAQEAAAAEA
@@ -1295,35 +1294,4 @@ The program does NOT
Af//4AAAAAAH///wAAAAAA////gAAAAAH////gAAAAB/////AAAAAP/////AAAAD/////+AAAAf//w== Af//4AAAAAAH///wAAAAAA////gAAAAAH////gAAAAB/////AAAAAP/////AAAAD/////+AAAAf//w==
</value> </value>
</data> </data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="IconOriginal" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\..\original-icon.ico;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="IconAmber" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\..\Icons\EVE-O_Amber.ico;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="IconBlue" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\..\Icons\EVE-O_Blue.ico;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="IconCherry" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\..\Icons\EVE-O_Cherry.ico;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="IconDal" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\..\Icons\EVE-O_Dal.ico;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="IconDark" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\..\Icons\EVE-O_Dark.ico;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="IconDefault" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\..\Icons\EVE-O_Default.ico;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="IconMint" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\..\Icons\EVE-O_Mint.ico;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="IconPurple" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\..\Icons\EVE-O_Purple.ico;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="IconUrns" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\..\Icons\EVE-O_urns.ico;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
</root> </root>

View File

@@ -0,0 +1,40 @@
namespace EveOPreview.View.Implementation {
partial class RegionPickerDialog {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
this.SuspendLayout();
//
// RegionPickerDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Name = "RegionPickerDialog";
this.Text = "Region Picker";
this.ResumeLayout(false);
}
#endregion
}
}

View File

@@ -0,0 +1,136 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace EveOPreview.View.Implementation {
public partial class RegionPickerDialog : Form {
private Point _startPoint;
private Point _endPoint;
private bool _isDrawing;
private Rectangle _selectedRegion;
public Rectangle SelectedRegion => _selectedRegion;
public RegionPickerDialog() {
InitializeComponent();
InitializeDialog();
}
private void InitializeDialog() {
// Make the form cover all screens
Rectangle totalBounds = GetTotalScreenBounds();
this.Bounds = totalBounds;
this.StartPosition = FormStartPosition.Manual;
this.FormBorderStyle = FormBorderStyle.None;
this.WindowState = FormWindowState.Maximized;
this.TopMost = true;
this.ShowInTaskbar = false;
this.Cursor = Cursors.Cross;
// Make the form semi-transparent but not fully transparent
this.BackColor = Color.Black;
this.Opacity = 0.3;
// Add event handlers
this.MouseDown += RegionPickerDialog_MouseDown;
this.MouseMove += RegionPickerDialog_MouseMove;
this.MouseUp += RegionPickerDialog_MouseUp;
this.KeyDown += RegionPickerDialog_KeyDown;
this.Paint += RegionPickerDialog_Paint;
// Add instructions label
var instructionsLabel = new Label { Text = "Click and drag to select a region. Press ESC to cancel.",
ForeColor = Color.White,
BackColor = Color.Black,
Font = new Font("Arial", 12, FontStyle.Bold),
AutoSize = true,
Location = new Point(10, 10) };
this.Controls.Add(instructionsLabel);
}
private Rectangle GetTotalScreenBounds() {
Rectangle bounds = Screen.PrimaryScreen.Bounds;
foreach (Screen screen in Screen.AllScreens) {
bounds = Rectangle.Union(bounds, screen.Bounds);
}
return bounds;
}
private void RegionPickerDialog_MouseDown(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
_startPoint = e.Location;
_isDrawing = true;
this.Capture = true;
this.Invalidate();
}
}
private void RegionPickerDialog_MouseMove(object sender, MouseEventArgs e) {
if (_isDrawing) {
_endPoint = e.Location;
this.Invalidate();
}
}
private void RegionPickerDialog_MouseUp(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left && _isDrawing) {
_isDrawing = false;
_endPoint = e.Location;
this.Capture = false;
// Calculate the selected region
int x = Math.Min(_startPoint.X, _endPoint.X);
int y = Math.Min(_startPoint.Y, _endPoint.Y);
int width = Math.Abs(_endPoint.X - _startPoint.X);
int height = Math.Abs(_endPoint.Y - _startPoint.Y);
if (width > 10 && height > 10) // Minimum size
{
_selectedRegion = new Rectangle(x, y, width, height);
this.DialogResult = DialogResult.OK;
this.Close();
} else {
// Reset if region is too small
_startPoint = Point.Empty;
_endPoint = Point.Empty;
this.Invalidate();
}
}
}
private void RegionPickerDialog_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.Escape) {
this.DialogResult = DialogResult.Cancel;
this.Close();
}
}
private void RegionPickerDialog_Paint(object sender, PaintEventArgs e) {
if (_isDrawing) {
// Draw selection rectangle
using (Pen pen = new Pen(Color.Red, 2)) {
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
int x = Math.Min(_startPoint.X, _endPoint.X);
int y = Math.Min(_startPoint.Y, _endPoint.Y);
int width = Math.Abs(_endPoint.X - _startPoint.X);
int height = Math.Abs(_endPoint.Y - _startPoint.Y);
e.Graphics.DrawRectangle(pen, x, y, width, height);
}
// Draw size information
if (_startPoint != Point.Empty && _endPoint != Point.Empty) {
int width = Math.Abs(_endPoint.X - _startPoint.X);
int height = Math.Abs(_endPoint.Y - _startPoint.Y);
string sizeText = $"{width} x {height}";
using (Font font = new Font("Arial", 10, FontStyle.Bold)) using (Brush brush =
new SolidBrush(Color.White)) {
e.Graphics.DrawString(sizeText, font, brush, _endPoint.X + 5, _endPoint.Y + 5);
}
}
}
}
}
}

View File

@@ -1,23 +1,17 @@
using System; using System;
using System.Windows.Forms; using System.Windows.Forms;
namespace EveOPreview.View namespace EveOPreview.View {
{ sealed class StaticThumbnailImage : PictureBox {
sealed class StaticThumbnailImage : PictureBox protected override void WndProc(ref Message m) {
{ const int WM_NCHITTEST = 0x0084;
protected override void WndProc(ref Message m) const int HTTRANSPARENT = (-1);
{
const int WM_NCHITTEST = 0x0084;
const int HTTRANSPARENT = (-1);
if (m.Msg == WM_NCHITTEST) if (m.Msg == WM_NCHITTEST) {
{ m.Result = (IntPtr)HTTRANSPARENT;
m.Result = (IntPtr)HTTRANSPARENT; } else {
} base.WndProc(ref m);
else }
{ }
base.WndProc(ref m); }
}
}
}
} }

View File

@@ -4,70 +4,93 @@ using System.Windows.Forms;
using EveOPreview.Configuration; using EveOPreview.Configuration;
using EveOPreview.Services; using EveOPreview.Services;
namespace EveOPreview.View namespace EveOPreview.View {
{ sealed class StaticThumbnailView : ThumbnailView {
sealed class StaticThumbnailView : ThumbnailView #region Private fields
{ private readonly PictureBox _thumbnail;
#region Private fields private IThumbnailConfiguration _config;
private readonly PictureBox _thumbnail; #endregion
private IThumbnailConfiguration _config;
#endregion
public StaticThumbnailView(IWindowManager windowManager, IThumbnailConfiguration config, IThumbnailManager thumbnailManager) public StaticThumbnailView(IWindowManager windowManager, IThumbnailConfiguration config,
: base(windowManager, config, thumbnailManager) IThumbnailManager thumbnailManager)
{ : base(windowManager, config, thumbnailManager) {
this._thumbnail = new StaticThumbnailImage this._thumbnail =
{ new StaticThumbnailImage { TabStop = false, SizeMode = PictureBoxSizeMode.StretchImage,
TabStop = false, Location = new Point(0, 0),
SizeMode = PictureBoxSizeMode.StretchImage, Size = new Size(this.ClientSize.Width, this.ClientSize.Height) };
Location = new Point(0, 0), this.Controls.Add(this._thumbnail);
Size = new Size(this.ClientSize.Width, this.ClientSize.Height) this._config = config;
}; }
this.Controls.Add(this._thumbnail);
this._config = config;
}
protected override void RefreshThumbnail(bool forceRefresh) protected override void RefreshThumbnail(bool forceRefresh) {
{ if (!forceRefresh) {
if (!forceRefresh) return;
{ }
return;
}
var thumbnail = this.WindowManager.GetStaticThumbnail(this.Id); var thumbnail = this.WindowManager.GetStaticThumbnail(this.Id);
if (thumbnail != null) if (thumbnail != null) {
{ var oldImage = this._thumbnail.Image;
var oldImage = this._thumbnail.Image; this._thumbnail.Image = thumbnail;
this._thumbnail.Image = thumbnail; oldImage?.Dispose();
oldImage?.Dispose(); }
} }
}
protected override void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop, int highlightWidthRight, int highlightWidthBottom, int highlightWidthLeft) protected override void ApplyRegionSettings() {
{ if (this._thumbnail.Image == null)
var left = 0 + highlightWidthLeft; return;
var top = 0 + highlightWidthTop;
if (this.IsLocationUpdateRequired(this._thumbnail.Location, left, top))
{
this._thumbnail.Location = new Point(left, top);
}
var width = baseWidth - highlightWidthLeft - highlightWidthRight; if (this._config.EnableThumbnailRegionSnipping) {
var height = baseHeight - highlightWidthTop - highlightWidthBottom; var region = this._config.GetThumbnailRegion(this.Title, this._config.DefaultThumbnailRegion);
if (this.IsSizeUpdateRequired(this._thumbnail.Size, width, height)) if (region.Width > 0 && region.Height > 0) {
{ // Crop the image to the specified region
this._thumbnail.Size = new Size(width, height); var croppedImage = CropImage((Image)this._thumbnail.Image, region);
} var oldImage = this._thumbnail.Image;
} this._thumbnail.Image = croppedImage;
oldImage?.Dispose();
}
}
}
private bool IsLocationUpdateRequired(Point currentLocation, int left, int top) private Image CropImage(Image sourceImage, Rectangle region) {
{ // Ensure the region is within the image bounds
return (currentLocation.X != left) || (currentLocation.Y != top); var imageRect = new Rectangle(0, 0, sourceImage.Width, sourceImage.Height);
} var cropRect = Rectangle.Intersect(region, imageRect);
private bool IsSizeUpdateRequired(Size currentSize, int width, int height) if (cropRect.Width <= 0 || cropRect.Height <= 0) {
{ return sourceImage; // Return original if region is invalid
return (currentSize.Width != width) || (currentSize.Height != height); }
}
} var croppedImage = new Bitmap(cropRect.Width, cropRect.Height);
using (var graphics = Graphics.FromImage(croppedImage)) {
graphics.DrawImage(sourceImage, new Rectangle(0, 0, cropRect.Width, cropRect.Height), cropRect,
GraphicsUnit.Pixel);
}
return croppedImage;
}
protected override void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop,
int highlightWidthRight, int highlightWidthBottom,
int highlightWidthLeft) {
var left = 0 + highlightWidthLeft;
var top = 0 + highlightWidthTop;
if (this.IsLocationUpdateRequired(this._thumbnail.Location, left, top)) {
this._thumbnail.Location = new Point(left, top);
}
var width = baseWidth - highlightWidthLeft - highlightWidthRight;
var height = baseHeight - highlightWidthTop - highlightWidthBottom;
if (this.IsSizeUpdateRequired(this._thumbnail.Size, width, height)) {
this._thumbnail.Size = new Size(width, height);
}
}
private bool IsLocationUpdateRequired(Point currentLocation, int left, int top) {
return (currentLocation.X != left) || (currentLocation.Y != top);
}
private bool IsSizeUpdateRequired(Size currentSize, int width, int height) {
return (currentSize.Width != width) || (currentSize.Height != height);
}
}
} }

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -1,14 +1,11 @@
namespace EveOPreview.View namespace EveOPreview.View {
{ sealed class ThumbnailDescription : IThumbnailDescription {
sealed class ThumbnailDescription : IThumbnailDescription public ThumbnailDescription(string title, bool isDisabled) {
{ this.Title = title;
public ThumbnailDescription(string title, bool isDisabled) this.IsDisabled = isDisabled;
{ }
this.Title = title;
this.IsDisabled = isDisabled;
}
public string Title { get; set; } public string Title { get; set; }
public bool IsDisabled { get; set; } public bool IsDisabled { get; set; }
} }
} }

View File

@@ -1,90 +1,85 @@
namespace EveOPreview.View namespace EveOPreview.View {
{ partial class ThumbnailOverlay {
partial class ThumbnailOverlay /// <summary>
{ /// Required designer variable.
/// <summary> /// </summary>
/// Required designer variable. private System.ComponentModel.IContainer components = null;
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary> /// <summary>
/// Clean up any resources being used. /// Clean up any resources being used.
/// </summary> /// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing) {
{ if (disposing && (components != null)) {
if (disposing && (components != null)) components.Dispose();
{ }
components.Dispose(); base.Dispose(disposing);
} }
base.Dispose(disposing);
}
#region Windows Form Designer generated code #region Windows Form Designer generated code
/// <summary> /// <summary>
/// Required method for Designer support - do not modify /// Required method for Designer support - do not modify
/// the contents of this method with the code editor. /// the contents of this method with the code editor.
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent() {
{ System.Windows.Forms.PictureBox OverlayAreaPictureBox;
System.Windows.Forms.PictureBox OverlayAreaPictureBox; this.OverlayLabel = new System.Windows.Forms.Label();
this.OverlayLabel = new System.Windows.Forms.Label(); OverlayAreaPictureBox = new System.Windows.Forms.PictureBox();
OverlayAreaPictureBox = new System.Windows.Forms.PictureBox(); ((System.ComponentModel.ISupportInitialize)(OverlayAreaPictureBox)).BeginInit();
((System.ComponentModel.ISupportInitialize)(OverlayAreaPictureBox)).BeginInit(); this.SuspendLayout();
this.SuspendLayout(); //
// // OverlayAreaPictureBox
// OverlayAreaPictureBox //
// OverlayAreaPictureBox.BackColor = System.Drawing.Color.Transparent;
OverlayAreaPictureBox.BackColor = System.Drawing.Color.Transparent; OverlayAreaPictureBox.Cursor = System.Windows.Forms.Cursors.Hand;
OverlayAreaPictureBox.Cursor = System.Windows.Forms.Cursors.Hand; OverlayAreaPictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
OverlayAreaPictureBox.Dock = System.Windows.Forms.DockStyle.Fill; OverlayAreaPictureBox.Location = new System.Drawing.Point(0, 0);
OverlayAreaPictureBox.Location = new System.Drawing.Point(0, 0); OverlayAreaPictureBox.Name = "OverlayAreaPictureBox";
OverlayAreaPictureBox.Name = "OverlayAreaPictureBox"; OverlayAreaPictureBox.Size = new System.Drawing.Size(284, 262);
OverlayAreaPictureBox.Size = new System.Drawing.Size(284, 262); OverlayAreaPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
OverlayAreaPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; OverlayAreaPictureBox.TabIndex = 0;
OverlayAreaPictureBox.TabIndex = 0; OverlayAreaPictureBox.TabStop = false;
OverlayAreaPictureBox.TabStop = false; OverlayAreaPictureBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OverlayArea_Click);
OverlayAreaPictureBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OverlayArea_Click); //
// // OverlayLabel
// OverlayLabel //
// this.OverlayLabel.AutoSize = true;
this.OverlayLabel.AutoSize = true; this.OverlayLabel.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular,
this.OverlayLabel.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.OverlayLabel.ForeColor = System.Drawing.Color.DarkGray; this.OverlayLabel.ForeColor = System.Drawing.Color.DarkGray;
this.OverlayLabel.Location = new System.Drawing.Point(8, 8); this.OverlayLabel.Location = new System.Drawing.Point(8, 8);
this.OverlayLabel.Name = "OverlayLabel"; this.OverlayLabel.Name = "OverlayLabel";
this.OverlayLabel.Size = new System.Drawing.Size(25, 13); this.OverlayLabel.Size = new System.Drawing.Size(25, 13);
this.OverlayLabel.TabIndex = 1; this.OverlayLabel.TabIndex = 1;
this.OverlayLabel.Text = "..."; this.OverlayLabel.Text = "...";
this.OverlayLabel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OverlayArea_Click); this.OverlayLabel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OverlayArea_Click);
// //
// ThumbnailOverlay // ThumbnailOverlay
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackColor = System.Drawing.Color.Black; this.BackColor = System.Drawing.Color.Black;
this.ClientSize = new System.Drawing.Size(284, 262); this.ClientSize = new System.Drawing.Size(284, 262);
this.ControlBox = false; this.ControlBox = false;
this.Controls.Add(this.OverlayLabel); this.Controls.Add(this.OverlayLabel);
this.Controls.Add(OverlayAreaPictureBox); this.Controls.Add(OverlayAreaPictureBox);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.MaximizeBox = false; this.MaximizeBox = false;
this.MinimizeBox = false; this.MinimizeBox = false;
this.Name = "ThumbnailOverlay"; this.Name = "ThumbnailOverlay";
this.ShowIcon = false; this.ShowIcon = false;
this.ShowInTaskbar = false; this.ShowInTaskbar = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.Text = "PreviewOverlay"; this.Text = "PreviewOverlay";
this.TransparencyKey = System.Drawing.Color.Black; this.TransparencyKey = System.Drawing.Color.Black;
((System.ComponentModel.ISupportInitialize)(OverlayAreaPictureBox)).EndInit(); ((System.ComponentModel.ISupportInitialize)(OverlayAreaPictureBox)).EndInit();
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();
}
} #endregion
#endregion private System.Windows.Forms.Label OverlayLabel;
}
private System.Windows.Forms.Label OverlayLabel;
}
} }

View File

@@ -3,49 +3,41 @@ using System.Windows.Forms;
using EveOPreview.Configuration; using EveOPreview.Configuration;
using EveOPreview.Services; using EveOPreview.Services;
namespace EveOPreview.View namespace EveOPreview.View {
{ public partial class ThumbnailOverlay : Form {
public partial class ThumbnailOverlay : Form #region Private fields
{ private readonly Action<object, MouseEventArgs> _areaClickAction;
#region Private fields #endregion
private readonly Action<object, MouseEventArgs> _areaClickAction;
#endregion
public ThumbnailOverlay(Form owner, Action<object, MouseEventArgs> areaClickAction) public ThumbnailOverlay(Form owner, Action<object, MouseEventArgs> areaClickAction) {
{ this.Owner = owner;
this.Owner = owner; this._areaClickAction = areaClickAction;
this._areaClickAction = areaClickAction;
InitializeComponent(); InitializeComponent();
} }
private void OverlayArea_Click(object sender, MouseEventArgs e) private void OverlayArea_Click(object sender, MouseEventArgs e) {
{ this._areaClickAction(this, e);
this._areaClickAction(this, e); }
}
public void SetOverlayLabel(string label) public void SetOverlayLabel(string label) {
{ this.OverlayLabel.Text = label;
this.OverlayLabel.Text = label; }
}
public void SetPropertiesOverlayLabel(int size, System.Drawing.Color c, ZoomAnchor anchor) public void SetPropertiesOverlayLabel(int size, System.Drawing.Color c, ZoomAnchor anchor) {
{ if (this.OverlayLabel.Font.Size != size) {
if (this.OverlayLabel.Font.Size != size) this.OverlayLabel.Font = new System.Drawing.Font(this.OverlayLabel.Font.FontFamily, size);
{ }
this.OverlayLabel.Font = new System.Drawing.Font(this.OverlayLabel.Font.FontFamily, size); this.OverlayLabel.ForeColor = c;
}
this.OverlayLabel.ForeColor = c;
int margin = 5; int margin = 5;
switch (anchor) switch (anchor) {
{ case ZoomAnchor.NW:
case ZoomAnchor.NW: this.OverlayLabel.Left = margin;
this.OverlayLabel.Left = margin; this.OverlayLabel.Top = margin;
this.OverlayLabel.Top = margin; this.OverlayLabel.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.OverlayLabel.TextAlign = System.Drawing.ContentAlignment.TopLeft; break;
break;
case ZoomAnchor.N: case ZoomAnchor.N:
this.OverlayLabel.Left = (this.Width / 2) - (this.OverlayLabel.Width / 2); this.OverlayLabel.Left = (this.Width / 2) - (this.OverlayLabel.Width / 2);
this.OverlayLabel.Top = margin; this.OverlayLabel.Top = margin;
@@ -87,21 +79,18 @@ namespace EveOPreview.View
this.OverlayLabel.TextAlign = System.Drawing.ContentAlignment.BottomRight; this.OverlayLabel.TextAlign = System.Drawing.ContentAlignment.BottomRight;
break; break;
} }
} }
public void EnableOverlayLabel(bool enable) public void EnableOverlayLabel(bool enable) {
{ this.OverlayLabel.Visible = enable;
this.OverlayLabel.Visible = enable; }
}
protected override CreateParams CreateParams protected override CreateParams CreateParams {
{ get {
get var Params = base.CreateParams;
{ Params.ExStyle |= (int)InteropConstants.WS_EX_TOOLWINDOW;
var Params = base.CreateParams; return Params;
Params.ExStyle |= (int)InteropConstants.WS_EX_TOOLWINDOW; }
return Params; }
} }
}
}
} }

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