Compare commits

...

32 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
554ed6098a Make ctrl-F16 track one window (instead of executable) 2025-06-27 02:24:54 +02:00
5373ba8cfe Fix up the title to be an iterated ID rather than PID 2025-06-26 22:18:56 +02:00
e1e223a097 Get rid of some unused shit 2025-06-26 22:01:21 +02:00
86a761fe96 Make ctrl-F16 register windows actually 2025-06-26 18:15:29 +02:00
eabda5da67 Make CTRL-T track windows with scroll lock on 2025-06-26 17:56:44 +02:00
435710c350 Make track wow 2025-06-04 17:33:27 +02:00
Izakbar
2ed6d10f3d #89 FileVersion not updating on build 2025-05-22 20:32:53 +01:00
Izakbar
ba308616d3 #88 re-ActivateWindow after minimize of previous window - as sometimes windows leaves the active window pointer on wrong window 2025-05-21 13:00:32 +01:00
DalShooth
d5527c1392 Merge pull request #83 from Proopai/bugfix/63-forum-url-causes-crash
Bugfix/63 forum url causes crash
2025-04-24 16:44:55 -07:00
Izakbar
703dbd0d47 Merge branch 'bugfix/63-forum-url-causes-crash' of https://github.com/Proopai/eve-o-preview into bugfix/63-forum-url-causes-crash 2025-04-24 23:50:18 +01:00
Izakbar
13cb0f0692 #63 fix click on forum url to display webpage as dotnet core 8 does not work the same as prior 2025-04-24 23:49:56 +01:00
Izakbar
84ad093f06 #63 fix click on forum url to display webpage as dotnet core 8 does not work the same as prior 2025-02-19 20:36:15 +00:00
110 changed files with 7561 additions and 6249 deletions

3
.clang-format Normal file
View File

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

View File

@@ -26,12 +26,12 @@ jobs:
- name: Build
run: |
echo "${{matrix.platform.name}} ${{ github.event.release.tag_name }}"
dotnet build src\\Eve-O-Preview\\Eve-O-Preview.csproj --configuration Release -p:EVEOTARGET="${{matrix.platform.name}}" -p:AssemblyVersion="${{ github.event.release.tag_name }}"
dotnet build src\\Eve-O-Preview\\Eve-O-Preview.csproj --configuration Release -p:EVEOTARGET="${{matrix.platform.name}}" -p:AssemblyVersion="${{ github.event.release.tag_name }}" -p:FileVersion="${{ github.event.release.tag_name }}"
- name: BuildPackage
run: |
git log --pretty=format:'%d %s' ${GITHUB_REF} | perl -pe 's| \(.*tag: v(\d+.\d+.\d+(-preview\d{3})?)(, .*?)*\)|\n## \1\n|g'
# Build everything
dotnet publish src\\Eve-O-Preview\\Eve-O-Preview.csproj -c Release -o "Eve-O-Preview-${{ github.event.release.tag_name }}-${{ matrix.platform.name }}" -p:EVEOTARGET="${{matrix.platform.name}}" -p:AssemblyVersion="${{ github.event.release.tag_name }}" --self-contained ${{matrix.platform.self_contained}}
dotnet publish src\\Eve-O-Preview\\Eve-O-Preview.csproj -c Release -o "Eve-O-Preview-${{ github.event.release.tag_name }}-${{ matrix.platform.name }}" -p:EVEOTARGET="${{matrix.platform.name}}" -p:AssemblyVersion="${{ github.event.release.tag_name }}" -p:FileVersion="${{ github.event.release.tag_name }}" --self-contained ${{matrix.platform.self_contained}}
- name: Create archive
run: |
Compress-Archive -Path "Eve-O-Preview-${{ github.event.release.tag_name }}-${{ matrix.platform.name }}\\*" -Destination "Release-${{ github.event.release.tag_name }}-${{ matrix.platform.name }}.zip"

5
.gitignore vendored
View File

