Merge branch 'develop'

This commit is contained in:
Anton Kasyanov
2021-05-08 21:33:54 +03:00
119 changed files with 1247 additions and 141 deletions

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Costura.Fody" version="4.1.0" targetFramework="net452" developmentDependency="true" />
<package id="Fody" version="6.1.1" targetFramework="net452" developmentDependency="true" />
<package id="LightInject" version="6.3.3" targetFramework="net462" />
<package id="MediatR" version="8.0.1" targetFramework="net462" />
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net462" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net462" />
</packages>

152
README.md
View File

@@ -1,4 +1,4 @@
# Overview
## Overview
The purpose of this application is to provide a simple way to keep an eye on several simultaneously running EVE Online clients and to easily switch between them. While running it shows a set of live thumbnails for each of the active EVE Online clients. These thumbnails allow fast switch to the corresponding EVE Online client either using mouse or configurable hotkeys.
@@ -11,24 +11,43 @@ The program does NOT (and will NOT ever) do the following things:
* broadcast any keyboard or mouse events
* anyhow interact with EVE Online except of bringing its main window to foreground or resizing/minimizing it
<div style="text-align: center;">
![EVE Partner](https://github.com/Phrynohyas/eve-o-preview/blob/develop/assets/PartnerBadge.png?raw=true)
</div>
<div style="page-break-after: always;"></div>
**Under any conditions you should NOT use EVE-O Preview for any actions that break EULA or ToS of EVE Online.**
If you have find out that some of the features or their combination of EVE-O Preview might cause actions that can be considered as breaking EULA or ToS of EVE Online you should consider them as a bug and immediately notify the Developer ( Phrynohyas Tig-Rah ) via in-game mail.
# System Requirements
<div style="page-break-after: always;"></div>
## How To Install & Use
1. Download and extract the contents of the .zip archive to a location of your choice (ie: Desktop, CCP folder, etc)
..* **Note**: Please do not install the application into the *Program Files* or *Program files (x86)* folders. These folders in general do not allow applications to write anything there while EVE-O Preview now stores its configuration file next to its executable, thus requiring the write access to the folder it is installed into.
2. Start up both EVE-O Preview and your EVE Clients (the order does not matter)
3. Adjust settings as you see fit. Program options are described below
Video Guides:
* [EVE-O Preview настройка с пояснениями](https://youtu.be/IW1-pzJzb80)
* [Eve online , How To : Eve-O Preview (multiboxing; legal)](https://youtu.be/2r0NMKbogXU)
## System Requirements
* Windows 7, Windows 8/8.1, Windows 10
* Microsoft .NET Framework 4.6.2+
* EVE clients Display Mode should be set to **Fixed Window** or **Window Mode**. **Fullscreen** mode is not supported.
# How To Install & Use
<div style="page-break-after: always;"></div>
1. Download and extract the contents of the .zip archive to a location of your choice (ie: Desktop, CCP folder, etc)
..**Note**: Please do not install the application into the *Program Files* or *Program files (x86)* folders. These folders in general do not allow applications to write anything there while EVE-O Preview now stores its configuration file next to its executable, thus requiring the write access to the folder it is installed into.
2. Start up both EVE-O Preview and your EVE Clients (the order does not matter)
3. Adjust settings as you see fit. Program options are described below
# EVE Online EULA/ToS
## EVE Online EULA/ToS
This application is legal under the EULA/ToS:
@@ -44,32 +63,53 @@ CCP Grimmi wrote:
> to bring the respective EVE Client to the front/put the window focus on it, in order to
> interact with it.
# Application Options
<div style="page-break-after: always;"></div>
## Application Options Available Via GUI
## Application Options
| Tab | Option | Description |
| --- | --- | --- |
| **General** | Minimize to System Tray | Determines whether the main window form be minimized to windows tray when it is closed |
| General | Track client locations | Determines whether the client's window position should be restored when it is activated or started |
| General | Hide preview of active EVE client | Determines whether the thumbnail corresponding to the active EVE client is not displayed |
| General | Minimize inactive EVE clients | Allows to auto-minimize inactive EVE clients to save CPU and GPU |
| General | Previews always on top | Determines whether EVE client thumbnails should stay on top of all other windows |
| General | Hide previews when EVE client is not active | Determines whether all thumbnails should be visible only when an EVE client is active |
| General | Unique layout for each EVE client | Determines whether thumbnails positions are different depending on the EVE client being active (f.e. links char have thumbnails of the Falcon and DPS char in the right bottom corner while DPS and Falcon alts have them placed at the top of the main EVE window ) |
| **Thumbnail** | Opacity | Determines the inactive EVE thumbnails opacity (from almost invisible 20% to 100% solid) |
| Thumbnail | Thumbnail Width | Thumbnails width. Can be set to any value from **100** to **640** points |
| Thumbnail | Thumbnail Height | Thumbnails Height. Can be set to any value from **80** to **400** points |
| **Zoom** | Zoom on hover | Determines whether a thumbnail should be zoomed when the mouse pointer is over it |
| Zoom | Zoom factor | Thumbnail zoom factor. Can be set to any value from **2** to **10** |
| Zoom | Zoom anchor | Sets the starting point of the thumbnail zoom |
| **Overlay** | Show overlay | Determines whether a name of the corresponding EVE client should be displayed on the thumbnail |
| Overlay | Show frames | Determines whether thumbnails should be displays with window caption and borders |
| Overlay | Highlight active client | Determines whether the thumbnail of the active EVE client should be highlighted with a bright border |
| Overlay | Color | Color used to highlight the active client's thumbnail in case the corresponding option is set |
| **Active Clients** | Thumbnails list | List of currently active EVE client thumbnails. Checking an element in this list will hide the corresponding thumbnail. However these checks are not persisted and on the next EVE client or EVE-O Preview run the thumbnail will be visible again |
### Application Options Available Via GUI
## Mouse Gestures and Actions
#### **General** Tab
| Option | Description |
| --- | --- |
| Minimize to System Tray | Determines whether the main window form be minimized to windows tray when it is closed |
| Track client locations | Determines whether the client's window position should be restored when it is activated or started |
| Hide preview of active EVE client | Determines whether the thumbnail corresponding to the active EVE client is not displayed |
| Minimize inactive EVE clients | Allows to auto-minimize inactive EVE clients to save CPU and GPU |
| Previews always on top | Determines whether EVE client thumbnails should stay on top of all other windows |
| Hide previews when EVE client is not active | Determines whether all thumbnails should be visible only when an EVE client is active |
| Unique layout for each EVE client | Determines whether thumbnails positions are different depending on the EVE client being active |
#### **Thumbnail** Tab
| Option | Description |
| --- | --- |
| Opacity | Determines the inactive EVE thumbnails opacity (from almost invisible 20% to 100% solid) |
| Thumbnail Width | Thumbnails width. Can be set to any value from **100** to **640** points |
| Thumbnail Height | Thumbnails Height. Can be set to any value from **80** to **400** points |
#### **Zoom** Tab
| Option | Description |
| --- | --- |
| Zoom on hover | Determines whether a thumbnail should be zoomed when the mouse pointer is over it |
| Zoom factor | Thumbnail zoom factor. Can be set to any value from **2** to **10** |
| Zoom anchor | Sets the starting point of the thumbnail zoom |
#### **Overlay** Tab
| Option | Description |
| --- | --- |
| Show overlay | Determines whether a name of the corresponding EVE client should be displayed on the thumbnail |
| Show frames | Determines whether thumbnails should be displays with window caption and borders |
| Highlight active client | Determines whether the thumbnail of the active EVE client should be highlighted with a bright border |
| Color | Color used to highlight the active client's thumbnail in case the corresponding option is set |
#### **Active Clients** Tab
| Option | Description |
| --- | --- |
| Thumbnails list | List of currently active EVE client thumbnails. Checking an element in this list will hide the corresponding thumbnail. However these checks are not persisted and on the next EVE client or EVE-O Preview run the thumbnail will be visible again |
<div style="page-break-after: always;"></div>
### Mouse Gestures and Actions
Mouse gestures are applied to the thumbnail window currently being hovered over.
@@ -82,7 +122,9 @@ Mouse gestures are applied to the thumbnail window currently being hovered over.
| Adjust thumbnail height | Press both left and right mouse buttons and move the mouse up or down |
| Adjust thumbnail width | Press both left and right mouse buttons and move the mouse left or right |
## Configuration File-Only Options
<div style="page-break-after: always;"></div>
### Configuration File-Only Options
Some of the application options are not exposed in the GUI. They can be adjusted directly in the configuration file.
@@ -90,14 +132,18 @@ Some of the application options are not exposed in the GUI. They can be adjusted
| Option | Description |
| --- | --- |
| **ActiveClientHighlightThickness** | Thickness of the border used to highlight the active client's thumbnail.<br />Allowed values are **1**...**6**.<br />The default value is **3**<br />For example: **"ActiveClientHighlightThickness": 3** |
| **CompatibilityMode** | Enables the alternative render mode (see below)<br />The default value is **false**<br />For example: **"CompatibilityMode": true** |
| **EnableThumbnailSnap** | Allows to disable thumbnails snap feature by setting its value to **false**<br />The default value is **true**<br />For example: **"EnableThumbnailSnap": true** |
| **PriorityClients** | Allows to set a list of clients that are not auto-minimized on inactivity even if the **Minimize inactive EVE clients** option is enabled. Listed clients still can be minimized using Windows hotkeys or via _Ctrl+Click_ on the corresponding thumbnail<br />The default value is empty list **[]**<br />For example: **"PriorityClients": [ "EVE - Phrynohyas Tig-Rah", "EVE - Ondatra Patrouette" ]** |
| **ThumbnailMinimumSize** | Minimum thumbnail size that can be set either via GUI or by resizing a thumbnail window. Value is written in the form "width, height"<br />The default value is **"100, 80"**.<br />For example: **"ThumbnailMinimumSize": "100, 80"** |
| **ThumbnailMaximumSize** | Maximum thumbnail size that can be set either via GUI or by resizing a thumbnail window. Value is written in the form "width, height"<br />The default value is **"640, 400"**.<br />For example: **"ThumbnailMaximumSize": "640, 400"** |
| **ActiveClientHighlightThickness** | <div style="font-size: small">Thickness of the border used to highlight the active client's thumbnail.<br />Allowed values are **1**...**6**.<br />The default value is **3**<br />For example: **"ActiveClientHighlightThickness": 3**</div> |
| **CompatibilityMode** | <div style="font-size: small">Enables the alternative render mode (see below)<br />The default value is **false**<br />For example: **"CompatibilityMode": true**</div> |
| **EnableThumbnailSnap** | <div style="font-size: small">Allows to disable thumbnails snap feature by setting its value to **false**<br />The default value is **true**<br />For example: **"EnableThumbnailSnap": true**</div> |
| **HideThumbnailsDelay** | <div style="font-size: small">Delay before thumbnails are hidden if the **General** -> **Hide previews when EVE client is not active** option is enabled<br />The delay is measured in thumbnail refresh periods<br />The default value is **2** (corresponds to 1 second delay)<br />For example: **"HideThumbnailsDelay": 2**</div> |
| **PriorityClients** | <div style="font-size: small">Allows to set a list of clients that are not auto-minimized on inactivity even if the **Minimize inactive EVE clients** option is enabled. Listed clients still can be minimized using Windows hotkeys or via _Ctrl+Click_ on the corresponding thumbnail<br />The default value is empty list **[]**<br />For example: **"PriorityClients": [ "EVE - Phrynohyas Tig-Rah", "EVE - Ondatra Patrouette" ]**</div> |
| **ThumbnailMinimumSize** | <div style="font-size: small">Minimum thumbnail size that can be set either via GUI or by resizing a thumbnail window. Value is written in the form "width, height"<br />The default value is **"100, 80"**.<br />For example: **"ThumbnailMinimumSize": "100, 80"**</div> |
| **ThumbnailMaximumSize** | <div style="font-size: small">Maximum thumbnail size that can be set either via GUI or by resizing a thumbnail window. Value is written in the form "width, height"<br />The default value is **"640, 400"**.<br />For example: **"ThumbnailMaximumSize": "640, 400"**</div> |
| **ThumbnailRefreshPeriod** | <div style="font-size: small">Thumbnail refresh period in milliseconds. This option accepts values between **300** and **1000** only.<br />The default value is **500** milliseconds.<br />For example: **"ThumbnailRefreshPeriod": 500**</div> |
## Hotkey Setup
<div style="page-break-after: always;"></div>
### Hotkey Setup
It is possible to set a key combinations to immediately jump to certain EVE window. However currently EVE-O Preview doesn't provide any GUI to set the these hotkeys. It should be done via editing the configuration file directly. Don't forget to make a backup copy of the file before editing it.
@@ -125,7 +171,9 @@ The following hotkey is described as `modifier+key` where `modifier` can be **Co
**Note:** Do not set hotkeys to use the key combinations already used by EVE. It won't work as "_I set hotkey for my DPS char to F1 and when I'll press F1 it will automatically open the DPS char's window and activate guns_". Key combination will be swallowed by EVE-O Preview and NOT retranslated to EVE window. So it will be only "_it will automatically open the DPS char's window_".
## Compatibility Mode
<div style="page-break-after: always;"></div>
### Compatibility Mode
This setting allows to enable an alternate thumbnail render. This render doesn't use advanced DWM API to create live previews. Instead it is a screenshot-based render with the following pros and cons:
* `+` Should work even in remote desktop environments
@@ -133,38 +181,44 @@ This setting allows to enable an alternate thumbnail render. This render doesn't
* `-` Thumbnail images are refreshed at 1 FPS rate
* `-` Possible short mouse cursor freezes
---
<div style="page-break-after: always;"></div>
# Credits
## Credits
## Maintained by
### Maintained by
* Phrynohyas Tig-Rah
## Created by
### Created by
* StinkRay
## Previous maintainers
### Previous maintainers
* Makari Aeron
* StinkRay
## With contributions from
### With contributions from
* CCP FoxFour
## Forum thread
### Forum thread
https://forums.eveonline.com/t/4202
## Original repository
### Original repository
https://bitbucket.org/ulph/eve-o-preview-git
<div style="page-break-after: always;"></div>
## CCP Copyright Notice
EVE Online, the EVE logo, EVE and all associated logos and designs are the intellectual property of CCP hf. All artwork, screenshots, characters, vehicles, storylines, world facts or other recognizable features of the intellectual property relating to these trademarks are likewise the intellectual property of CCP hf. EVE Online and the EVE logo are the registered trademarks of CCP hf. All rights are reserved worldwide. All other trademarks are the property of their respective owners. CCP hf. has granted permission to pyfa to use EVE Online and all associated logos and designs for promotional and information purposes on its website but does not endorse, and is not in any way affiliated with, pyfa. CCP is in no way responsible for the content on or functioning of this program, nor can it be liable for any damage arising from the use of this program.

BIN
assets/PartnerBadge.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

32
build/Build.csproj Normal file
View File

@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<PackAsTool>true</PackAsTool>
<!-- Make sure start same folder .NET Core CLI and Visual Studio -->
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
<Configurations>Debug;Release;Build</Configurations>
</PropertyGroup>
<ItemGroup>
<None Remove="Themes\Github\Theme.css" />
<None Remove="Themes\Github\Theme.html" />
</ItemGroup>
<ItemGroup>
<Content Include="Themes\Github\Theme.css">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Themes\Github\Theme.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Cake.Frosting" Version="1.0.0-rc0002" />
<PackageReference Include="Cake.MarkdownToPdf" Version="2.5.2" />
</ItemGroup>
</Project>

14
build/Configuration.cs Normal file
View File

@@ -0,0 +1,14 @@
namespace Build
{
static class Configuration
{
public const string SolutionName = @"./src/EVE-O-Preview.sln";
public const string BinFolder = @"./bin";
public const string ToolsFolder = @"./tools";
public const string PublishFolder = @"./publish";
public const string BuildConfiguration = @"Release";
public const string BuildToolPath = @"c:\Developer Tools\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe"; // Set to NULL to let Cake to try to use the default MSBuild instance
}
}

13
build/Context.cs Normal file
View File

@@ -0,0 +1,13 @@
using Cake.Core;
using Cake.Frosting;
namespace Build
{
public class Context : FrostingContext
{
public Context(ICakeContext context)
: base(context)
{
}
}
}

59
build/Lifetime.cs Normal file
View File

@@ -0,0 +1,59 @@
using Cake.Common.Diagnostics;
using Cake.Common.IO;
using Cake.Common.Net;
using Cake.Core;
using Cake.Core.IO;
using Cake.Frosting;
namespace Build
{
public sealed class Lifetime : FrostingLifetime<Context>
{
private const string NuGetUrl = @"https://dist.nuget.org/win-x86-commandline/latest/nuget.exe";
private void DeleteDirectory(Context context, string directoryName)
{
if (!context.DirectoryExists(directoryName))
{
return;
}
context.DeleteDirectory(directoryName, new DeleteDirectorySettings { Force = true, Recursive = true });
}
private void DownloadNuGet(Context context)
{
if (context.FileExists(Configuration.ToolsFolder + "/nuget.exe"))
{
return;
}
if (!context.DirectoryExists(Configuration.ToolsFolder))
{
context.CreateDirectory(Configuration.ToolsFolder);
}
var tempFile = context.DownloadFile(NuGetUrl);
context.CopyFile(tempFile, new FilePath(Configuration.ToolsFolder + "/nuget.exe"));
}
public override void Setup(Context context)
{
context.Information("Setting things up...");
context.Information("Delete bin and publish folders");
this.DeleteDirectory(context, Configuration.BinFolder);
this.DeleteDirectory(context, Configuration.PublishFolder);
context.Information("Download NuGet");
this.DownloadNuGet(context);
}
public override void Teardown(Context context, ITeardownContext info)
{
context.Information("Tearing things down...");
//this.DeleteDirectory(context, ToolsDirectoryName);
}
}
}

22
build/Program.cs Normal file
View File

@@ -0,0 +1,22 @@
using Cake.Frosting;
using Microsoft.Extensions.DependencyInjection;
namespace Build
{
public class Program : IFrostingStartup
{
public static int Main(string[] args)
=> new CakeHost()
.UseStartup<Program>()
.Run(args);
public void Configure(IServiceCollection services)
{
services.UseContext<Context>();
services.UseLifetime<Lifetime>();
//move up from build directory and searching for sln or csproj files
services.UseWorkingDirectory("..");
}
}
}

26
build/Tasks/Build.cs Normal file
View File

@@ -0,0 +1,26 @@
using Cake.Common.Diagnostics;
using Cake.Common.Tools.MSBuild;
using Cake.Frosting;
namespace Build.Tasks
{
[Dependency(typeof(Restore))]
public sealed class Build : FrostingTask<Context>
{
public override void Run(Context context)
{
context.Information("Build started...");
context.MSBuild(Configuration.SolutionName, settings =>
{
settings.Configuration = Configuration.BuildConfiguration;
settings.ToolVersion = MSBuildToolVersion.Default;
if (!string.IsNullOrEmpty(Configuration.BuildToolPath))
{
settings.ToolPath = Configuration.BuildToolPath;
}
});
}
}
}

9
build/Tasks/Default.cs Normal file
View File

@@ -0,0 +1,9 @@
using Cake.Frosting;
namespace Build.Tasks
{
[Dependency(typeof(Zip))]
public sealed class Default : FrostingTask<Context>
{
}
}

View File

@@ -0,0 +1,22 @@
using Cake.Common.Diagnostics;
using Cake.Frosting;
using Cake.MarkdownToPdf;
using Markdig;
namespace Build.Tasks
{
public sealed class Documentation : FrostingTask<Context>
{
public override void Run(Context context)
{
context.Information("Convert README.MD");
context.MarkdownFileToPdf("readme.md", Configuration.BinFolder + "/readme.pdf", settings =>
{
settings.Theme = Themes.Github;
settings.UseAdvancedMarkdownTables();
settings.MarkdownPipeline.UseGridTables();
});
}
}
}

17
build/Tasks/Restore.cs Normal file
View File

@@ -0,0 +1,17 @@
using Cake.Common.Diagnostics;
using Cake.Common.Tools.NuGet;
using Cake.Common.Tools.NuGet.Restore;
using Cake.Frosting;
namespace Build.Tasks
{
[Dependency(typeof(Documentation))]
public sealed class Restore : FrostingTask<Context>
{
public override void Run(Context context)
{
context.Information("Restore started...");
context.NuGetRestore(Configuration.SolutionName, new NuGetRestoreSettings { NoCache = true });
}
}
}

20
build/Tasks/Zip.cs Normal file
View File

@@ -0,0 +1,20 @@
using Cake.Common.IO;
using Cake.Frosting;
namespace Build.Tasks
{
[Dependency(typeof(Build))]
public sealed class Zip : FrostingTask<Context>
{
public override void Run(Context context)
{
if (!context.DirectoryExists(Configuration.PublishFolder))
{
context.CreateDirectory(Configuration.PublishFolder);
}
context.Zip(Configuration.BinFolder, Configuration.PublishFolder + "/EVE-O Preview.zip",
new[] { Configuration.BinFolder + "/EVE-O Preview.exe", Configuration.BinFolder + "/readme.pdf" });
}
}
}

View File

@@ -0,0 +1,707 @@
@font-face {
font-family: octicons-link;
src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format('woff');
}
.markdown-body {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
line-height: 1.5;
color: #24292e;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 16px;
line-height: 1.5;
word-wrap: break-word;
}
.markdown-body .pl-c {
color: #6a737d;
}
.markdown-body .pl-c1,
.markdown-body .pl-s .pl-v {
color: #005cc5;
}
.markdown-body .pl-e,
.markdown-body .pl-en {
color: #6f42c1;
}
.markdown-body .pl-smi,
.markdown-body .pl-s .pl-s1 {
color: #24292e;
}
.markdown-body .pl-ent {
color: #22863a;
}
.markdown-body .pl-k {
color: #d73a49;
}
.markdown-body .pl-s,
.markdown-body .pl-pds,
.markdown-body .pl-s .pl-pse .pl-s1,
.markdown-body .pl-sr,
.markdown-body .pl-sr .pl-cce,
.markdown-body .pl-sr .pl-sre,
.markdown-body .pl-sr .pl-sra {
color: #032f62;
}
.markdown-body .pl-v,
.markdown-body .pl-smw {
color: #e36209;
}
.markdown-body .pl-bu {
color: #b31d28;
}
.markdown-body .pl-ii {
color: #fafbfc;
background-color: #b31d28;
}
.markdown-body .pl-c2 {
color: #fafbfc;
background-color: #d73a49;
}
.markdown-body .pl-c2::before {
content: "^M";
}
.markdown-body .pl-sr .pl-cce {
font-weight: bold;
color: #22863a;
}
.markdown-body .pl-ml {
color: #735c0f;
}
.markdown-body .pl-mh,
.markdown-body .pl-mh .pl-en,
.markdown-body .pl-ms {
font-weight: bold;
color: #005cc5;
}
.markdown-body .pl-mi {
font-style: italic;
color: #24292e;
}
.markdown-body .pl-mb {
font-weight: bold;
color: #24292e;
}
.markdown-body .pl-md {
color: #b31d28;
background-color: #ffeef0;
}
.markdown-body .pl-mi1 {
color: #22863a;
background-color: #f0fff4;
}
.markdown-body .pl-mc {
color: #e36209;
background-color: #ffebda;
}
.markdown-body .pl-mi2 {
color: #f6f8fa;
background-color: #005cc5;
}
.markdown-body .pl-mdr {
font-weight: bold;
color: #6f42c1;
}
.markdown-body .pl-ba {
color: #586069;
}
.markdown-body .pl-sg {
color: #959da5;
}
.markdown-body .pl-corl {
text-decoration: underline;
color: #032f62;
}
.markdown-body .octicon {
display: inline-block;
vertical-align: text-top;
fill: currentColor;
}
.markdown-body a {
background-color: transparent;
-webkit-text-decoration-skip: objects;
}
.markdown-body a:active,
.markdown-body a:hover {
outline-width: 0;
}
.markdown-body strong {
font-weight: inherit;
}
.markdown-body strong {
font-weight: bolder;
}
.markdown-body h1 {
font-size: 2em;
margin: 0.67em 0;
}
.markdown-body img {
border-style: none;
}
.markdown-body svg:not(:root) {
overflow: hidden;
}
.markdown-body code,
.markdown-body kbd,
.markdown-body pre {
font-family: monospace, monospace;
font-size: 1em;
}
.markdown-body hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
.markdown-body input {
font: inherit;
margin: 0;
}
.markdown-body input {
overflow: visible;
}
.markdown-body [type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
.markdown-body * {
box-sizing: border-box;
}
.markdown-body input {
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
.markdown-body a {
color: #0366d6;
text-decoration: none;
}
.markdown-body a:hover {
text-decoration: underline;
}
.markdown-body strong {
font-weight: 600;
}
.markdown-body hr {
height: 0;
margin: 15px 0;
overflow: hidden;
background: transparent;
border: 0;
border-bottom: 1px solid #dfe2e5;
}
.markdown-body hr::before {
display: table;
content: "";
}
.markdown-body hr::after {
display: table;
clear: both;
content: "";
}
.markdown-body table {
border-spacing: 0;
border-collapse: collapse;
}
.markdown-body td,
.markdown-body th {
padding: 0;
}
.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
margin-top: 0;
margin-bottom: 0;
}
.markdown-body h1 {
font-size: 32px;
font-weight: 600;
}
.markdown-body h2 {
font-size: 24px;
font-weight: 600;
}
.markdown-body h3 {
font-size: 20px;
font-weight: 600;
}
.markdown-body h4 {
font-size: 16px;
font-weight: 600;
}
.markdown-body h5 {
font-size: 14px;
font-weight: 600;
}
.markdown-body h6 {
font-size: 12px;
font-weight: 600;
}
.markdown-body p {
margin-top: 0;
margin-bottom: 10px;
}
.markdown-body blockquote {
margin: 0;
}
.markdown-body ul,
.markdown-body ol {
padding-left: 0;
margin-top: 0;
margin-bottom: 0;
}
.markdown-body ol ol,
.markdown-body ul ol {
list-style-type: lower-roman;
}
.markdown-body ul ul ol,
.markdown-body ul ol ol,
.markdown-body ol ul ol,
.markdown-body ol ol ol {
list-style-type: lower-alpha;
}
.markdown-body dd {
margin-left: 0;
}
.markdown-body code {
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 12px;
}
.markdown-body pre {
margin-top: 0;
margin-bottom: 0;
font: 12px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
}
.markdown-body .octicon {
vertical-align: text-bottom;
}
.markdown-body .pl-0 {
padding-left: 0 !important;
}
.markdown-body .pl-1 {
padding-left: 4px !important;
}
.markdown-body .pl-2 {
padding-left: 8px !important;
}
.markdown-body .pl-3 {
padding-left: 16px !important;
}
.markdown-body .pl-4 {
padding-left: 24px !important;
}
.markdown-body .pl-5 {
padding-left: 32px !important;
}
.markdown-body .pl-6 {
padding-left: 40px !important;
}
.markdown-body::before {
display: table;
content: "";
}
.markdown-body::after {
display: table;
clear: both;
content: "";
}
.markdown-body>*:first-child {
margin-top: 0 !important;
}
.markdown-body>*:last-child {
margin-bottom: 0 !important;
}
.markdown-body a:not([href]) {
color: inherit;
text-decoration: none;
}
.markdown-body .anchor {
float: left;
padding-right: 4px;
margin-left: -20px;
line-height: 1;
}
.markdown-body .anchor:focus {
outline: none;
}
.markdown-body p,
.markdown-body blockquote,
.markdown-body ul,
.markdown-body ol,
.markdown-body dl,
.markdown-body table,
.markdown-body pre {
margin-top: 0;
margin-bottom: 16px;
}
.markdown-body hr {
height: 0.25em;
padding: 0;
margin: 24px 0;
background-color: #e1e4e8;
border: 0;
}
.markdown-body blockquote {
padding: 0 1em;
color: #6a737d;
border-left: 0.25em solid #dfe2e5;
}
.markdown-body blockquote>:first-child {
margin-top: 0;
}
.markdown-body blockquote>:last-child {
margin-bottom: 0;
}
.markdown-body kbd {
display: inline-block;
padding: 3px 5px;
font-size: 11px;
line-height: 10px;
color: #444d56;
vertical-align: middle;
background-color: #fafbfc;
border: solid 1px #c6cbd1;
border-bottom-color: #959da5;
border-radius: 3px;
box-shadow: inset 0 -1px 0 #959da5;
}
.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
margin-top: 24px;
margin-bottom: 16px;
font-weight: 600;
line-height: 1.25;
}
.markdown-body h1 .octicon-link,
.markdown-body h2 .octicon-link,
.markdown-body h3 .octicon-link,
.markdown-body h4 .octicon-link,
.markdown-body h5 .octicon-link,
.markdown-body h6 .octicon-link {
color: #1b1f23;
vertical-align: middle;
visibility: hidden;
}
.markdown-body h1:hover .anchor,
.markdown-body h2:hover .anchor,
.markdown-body h3:hover .anchor,
.markdown-body h4:hover .anchor,
.markdown-body h5:hover .anchor,
.markdown-body h6:hover .anchor {
text-decoration: none;
}
.markdown-body h1:hover .anchor .octicon-link,
.markdown-body h2:hover .anchor .octicon-link,
.markdown-body h3:hover .anchor .octicon-link,
.markdown-body h4:hover .anchor .octicon-link,
.markdown-body h5:hover .anchor .octicon-link,
.markdown-body h6:hover .anchor .octicon-link {
visibility: visible;
}
.markdown-body h1 {
padding-bottom: 0.3em;
font-size: 2em;
border-bottom: 1px solid #eaecef;
}
.markdown-body h2 {
padding-bottom: 0.3em;
font-size: 1.5em;
border-bottom: 1px solid #eaecef;
}
.markdown-body h3 {
font-size: 1.25em;
}
.markdown-body h4 {
font-size: 1em;
}
.markdown-body h5 {
font-size: 0.875em;
}
.markdown-body h6 {
font-size: 0.85em;
color: #6a737d;
}
.markdown-body ul,
.markdown-body ol {
padding-left: 2em;
}
.markdown-body ul ul,
.markdown-body ul ol,
.markdown-body ol ol,
.markdown-body ol ul {
margin-top: 0;
margin-bottom: 0;
}
.markdown-body li>p {
margin-top: 16px;
}
.markdown-body li+li {
margin-top: 0.25em;
}
.markdown-body dl {
padding: 0;
}
.markdown-body dl dt {
padding: 0;
margin-top: 16px;
font-size: 1em;
font-style: italic;
font-weight: 600;
}
.markdown-body dl dd {
padding: 0 16px;
margin-bottom: 16px;
}
.markdown-body table {
display: block;
width: 100%;
overflow: auto;
}
.markdown-body table th {
font-weight: 600;
}
.markdown-body table th,
.markdown-body table td {
padding: 6px 13px;
border: 1px solid #dfe2e5;
}
.markdown-body table tr {
background-color: #fff;
border-top: 1px solid #c6cbd1;
}
.markdown-body table tr:nth-child(2n) {
background-color: #f6f8fa;
}
.markdown-body img {
max-width: 100%;
box-sizing: content-box;
background-color: #fff;
}
.markdown-body code {
padding: 0;
padding-top: 0.2em;
padding-bottom: 0.2em;
margin: 0;
font-size: 85%;
background-color: rgba(27,31,35,0.05);
border-radius: 3px;
}
.markdown-body code::before,
.markdown-body code::after {
letter-spacing: -0.2em;
content: "\00a0";
}
.markdown-body pre {
word-wrap: normal;
}
.markdown-body pre>code {
padding: 0;
margin: 0;
font-size: 100%;
word-break: normal;
white-space: pre;
background: transparent;
border: 0;
}
.markdown-body .highlight {
margin-bottom: 16px;
}
.markdown-body .highlight pre {
margin-bottom: 0;
word-break: normal;
}
.markdown-body .highlight pre,
.markdown-body pre {
padding: 16px;
overflow: auto;
font-size: 85%;
line-height: 1.45;
background-color: #f6f8fa;
border-radius: 3px;
}
.markdown-body pre code {
display: inline;
max-width: auto;
padding: 0;
margin: 0;
overflow: visible;
line-height: inherit;
word-wrap: normal;
background-color: transparent;
border: 0;
}
.markdown-body pre code::before,
.markdown-body pre code::after {
content: normal;
}
.markdown-body .full-commit .btn-outline:not(:disabled):hover {
color: #005cc5;
border-color: #005cc5;
}
.markdown-body kbd {
display: inline-block;
padding: 3px 5px;
font: 11px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
line-height: 10px;
color: #444d56;
vertical-align: middle;
background-color: #fafbfc;
border: solid 1px #d1d5da;
border-bottom-color: #c6cbd1;
border-radius: 3px;
box-shadow: inset 0 -1px 0 #c6cbd1;
}
.markdown-body :checked+.radio-label {
position: relative;
z-index: 1;
border-color: #0366d6;
}
.markdown-body .task-list-item {
list-style-type: none;
}
.markdown-body .task-list-item+.task-list-item {
margin-top: 3px;
}
.markdown-body .task-list-item input {
margin: 0 0.2em 0.25em -1.6em;
vertical-align: middle;
}
.markdown-body hr {
border-bottom-color: #eee;
}
#Main {
margin: 0 auto;
padding: 10px 40px;
max-width: 888px;
}

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<base href="{$docPath}" />
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<link href="{$cssFile}" rel="stylesheet"/>
</head>
<body>
<div id="Main" class="markdown-body">
{$html}
</div>
</body>
</html>

View File

@@ -1,26 +1,40 @@

Microsoft Visual Studio Solution File, Format Version 14.00
# Visual Studio 2015
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30907.101
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Eve-O-Preview", "Eve-O-Preview\Eve-O-Preview.csproj", "{6CA62DF3-8589-484C-8BC8-F763CA66BBB1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Eve-O-Mock", "Eve-O-Mock\Eve-O-Mock.csproj", "{BE2C3A13-CC19-4525-895F-381DD71C5833}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Build", "..\build\Build.csproj", "{68083BCC-92B8-4A73-BFD2-0DE619873F86}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Build|Any CPU = Build|Any CPU
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6CA62DF3-8589-484C-8BC8-F763CA66BBB1}.Build|Any CPU.ActiveCfg = Build|Any CPU
{6CA62DF3-8589-484C-8BC8-F763CA66BBB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6CA62DF3-8589-484C-8BC8-F763CA66BBB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6CA62DF3-8589-484C-8BC8-F763CA66BBB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6CA62DF3-8589-484C-8BC8-F763CA66BBB1}.Release|Any CPU.Build.0 = Release|Any CPU
{BE2C3A13-CC19-4525-895F-381DD71C5833}.Build|Any CPU.ActiveCfg = Build|Any CPU
{BE2C3A13-CC19-4525-895F-381DD71C5833}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BE2C3A13-CC19-4525-895F-381DD71C5833}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BE2C3A13-CC19-4525-895F-381DD71C5833}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BE2C3A13-CC19-4525-895F-381DD71C5833}.Release|Any CPU.Build.0 = Release|Any CPU
{68083BCC-92B8-4A73-BFD2-0DE619873F86}.Build|Any CPU.ActiveCfg = Build|Any CPU
{68083BCC-92B8-4A73-BFD2-0DE619873F86}.Build|Any CPU.Build.0 = Build|Any CPU
{68083BCC-92B8-4A73-BFD2-0DE619873F86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{68083BCC-92B8-4A73-BFD2-0DE619873F86}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {157D7AB8-ED90-4599-BD45-ECE31A4226A8}
EndGlobalSection
EndGlobal

View File

@@ -34,6 +34,16 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Build|AnyCPU'">
<OutputPath>bin\Build\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />

View File

@@ -32,9 +32,11 @@ namespace EveOPreview.Configuration.Implementation
this.HideActiveClientThumbnail = false;
this.MinimizeInactiveClients = false;
this.ShowThumbnailsAlwaysOnTop = true;
this.HideThumbnailsOnLostFocus = false;
this.EnablePerClientThumbnailLayouts = false;
this.HideThumbnailsOnLostFocus = false;
this.HideThumbnailsDelay = 2; // 2 thumbnails refresh cycles (1.0 sec)
this.ThumbnailSize = new Size(384, 216);
this.ThumbnailMinimumSize = new Size(192, 108);
this.ThumbnailMaximumSize = new Size(960, 540);
@@ -79,7 +81,6 @@ namespace EveOPreview.Configuration.Implementation
public bool HideActiveClientThumbnail { get; set; }
public bool MinimizeInactiveClients { get; set; }
public bool ShowThumbnailsAlwaysOnTop { get; set; }
public bool HideThumbnailsOnLostFocus { get; set; }
public bool EnablePerClientThumbnailLayouts
{
@@ -95,6 +96,9 @@ namespace EveOPreview.Configuration.Implementation
}
}
public bool HideThumbnailsOnLostFocus { get; set; }
public int HideThumbnailsDelay { get; set; }
public Size ThumbnailSize { get; set; }
public Size ThumbnailMaximumSize { get; set; }
public Size ThumbnailMinimumSize { get; set; }

View File

@@ -16,9 +16,11 @@ namespace EveOPreview.Configuration
bool HideActiveClientThumbnail { get; set; }
bool MinimizeInactiveClients { get; set; }
bool ShowThumbnailsAlwaysOnTop { get; set; }
bool HideThumbnailsOnLostFocus { get; set; }
bool EnablePerClientThumbnailLayouts { get; set; }
bool HideThumbnailsOnLostFocus { get; set; }
int HideThumbnailsDelay { get; set; }
Size ThumbnailSize { get; set; }
Size ThumbnailMinimumSize { get; set; }
Size ThumbnailMaximumSize { get; set; }

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
<Import Project="..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props" Condition="Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -31,7 +30,7 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\bin</OutputPath>
<OutputPath>..\..\bin</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
@@ -75,20 +74,18 @@
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Build|AnyCPU'">
<OutputPath>bin\Build\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="Costura, Version=4.1.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
<HintPath>..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll</HintPath>
</Reference>
<Reference Include="LightInject, Version=6.3.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LightInject.6.3.3\lib\net46\LightInject.dll</HintPath>
</Reference>
<Reference Include="MediatR, Version=8.0.1.0, Culture=neutral, PublicKeyToken=bb9a41a5e8aaa7e2, processorArchitecture=MSIL">
<HintPath>..\packages\MediatR.8.0.1\lib\net461\MediatR.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
@@ -96,9 +93,6 @@
<Reference Include="System.Linq.Expressions" />
<Reference Include="System.Runtime" />
<Reference Include="System.Threading.Tasks" />
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Windows.Forms" />
<Reference Include="System.XML" />
<Reference Include="System.Xml.Linq" />
@@ -227,24 +221,34 @@
<ItemGroup>
<None Include="app.config" />
<EmbeddedResource Include="app.manifest" />
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<None Include="FodyWeavers.xml" />
<Content Include="icon.ico" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<PackageReference Include="Costura.Fody">
<Version>3.3.2</Version>
</PackageReference>
<PackageReference Include="Fody">
<Version>4.0.2</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="LightInject">
<Version>6.4.0</Version>
</PackageReference>
<PackageReference Include="MediatR">
<Version>9.0.0</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>13.0.1</Version>
</PackageReference>
<PackageReference Include="System.ValueTuple">
<Version>4.5.0</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Fody.6.1.1\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.6.1.1\build\Fody.targets'))" />
<Error Condition="!Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props'))" />
</Target>
<Import Project="..\packages\Fody.6.1.1\build\Fody.targets" Condition="Exists('..\packages\Fody.6.1.1\build\Fody.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