@@ -1,4 +1,3 @@
bin/
obj/
publish/
tools/
@@ -9,3 +8,7 @@ src/*/.vs/
*.DotSettings
build/Fody*
*.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;
namespace EveOMock
{
public partial class App : Application
{
}
namespace EveOMock {
public partial class App : Application {}
}

View File

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

View File

@@ -2,16 +2,14 @@
using System.Windows;
using System.Windows.Media;
namespace EveOMock
{
public partial class MainWindow : Window
{
public MainWindow()
{
namespace EveOMock {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
Random random = new Random();
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)));
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

@@ -13,8 +13,7 @@ using System.Windows;
[assembly:ComVisible(false)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
[assembly:ThemeInfo(ResourceDictionaryLocation.None, // where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly // where the generic resource dictionary is located

View File

@@ -11,7 +11,6 @@
namespace EveOMock.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
@@ -19,27 +18,29 @@ namespace EveOMock.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[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.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance",
"CA1811:AvoidUncalledPrivateCode")]
internal Resources() {}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </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 {
get {
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;
}
return resourceMan;
@@ -50,14 +51,11 @@ namespace EveOMock.Properties {
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
[global::System.ComponentModel.EditorBrowsableAttribute(
global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
get { return resourceCulture; }
set { resourceCulture = value; }
}
}
}

View File

@@ -10,17 +10,15 @@
namespace EveOMock.Properties {
[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 {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
private static Settings defaultInstance =
((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
get { return defaultInstance; }
}
}
}

View File

@@ -1,7 +1,5 @@
namespace PreviewToy
{
partial class AboutBox
{
namespace PreviewToy {
partial class AboutBox {
/// <summary>
/// Required designer variable.
/// </summary>
@@ -10,10 +8,8 @@
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
@@ -25,8 +21,7 @@
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
private void InitializeComponent() {
this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
this.logoPictureBox = new System.Windows.Forms.PictureBox();
this.labelProductName = new System.Windows.Forms.Label();
@@ -42,8 +37,10 @@
// tableLayoutPanel
//
this.tableLayoutPanel.ColumnCount = 2;
this.tableLayoutPanel.ColumnStyles.Add(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.ColumnStyles.Add(
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.labelProductName, 1, 0);
this.tableLayoutPanel.Controls.Add(this.labelVersion, 1, 1);
@@ -55,12 +52,18 @@
this.tableLayoutPanel.Location = new System.Drawing.Point(9, 9);
this.tableLayoutPanel.Name = "tableLayoutPanel";
this.tableLayoutPanel.RowCount = 6;
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, 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, 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.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, 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, 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.TabIndex = 0;
//
@@ -112,7 +115,8 @@
this.labelCopyright.TabStop = true;
this.labelCopyright.Text = "Copyright";
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
//
@@ -126,11 +130,13 @@
this.labelCompanyName.TabStop = true;
this.labelCompanyName.Text = "Company Name";
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
//
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.Location = new System.Drawing.Point(456, 464);
this.okButton.Name = "okButton";
@@ -142,7 +148,9 @@
//
this.richTextBoxDescription.BackColor = System.Drawing.SystemColors.Control;
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.Name = "richTextBoxDescription";
this.richTextBoxDescription.ReadOnly = true;
@@ -169,7 +177,6 @@
this.tableLayoutPanel.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit();
this.ResumeLayout(false);
}
#endregion

View File

@@ -7,12 +7,9 @@ using System.Linq;
using System.Reflection;
using System.Windows.Forms;
namespace PreviewToy
{
partial class AboutBox : Form
{
public AboutBox()
{
namespace PreviewToy {
partial class AboutBox : Form {
public AboutBox() {
InitializeComponent();
this.Text = String.Format("About {0}", AssemblyTitle);
this.labelProductName.Text = AssemblyProduct;
@@ -41,16 +38,14 @@ namespace PreviewToy
}
// 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";
ProcessStartInfo sInfo = new ProcessStartInfo(new Uri(url).AbsoluteUri);
Process.Start(sInfo);
}
// 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";
ProcessStartInfo sInfo = new ProcessStartInfo(new Uri(url).AbsoluteUri);
Process.Start(sInfo);
@@ -58,16 +53,13 @@ namespace PreviewToy
#region Assembly Attribute Accessors
public string AssemblyTitle
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
if (attributes.Length > 0)
{
public string AssemblyTitle {
get {
object[] attributes =
Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
if (attributes.Length > 0) {
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
if (titleAttribute.Title != "")
{
if (titleAttribute.Title != "") {
return titleAttribute.Title;
}
}
@@ -75,60 +67,48 @@ namespace PreviewToy
}
}
public string AssemblyVersion
{
get
{
return Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
public string AssemblyVersion {
get { return Assembly.GetExecutingAssembly().GetName().Version.ToString(); }
}
public string AssemblyDescription
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
if (attributes.Length == 0)
{
public string AssemblyDescription {
get {
object[] attributes =
Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
if (attributes.Length == 0) {
return "";
}
return ((AssemblyDescriptionAttribute)attributes[0]).Description;
}
}
public string AssemblyProduct
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
if (attributes.Length == 0)
{
public string AssemblyProduct {
get {
object[] attributes =
Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
if (attributes.Length == 0) {
return "";
}
return ((AssemblyProductAttribute)attributes[0]).Product;
}
}
public string AssemblyCopyright
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
if (attributes.Length == 0)
{
public string AssemblyCopyright {
get {
object[] attributes =
Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
if (attributes.Length == 0) {
return "";
}
return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
}
}
public string AssemblyCompany
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
if (attributes.Length == 0)
{
public string AssemblyCompany {
get {
object[] attributes =
Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
if (attributes.Length == 0) {
return "";
}
return ((AssemblyCompanyAttribute)attributes[0]).Company;

View File

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

View File

@@ -3,48 +3,40 @@ using System.IO;
using System.Threading;
using System.Windows.Forms;
namespace EveOPreview
{
namespace EveOPreview {
// A really very primitive exception handler stuff here
// No IoC, no fancy DI containers - just a plain exception stacktrace dump
// If this code is called then something was gone really bad
// so even the DI infrastructure might be dead already.
// 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 = "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()
{
if (System.Diagnostics.Debugger.IsAttached)
{
public void SetupExceptionHandlers() {
if (System.Diagnostics.Debugger.IsAttached) {
return;
}
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += delegate (Object sender, ThreadExceptionEventArgs e)
{
Application.ThreadException += delegate(Object sender, ThreadExceptionEventArgs e) {
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);
};
}
private void ExceptionEventHandler(Exception exception)
{
try
{
private void ExceptionEventHandler(Exception exception) {
try {
String exceptionMessage = exception.ToString();
File.WriteAllText(ExceptionHandler.EXCEPTION_DUMP_FILE_NAME, exceptionMessage);
MessageBox.Show(ExceptionHandler.EXCEPTION_MESSAGE, @"EVE-O-Preview", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch
{
MessageBox.Show(ExceptionHandler.EXCEPTION_MESSAGE, @"EVE-O-Preview", MessageBoxButtons.OK,
MessageBoxIcon.Error);
} catch {
// 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
}

View File

@@ -1,10 +1,8 @@
namespace EveOPreview
{
namespace EveOPreview {
/// <summary>
/// Application controller
/// </summary>
public interface IApplicationController
{
public interface IApplicationController {
IApplicationController RegisterView<TView, TPresenter>()
where TPresenter : class, TView
where TView : IView;
@@ -21,6 +19,4 @@
where TPresenter : class, IPresenter<TArgument>;
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.Reflection;
namespace EveOPreview
{
namespace EveOPreview {
/// <summary>
/// Generic interface for an Inversion Of Control container
/// </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>();
}
}
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
{
public interface IPresenter
{
namespace EveOPreview {
public interface IPresenter {
void Run();
}
}

View File

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

View File

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

View File

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

View File

@@ -1,21 +1,17 @@
namespace EveOPreview
{
namespace EveOPreview {
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
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.View = view;
}
public void Run()
{
public void Run() {
this.View.Show();
}
}

View File

@@ -1,15 +1,12 @@
namespace EveOPreview
{
namespace EveOPreview {
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
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.View = view;
}

View File

@@ -1,9 +1,6 @@
namespace EveOPreview.Configuration.Implementation
{
class AppConfig : IAppConfig
{
public AppConfig()
{
namespace EveOPreview.Configuration.Implementation {
class AppConfig : IAppConfig {
public AppConfig() {
// Default values
this.ConfigFileName = null;
}

View File

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

View File

@@ -5,73 +5,56 @@ using System.Linq;
using System.Windows.Forms;
using Newtonsoft.Json;
namespace EveOPreview.Configuration.Implementation
{
sealed class ThumbnailConfiguration : IThumbnailConfiguration
{
namespace EveOPreview.Configuration.Implementation {
sealed class ThumbnailConfiguration : IThumbnailConfiguration {
#region Private fields
private bool _enablePerClientThumbnailLayouts;
private bool _enableClientLayoutTracking;
#endregion
public ThumbnailConfiguration()
{
public ThumbnailConfiguration() {
this.ConfigVersion = 1;
this.CycleGroup1ForwardHotkeys = new List<string> { "F14", "Control+F14" };
this.CycleGroup1BackwardHotkeys = new List<string> { "F13", "Control+F13" };
this.CycleGroup1ClientsOrder = new Dictionary<string, int>
{
{ "EVE - Example DPS Toon 1", 1 },
{ "EVE - Example DPS Toon 2", 2 },
{ "EVE - Example DPS Toon 3", 3 }
this.CycleGroup1ClientsOrder = new Dictionary<string, int> {
{ "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.CycleGroup2BackwardHotkeys = new List<string> { "F15", "Control+F15" };
this.CycleGroup2ClientsOrder = new Dictionary<string, int>
{
{ "EVE - Example Logi Toon 1", 1 },
this.CycleGroup2ClientsOrder = new Dictionary<string, int> { { "EVE - Example Logi Toon 1", 1 },
{ "EVE - Example Scout Toon 2", 2 },
{ "EVE - Example Tackle Toon 3", 3 }
};
{ "EVE - Example Tackle Toon 3", 3 } };
this.CycleGroup3ForwardHotkeys = 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 },
};
this.CycleGroup4ForwardHotkeys = 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 },
};
this.CycleGroup5ForwardHotkeys = new List<string> { "" };
this.CycleGroup5BackwardHotkeys = new List<string> { "" };
this.CycleGroup5ClientsOrder = new Dictionary<string, int>
{
this.CycleGroup5ClientsOrder = new Dictionary<string, int> {
{ "EVE - cycle group 5", 1 },
};
this.PerClientActiveClientHighlightColor = new Dictionary<string, Color>
{
{"EVE - Example Toon 1", Color.Red},
{"EVE - Example Toon 2", Color.Green}
};
this.PerClientActiveClientHighlightColor =
new Dictionary<string, Color> { { "EVE - Example Toon 1", Color.Red },
{ "EVE - Example Toon 2", Color.Green } };
this.PerClientThumbnailSize = new Dictionary<string, Size>
{
{"EVE - Example Toon 1", new Size(200, 200)},
{"EVE - Example Toon 2", new Size(200, 200)}
};
this.PerClientThumbnailSize =
new Dictionary<string, Size> { { "EVE - Example Toon 1", new Size(200, 200) },
{ "EVE - Example Toon 2", new Size(200, 200) } };
this.PerClientZoomAnchor = new Dictionary<string, ZoomAnchor>
{
{"EVE - Example Toon 1", ZoomAnchor.N },
{"EVE - Example Toon 2", ZoomAnchor.S}
};
this.PerClientThumbnailRegion = new Dictionary<string, Rectangle>();
this.PerClientZoomAnchor = new Dictionary<string, ZoomAnchor> { { "EVE - Example Toon 1", ZoomAnchor.N },
{ "EVE - Example Toon 2", ZoomAnchor.S } };
this.PerClientLayout = new Dictionary<string, Dictionary<string, Point>>();
this.FlatLayout = new Dictionary<string, Point>();
@@ -110,6 +93,7 @@ namespace EveOPreview.Configuration.Implementation
this.ThumbnailMaximumSize = new Size(960, 540);
this.EnableThumbnailSnap = true;
this.ThumbnailSnapRange = 20;
this.ThumbnailZoomEnabled = false;
this.ThumbnailZoomFactor = 2;
@@ -131,85 +115,136 @@ namespace EveOPreview.Configuration.Implementation
this.OverlayLabelColor = Color.Orange;
this.OverlayLabelSize = 10;
this.EnableThumbnailRegionSnipping = false;
this.DefaultThumbnailRegion = new Rectangle(0, 0, 384, 216);
this.CurrentProfile = "Default";
this.AvailableProfiles = new List<string> { "Default" };
this.IconName = "";
this.LoginThumbnailLocation = new Point(5, 5);
this.ToggleTrackingHotkey = "Alt+F16";
this.ToggleSingleProcessHotkey = "Control+F16";
this.ToggleAllThumbnailsHotkey = "Alt+F12";
this.ThumbnailsManuallyHidden = false;
}
[JsonProperty("ConfigVersion")]
public int ConfigVersion { get; set; }
[JsonProperty("CycleGroup1ForwardHotkeys")]
public List<string> CycleGroup1ForwardHotkeys { get; set; }
public List<string> CycleGroup1ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup1BackwardHotkeys")]
public List<string> CycleGroup1BackwardHotkeys { get; set; }
public List<string> CycleGroup1BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup1ClientsOrder")]
public Dictionary<string, int> CycleGroup1ClientsOrder { get; set; }
public Dictionary<string, int> CycleGroup1ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup2ForwardHotkeys")]
public List<string> CycleGroup2ForwardHotkeys { get; set; }
public List<string> CycleGroup2ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup2BackwardHotkeys")]
public List<string> CycleGroup2BackwardHotkeys { get; set; }
public List<string> CycleGroup2BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup2ClientsOrder")]
public Dictionary<string, int> CycleGroup2ClientsOrder { get; set; }
public Dictionary<string, int> CycleGroup2ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup3ForwardHotkeys")]
public List<string> CycleGroup3ForwardHotkeys { get; set; }
public List<string> CycleGroup3ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup3BackwardHotkeys")]
public List<string> CycleGroup3BackwardHotkeys { get; set; }
public List<string> CycleGroup3BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup3ClientsOrder")]
public Dictionary<string, int> CycleGroup3ClientsOrder { get; set; }
public Dictionary<string, int> CycleGroup3ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup4ForwardHotkeys")]
public List<string> CycleGroup4ForwardHotkeys { get; set; }
public List<string> CycleGroup4ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup4BackwardHotkeys")]
public List<string> CycleGroup4BackwardHotkeys { get; set; }
public List<string> CycleGroup4BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup4ClientsOrder")]
public Dictionary<string, int> CycleGroup4ClientsOrder { get; set; }
public Dictionary<string, int> CycleGroup4ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup5ForwardHotkeys")]
public List<string> CycleGroup5ForwardHotkeys { get; set; }
public List<string> CycleGroup5ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup5BackwardHotkeys")]
public List<string> CycleGroup5BackwardHotkeys { get; set; }
public List<string> CycleGroup5BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup5ClientsOrder")]
public Dictionary<string, int> CycleGroup5ClientsOrder { get; set; }
public Dictionary<string, int> CycleGroup5ClientsOrder {
get; set;
}
[JsonProperty("PerClientActiveClientHighlightColor")]
public Dictionary<string, Color> PerClientActiveClientHighlightColor { get; set; }
public Dictionary<string, Color> PerClientActiveClientHighlightColor {
get; set;
}
[JsonProperty("PerClientThumbnailSize")]
public Dictionary<string, Size> PerClientThumbnailSize { get; set; }
public Dictionary<string, Size> PerClientThumbnailSize {
get; set;
}
[JsonProperty("PerClientThumbnailRegion")]
public Dictionary<string, Rectangle> PerClientThumbnailRegion {
get; set;
}
[JsonProperty("PerClientZoomAnchor")]
public Dictionary<string, ZoomAnchor> PerClientZoomAnchor{ get; set; }
public Dictionary<string, ZoomAnchor> PerClientZoomAnchor {
get; set;
}
public bool MinimizeToTray { get; set; }
public int ThumbnailRefreshPeriod { get; set; }
public int ThumbnailResizeTimeoutPeriod { get; set; }
[JsonProperty("WineCompatibilityMode")]
public bool EnableWineCompatibilityMode { get; set; }
public bool EnableWineCompatibilityMode {
get; set;
}
[JsonProperty("ThumbnailsOpacity")]
public double ThumbnailOpacity { get; set; }
public double ThumbnailOpacity {
get; set;
}
public bool EnableClientLayoutTracking
{
public bool EnableClientLayoutTracking {
get => this._enableClientLayoutTracking;
set
{
if (!value)
{
set {
if (!value) {
this.ClientLayout.Clear();
}
@@ -223,13 +258,10 @@ namespace EveOPreview.Configuration.Implementation
public AnimationStyle WindowsAnimationStyle { get; set; }
public bool ShowThumbnailsAlwaysOnTop { get; set; }
public bool EnablePerClientThumbnailLayouts
{
public bool EnablePerClientThumbnailLayouts {
get => this._enablePerClientThumbnailLayouts;
set
{
if (!value)
{
set {
if (!value) {
this.PerClientLayout.Clear();
}
@@ -245,9 +277,12 @@ namespace EveOPreview.Configuration.Implementation
public Size ThumbnailMinimumSize { get; set; }
public bool EnableThumbnailSnap { get; set; }
public int ThumbnailSnapRange { get; set; }
[JsonProperty("EnableThumbnailZoom")]
public bool ThumbnailZoomEnabled { get; set; }
public bool ThumbnailZoomEnabled {
get; set;
}
public int ThumbnailZoomFactor { get; set; }
public ZoomAnchor ThumbnailZoomAnchor { get; set; }
public ZoomAnchor OverlayLabelAnchor { get; set; }
@@ -264,30 +299,74 @@ namespace EveOPreview.Configuration.Implementation
public Color ActiveClientHighlightColor { get; set; }
public Color OverlayLabelColor { get; set; }
public int OverlayLabelSize { get; set; }
public string IconName { get; set; }
public bool EnableThumbnailRegionSnipping { get; set; }
public Rectangle DefaultThumbnailRegion { get; set; }
public string CurrentProfile { get; set; }
public List<string> AvailableProfiles { get; set; }
[JsonProperty("IconName")]
public string IconName {
get; set;
}
public int ActiveClientHighlightThickness { get; set; }
[JsonProperty("LoginThumbnailLocation")]
public Point LoginThumbnailLocation { get; set; }
public Point LoginThumbnailLocation {
get; set;
}
[JsonProperty("ToggleTrackingHotkey")]
public string ToggleTrackingHotkey {
get; set;
}
[JsonProperty("ToggleSingleProcessHotkey")]
public string ToggleSingleProcessHotkey {
get; set;
}
[JsonProperty("ToggleAllThumbnailsHotkey")]
public string ToggleAllThumbnailsHotkey {
get; set;
}
[JsonProperty("ThumbnailsManuallyHidden")]
public bool ThumbnailsManuallyHidden {
get; set;
}
[JsonProperty]
private Dictionary<string, Dictionary<string, Point>> PerClientLayout { get; set; }
private Dictionary<string, Dictionary<string, Point>> PerClientLayout {
get; set;
}
[JsonProperty]
private Dictionary<string, Point> FlatLayout { get; set; }
private Dictionary<string, Point> FlatLayout {
get; set;
}
[JsonProperty]
private Dictionary<string, ClientLayout> ClientLayout { get; set; }
private Dictionary<string, ClientLayout> ClientLayout {
get; set;
}
[JsonProperty]
private Dictionary<string, string> ClientHotkey { get; set; }
private Dictionary<string, string> ClientHotkey {
get; set;
}
[JsonProperty]
private Dictionary<string, bool> DisableThumbnail { get; set; }
private Dictionary<string, bool> DisableThumbnail {
get; set;
}
[JsonProperty]
private List<string> PriorityClients { get; set; }
private List<string> PriorityClients {
get; set;
}
[JsonProperty]
private List<string> ExecutablesToPreview { get; set; }
public List<string> ExecutablesToPreview {
get; set;
}
public Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation)
{
public Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation) {
Point location;
// What this code does:
@@ -298,11 +377,10 @@ namespace EveOPreview.Configuration.Implementation
// 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))
{
if (this.EnablePerClientThumbnailLayouts && !string.IsNullOrEmpty(activeClient)) {
Dictionary<string, Point> layoutSource;
if (this.PerClientLayout.TryGetValue(activeClient, out layoutSource) && layoutSource.TryGetValue(currentClient, out location))
{
if (this.PerClientLayout.TryGetValue(activeClient, out layoutSource) &&
layoutSource.TryGetValue(currentClient, out location)) {
return location;
}
}
@@ -310,60 +388,81 @@ namespace EveOPreview.Configuration.Implementation
return this.FlatLayout.TryGetValue(currentClient, out location) ? location : defaultLocation;
}
public Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize)
{
public Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize) {
Size sizeOfThumbnail;
return this.PerClientThumbnailSize.TryGetValue(currentClient, out sizeOfThumbnail) ? sizeOfThumbnail : defaultSize;
return this.PerClientThumbnailSize.TryGetValue(currentClient, out sizeOfThumbnail) ? sizeOfThumbnail
: defaultSize;
}
public ZoomAnchor GetZoomAnchor(string currentClient, ZoomAnchor defaultZoomAnchor)
{
public Rectangle GetThumbnailRegion(string currentClient, Rectangle defaultRegion) {
Rectangle region;
return this.PerClientThumbnailRegion.TryGetValue(currentClient, out region) ? region : defaultRegion;
}
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)
{
public void SetThumbnailLocation(string currentClient, string activeClient, Point location) {
Dictionary<string, Point> layoutSource;
if (this.EnablePerClientThumbnailLayouts)
{
if (string.IsNullOrEmpty(activeClient))
{
if (this.EnablePerClientThumbnailLayouts) {
if (string.IsNullOrEmpty(activeClient)) {
return;
}
if (!this.PerClientLayout.TryGetValue(activeClient, out layoutSource))
{
if (!this.PerClientLayout.TryGetValue(activeClient, out layoutSource)) {
layoutSource = new Dictionary<string, Point>();
this.PerClientLayout[activeClient] = layoutSource;
}
}
else
{
} else {
layoutSource = this.FlatLayout;
}
layoutSource[currentClient] = location;
}
public ClientLayout GetClientLayout(string currentClient)
{
public void SetThumbnailRegion(string currentClient, Rectangle region) {
this.PerClientThumbnailRegion[currentClient] = region;
}
public void SaveProfile(string profileName) {
if (!this.AvailableProfiles.Contains(profileName)) {
this.AvailableProfiles.Add(profileName);
}
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)
{
public void SetClientLayout(string currentClient, ClientLayout layout) {
this.ClientLayout[currentClient] = layout;
}
public Keys GetClientHotkey(string currentClient)
{
public Keys GetClientHotkey(string currentClient) {
string hotkey;
if (this.ClientHotkey.TryGetValue(currentClient, out 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;
@@ -372,63 +471,61 @@ namespace EveOPreview.Configuration.Implementation
return Keys.None;
}
public void SetClientHotkey(string currentClient, Keys hotkey)
{
public void SetClientHotkey(string currentClient, Keys hotkey) {
this.ClientHotkey[currentClient] = (new KeysConverter()).ConvertToInvariantString(hotkey);
}
public Keys StringToKey(string hotkey)
{
public Keys StringToKey(string hotkey) {
object rawValue = (new KeysConverter()).ConvertFromInvariantString(hotkey);
return rawValue != null ? (Keys)rawValue : Keys.None;
}
public bool IsPriorityClient(string currentClient)
{
public bool IsPriorityClient(string currentClient) {
return this.PriorityClients.Contains(currentClient);
}
public bool IsExecutableToPreview(string processName)
{
public bool IsExecutableToPreview(string processName) {
return this.ExecutablesToPreview.Any(s => s.Equals(processName, StringComparison.OrdinalIgnoreCase));
}
public bool IsThumbnailDisabled(string currentClient)
{
public bool IsThumbnailDisabled(string currentClient) {
return this.DisableThumbnail.TryGetValue(currentClient, out bool isDisabled) && isDisabled;
}
public void ToggleThumbnail(string currentClient, bool 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()
{
public void ApplyRestrictions() {
#if LINUX
this.ThumbnailRefreshPeriod = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailRefreshPeriod, 10, 1000);
this.ThumbnailRefreshPeriod =
ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailRefreshPeriod, 10, 1000);
#else
this.ThumbnailRefreshPeriod = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailRefreshPeriod, 300, 1000);
this.ThumbnailRefreshPeriod =
ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailRefreshPeriod, 300, 1000);
#endif
this.ThumbnailResizeTimeoutPeriod = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailResizeTimeoutPeriod, 200, 5000);
this.ThumbnailSize = new Size(ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailSize.Width, this.ThumbnailMinimumSize.Width, this.ThumbnailMaximumSize.Width),
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.ThumbnailResizeTimeoutPeriod =
ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailResizeTimeoutPeriod, 200, 5000);
this.ThumbnailSize = new Size(
ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailSize.Width, this.ThumbnailMinimumSize.Width,
this.ThumbnailMaximumSize.Width),
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);
this.ActiveClientHighlightThickness =
ThumbnailConfiguration.ApplyRestrictions(this.ActiveClientHighlightThickness, 1, 6);
}
private static int ApplyRestrictions(int value, int minimum, int maximum)
{
if (value <= minimum)
{
private static int ApplyRestrictions(int value, int minimum, int maximum) {
if (value <= minimum) {
return minimum;
}
if (value >= maximum)
{
if (value >= maximum) {
return maximum;
}

View File

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

View File

@@ -1,13 +1,8 @@
namespace EveOPreview.Configuration
{
public class ClientLayout
{
public ClientLayout()
{
}
namespace EveOPreview.Configuration {
public class 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.Y = y;
this.Width = width;

View File

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

View File

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

View File

@@ -2,10 +2,8 @@
using System.Drawing;
using System.Windows.Forms;
namespace EveOPreview.Configuration
{
public interface IThumbnailConfiguration
{
namespace EveOPreview.Configuration {
public interface IThumbnailConfiguration {
List<string> CycleGroup1ForwardHotkeys { get; set; }
List<string> CycleGroup1BackwardHotkeys { get; set; }
Dictionary<string, int> CycleGroup1ClientsOrder { get; set; }
@@ -26,8 +24,14 @@ namespace EveOPreview.Configuration
List<string> CycleGroup5BackwardHotkeys { get; set; }
Dictionary<string, int> CycleGroup5ClientsOrder { 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, Size> PerClientThumbnailSize { get; set; }
Dictionary<string, Rectangle> PerClientThumbnailRegion { get; set; }
bool MinimizeToTray { get; set; }
int ThumbnailRefreshPeriod { get; set; }
@@ -52,6 +56,7 @@ namespace EveOPreview.Configuration
Size ThumbnailMaximumSize { get; set; }
bool EnableThumbnailSnap { get; set; }
int ThumbnailSnapRange { get; set; }
bool ThumbnailZoomEnabled { get; set; }
int ThumbnailZoomFactor { get; set; }
@@ -71,6 +76,12 @@ namespace EveOPreview.Configuration
Color OverlayLabelColor { get; set; }
int OverlayLabelSize { get; set; }
bool EnableThumbnailRegionSnipping { get; set; }
Rectangle DefaultThumbnailRegion { get; set; }
string CurrentProfile { get; set; }
List<string> AvailableProfiles { get; set; }
string IconName { get; set; }
Point LoginThumbnailLocation { get; set; }
@@ -78,7 +89,13 @@ namespace EveOPreview.Configuration
Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation);
Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize);
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);
void SaveProfile(string profileName);
void LoadProfile(string profileName);
void DeleteProfile(string profileName);
ClientLayout GetClientLayout(string currentClient);
void SetClientLayout(string currentClient, ClientLayout layout);
@@ -89,6 +106,7 @@ namespace EveOPreview.Configuration
bool IsPriorityClient(string currentClient);
bool IsExecutableToPreview(string processName);
List<string> ExecutablesToPreview { get; set; }
bool IsThumbnailDisabled(string currentClient);
void ToggleThumbnail(string currentClient, bool isDisabled);

View File

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

View File

@@ -2,10 +2,8 @@ using System;
using System.Windows.Forms;
using System.ComponentModel;
namespace EveOPreview.UI.Hotkeys
{
class HotkeyHandler : IMessageFilter, IDisposable
{
namespace EveOPreview.UI.Hotkeys {
class HotkeyHandler : IMessageFilter, IDisposable {
private static int _currentId;
private const int MAX_ID = 0xBFFF;
@@ -14,8 +12,7 @@ namespace EveOPreview.UI.Hotkeys
private readonly IntPtr _hotkeyTarget;
#endregion
public HotkeyHandler(IntPtr target, Keys hotkey)
{
public HotkeyHandler(IntPtr target, Keys hotkey) {
this._hotkeyId = HotkeyHandler._currentId;
HotkeyHandler._currentId = (HotkeyHandler._currentId + 1) & HotkeyHandler.MAX_ID;
@@ -27,14 +24,12 @@ namespace EveOPreview.UI.Hotkeys
this.KeyCode = hotkey;
}
public void Dispose()
{
public void Dispose() {
this.Unregister();
GC.SuppressFinalize(this);
}
~HotkeyHandler()
{
~HotkeyHandler() {
// Unregister the hotkey if necessary
this.Unregister();
}
@@ -45,11 +40,9 @@ namespace EveOPreview.UI.Hotkeys
public event HandledEventHandler Pressed;
public bool CanRegister()
{
public bool CanRegister() {
// Attempt to register
if (this.Register())
{
if (this.Register()) {
// Unregister and say we managed it
this.Unregister();
return true;
@@ -58,16 +51,13 @@ namespace EveOPreview.UI.Hotkeys
return false;
}
public bool Register()
{
public bool Register() {
// Check that we have not registered
if (this.IsRegistered)
{
if (this.IsRegistered) {
return false;
}
if (this.KeyCode == Keys.None)
{
if (this.KeyCode == Keys.None) {
return false;
}
@@ -75,13 +65,12 @@ namespace EveOPreview.UI.Hotkeys
uint key = (uint)this.KeyCode & (~(uint)Keys.Alt) & (~(uint)Keys.Control) & (~(uint)Keys.Shift);
// Get unmanaged version of the modifiers code
uint modifiers = (this.KeyCode.HasFlag(Keys.Alt) ? HotkeyHandlerNativeMethods.MOD_ALT : 0)
| (this.KeyCode.HasFlag(Keys.Control) ? HotkeyHandlerNativeMethods.MOD_CONTROL : 0)
| (this.KeyCode.HasFlag(Keys.Shift) ? HotkeyHandlerNativeMethods.MOD_SHIFT : 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.Shift) ? HotkeyHandlerNativeMethods.MOD_SHIFT : 0);
// Register the hotkey
if (!HotkeyHandlerNativeMethods.RegisterHotKey(this._hotkeyTarget, this._hotkeyId, modifiers, key))
{
if (!HotkeyHandlerNativeMethods.RegisterHotKey(this._hotkeyTarget, this._hotkeyId, modifiers, key)) {
return false;
}
@@ -93,11 +82,9 @@ namespace EveOPreview.UI.Hotkeys
return true;
}
public void Unregister()
{
public void Unregister() {
// Check that we have registered
if (!this.IsRegistered)
{
if (!this.IsRegistered) {
return;
}
@@ -110,17 +97,13 @@ namespace EveOPreview.UI.Hotkeys
}
#region IMessageFilter
public bool PreFilterMessage(ref Message message)
{
return this.IsRegistered
&& (message.Msg == HotkeyHandlerNativeMethods.WM_HOTKEY)
&& (message.WParam.ToInt32() == this._hotkeyId)
&& this.OnPressed();
public bool PreFilterMessage(ref Message message) {
return this.IsRegistered && (message.Msg == HotkeyHandlerNativeMethods.WM_HOTKEY) &&
(message.WParam.ToInt32() == this._hotkeyId) && this.OnPressed();
}
#endregion
private bool OnPressed()
{
private bool OnPressed() {
// Fire the event if we can
HandledEventArgs handledEventArgs = new HandledEventArgs(false);
this.Pressed?.Invoke(this, handledEventArgs);

View File

@@ -1,10 +1,8 @@
using System;
using System.Runtime.InteropServices;
namespace EveOPreview.UI.Hotkeys
{
static class HotkeyHandlerNativeMethods
{
namespace EveOPreview.UI.Hotkeys {
static class HotkeyHandlerNativeMethods {
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

View File

@@ -4,19 +4,15 @@ using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages;
using MediatR;
namespace EveOPreview.Mediator.Handlers.Configuration
{
sealed class SaveConfigurationHandler : IRequestHandler<SaveConfiguration>
{
namespace EveOPreview.Mediator.Handlers.Configuration {
sealed class SaveConfigurationHandler : IRequestHandler<SaveConfiguration> {
private readonly IConfigurationStorage _storage;
public SaveConfigurationHandler(IConfigurationStorage storage)
{
public SaveConfigurationHandler(IConfigurationStorage storage) {
this._storage = storage;
}
public Task<Unit> Handle(SaveConfiguration message, CancellationToken cancellationToken)
{
public Task<Unit> Handle(SaveConfiguration message, CancellationToken cancellationToken) {
this._storage.Save();
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,26 +4,21 @@ using EveOPreview.Mediator.Messages;
using EveOPreview.Services;
using MediatR;
namespace EveOPreview.Mediator.Handlers.Services
{
sealed class StartStopServiceHandler : IRequestHandler<StartService>, IRequestHandler<StopService>
{
namespace EveOPreview.Mediator.Handlers.Services {
sealed class StartStopServiceHandler : IRequestHandler<StartService>, IRequestHandler<StopService> {
private readonly IThumbnailManager _manager;
public StartStopServiceHandler(IThumbnailManager manager)
{
public StartStopServiceHandler(IThumbnailManager manager) {
this._manager = manager;
}
public Task<Unit> Handle(StartService message, CancellationToken cancellationToken)
{
public Task<Unit> Handle(StartService message, CancellationToken cancellationToken) {
this._manager.Start();
return Unit.Task;
}
public Task<Unit> Handle(StopService message, CancellationToken cancellationToken)
{
public Task<Unit> Handle(StopService message, CancellationToken cancellationToken) {
this._manager.Stop();
return Unit.Task;

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,22 +4,19 @@ using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages;
using MediatR;
namespace EveOPreview.Mediator.Handlers.Thumbnails
{
sealed class ThumbnailLocationUpdatedHandler : INotificationHandler<ThumbnailLocationUpdated>
{
namespace EveOPreview.Mediator.Handlers.Thumbnails {
sealed class ThumbnailLocationUpdatedHandler : INotificationHandler<ThumbnailLocationUpdated> {
private readonly IMediator _mediator;
private readonly IThumbnailConfiguration _configuration;
public ThumbnailLocationUpdatedHandler(IMediator mediator, IThumbnailConfiguration configuration)
{
public ThumbnailLocationUpdatedHandler(IMediator mediator, IThumbnailConfiguration configuration) {
this._mediator = mediator;
this._configuration = configuration;
}
public Task Handle(ThumbnailLocationUpdated notification, CancellationToken cancellationToken)
{
this._configuration.SetThumbnailLocation(notification.ThumbnailName, notification.ActiveClientName, notification.Location);
public Task Handle(ThumbnailLocationUpdated notification, CancellationToken cancellationToken) {
this._configuration.SetThumbnailLocation(notification.ThumbnailName, notification.ActiveClientName,
notification.Location);
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,11 +1,8 @@
using MediatR;
namespace EveOPreview.Mediator.Messages
{
abstract class NotificationBase<TValue> : INotification
{
protected NotificationBase(TValue value)
{
namespace EveOPreview.Mediator.Messages {
abstract class NotificationBase<TValue> : INotification {
protected NotificationBase(TValue value) {
this.Value = value;
}

View File

@@ -1,8 +1,5 @@
using MediatR;
namespace EveOPreview.Mediator.Messages
{
sealed class SaveConfiguration : IRequest
{
}
namespace EveOPreview.Mediator.Messages {
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;
namespace EveOPreview.Mediator.Messages
{
sealed class StartService : IRequest
{
}
namespace EveOPreview.Mediator.Messages {
sealed class StartService : IRequest {}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,13 +4,12 @@ using System.Diagnostics;
using System.Drawing;
using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages;
using EveOPreview.View;
using MediatR;
namespace EveOPreview.Presenters
{
public class MainFormPresenter : Presenter<IMainFormView>, IMainFormPresenter
{
namespace EveOPreview.Presenters {
public class MainFormPresenter : Presenter<IMainFormView>, IMainFormPresenter {
#region Private constants
private const string FORUM_URL = @"https://forum.eveonline.com/t/4202";
#endregion
@@ -25,9 +24,9 @@ namespace EveOPreview.Presenters
private bool _exitApplication;
#endregion
public MainFormPresenter(IApplicationController controller, IMainFormView view, IMediator mediator, IThumbnailConfiguration configuration, IConfigurationStorage configurationStorage)
: base(controller, view)
{
public MainFormPresenter(IApplicationController controller, IMainFormView view, IMediator mediator,
IThumbnailConfiguration configuration, IConfigurationStorage configurationStorage)
: base(controller, view) {
this._mediator = mediator;
this._configuration = configuration;
this._configurationStorage = configurationStorage;
@@ -49,14 +48,12 @@ namespace EveOPreview.Presenters
this.View.IconName = this._configuration.IconName;
}
private void Activate()
{
private void Activate() {
this._suppressSizeNotifications = true;
this.LoadApplicationSettings();
this.View.SetDocumentationUrl(MainFormPresenter.FORUM_URL);
this.View.SetVersionInfo(this.GetApplicationVersion());
if (this._configuration.MinimizeToTray)
{
if (this._configuration.MinimizeToTray) {
this.View.Minimize();
}
@@ -64,20 +61,16 @@ namespace EveOPreview.Presenters
this._suppressSizeNotifications = false;
}
private void Minimize()
{
if (!this._configuration.MinimizeToTray)
{
private void Minimize() {
if (!this._configuration.MinimizeToTray) {
return;
}
this.View.Hide();
}
private void Close(ViewCloseRequest request)
{
if (this._exitApplication || !this.View.MinimizeToTray)
{
private void Close(ViewCloseRequest request) {
if (this._exitApplication || !this.View.MinimizeToTray) {
this._mediator.Send(new StopService()).Wait();
this._configurationStorage.Save();
@@ -89,17 +82,14 @@ namespace EveOPreview.Presenters
this.View.Minimize();
}
private async void UpdateThumbnailsSize()
{
if (!this._suppressSizeNotifications)
{
private async void UpdateThumbnailsSize() {
if (!this._suppressSizeNotifications) {
this.SaveApplicationSettings();
await this._mediator.Publish(new ThumbnailConfiguredSizeUpdated());
}
}
private void LoadApplicationSettings()
{
private void LoadApplicationSettings() {
this._configurationStorage.Load();
this.View.MinimizeToTray = this._configuration.MinimizeToTray;
@@ -109,12 +99,14 @@ namespace EveOPreview.Presenters
this.View.EnableClientLayoutTracking = this._configuration.EnableClientLayoutTracking;
this.View.HideActiveClientThumbnail = this._configuration.HideActiveClientThumbnail;
this.View.MinimizeInactiveClients = this._configuration.MinimizeInactiveClients;
this.View.WindowsAnimationStyle = ViewAnimationStyleConverter.Convert(this._configuration.WindowsAnimationStyle);
this.View.WindowsAnimationStyle =
ViewAnimationStyleConverter.Convert(this._configuration.WindowsAnimationStyle);
this.View.ShowThumbnailsAlwaysOnTop = this._configuration.ShowThumbnailsAlwaysOnTop;
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._configuration.ThumbnailMaximumSize);
this.View.ThumbnailSize = this._configuration.ThumbnailSize;
this.View.EnableThumbnailZoom = this._configuration.ThumbnailZoomEnabled;
@@ -128,17 +120,27 @@ namespace EveOPreview.Presenters
this.View.ThumbnailSnapToGrid = this._configuration.ThumbnailSnapToGrid;
this.View.ThumbnailSnapToGridSizeX = this._configuration.ThumbnailSnapToGridSizeX;
this.View.ThumbnailSnapToGridSizeY = this._configuration.ThumbnailSnapToGridSizeY;
this.View.ThumbnailSnapRange = this._configuration.ThumbnailSnapRange;
this.View.EnableActiveClientHighlight = this._configuration.EnableActiveClientHighlight;
this.View.ActiveClientHighlightColor = this._configuration.ActiveClientHighlightColor;
this.View.OverlayLabelColor = this._configuration.OverlayLabelColor;
this.View.OverlayLabelSize = this._configuration.OverlayLabelSize;
this.View.EnableThumbnailRegionSnipping = this._configuration.EnableThumbnailRegionSnipping;
this.View.DefaultThumbnailRegion = this._configuration.DefaultThumbnailRegion;
this.View.AvailableProfiles = this._configuration.AvailableProfiles;
this.View.CurrentProfile = this._configuration.CurrentProfile;
this.View.ToggleTrackingHotkey = this._configuration.ToggleTrackingHotkey;
this.View.ToggleSingleProcessHotkey = this._configuration.ToggleSingleProcessHotkey;
this.View.ToggleAllThumbnailsHotkey = this._configuration.ToggleAllThumbnailsHotkey;
this.View.IconName = this._configuration.IconName;
}
private async void SaveApplicationSettings()
{
private async void SaveApplicationSettings() {
this._configuration.MinimizeToTray = this.View.MinimizeToTray;
this._configuration.ThumbnailOpacity = (float)this.View.ThumbnailOpacity;
@@ -146,7 +148,8 @@ namespace EveOPreview.Presenters
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.WindowsAnimationStyle =
ViewAnimationStyleConverter.Convert(this.View.WindowsAnimationStyle);
this._configuration.ShowThumbnailsAlwaysOnTop = this.View.ShowThumbnailsAlwaysOnTop;
this._configuration.HideThumbnailsOnLostFocus = this.View.HideThumbnailsOnLostFocus;
this._configuration.EnablePerClientThumbnailLayouts = this.View.EnablePerClientThumbnailLayouts;
@@ -159,8 +162,7 @@ namespace EveOPreview.Presenters
this._configuration.OverlayLabelAnchor = ViewZoomAnchorConverter.Convert(this.View.OverlayLabelAnchor);
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;
await this._mediator.Publish(new ThumbnailFrameSettingsUpdated());
}
@@ -169,6 +171,7 @@ namespace EveOPreview.Presenters
this._configuration.ThumbnailSnapToGrid = this.View.ThumbnailSnapToGrid;
this._configuration.ThumbnailSnapToGridSizeX = this.View.ThumbnailSnapToGridSizeX;
this._configuration.ThumbnailSnapToGridSizeY = this.View.ThumbnailSnapToGridSizeY;
this._configuration.ThumbnailSnapRange = this.View.ThumbnailSnapRange;
this._configuration.EnableActiveClientHighlight = this.View.EnableActiveClientHighlight;
this._configuration.ActiveClientHighlightColor = this.View.ActiveClientHighlightColor;
@@ -176,6 +179,25 @@ namespace EveOPreview.Presenters
this._configuration.OverlayLabelColor = this.View.OverlayLabelColor;
this._configuration.OverlayLabelSize = this.View.OverlayLabelSize;
this._configuration.EnableThumbnailRegionSnipping = this.View.EnableThumbnailRegionSnipping;
this._configuration.DefaultThumbnailRegion = this.View.DefaultThumbnailRegion;
this._configuration.AvailableProfiles = this.View.AvailableProfiles;
this._configuration.CurrentProfile = this.View.CurrentProfile;
this._configuration.ToggleTrackingHotkey = this.View.ToggleTrackingHotkey;
this._configuration.ToggleSingleProcessHotkey = this.View.ToggleSingleProcessHotkey;
this._configuration.ToggleAllThumbnailsHotkey = this.View.ToggleAllThumbnailsHotkey;
// 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());
}
this._configuration.IconName = this.View.IconName;
this._configurationStorage.Save();
@@ -185,15 +207,11 @@ namespace EveOPreview.Presenters
await this._mediator.Send(new SaveConfiguration());
}
public void AddThumbnails(IList<string> thumbnailTitles)
{
public void AddThumbnails(IList<string> thumbnailTitles) {
IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count);
lock (this._descriptionsCache)
{
foreach (string title in thumbnailTitles)
{
lock (this._descriptionsCache) {
foreach (string title in thumbnailTitles) {
IThumbnailDescription description = this.CreateThumbnailDescription(title);
this._descriptionsCache[title] = description;
@@ -204,16 +222,12 @@ namespace EveOPreview.Presenters
this.View.AddThumbnails(descriptions);
}
public void RemoveThumbnails(IList<string> thumbnailTitles)
{
public void RemoveThumbnails(IList<string> thumbnailTitles) {
IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count);
lock (this._descriptionsCache)
{
foreach (string title in thumbnailTitles)
{
if (!this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description))
{
lock (this._descriptionsCache) {
foreach (string title in thumbnailTitles) {
if (!this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description)) {
continue;
}
@@ -225,38 +239,41 @@ namespace EveOPreview.Presenters
this.View.RemoveThumbnails(descriptions);
}
private IThumbnailDescription CreateThumbnailDescription(string title)
{
private IThumbnailDescription CreateThumbnailDescription(string title) {
bool isDisabled = this._configuration.IsThumbnailDisabled(title);
return new ThumbnailDescription(title, isDisabled);
}
private async void UpdateThumbnailState(String title)
{
if (this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description))
{
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)
{
public void UpdateThumbnailSize(Size size) {
this._suppressSizeNotifications = true;
this.View.ThumbnailSize = size;
this._suppressSizeNotifications = false;
}
private void OpenDocumentationLink()
{
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
Process.Start("xdg-open", new Uri(MainFormPresenter.FORUM_URL).AbsoluteUri);
#else
ProcessStartInfo processStartInfo = new ProcessStartInfo(new Uri(MainFormPresenter.FORUM_URL).AbsoluteUri);
processStartInfo.UseShellExecute = true;
Process.Start(processStartInfo);
#endif
}
private string GetApplicationVersion()
{
private string GetApplicationVersion() {
Version version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version;
string target = "Windows";
#if LINUX
@@ -265,8 +282,7 @@ namespace EveOPreview.Presenters
return $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision} {target}";
}
private void ExitApplication()
{
private void ExitApplication() {
this._exitApplication = true;
this.View.Close();
}

View File

@@ -1,17 +1,13 @@
using EveOPreview.Configuration;
namespace EveOPreview.View
{
static class ViewAnimationStyleConverter
{
public static AnimationStyle Convert(ViewAnimationStyle value)
{
namespace EveOPreview.View {
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
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
return (ViewAnimationStyle)((int)value);
}

View File

@@ -1,17 +1,13 @@
using EveOPreview.Configuration;
namespace EveOPreview.View
{
static class ViewZoomAnchorConverter
{
public static ZoomAnchor Convert(ViewZoomAnchor value)
{
namespace EveOPreview.View {
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
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
return (ViewZoomAnchor)((int)value);
}

View File

@@ -1,10 +1,8 @@
using System.Collections.Generic;
using System.Drawing;
namespace EveOPreview.Presenters
{
interface IMainFormPresenter
{
namespace EveOPreview.Presenters {
interface IMainFormPresenter {
void AddThumbnails(IList<string> thumbnailTitles);
void RemoveThumbnails(IList<string> thumbnailTitles);

View File

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

View File

@@ -7,18 +7,15 @@ using EveOPreview.Services;
using EveOPreview.View;
using MediatR;
namespace EveOPreview
{
static class Program
{
namespace EveOPreview {
static class Program {
private static string MUTEX_NAME = "EVE-O-Preview Single Instance Mutex";
private static Mutex _singleInstanceMutex;
/// <summary>The main entry point for the application.</summary>
[STAThread]
static void Main()
{
static void Main() {
// The very usual Mutex-based single-instance screening
// 'token' variable is used to store reference to the instance Mutex
// during the app lifetime
@@ -26,8 +23,7 @@ namespace EveOPreview
// If it was not possible to acquire the app token then another app instance is already running
// Nothing to do here
if (Program._singleInstanceMutex == null)
{
if (Program._singleInstanceMutex == null) {
return;
}
@@ -40,32 +36,25 @@ namespace EveOPreview
controller.Run<MainFormPresenter>();
}
private static Mutex GetInstanceToken()
{
private static Mutex GetInstanceToken() {
// The code might look overcomplicated here for a single Mutex operation
// Yet we had already experienced a Windows-level issue
// where .NET finalizer thread was literally paralyzed by
// a failed Mutex operation. That did lead to weird OutOfMemory
// exceptions later
try
{
try {
Mutex.OpenExisting(Program.MUTEX_NAME);
// if that didn't fail then another instance is already running
return null;
}
catch (UnauthorizedAccessException)
{
} catch (UnauthorizedAccessException) {
return null;
}
catch (Exception)
{
} 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.SetCompatibleTextRenderingDefault(false);
#if WINDOWS
@@ -73,8 +62,7 @@ namespace EveOPreview
#endif
}
private static IApplicationController InitializeApplicationController()
{
private static IApplicationController InitializeApplicationController() {
IIocContainer container = new LightInjectContainer();
// Singleton registration is used for services

View File

@@ -11,7 +11,6 @@
namespace EveOPreview.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
@@ -19,27 +18,29 @@ namespace EveOPreview.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[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.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance",
"CA1811:AvoidUncalledPrivateCode")]
internal Resources() {}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </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 {
get {
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;
}
return resourceMan;
@@ -50,14 +51,11 @@ namespace EveOPreview.Properties {
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
[global::System.ComponentModel.EditorBrowsableAttribute(
global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
get { return resourceCulture; }
set { resourceCulture = value; }
}
}
}

View File

@@ -2,100 +2,84 @@
using System.Runtime.InteropServices;
using EveOPreview.Services.Interop;
namespace EveOPreview.Services.Implementation
{
class DwmThumbnail : IDwmThumbnail
{
namespace EveOPreview.Services.Implementation {
class DwmThumbnail : IDwmThumbnail {
#region Private fields
private readonly IWindowManager _windowManager;
private IntPtr _handle;
private DWM_THUMBNAIL_PROPERTIES _properties;
#endregion
public DwmThumbnail(IWindowManager windowManager)
{
public DwmThumbnail(IWindowManager windowManager) {
this._windowManager = windowManager;
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.dwFlags = DWM_TNP_CONSTANTS.DWM_TNP_VISIBLE
+ DWM_TNP_CONSTANTS.DWM_TNP_OPACITY
+ DWM_TNP_CONSTANTS.DWM_TNP_RECTDESTINATION
+ DWM_TNP_CONSTANTS.DWM_TNP_SOURCECLIENTAREAONLY;
this._properties.dwFlags = DWM_TNP_CONSTANTS.DWM_TNP_VISIBLE + DWM_TNP_CONSTANTS.DWM_TNP_OPACITY +
DWM_TNP_CONSTANTS.DWM_TNP_RECTDESTINATION +
DWM_TNP_CONSTANTS.DWM_TNP_SOURCECLIENTAREAONLY;
this._properties.opacity = 255;
this._properties.fVisible = true;
this._properties.fSourceClientAreaOnly = true;
this._properties.rcSource = new RECT(0, 0, 0, 0); // Initialize with empty source rect
if (!this._windowManager.IsCompositionEnabled)
{
if (!this._windowManager.IsCompositionEnabled) {
return;
}
try
{
try {
this._handle = DwmNativeMethods.DwmRegisterThumbnail(destination, source);
}
catch (ArgumentException)
{
} catch (ArgumentException) {
// This exception is raised if the source client is already closed
// 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
// a thumbnail source
this._handle = IntPtr.Zero;
}
catch (COMException)
{
} 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()
{
if ((!this._windowManager.IsCompositionEnabled) || (this._handle == IntPtr.Zero))
{
public void Unregister() {
if ((!this._windowManager.IsCompositionEnabled) || (this._handle == IntPtr.Zero)) {
return;
}
try
{
try {
DwmNativeMethods.DwmUnregisterThumbnail(this._handle);
}
catch (ArgumentException)
{
}
catch (COMException)
{
} catch (ArgumentException) {
} 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);
}
public void Update()
{
if ((!this._windowManager.IsCompositionEnabled) || (this._handle == IntPtr.Zero))
{
public void SetSourceRegion(int left, int top, int right, int bottom) {
this._properties.rcSource = new RECT(left, top, right, bottom);
this._properties.dwFlags |= DWM_TNP_CONSTANTS.DWM_TNP_RECTSOURCE;
}
public void ClearSourceRegion() {
this._properties.dwFlags &= ~DWM_TNP_CONSTANTS.DWM_TNP_RECTSOURCE;
}
public void Update() {
if ((!this._windowManager.IsCompositionEnabled) || (this._handle == IntPtr.Zero)) {
return;
}
try
{
try {
DwmNativeMethods.DwmUpdateThumbnailProperties(this._handle, this._properties);
}
catch (ArgumentException)
{
} catch (ArgumentException) {
// This exception will be thrown if the EVE client disappears while this method is running
}
catch (COMException)
{
} catch (COMException) {
// This exception is raised when DWM is not available for some reason
}
}

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -5,10 +5,8 @@ using System.Runtime.InteropServices;
using EveOPreview.Configuration;
using EveOPreview.Services.Interop;
namespace EveOPreview.Services.Implementation
{
public class WindowManager : IWindowManager
{
namespace EveOPreview.Services.Implementation {
public class WindowManager : IWindowManager {
#region Private constants
private const int WINDOW_SIZE_THRESHOLD = 300;
private const int NO_ANIMATION = 0;
@@ -21,9 +19,7 @@ namespace EveOPreview.Services.Implementation
private const string EXCEPTION_DUMP_FILE_NAME = "EVE-O-Preview.log";
#endregion
public WindowManager(IThumbnailConfiguration configuration)
{
public WindowManager(IThumbnailConfiguration configuration) {
#if LINUX
this._enableWineCompatabilityMode = configuration.EnableWineCompatibilityMode;
this._bashLocation = FindLinuxBinLocation("bash");
@@ -31,21 +27,19 @@ namespace EveOPreview.Services.Implementation
#endif
// Composition is always enabled for Windows 8+
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.Minor >= 2)) // Win 8 and Win 8.1
|| (Environment.OSVersion.Version.Major >= 10) // Win 10
|| DwmNativeMethods.DwmIsCompositionEnabled(); // In case of Win 7 an API call is requiredWin 7
_animationParam.cbSize = (System.UInt32)Marshal.SizeOf(typeof(ANIMATIONINFO));
}
#if LINUX
private string FindLinuxBinLocation(string command)
{
private string FindLinuxBinLocation(string command) {
// Check common paths for command
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))
{
if (System.IO.File.Exists(locationToCheck)) {
string binLocation = System.IO.Path.GetDirectoryName(locationToCheck);
string binLocationUnixStyle = binLocation.Replace("\\", "/");
@@ -58,14 +52,10 @@ namespace EveOPreview.Services.Implementation
}
#endif
private void WriteToLog(string message)
{
try
{
private void WriteToLog(string message) {
try {
System.IO.File.AppendAllText(EXCEPTION_DUMP_FILE_NAME, message + Environment.NewLine);
}
catch (Exception ex)
{
} catch (Exception ex) {
Console.WriteLine($"Failed to write to log file: {ex.Message}");
}
}
@@ -75,117 +65,97 @@ namespace EveOPreview.Services.Implementation
public bool IsCompositionEnabled { get; }
public IntPtr GetForegroundWindowHandle()
{
public IntPtr GetForegroundWindowHandle() {
return User32NativeMethods.GetForegroundWindow();
}
private void TurnOffAnimation()
{
var currentAnimationSetup = User32NativeMethods.SystemParametersInfo(User32NativeMethods.SPI_GETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)), ref _animationParam, 0);
if (_currentAnimationSetting == null)
{
private void TurnOffAnimation() {
var currentAnimationSetup = User32NativeMethods.SystemParametersInfo(
User32NativeMethods.SPI_GETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)),
ref _animationParam, 0);
if (_currentAnimationSetting == null) {
// Store the current Animation Setting
_currentAnimationSetting = _animationParam.iMinAnimate;
}
if (currentAnimationSetup != NO_ANIMATION)
{
if (currentAnimationSetup != NO_ANIMATION) {
// Turn off Animation
_animationParam.iMinAnimate = NO_ANIMATION;
var animationOffReturn = User32NativeMethods.SystemParametersInfo(User32NativeMethods.SPI_SETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)), ref _animationParam, 0);
var animationOffReturn = User32NativeMethods.SystemParametersInfo(
User32NativeMethods.SPI_SETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)),
ref _animationParam, 0);
}
}
private void RestoreAnimation()
{
var currentAnimationSetup = User32NativeMethods.SystemParametersInfo(User32NativeMethods.SPI_GETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)), ref _animationParam, 0);
private void RestoreAnimation() {
var currentAnimationSetup = User32NativeMethods.SystemParametersInfo(
User32NativeMethods.SPI_GETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)),
ref _animationParam, 0);
// Restore current Animation Settings
if (_animationParam.iMinAnimate != (int)_currentAnimationSetting)
{
if (_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 LINUX
private void WindowsActivateWindow(IntPtr handle)
{
private void WindowsActivateWindow(IntPtr handle) {
User32NativeMethods.SetForegroundWindow(handle);
User32NativeMethods.SetFocus(handle);
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);
}
}
private void WineActivateWindow(string windowName)
{
private void WineActivateWindow(string windowName) {
// On Wine it is not possible to manipulate windows directly.
// They are managed by native Window Manager
// So a separate command-line utility is used
if (string.IsNullOrEmpty(windowName))
{
if (string.IsNullOrEmpty(windowName)) {
return;
}
string cmd = "";
try
{
try {
// 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 + "\"\"\"";
}
else
{
} else {
cmd = $"-c \"{this._wmctrlLocation}/wmctrl -a \"\"" + windowName + "\"\"\"";
}
// Configure and start the process
var processStartInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = $"{this._bashLocation}/bash",
Arguments = cmd,
UseShellExecute = false,
CreateNoWindow = false
};
var processStartInfo =
new System.Diagnostics.ProcessStartInfo { FileName = $"{this._bashLocation}/bash", Arguments = cmd,
UseShellExecute = false, CreateNoWindow = false };
using (var process = System.Diagnostics.Process.Start(processStartInfo))
{
using (var process = System.Diagnostics.Process.Start(processStartInfo)) {
process.WaitForExit();
}
}
catch (Exception ex)
{
} catch (Exception ex) {
WriteToLog($"[{DateTime.Now}] executing wmctrl - Exception: {ex.Message}");
}
}
public void ActivateWindow(IntPtr handle, string windowName)
{
if (this._enableWineCompatabilityMode)
{
public void ActivateWindow(IntPtr handle, string windowName) {
if (this._enableWineCompatabilityMode) {
this.WineActivateWindow(windowName);
}
else
{
} else {
this.WindowsActivateWindow(handle);
}
}
public void MinimizeWindow(IntPtr handle, bool enableAnimation)
{
if (enableAnimation)
{
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND, InteropConstants.SC_MINIMIZE, 0);
}
else
{
public void MinimizeWindow(IntPtr handle, bool enableAnimation) {
if (enableAnimation) {
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND, InteropConstants.SC_MINIMIZE,
0);
} else {
WINDOWPLACEMENT param = new WINDOWPLACEMENT();
param.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
User32NativeMethods.GetWindowPlacement(handle, ref param);
@@ -197,17 +167,14 @@ namespace EveOPreview.Services.Implementation
#endif
#if WINDOWS
public void ActivateWindow(IntPtr handle, AnimationStyle animation)
{
public void ActivateWindow(IntPtr handle, AnimationStyle animation) {
User32NativeMethods.SetForegroundWindow(handle);
User32NativeMethods.SetFocus(handle);
int style = User32NativeMethods.GetWindowLong(handle, InteropConstants.GWL_STYLE);
if ((style & InteropConstants.WS_MINIMIZE) == InteropConstants.WS_MINIMIZE)
{
switch (animation)
{
if ((style & InteropConstants.WS_MINIMIZE) == InteropConstants.WS_MINIMIZE) {
switch (animation) {
case AnimationStyle.OriginalAnimation:
User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_RESTORE);
break;
@@ -220,26 +187,22 @@ namespace EveOPreview.Services.Implementation
}
}
public void MinimizeWindow(IntPtr handle, AnimationStyle animation, bool enableAnimation)
{
if (enableAnimation)
{
switch (animation)
{
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);
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);
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND,
InteropConstants.SC_MINIMIZE, 0);
RestoreAnimation();
break;
}
}
else
{
switch (animation)
{
} else {
switch (animation) {
case AnimationStyle.OriginalAnimation:
WINDOWPLACEMENT param = new WINDOWPLACEMENT();
param.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
@@ -249,7 +212,8 @@ namespace EveOPreview.Services.Implementation
break;
case AnimationStyle.NoAnimation:
TurnOffAnimation();
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND, InteropConstants.SC_MINIMIZE, 0);
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND,
InteropConstants.SC_MINIMIZE, 0);
RestoreAnimation();
break;
}
@@ -257,43 +221,36 @@ namespace EveOPreview.Services.Implementation
}
#endif
public void MoveWindow(IntPtr handle, int left, int top, int width, int height)
{
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)
{
public void MaximizeWindow(IntPtr handle) {
User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_SHOWMAXIMIZED);
}
public (int Left, int Top, int Right, int Bottom) GetWindowPosition(IntPtr handle)
{
public (int Left, int Top, int Right, int Bottom) GetWindowPosition(IntPtr handle) {
User32NativeMethods.GetWindowRect(handle, out RECT windowRectangle);
return (windowRectangle.Left, windowRectangle.Top, windowRectangle.Right, windowRectangle.Bottom);
}
public bool IsWindowMaximized(IntPtr handle)
{
public bool IsWindowMaximized(IntPtr handle) {
return User32NativeMethods.IsZoomed(handle);
}
public bool IsWindowMinimized(IntPtr handle)
{
public bool IsWindowMinimized(IntPtr handle) {
return User32NativeMethods.IsIconic(handle);
}
public IDwmThumbnail GetLiveThumbnail(IntPtr destination, IntPtr source)
{
public IDwmThumbnail GetLiveThumbnail(IntPtr destination, IntPtr source) {
IDwmThumbnail thumbnail = new DwmThumbnail(this);
thumbnail.Register(destination, source);
return thumbnail;
}
public Image GetStaticThumbnail(IntPtr source)
{
public Image GetStaticThumbnail(IntPtr source) {
var sourceContext = User32NativeMethods.GetDC(source);
User32NativeMethods.GetClientRect(source, out RECT windowRect);
@@ -302,8 +259,7 @@ namespace EveOPreview.Services.Implementation
var height = windowRect.Bottom - windowRect.Top;
// Check if there is anything to make thumbnail of
if ((width < WINDOW_SIZE_THRESHOLD) || (height < WINDOW_SIZE_THRESHOLD))
{
if ((width < WINDOW_SIZE_THRESHOLD) || (height < WINDOW_SIZE_THRESHOLD)) {
return null;
}
@@ -311,7 +267,8 @@ namespace EveOPreview.Services.Implementation
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.BitBlt(destContext, 0, 0, width, height, sourceContext, 0, 0,
Gdi32NativeMethods.SRCCOPY);
Gdi32NativeMethods.SelectObject(destContext, oldBitmap);
Gdi32NativeMethods.DeleteDC(destContext);
User32NativeMethods.ReleaseDC(source, sourceContext);

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,10 +2,8 @@
using System;
using System.Drawing;
namespace EveOPreview.Services
{
public interface IWindowManager
{
namespace EveOPreview.Services {
public interface IWindowManager {
bool IsCompositionEnabled { get; }
IntPtr GetForegroundWindowHandle();

View File

@@ -1,9 +1,7 @@
using System;
namespace EveOPreview.Services
{
public static class InteropConstants
{
namespace EveOPreview.Services {
public static class InteropConstants {
public const int GWL_ID = (-12);
public const int GWL_STYLE = (-16);
public const int GWL_EXSTYLE = (-20);

View File

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

View File

@@ -1,11 +1,9 @@
using System;
using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop
{
namespace EveOPreview.Services.Interop {
[StructLayout(LayoutKind.Sequential)]
class DWM_BLURBEHIND
{
class DWM_BLURBEHIND {
public uint dwFlags;
[MarshalAs(UnmanagedType.Bool)]
public bool fEnable;

View File

@@ -1,10 +1,8 @@
using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop
{
namespace EveOPreview.Services.Interop {
[StructLayout(LayoutKind.Sequential)]
class DWM_THUMBNAIL_PROPERTIES
{
class DWM_THUMBNAIL_PROPERTIES {
public uint dwFlags;
public RECT rcDestination;
public RECT rcSource;

View File

@@ -1,7 +1,5 @@
namespace EveOPreview.Services.Interop
{
static class DWM_TNP_CONSTANTS
{
namespace EveOPreview.Services.Interop {
static class DWM_TNP_CONSTANTS {
public const uint DWM_TNP_RECTDESTINATION = 0x00000001;
public const uint DWM_TNP_RECTSOURCE = 0x00000002;
public const uint DWM_TNP_OPACITY = 0x00000004;

View File

@@ -2,10 +2,8 @@ using System;
using System.Runtime.InteropServices;
using System.Drawing;
namespace EveOPreview.Services.Interop
{
static class DwmNativeMethods
{
namespace EveOPreview.Services.Interop {
static class DwmNativeMethods {
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmEnableBlurBehindWindow(IntPtr hWnd, DWM_BLURBEHIND pBlurBehind);
@@ -16,8 +14,7 @@ namespace EveOPreview.Services.Interop
public static extern bool DwmIsCompositionEnabled();
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmGetColorizationColor(
out int pcrColorization,
public static extern void DwmGetColorizationColor(out int pcrColorization,
[MarshalAs(UnmanagedType.Bool)] out bool pfOpaqueBlend);
[DllImport("dwmapi.dll", PreserveSig = false)]

View File

@@ -1,10 +1,8 @@
using System;
using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop
{
static class Gdi32NativeMethods
{
namespace EveOPreview.Services.Interop {
static class Gdi32NativeMethods {
public const int SRCCOPY = 13369376;
[DllImport("gdi32.dll")]
@@ -23,6 +21,7 @@ namespace EveOPreview.Services.Interop
public static extern bool DeleteObject(IntPtr hObject);
[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,17 +1,14 @@
using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop
{
namespace EveOPreview.Services.Interop {
[StructLayout(LayoutKind.Sequential)]
class MARGINS
{
class MARGINS {
public int cxLeftWidth;
public int cxRightWidth;
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;
cyTopHeight = top;
cxRightWidth = right;

View File

@@ -1,17 +1,14 @@
using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop
{
namespace EveOPreview.Services.Interop {
[StructLayout(LayoutKind.Sequential)]
struct RECT
{
struct RECT {
public int Left;
public int Top;
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.Top = top;
this.Right = right;

View File

@@ -1,10 +1,8 @@
using System;
using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop
{
static class User32NativeMethods
{
namespace EveOPreview.Services.Interop {
static class User32NativeMethods {
public const uint SPI_SETANIMATION = 0x0049;
public const uint SPI_GETANIMATION = 0x0048;
@@ -65,6 +63,7 @@ namespace EveOPreview.Services.Interop
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hdc);
[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,11 +1,9 @@
using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop
{
namespace EveOPreview.Services.Interop {
// Definition for Window Placement Structure
[StructLayout(LayoutKind.Sequential)]
struct WINDOWPLACEMENT
{
struct WINDOWPLACEMENT {
public int length;
public int flags;
public int showCmd;

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,10 +3,8 @@ using System.Drawing;
using EveOPreview.Configuration;
using EveOPreview.Services;
namespace EveOPreview.View
{
sealed class LiveThumbnailView : ThumbnailView
{
namespace EveOPreview.View {
sealed class LiveThumbnailView : ThumbnailView {
#region Private fields
private IDwmThumbnail _thumbnail;
private Point _startLocation;
@@ -14,36 +12,53 @@ namespace EveOPreview.View
private IThumbnailConfiguration _config;
#endregion
public LiveThumbnailView(IWindowManager windowManager, IThumbnailConfiguration config, IThumbnailManager thumbnailManager)
: base(windowManager, config, thumbnailManager)
{
public LiveThumbnailView(IWindowManager windowManager, IThumbnailConfiguration config,
IThumbnailManager thumbnailManager)
: base(windowManager, config, thumbnailManager) {
this._startLocation = new Point(0, 0);
this._endLocation = new Point(this.ClientSize);
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
IDwmThumbnail obsoleteThumbnail = forceRefresh ? this._thumbnail : null;
if ((this._thumbnail == null) || forceRefresh)
{
if ((this._thumbnail == null) || forceRefresh) {
this.RegisterThumbnail();
}
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)
return;
if (this._config.EnableThumbnailRegionSnipping) {
var region = this._config.GetThumbnailRegion(this.Title, this._config.DefaultThumbnailRegion);
if (region.Width > 0 && region.Height > 0) {
this._thumbnail.SetSourceRegion(region.Left, region.Top, region.Right, region.Bottom);
} else {
this._thumbnail.ClearSourceRegion();
}
} else {
this._thumbnail.ClearSourceRegion();
}
this._thumbnail.Update();
}
protected override void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop,
int highlightWidthRight, int highlightWidthBottom,
int highlightWidthLeft) {
var left = 0 + highlightWidthLeft;
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._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);
@@ -53,10 +68,10 @@ namespace EveOPreview.View
this._thumbnail.Update();
}
private void RegisterThumbnail()
{
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.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

View File

@@ -7,11 +7,10 @@ using System.IO;
using System.Linq;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using EveOPreview.View.Implementation;
namespace EveOPreview.View
{
public partial class MainForm : Form, IMainFormView
{
namespace EveOPreview.View {
public partial class MainForm : Form, IMainFormView {
#region Private fields
private readonly ApplicationContext _context;
private readonly Dictionary<ViewZoomAnchor, RadioButton> _zoomAnchorMap;
@@ -24,8 +23,7 @@ namespace EveOPreview.View
private string _iconName;
#endregion
public MainForm(ApplicationContext context)
{
public MainForm(ApplicationContext context) {
this._context = context;
this._zoomAnchorMap = new Dictionary<ViewZoomAnchor, RadioButton>();
this._overlayLabelMap = new Dictionary<ViewZoomAnchor, RadioButton>();
@@ -43,63 +41,53 @@ namespace EveOPreview.View
this.InitFormSize();
this.AnimationStyleCombo.DataSource = Enum.GetValues(typeof(AnimationStyle));
// Add mouse wheel event handlers for aspect ratio maintenance
this.ThumbnailsWidthNumericEdit.MouseWheel += ThumbnailSizeNumeric_MouseWheel;
this.ThumbnailsHeightNumericEdit.MouseWheel += ThumbnailSizeNumeric_MouseWheel;
}
public bool MinimizeToTray
{
public bool MinimizeToTray {
get => this.MinimizeToTrayCheckBox.Checked;
set => this.MinimizeToTrayCheckBox.Checked = value;
}
public string IconName
{
public string IconName {
get => this._iconName;
set {
this._iconName = value;
// Set Icon
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
if (this._iconName == null || ((resources.GetObject(this._iconName))) == null)
{
System.ComponentModel.ComponentResourceManager resources =
new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
if (this._iconName == null || ((resources.GetObject(this._iconName))) == null) {
this._iconName = "IconOriginal";
}
// pull icon from resources
try
{
try {
var iconBytes = (byte[])resources.GetObject(this._iconName);
using (MemoryStream ms = new MemoryStream(iconBytes))
{
using (MemoryStream ms = new MemoryStream(iconBytes)) {
this.Icon = new Icon(ms);
this.NotifyIcon.Icon = this.Icon;
}
}
catch (Exception ex)
{
} catch (Exception) {
// Log ?
}
if (value != "")
{
if (value != "") {
this.ApplicationSettingsChanged?.Invoke();
}
}
}
public double ThumbnailOpacity
{
public double ThumbnailOpacity {
get => Math.Min(this.ThumbnailOpacityTrackBar.Value / 100.00, 1.00);
set
{
set {
int barValue = (int)(100.0 * value);
if (barValue > 100)
{
if (barValue > 100) {
barValue = 100;
}
else if (barValue < 10)
{
} else if (barValue < 10) {
barValue = 10;
}
@@ -107,86 +95,69 @@ namespace EveOPreview.View
}
}
public bool EnableClientLayoutTracking
{
public bool EnableClientLayoutTracking {
get => this.EnableClientLayoutTrackingCheckBox.Checked;
set => this.EnableClientLayoutTrackingCheckBox.Checked = value;
}
public bool HideActiveClientThumbnail
{
public bool HideActiveClientThumbnail {
get => this.HideActiveClientThumbnailCheckBox.Checked;
set => this.HideActiveClientThumbnailCheckBox.Checked = value;
}
public bool MinimizeInactiveClients
{
public bool MinimizeInactiveClients {
get => this.MinimizeInactiveClientsCheckBox.Checked;
set => this.MinimizeInactiveClientsCheckBox.Checked = value;
}
public ViewAnimationStyle WindowsAnimationStyle
{
public ViewAnimationStyle WindowsAnimationStyle {
get => (ViewAnimationStyle)this.AnimationStyleCombo.SelectedItem;
set => this.AnimationStyleCombo.SelectedIndex = (int)value;
}
public bool ShowThumbnailsAlwaysOnTop
{
public bool ShowThumbnailsAlwaysOnTop {
get => this.ShowThumbnailsAlwaysOnTopCheckBox.Checked;
set => this.ShowThumbnailsAlwaysOnTopCheckBox.Checked = value;
}
public bool HideThumbnailsOnLostFocus
{
public bool HideThumbnailsOnLostFocus {
get => this.HideThumbnailsOnLostFocusCheckBox.Checked;
set => this.HideThumbnailsOnLostFocusCheckBox.Checked = value;
}
public bool EnablePerClientThumbnailLayouts
{
public bool EnablePerClientThumbnailLayouts {
get => this.EnablePerClientThumbnailsLayoutsCheckBox.Checked;
set => this.EnablePerClientThumbnailsLayoutsCheckBox.Checked = value;
}
public Size ThumbnailSize
{
public Size ThumbnailSize {
get => new Size((int)this.ThumbnailsWidthNumericEdit.Value, (int)this.ThumbnailsHeightNumericEdit.Value);
set
{
set {
this.ThumbnailsWidthNumericEdit.Value = value.Width;
this.ThumbnailsHeightNumericEdit.Value = value.Height;
}
}
public bool EnableThumbnailZoom
{
public bool EnableThumbnailZoom {
get => this.EnableThumbnailZoomCheckBox.Checked;
set
{
set {
this.EnableThumbnailZoomCheckBox.Checked = value;
this.RefreshZoomSettings();
}
}
public int ThumbnailZoomFactor
{
public int ThumbnailZoomFactor {
get => (int)this.ThumbnailZoomFactorNumericEdit.Value;
set => this.ThumbnailZoomFactorNumericEdit.Value = value;
}
public ViewZoomAnchor ThumbnailZoomAnchor
{
get
{
if (this._zoomAnchorMap[this._cachedThumbnailZoomAnchor].Checked)
{
public ViewZoomAnchor ThumbnailZoomAnchor {
get {
if (this._zoomAnchorMap[this._cachedThumbnailZoomAnchor].Checked) {
return this._cachedThumbnailZoomAnchor;
}
foreach (KeyValuePair<ViewZoomAnchor, RadioButton> valuePair in this._zoomAnchorMap)
{
if (!valuePair.Value.Checked)
{
foreach (KeyValuePair<ViewZoomAnchor, RadioButton> valuePair in this._zoomAnchorMap) {
if (!valuePair.Value.Checked) {
continue;
}
@@ -197,26 +168,20 @@ namespace EveOPreview.View
// Default value
return ViewZoomAnchor.NW;
}
set
{
set {
this._cachedThumbnailZoomAnchor = value;
this._zoomAnchorMap[this._cachedThumbnailZoomAnchor].Checked = true;
}
}
public ViewZoomAnchor OverlayLabelAnchor
{
get
{
if (this._overlayLabelMap[this._cachedOverlayLabelAnchor].Checked)
{
public ViewZoomAnchor OverlayLabelAnchor {
get {
if (this._overlayLabelMap[this._cachedOverlayLabelAnchor].Checked) {
return this._cachedOverlayLabelAnchor;
}
foreach (KeyValuePair<ViewZoomAnchor, RadioButton> valuePair in this._overlayLabelMap)
{
if (!valuePair.Value.Checked)
{
foreach (KeyValuePair<ViewZoomAnchor, RadioButton> valuePair in this._overlayLabelMap) {
if (!valuePair.Value.Checked) {
continue;
}
@@ -227,84 +192,165 @@ namespace EveOPreview.View
// Default Value
return ViewZoomAnchor.NW;
}
set
{
set {
this._cachedOverlayLabelAnchor = value;
this._overlayLabelMap[this._cachedOverlayLabelAnchor].Checked = true;
}
}
public bool ShowThumbnailOverlays
{
public bool ShowThumbnailOverlays {
get => this.ShowThumbnailOverlaysCheckBox.Checked;
set => this.ShowThumbnailOverlaysCheckBox.Checked = value;
}
public bool ShowThumbnailFrames
{
public bool ShowThumbnailFrames {
get => this.ShowThumbnailFramesCheckBox.Checked;
set => this.ShowThumbnailFramesCheckBox.Checked = value;
}
public bool LockThumbnailLocation
{
public bool LockThumbnailLocation {
get => this.LockThumbnailLocationCheckbox.Checked;
set => this.LockThumbnailLocationCheckbox.Checked = value;
}
public bool ThumbnailSnapToGrid
{
public bool ThumbnailSnapToGrid {
get => this.ThumbnailSnapToGridCheckBox.Checked;
set => this.ThumbnailSnapToGridCheckBox.Checked = value;
}
public int ThumbnailSnapToGridSizeX
{
public int ThumbnailSnapToGridSizeX {
get => (int)ThumbnailSnapToGridSizeXNumericEdit.Value;
set => ThumbnailSnapToGridSizeXNumericEdit.Value = value;
}
public int ThumbnailSnapToGridSizeY
{
public int ThumbnailSnapToGridSizeY {
get => (int)ThumbnailSnapToGridSizeYNumericEdit.Value;
set => ThumbnailSnapToGridSizeYNumericEdit.Value = value;
}
public bool EnableActiveClientHighlight
{
public int ThumbnailSnapRange {
get => (int)ThumbnailSnapRangeNumericEdit.Value;
set => ThumbnailSnapRangeNumericEdit.Value = value;
}
public string ToggleTrackingHotkey {
get => this.ToggleTrackingHotkeyTextBox.Text;
set => this.ToggleTrackingHotkeyTextBox.Text = value;
}
public string ToggleSingleProcessHotkey {
get => this.ToggleSingleProcessHotkeyTextBox.Text;
set => this.ToggleSingleProcessHotkeyTextBox.Text = value;
}
public string ToggleAllThumbnailsHotkey {
get => this.ToggleAllThumbnailsHotkeyTextBox.Text;
set => this.ToggleAllThumbnailsHotkeyTextBox.Text = value;
}
public bool EnableActiveClientHighlight {
get => this.EnableActiveClientHighlightCheckBox.Checked;
set => this.EnableActiveClientHighlightCheckBox.Checked = value;
}
public Color ActiveClientHighlightColor
{
public Color ActiveClientHighlightColor {
get => this._activeClientHighlightColor;
set
{
set {
this._activeClientHighlightColor = value;
this.ActiveClientHighlightColorButton.BackColor = value;
}
}
private Color _activeClientHighlightColor;
public Color OverlayLabelColor
{
public Color OverlayLabelColor {
get => this._OverlayLabelColor;
set
{
set {
this._OverlayLabelColor = value;
this.OverlayLabelColorButton.BackColor = value;
}
}
private Color _OverlayLabelColor;
public int OverlayLabelSize
{
public int OverlayLabelSize {
get => (int)this.OverlayLabelSizeNumericEdit.Value;
set
{
this.OverlayLabelSizeNumericEdit.Value = value;
set => this.OverlayLabelSizeNumericEdit.Value = value;
}
public bool EnableThumbnailRegionSnipping {
get => this.EnableThumbnailRegionSnippingCheckBox.Checked;
set => this.EnableThumbnailRegionSnippingCheckBox.Checked = value;
}
public Rectangle DefaultThumbnailRegion {
get => new Rectangle((int)this.RegionLeftNumericEdit.Value, (int)this.RegionTopNumericEdit.Value,
(int)this.RegionWidthNumericEdit.Value, (int)this.RegionHeightNumericEdit.Value);
set {
this.RegionLeftNumericEdit.Value = value.Left;
this.RegionTopNumericEdit.Value = value.Top;
this.RegionWidthNumericEdit.Value = value.Width;
this.RegionHeightNumericEdit.Value = value.Height;
}
}
public new void Show()
{
// Registers the current instance as the application's Main Form
private void PickRegionButton_Click(object sender, EventArgs e) {
using (var picker = new RegionPickerDialog()) {
if (picker.ShowDialog() == DialogResult.OK) {
var region = picker.SelectedRegion;
this.DefaultThumbnailRegion = region;
// Auto-set the thumbnail width and height to match the picked region
this.ThumbnailSize = new Size(region.Width, region.Height);
this.ApplicationSettingsChanged?.Invoke();
}
}
}
public string CurrentProfile {
get => this.ProfileComboBox.Text;
set {
if (this.ProfileComboBox.Items.Contains(value)) {
this.ProfileComboBox.SelectedItem = value;
}
}
}
public List<string> AvailableProfiles {
get => this.ProfileComboBox.Items.Cast<string>().ToList();
set {
this.ProfileComboBox.Items.Clear();
foreach (var profile in value) {
this.ProfileComboBox.Items.Add(profile);
}
}
}
private void ProfileComboBox_SelectedIndexChanged(object sender, EventArgs e) {
if (!this._suppressEvents) {
this.ApplicationSettingsChanged?.Invoke();
}
}
private void SaveProfileButton_Click(object sender, EventArgs e) {
using (var inputDialog = new InputDialog("Save Profile", "Enter profile name:")) {
if (inputDialog.ShowDialog() == DialogResult.OK) {
string profileName = inputDialog.InputText;
if (!string.IsNullOrWhiteSpace(profileName)) {
this.ProfileComboBox.Items.Add(profileName);
this.ProfileComboBox.SelectedItem = profileName;
this.ApplicationSettingsChanged?.Invoke();
}
}
}
}
private void DeleteProfileButton_Click(object sender, EventArgs e) {
if (this.ProfileComboBox.SelectedItem != null) {
string selectedProfile = this.ProfileComboBox.SelectedItem.ToString();
if (selectedProfile != "Default") {
this.ProfileComboBox.Items.Remove(selectedProfile);
this.ApplicationSettingsChanged?.Invoke();
}
}
}
public new void Show() {// Registers the current instance as the application's Main Form
this._context.MainForm = this;
this._suppressEvents = true;
@@ -314,53 +360,44 @@ namespace EveOPreview.View
Application.Run(this._context);
}
public void SetThumbnailSizeLimitations(Size minimumSize, Size maximumSize)
{
public void SetThumbnailSizeLimitations(Size minimumSize, Size maximumSize) {
this._minimumSize = minimumSize;
this._maximumSize = maximumSize;
}
public void Minimize()
{
public void Minimize() {
this.WindowState = FormWindowState.Minimized;
}
public void SetVersionInfo(string version)
{
public void SetVersionInfo(string version) {
this.VersionLabel.Text = version;
}
public void SetDocumentationUrl(string url)
{
public void SetDocumentationUrl(string url) {
this.DocumentationLink.Text = url;
}
public void AddThumbnails(IList<IThumbnailDescription> thumbnails)
{
public void AddThumbnails(IList<IThumbnailDescription> thumbnails) {
this.ThumbnailsList.BeginUpdate();
foreach (IThumbnailDescription view in thumbnails)
{
foreach (IThumbnailDescription view in thumbnails) {
this.ThumbnailsList.SetItemChecked(this.ThumbnailsList.Items.Add(view), view.IsDisabled);
}
this.ThumbnailsList.EndUpdate();
}
public void RemoveThumbnails(IList<IThumbnailDescription> thumbnails)
{
public void RemoveThumbnails(IList<IThumbnailDescription> thumbnails) {
this.ThumbnailsList.BeginUpdate();
foreach (IThumbnailDescription view in thumbnails)
{
foreach (IThumbnailDescription view in thumbnails) {
this.ThumbnailsList.Items.Remove(view);
}
this.ThumbnailsList.EndUpdate();
}
public void RefreshZoomSettings()
{
public void RefreshZoomSettings() {
bool enableControls = this.EnableThumbnailZoom;
this.ThumbnailZoomFactorNumericEdit.Enabled = enableControls;
this.ZoomAnchorPanel.Enabled = enableControls;
@@ -383,8 +420,7 @@ namespace EveOPreview.View
public Action DocumentationLinkActivated { get; set; }
#region UI events
private void ContentTabControl_DrawItem(object sender, DrawItemEventArgs e)
{
private void ContentTabControl_DrawItem(object sender, DrawItemEventArgs e) {
TabControl control = (TabControl)sender;
TabPage page = control.TabPages[e.Index];
Rectangle bounds = control.GetTabRect(e.Index);
@@ -392,8 +428,7 @@ namespace EveOPreview.View
Graphics graphics = e.Graphics;
Brush textBrush = new SolidBrush(SystemColors.ActiveCaptionText);
Brush backgroundBrush = (e.State == DrawItemState.Selected)
? new SolidBrush(SystemColors.Control)
Brush backgroundBrush = (e.State == DrawItemState.Selected) ? new SolidBrush(SystemColors.Control)
: new SolidBrush(SystemColors.ControlDark);
graphics.FillRectangle(backgroundBrush, e.Bounds);
@@ -408,42 +443,133 @@ namespace EveOPreview.View
graphics.DrawString(page.Text, font, textBrush, bounds, stringFlags);
}
private void OptionChanged_Handler(object sender, EventArgs e)
{
if (this._suppressEvents)
{
private void OptionChanged_Handler(object sender, EventArgs e) {
if (this._suppressEvents) {
return;
}
this.ApplicationSettingsChanged?.Invoke();
}
private void ThumbnailSizeChanged_Handler(object sender, EventArgs e)
{
if (this._suppressEvents)
{
private void ThumbnailSizeChanged_Handler(object sender, EventArgs e) {
if (this._suppressEvents) {
return;
}
// Perform some View work that is not properly done in the Control
// Check if shift is held down for aspect ratio maintenance
bool maintainAspectRatio = ModifierKeys.HasFlag(Keys.Shift);
if (maintainAspectRatio && sender is NumericUpDown changedControl) {
// Calculate the aspect ratio from the current size before the change
double aspectRatio =
(double)this.ThumbnailsWidthNumericEdit.Value / (double)this.ThumbnailsHeightNumericEdit.Value;
// Determine which control was changed and update the other accordingly
if (changedControl == this.ThumbnailsWidthNumericEdit) {
int newWidth = (int)changedControl.Value;
int newHeight = (int)(newWidth / aspectRatio);
// Apply size constraints
newWidth = Math.Min(Math.Max(newWidth, this._minimumSize.Width), this._maximumSize.Width);
newHeight = Math.Min(Math.Max(newHeight, this._minimumSize.Height), this._maximumSize.Height);
this._suppressEvents = true;
this.ThumbnailsWidthNumericEdit.Value = newWidth;
this.ThumbnailsHeightNumericEdit.Value = newHeight;
this._suppressEvents = false;
} else if (changedControl == this.ThumbnailsHeightNumericEdit) {
int newHeight = (int)changedControl.Value;
int newWidth = (int)(newHeight * aspectRatio);
// Apply size constraints
newWidth = Math.Min(Math.Max(newWidth, this._minimumSize.Width), this._maximumSize.Width);
newHeight = Math.Min(Math.Max(newHeight, this._minimumSize.Height), this._maximumSize.Height);
this._suppressEvents = true;
this.ThumbnailsWidthNumericEdit.Value = newWidth;
this.ThumbnailsHeightNumericEdit.Value = newHeight;
this._suppressEvents = false;
}
} else {
// Normal behavior without aspect ratio maintenance
this._suppressEvents = true;
Size thumbnailSize = this.ThumbnailSize;
thumbnailSize.Width = Math.Min(Math.Max(thumbnailSize.Width, this._minimumSize.Width), this._maximumSize.Width);
thumbnailSize.Height = Math.Min(Math.Max(thumbnailSize.Height, this._minimumSize.Height), this._maximumSize.Height);
thumbnailSize.Width =
Math.Min(Math.Max(thumbnailSize.Width, this._minimumSize.Width), this._maximumSize.Width);
thumbnailSize.Height =
Math.Min(Math.Max(thumbnailSize.Height, this._minimumSize.Height), this._maximumSize.Height);
this.ThumbnailSize = thumbnailSize;
this._suppressEvents = false;
}
// Update snap grid X and Y to 1/4 of width and height
Size currentSize = this.ThumbnailSize;
this.ThumbnailSnapToGridSizeX = currentSize.Width / 4;
this.ThumbnailSnapToGridSizeY = currentSize.Height / 4;
this.ThumbnailsSizeChanged?.Invoke();
}
private void ActiveClientHighlightColorButton_Click(object sender, EventArgs e)
{
using (ColorDialog dialog = new ColorDialog())
{
private void ThumbnailSizeNumeric_MouseWheel(object sender, MouseEventArgs e) {
if (this._suppressEvents) {
return;
}
// Check if shift is held down for aspect ratio maintenance
bool maintainAspectRatio = ModifierKeys.HasFlag(Keys.Shift);
if (maintainAspectRatio && sender is NumericUpDown control) {
// Calculate the aspect ratio from the current size
double aspectRatio =
(double)this.ThumbnailsWidthNumericEdit.Value / (double)this.ThumbnailsHeightNumericEdit.Value;
// Determine scroll direction and increment
int increment = e.Delta > 0 ? (int)control.Increment : -(int)control.Increment;
// Determine which control was scrolled and update both accordingly
if (control == this.ThumbnailsWidthNumericEdit) {
int newWidth = (int)control.Value + increment;
int newHeight = (int)(newWidth / aspectRatio);
// Apply size constraints
newWidth = Math.Min(Math.Max(newWidth, this._minimumSize.Width), this._maximumSize.Width);
newHeight = Math.Min(Math.Max(newHeight, this._minimumSize.Height), this._maximumSize.Height);
this._suppressEvents = true;
this.ThumbnailsWidthNumericEdit.Value = newWidth;
this.ThumbnailsHeightNumericEdit.Value = newHeight;
this._suppressEvents = false;
} else if (control == this.ThumbnailsHeightNumericEdit) {
int newHeight = (int)control.Value + increment;
int newWidth = (int)(newHeight * aspectRatio);
// Apply size constraints
newWidth = Math.Min(Math.Max(newWidth, this._minimumSize.Width), this._maximumSize.Width);
newHeight = Math.Min(Math.Max(newHeight, this._minimumSize.Height), this._maximumSize.Height);
this._suppressEvents = true;
this.ThumbnailsWidthNumericEdit.Value = newWidth;
this.ThumbnailsHeightNumericEdit.Value = newHeight;
this._suppressEvents = false;
}
// Update snap grid X and Y to 1/4 of width and height
Size currentSize = this.ThumbnailSize;
this.ThumbnailSnapToGridSizeX = currentSize.Width / 4;
this.ThumbnailSnapToGridSizeY = currentSize.Height / 4;
// Prevent the default scroll behavior
((HandledMouseEventArgs)e).Handled = true;
this.ThumbnailsSizeChanged?.Invoke();
}
}
private void ActiveClientHighlightColorButton_Click(object sender, EventArgs e) {
using (ColorDialog dialog = new ColorDialog()) {
dialog.Color = this.ActiveClientHighlightColor;
if (dialog.ShowDialog() != DialogResult.OK)
{
if (dialog.ShowDialog() != DialogResult.OK) {
return;
}
@@ -453,14 +579,11 @@ namespace EveOPreview.View
this.OptionChanged_Handler(sender, e);
}
private void OverlayLabelColorButton_Click(object sender, EventArgs e)
{
using (ColorDialog dialog = new ColorDialog())
{
private void OverlayLabelColorButton_Click(object sender, EventArgs e) {
using (ColorDialog dialog = new ColorDialog()) {
dialog.Color = this.OverlayLabelColor;
if (dialog.ShowDialog() != DialogResult.OK)
{
if (dialog.ShowDialog() != DialogResult.OK) {
return;
}
this.OverlayLabelColor = dialog.Color;
@@ -469,10 +592,8 @@ namespace EveOPreview.View
this.OptionChanged_Handler(sender, e);
}
private void ThumbnailsList_ItemCheck_Handler(object sender, ItemCheckEventArgs e)
{
if (!(this.ThumbnailsList.Items[e.Index] is IThumbnailDescription selectedItem))
{
private void ThumbnailsList_ItemCheck_Handler(object sender, ItemCheckEventArgs e) {
if (!(this.ThumbnailsList.Items[e.Index] is IThumbnailDescription selectedItem)) {
return;
}
@@ -481,23 +602,19 @@ namespace EveOPreview.View
this.ThumbnailStateChanged?.Invoke(selectedItem.Title);
}
private void DocumentationLinkClicked_Handler(object sender, LinkLabelLinkClickedEventArgs e)
{
private void DocumentationLinkClicked_Handler(object sender, LinkLabelLinkClickedEventArgs e) {
this.DocumentationLinkActivated?.Invoke();
}
private void MainFormResize_Handler(object sender, EventArgs e)
{
if (this.WindowState != FormWindowState.Minimized)
{
private void MainFormResize_Handler(object sender, EventArgs e) {
if (this.WindowState != FormWindowState.Minimized) {
return;
}
this.FormMinimized?.Invoke();
}
private void MainFormClosing_Handler(object sender, FormClosingEventArgs e)
{
private void MainFormClosing_Handler(object sender, FormClosingEventArgs e) {
ViewCloseRequest request = new ViewCloseRequest();
this.FormCloseRequested?.Invoke(request);
@@ -505,22 +622,19 @@ namespace EveOPreview.View
e.Cancel = !request.Allow;
}
private void RestoreMainForm_Handler(object sender, EventArgs e)
{
private void RestoreMainForm_Handler(object sender, EventArgs e) {
// This is form's GUI lifecycle event that is invariant to the Form data
base.Show();
this.WindowState = FormWindowState.Normal;
this.BringToFront();
}
private void ExitMenuItemClick_Handler(object sender, EventArgs e)
{
private void ExitMenuItemClick_Handler(object sender, EventArgs e) {
this.ApplicationExitRequested?.Invoke();
}
#endregion
private void InitZoomAnchorMap()
{
private void InitZoomAnchorMap() {
this._zoomAnchorMap[ViewZoomAnchor.NW] = this.ZoomAanchorNWRadioButton;
this._zoomAnchorMap[ViewZoomAnchor.N] = this.ZoomAanchorNRadioButton;
this._zoomAnchorMap[ViewZoomAnchor.NE] = this.ZoomAanchorNERadioButton;
@@ -531,8 +645,7 @@ namespace EveOPreview.View
this._zoomAnchorMap[ViewZoomAnchor.S] = this.ZoomAanchorSRadioButton;
this._zoomAnchorMap[ViewZoomAnchor.SE] = this.ZoomAanchorSERadioButton;
}
private void InitOverlayLabelMap()
{
private void InitOverlayLabelMap() {
this._overlayLabelMap[ViewZoomAnchor.NW] = this.OverlayLabelNWRadioButton;
this._overlayLabelMap[ViewZoomAnchor.N] = this.OverlayLabelNRadioButton;
this._overlayLabelMap[ViewZoomAnchor.NE] = this.OverlayLabelNERadioButton;
@@ -543,30 +656,53 @@ namespace EveOPreview.View
this._overlayLabelMap[ViewZoomAnchor.S] = this.OverlayLabelSRadioButton;
this._overlayLabelMap[ViewZoomAnchor.SE] = this.OverlayLabelSERadioButton;
}
private void InitFormSize()
{
private void InitFormSize() {
const int BUFFER_PIXEL_AMOUNT = 8;
// resize form height based on tabbed control item height
var tabControl = (System.Windows.Forms.TabControl)this.Controls.Find("ContentTabControl", false).First();
if (tabControl != null)
{
if (tabControl != null) {
var furnitureSize = this.Height - tabControl.Height;
var calculatedHeight = (tabControl.ItemSize.Width * tabControl.Controls.Count) + furnitureSize + BUFFER_PIXEL_AMOUNT;
if (this.Height < calculatedHeight)
{
var calculatedHeight =
(tabControl.ItemSize.Width * tabControl.Controls.Count) + furnitureSize + BUFFER_PIXEL_AMOUNT;
if (this.Height < calculatedHeight) {
this.Height = calculatedHeight;
}
}
}
private void AnimationStyleCombo_SelectedIndexChanged(object sender, EventArgs e)
{
private void AnimationStyleCombo_SelectedIndexChanged(object sender, EventArgs e) {}
private void GeneralSettingsPanel_Paint(object sender, PaintEventArgs e) {}
private void HotkeyTextBox_Leave(object sender, EventArgs e) {
if (sender is System.Windows.Forms.TextBox textBox) {
string hotkeyText = textBox.Text.Trim();
if (!string.IsNullOrEmpty(hotkeyText)) {
try {
// Try to parse the hotkey to validate it
var keysConverter = new KeysConverter();
var key = keysConverter.ConvertFromInvariantString(hotkeyText);
if (key == null || (Keys)key == Keys.None) {
MessageBox.Show(
$"Invalid hotkey: {hotkeyText}\n\nPlease enter a valid hotkey combination (e.g., Alt+F1, Ctrl+Shift+A)",
"Invalid Hotkey", MessageBoxButtons.OK, MessageBoxIcon.Warning);
textBox.Focus();
return;
}
} catch (Exception) {
MessageBox.Show(
$"Invalid hotkey: {hotkeyText}\n\nPlease enter a valid hotkey combination (e.g., Alt+F1, Ctrl+Shift+A)",
"Invalid Hotkey", MessageBoxButtons.OK, MessageBoxIcon.Warning);
textBox.Focus();
return;
}
}
private void GeneralSettingsPanel_Paint(object sender, PaintEventArgs e)
{
// If we get here, the hotkey is valid (or empty), so trigger the option change
this.OptionChanged_Handler(sender, e);
}
}
}
}

View File

@@ -117,85 +117,84 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="RestoreWindowMenuItem.GenerateMember" type="System.Boolean, mscorlib">
<metadata name="RestoreWindowMenuItem.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="ExitMenuItem.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="ExitMenuItem.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="TitleMenuItem.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="TitleMenuItem.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="SeparatorMenuItem.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="SeparatorMenuItem.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="ContentTabControl.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="ContentTabControl.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="GeneralTabPage.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="GeneralTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="GeneralSettingsPanel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="GeneralSettingsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="label4.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="label4.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="ThumbnailTabPage.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="ThumbnailTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="ThumbnailSettingsPanel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="ThumbnailSettingsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="HeigthLabel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="HeigthLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="WidthLabel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="WidthLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="OpacityLabel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="OpacityLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="ZoomSettingsPanel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="ZoomSettingsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="ZoomFactorLabel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="ZoomFactorLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="ZoomAnchorLabel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="ZoomAnchorLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="OverlayTabPage.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="OverlayTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="OverlaySettingsPanel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="OverlaySettingsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="ClientsTabPage.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="ClientsTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="ClientsPanel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="ClientsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="ThumbnailsListLabel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="ThumbnailsListLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="AboutTabPage.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="AboutTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="AboutPanel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="AboutPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="CreditMaintLabel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="CreditMaintLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="DocumentationLinkLabel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="DocumentationLinkLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="DescriptionLabel.GenerateMember" type="System.Boolean, mscorlib">
</metadata>
<metadata name="DescriptionLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
</metadata>
<data name="DescriptionLabel.Text" xml:space="preserve">
<value>An advanced task switcher for EVE Online clients.
@@ -206,16 +205,16 @@ The program does NOT
• interact with EVE Online except of;
- resizing or bringing it to the foreground</value>
</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>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="NotifyIcon.TrayLocation" type="System.Drawing.Point, System.Drawing">
</metadata>
<metadata name="NotifyIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</data>
<data name="TrayMenu.TrayLocation" type="System.Drawing.Point, System.Drawing">
</metadata>
<metadata name="TrayMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<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">
<value>
AAABAAQAEBAAAAEAIABoBAAARgAAACAgAAABACAAqBAAAK4EAAAwMAAAAQAgAKglAABWFQAAQEAAAAEA
@@ -754,9 +753,9 @@ The program does NOT
Af//4AAAAAAH///wAAAAAA////gAAAAAH////gAAAAB/////AAAAAP/////AAAAD/////+AAAAf//w==
</value>
</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>
</data>
</metadata>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAQAEBAAAAEAIABoBAAARgAAACAgAAABACAAqBAAAK4EAAAwMAAAAQAgAKglAABWFQAAQEAAAAEA
@@ -1295,35 +1294,4 @@ The program does NOT
Af//4AAAAAAH///wAAAAAA////gAAAAAH////gAAAAB/////AAAAAP/////AAAAD/////+AAAAf//w==
</value>
</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>

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,21 +1,15 @@
using System;
using System.Windows.Forms;
namespace EveOPreview.View
{
sealed class StaticThumbnailImage : PictureBox
{
protected override void WndProc(ref Message m)
{
namespace EveOPreview.View {
sealed class StaticThumbnailImage : PictureBox {
protected override void WndProc(ref Message m) {
const int WM_NCHITTEST = 0x0084;
const int HTTRANSPARENT = (-1);
if (m.Msg == WM_NCHITTEST)
{
if (m.Msg == WM_NCHITTEST) {
m.Result = (IntPtr)HTTRANSPARENT;
}
else
{
} else {
base.WndProc(ref m);
}
}

View File

@@ -4,69 +4,92 @@ using System.Windows.Forms;
using EveOPreview.Configuration;
using EveOPreview.Services;
namespace EveOPreview.View
{
sealed class StaticThumbnailView : ThumbnailView
{
namespace EveOPreview.View {
sealed class StaticThumbnailView : ThumbnailView {
#region Private fields
private readonly PictureBox _thumbnail;
private IThumbnailConfiguration _config;
#endregion
public StaticThumbnailView(IWindowManager windowManager, IThumbnailConfiguration config, IThumbnailManager thumbnailManager)
: base(windowManager, config, thumbnailManager)
{
this._thumbnail = new StaticThumbnailImage
{
TabStop = false,
SizeMode = PictureBoxSizeMode.StretchImage,
public StaticThumbnailView(IWindowManager windowManager, IThumbnailConfiguration config,
IThumbnailManager thumbnailManager)
: base(windowManager, config, thumbnailManager) {
this._thumbnail =
new StaticThumbnailImage { TabStop = false, SizeMode = PictureBoxSizeMode.StretchImage,
Location = new Point(0, 0),
Size = new Size(this.ClientSize.Width, this.ClientSize.Height)
};
Size = new Size(this.ClientSize.Width, this.ClientSize.Height) };
this.Controls.Add(this._thumbnail);
this._config = config;
}
protected override void RefreshThumbnail(bool forceRefresh)
{
if (!forceRefresh)
{
protected override void RefreshThumbnail(bool forceRefresh) {
if (!forceRefresh) {
return;
}
var thumbnail = this.WindowManager.GetStaticThumbnail(this.Id);
if (thumbnail != null)
{
if (thumbnail != null) {
var oldImage = this._thumbnail.Image;
this._thumbnail.Image = thumbnail;
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)
return;
if (this._config.EnableThumbnailRegionSnipping) {
var region = this._config.GetThumbnailRegion(this.Title, this._config.DefaultThumbnailRegion);
if (region.Width > 0 && region.Height > 0) {
// Crop the image to the specified region
var croppedImage = CropImage((Image)this._thumbnail.Image, region);
var oldImage = this._thumbnail.Image;
this._thumbnail.Image = croppedImage;
oldImage?.Dispose();
}
}
}
private Image CropImage(Image sourceImage, Rectangle region) {
// Ensure the region is within the image bounds
var imageRect = new Rectangle(0, 0, sourceImage.Width, sourceImage.Height);
var cropRect = Rectangle.Intersect(region, imageRect);
if (cropRect.Width <= 0 || cropRect.Height <= 0) {
return sourceImage; // Return original if region is invalid
}
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))
{
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))
{
if (this.IsSizeUpdateRequired(this._thumbnail.Size, width, height)) {
this._thumbnail.Size = new Size(width, height);
}
}
private bool IsLocationUpdateRequired(Point currentLocation, int left, int top)
{
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)
{
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,9 +1,6 @@
namespace EveOPreview.View
{
sealed class ThumbnailDescription : IThumbnailDescription
{
public ThumbnailDescription(string title, bool isDisabled)
{
namespace EveOPreview.View {
sealed class ThumbnailDescription : IThumbnailDescription {
public ThumbnailDescription(string title, bool isDisabled) {
this.Title = title;
this.IsDisabled = isDisabled;
}

View File

@@ -1,7 +1,5 @@
namespace EveOPreview.View
{
partial class ThumbnailOverlay
{
namespace EveOPreview.View {
partial class ThumbnailOverlay {
/// <summary>
/// Required designer variable.
/// </summary>
@@ -11,10 +9,8 @@
/// 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))
{
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
@@ -26,8 +22,7 @@
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
private void InitializeComponent() {
System.Windows.Forms.PictureBox OverlayAreaPictureBox;
this.OverlayLabel = new System.Windows.Forms.Label();
OverlayAreaPictureBox = new System.Windows.Forms.PictureBox();
@@ -50,7 +45,8 @@
// OverlayLabel
//
this.OverlayLabel.AutoSize = true;
this.OverlayLabel.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.OverlayLabel.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.OverlayLabel.ForeColor = System.Drawing.Color.DarkGray;
this.OverlayLabel.Location = new System.Drawing.Point(8, 8);
this.OverlayLabel.Name = "OverlayLabel";
@@ -80,7 +76,6 @@
((System.ComponentModel.ISupportInitialize)(OverlayAreaPictureBox)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion

View File

@@ -3,44 +3,36 @@ using System.Windows.Forms;
using EveOPreview.Configuration;
using EveOPreview.Services;
namespace EveOPreview.View
{
public partial class ThumbnailOverlay : Form
{
namespace EveOPreview.View {
public partial class ThumbnailOverlay : Form {
#region Private fields
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._areaClickAction = areaClickAction;
InitializeComponent();
}
private void OverlayArea_Click(object sender, MouseEventArgs e)
{
private void OverlayArea_Click(object sender, MouseEventArgs e) {
this._areaClickAction(this, e);
}
public void SetOverlayLabel(string label)
{
public void SetOverlayLabel(string label) {
this.OverlayLabel.Text = label;
}
public void SetPropertiesOverlayLabel(int size, System.Drawing.Color c, ZoomAnchor anchor)
{
if (this.OverlayLabel.Font.Size != size)
{
public void SetPropertiesOverlayLabel(int size, System.Drawing.Color c, ZoomAnchor anchor) {
if (this.OverlayLabel.Font.Size != size) {
this.OverlayLabel.Font = new System.Drawing.Font(this.OverlayLabel.Font.FontFamily, size);
}
this.OverlayLabel.ForeColor = c;
int margin = 5;
switch (anchor)
{
switch (anchor) {
case ZoomAnchor.NW:
this.OverlayLabel.Left = margin;
this.OverlayLabel.Top = margin;
@@ -89,15 +81,12 @@ namespace EveOPreview.View
}
}
public void EnableOverlayLabel(bool enable)
{
public void EnableOverlayLabel(bool enable) {
this.OverlayLabel.Visible = enable;
}
protected override CreateParams CreateParams
{
get
{
protected override CreateParams CreateParams {
get {
var Params = base.CreateParams;
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