View File

@@ -12,7 +12,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("04f08f8d-9e98-423b-acdb-4effb31c0d35")]
[assembly: AssemblyVersion("5.0.1.0")]
[assembly: AssemblyFileVersion("5.0.1.0")]
[assembly: AssemblyVersion("5.1.0.0")]
[assembly: AssemblyFileVersion("5.1.0.0")]
[assembly: CLSCompliant(false)]

View File

@@ -8,15 +8,21 @@ namespace EveOPreview.Services.Implementation
{
#region Private constants
private const string DEFAULT_PROCESS_NAME = "ExeFile";
private const string CURRENT_PROCESS_NAME = "EVE-O Preview";
#endregion
#region Private fields
private readonly IDictionary<IntPtr, string> _processCache;
private IProcessInfo _currentProcessInfo;
#endregion
public ProcessMonitor()
{
this._processCache = new Dictionary<IntPtr, string>(512);
// 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)
@@ -25,6 +31,41 @@ namespace EveOPreview.Services.Implementation
return String.Equals(processName, ProcessMonitor.DEFAULT_PROCESS_NAME, StringComparison.OrdinalIgnoreCase);
}
private IProcessInfo GetCurrentProcessInfo()
{
var currentProcess = Process.GetCurrentProcess();
return new ProcessInfo(currentProcess.MainWindowHandle, currentProcess.MainWindowTitle);
}
public IProcessInfo GetMainProcess()
{
if (this._currentProcessInfo.Handle == IntPtr.Zero)
{
var processInfo = this.GetCurrentProcessInfo();
// Are we initialized yet?
if (processInfo.Title != "")
{
this._currentProcessInfo = processInfo;
}
}
return this._currentProcessInfo;
}
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)
{
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)
{
addedProcesses = new List<IProcessInfo>(16);
@@ -76,18 +117,5 @@ namespace EveOPreview.Services.Implementation
this._processCache.Remove(index);
}
}
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)
{
result.Add(new ProcessInfo(entry.Key, entry.Value));
}
return result;
}
}
}

View File

@@ -41,6 +41,7 @@ namespace EveOPreview.Services
private bool _isHoverEffectActive;
private int _refreshCycleCount;
private int _hideThumbnailsDelay;
#endregion
public ThumbnailManager(IMediator mediator, IThumbnailConfiguration configuration, IProcessMonitor processMonitor, IWindowManager windowManager, IThumbnailViewFactory factory)
@@ -66,6 +67,8 @@ namespace EveOPreview.Services
this._thumbnailUpdateTimer = new DispatcherTimer();
this._thumbnailUpdateTimer.Tick += ThumbnailUpdateTimerTick;
this._thumbnailUpdateTimer.Interval = new TimeSpan(0, 0, 0, 0, configuration.ThumbnailRefreshPeriod);
this._hideThumbnailsDelay = this._configuration.HideThumbnailsDelay;
}
public void Start()
@@ -180,10 +183,19 @@ namespace EveOPreview.Services
{
// TODO Split this method
IntPtr foregroundWindowHandle = this._windowManager.GetForegroundWindowHandle();
// The foreground window can be NULL in certain circumstances, such as when a window is losing activation.
// It is safer to just skip this refresh round than to do something while the system state is undefined
if (foregroundWindowHandle == IntPtr.Zero)
{
return;
}
string foregroundWindowTitle = null;
// Check if the foreground window handle is one of the known handles for client windows or their thumbnails
bool isClientWindow = this.IsClientWindowActive(foregroundWindowHandle);
bool isMainWindowActive = this.IsMainWindowActive(foregroundWindowHandle);
if (foregroundWindowHandle == this._activeClient.Handle)
{
@@ -196,12 +208,7 @@ namespace EveOPreview.Services
}
else if (!isClientWindow)
{
// Under some circumstances Foreground WindowHandle can be zero
// (f.e. when Thumbnail is silently stealing focus from the currently open app)
if (foregroundWindowHandle != IntPtr.Zero)
{
this._externalApplication = foregroundWindowHandle;
}
this._externalApplication = foregroundWindowHandle;
}
// No need to minimize EVE clients when switching out to non-EVE window (like thumbnail)
@@ -210,7 +217,25 @@ namespace EveOPreview.Services
this.SwitchActiveClient(foregroundWindowHandle, foregroundWindowTitle);
}
bool hideAllThumbnails = this._configuration.HideThumbnailsOnLostFocus && !isClientWindow;
bool hideAllThumbnails = this._configuration.HideThumbnailsOnLostFocus && !(isClientWindow || isMainWindowActive);
// Wait for some time before hiding all previews
if (hideAllThumbnails)
{
this._hideThumbnailsDelay--;
if (this._hideThumbnailsDelay > 0)
{
hideAllThumbnails = false; // Postpone the 'hide all' operation
}
else
{
this._hideThumbnailsDelay = 0; // Stop the counter
}
}
else
{
this._hideThumbnailsDelay = this._configuration.HideThumbnailsDelay; // Reset the counter
}
this._refreshCycleCount++;
@@ -456,6 +481,7 @@ namespace EveOPreview.Services
this.EnqueueLocationChange(view);
}
// Checks whether currently active window belongs to an EVE client or its thumbnail
private bool IsClientWindowActive(IntPtr windowHandle)
{
if (windowHandle == IntPtr.Zero)
@@ -476,6 +502,12 @@ namespace EveOPreview.Services
return false;
}
// Check whether the currently active window belongs to EVE-O Preview itself
private bool IsMainWindowActive(IntPtr windowHandle)
{
return (this._processMonitor.GetMainProcess().Handle == windowHandle);
}
private void ThumbnailZoomIn(IThumbnailView view)
{
this.DisableViewEvents();
@@ -583,6 +615,12 @@ namespace EveOPreview.Services
return;
}
// No need to apply layout for not yet logged-in clients
if (clientTitle == ThumbnailManager.DEFAULT_CLIENT_TITLE)
{
return;
}
ClientLayout clientLayout = this._configuration.GetClientLayout(clientTitle);
if (clientLayout == null)
@@ -610,6 +648,13 @@ namespace EveOPreview.Services
foreach (KeyValuePair<IntPtr, IThumbnailView> entry in this._thumbnailViews)
{
IThumbnailView view = entry.Value;
// No need to save layout for not yet logged-in clients
if (view.Title == ThumbnailManager.DEFAULT_CLIENT_TITLE)
{
continue;
}
(int Left, int Top, int Right, int Bottom) position = this._windowManager.GetWindowPosition(view.Id);
int width = Math.Abs(position.Right - position.Left);
int height = Math.Abs(position.Bottom - position.Top);

View File

@@ -4,6 +4,7 @@ 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);
}

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