Merge branch 'develop'

This commit is contained in:
Anton Kasyanov
2018-03-30 01:36:02 +03:00
78 changed files with 2271 additions and 1150 deletions

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@ bin/
obj/
*.suo
*.user
*.DotSettings

View File

@@ -17,6 +17,11 @@ namespace EveOPreview
public void SetupExceptionHandlers()
{
if (System.Diagnostics.Debugger.IsAttached)
{
return;
}
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += delegate (Object sender, ThreadExceptionEventArgs e)
{

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
namespace EveOPreview
{
@@ -8,11 +10,17 @@ namespace EveOPreview
/// </summary>
public interface IIocContainer
{
void Register<TService, TImplementation>() where TImplementation : TService;
void Register<TService, TImplementation>()
where TImplementation : TService;
void Register(Type serviceType, Assembly container);
void Register<TService>();
void RegisterInstance<T>(T instance);
TService Resolve<TService>();
bool IsRegistered<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,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using LightInject;
namespace EveOPreview
@@ -19,9 +21,38 @@ namespace EveOPreview
return this._container.CanGetInstance(typeof(TService), "");
}
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)
{
continue;
}
if (serviceType.IsAssignableFrom(implementationType))
{
this._container.Register(serviceType, implementationType, new PerContainerLifetime());
}
}
}
}
public void Register<TService>()
{
this._container.Register<TService>();
this.Register(typeof(TService), typeof(TService).Assembly);
}
public void Register<TService, TImplementation>()
@@ -30,12 +61,17 @@ namespace EveOPreview
this._container.Register<TService, TImplementation>();
}
public void Register<TService>(Expression<Func<TService>> factory)
{
this._container.Register(f => factory);
}
public void Register<TService, TArgument>(Expression<Func<TArgument, TService>> factory)
{
this._container.Register(f => factory);
}
public void RegisterInstance<T>(T instance)
public void RegisterInstance<TService>(TService instance)
{
this._container.RegisterInstance(instance);
}
@@ -44,5 +80,20 @@ namespace EveOPreview
{
return this._container.GetInstance<TService>();
}
public IEnumerable<TService> ResolveAll<TService>()
{
return this._container.GetAllInstances<TService>();
}
public object Resolve(Type serviceType)
{
return this._container.GetInstance(serviceType);
}
public IEnumerable<object> ResolveAll(Type serviceType)
{
return this._container.GetAllInstances(serviceType);
}
}
}

View File

@@ -2,6 +2,18 @@ namespace EveOPreview.Configuration
{
public class ClientLayout
{
public ClientLayout()
{
}
public ClientLayout(int x, int y, int width, int height)
{
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
}
public int X { get; set; }
public int Y { get; set; }

View File

@@ -9,12 +9,12 @@ namespace EveOPreview.Configuration
private const string ConfigurationFileName = "EVE-O Preview.json";
private readonly IAppConfig _appConfig;
private readonly IThumbnailConfig _thumbnailConfig;
private readonly IThumbnailConfiguration _thumbnailConfiguration;
public ConfigurationStorage(IAppConfig appConfig, IThumbnailConfig thumbnailConfig)
public ConfigurationStorage(IAppConfig appConfig, IThumbnailConfiguration thumbnailConfiguration)
{
this._appConfig = appConfig;
this._thumbnailConfig = thumbnailConfig;
this._thumbnailConfiguration = thumbnailConfiguration;
}
public void Load()
@@ -28,16 +28,20 @@ namespace EveOPreview.Configuration
string rawData = File.ReadAllText(filename);
JsonConvert.PopulateObject(rawData, this._thumbnailConfig);
JsonConvert.PopulateObject(rawData, this._thumbnailConfiguration);
// Validate data after loading it
this._thumbnailConfig.ApplyRestrictions();
this._thumbnailConfiguration.ApplyRestrictions();
}
public void Save()
{
<<<<<<< HEAD
string rawData = JsonConvert.SerializeObject(this._thumbnailConfig, Formatting.Indented);
string filename = this.GetConfigFileName();
=======
string rawData = JsonConvert.SerializeObject(this._thumbnailConfiguration, Formatting.Indented);
>>>>>>> develop
try
{

View File

@@ -3,12 +3,24 @@ using System.Drawing;
using System.Windows.Forms;
using Newtonsoft.Json;
namespace EveOPreview.Configuration
namespace EveOPreview.Configuration.Omplementation
{
class ThumbnailConfig : IThumbnailConfig
sealed class ThumbnailConfiguration : IThumbnailConfiguration
{
public ThumbnailConfig()
#region Private fields
private bool _enablePerClientThumbnailLayouts;
private bool _enableClientLayoutTracking;
#endregion
public ThumbnailConfiguration()
{
this.PerClientLayout = new Dictionary<string, Dictionary<string, Point>>();
this.FlatLayout = new Dictionary<string, Point>();
this.ClientLayout = new Dictionary<string, ClientLayout>();
this.ClientHotkey = new Dictionary<string, string>();
this.DisableThumbnail = new Dictionary<string, bool>();
this.PriorityClients = new List<string>();
this.MinimizeToTray = false;
this.ThumbnailRefreshPeriod = 500;
@@ -16,29 +28,27 @@ namespace EveOPreview.Configuration
this.EnableClientLayoutTracking = false;
this.HideActiveClientThumbnail = false;
this.MinimizeInactiveClients = false;
this.ShowThumbnailsAlwaysOnTop = true;
this.HideThumbnailsOnLostFocus = false;
this.EnablePerClientThumbnailLayouts = false;
this.ThumbnailSize = new Size(250, 150);
this.ThumbnailMinimumSize = new Size(100, 80);
this.ThumbnailMaximumSize = new Size(640, 400);
this.ThumbnailSize = new Size(384, 216);
this.ThumbnailMinimumSize = new Size(192, 108);
this.ThumbnailMaximumSize = new Size(960, 540);
this.EnableThumbnailSnap = true;
this.ThumbnailZoomEnabled = false;
this.ThumbnailZoomFactor = 2;
this.ThumbnailZoomAnchor = ZoomAnchor.NW;
this.ShowThumbnailOverlays = true;
this.ShowThumbnailFrames = true;
this.ShowThumbnailFrames = false;
this.EnableActiveClientHighlight = false;
this.ActiveClientHighlightColor = Color.GreenYellow;
this.ActiveClientHighlightThickness = 3;
this.PerClientLayout = new Dictionary<string, Dictionary<string, Point>>();
this.FlatLayout = new Dictionary<string, Point>();
this.ClientLayout = new Dictionary<string, ClientLayout>();
this.ClientHotkey = new Dictionary<string, string>();
}
public bool MinimizeToTray { get; set; }
@@ -47,16 +57,45 @@ namespace EveOPreview.Configuration
[JsonProperty("ThumbnailsOpacity")]
public double ThumbnailOpacity { get; set; }
public bool EnableClientLayoutTracking { get; set; }
public bool EnableClientLayoutTracking
{
get => this._enableClientLayoutTracking;
set
{
if (!value)
{
this.ClientLayout.Clear();
}
this._enableClientLayoutTracking = value;
}
}
public bool HideActiveClientThumbnail { get; set; }
public bool MinimizeInactiveClients { get; set; }
public bool ShowThumbnailsAlwaysOnTop { get; set; }
public bool HideThumbnailsOnLostFocus { get; set; }
public bool EnablePerClientThumbnailLayouts { get; set; }
public bool EnablePerClientThumbnailLayouts
{
get => this._enablePerClientThumbnailLayouts;
set
{
if (!value)
{
this.PerClientLayout.Clear();
}
this._enablePerClientThumbnailLayouts = value;
}
}
public Size ThumbnailSize { get; set; }
public Size ThumbnailMaximumSize { get; set; }
public Size ThumbnailMinimumSize { get; set; }
public bool EnableThumbnailSnap { get; set; }
[JsonProperty("EnableThumbnailZoom")]
public bool ThumbnailZoomEnabled { get; set; }
public int ThumbnailZoomFactor { get; set; }
@@ -79,6 +118,10 @@ namespace EveOPreview.Configuration
private Dictionary<string, ClientLayout> ClientLayout { get; set; }
[JsonProperty]
private Dictionary<string, string> ClientHotkey { get; set; }
[JsonProperty]
private Dictionary<string, bool> DisableThumbnail { get; set; }
[JsonProperty]
private List<string> PriorityClients { get; set; }
public Point GetDefaultThumbnailLocation()
{
@@ -168,17 +211,32 @@ namespace EveOPreview.Configuration
this.ClientHotkey[currentClient] = (new KeysConverter()).ConvertToInvariantString(hotkey);
}
public bool IsPriorityClient(string currentClient)
{
return this.PriorityClients.Contains(currentClient);
}
public bool IsThumbnailDisabled(string currentClient)
{
return this.DisableThumbnail.TryGetValue(currentClient, out bool isDisabled) && isDisabled;
}
public void ToggleThumbnail(string currentClient, bool isDisabled)
{
this.DisableThumbnail[currentClient] = isDisabled;
}
/// <summary>
/// Applies restrictions to different parameters of the config
/// </summary>
public void ApplyRestrictions()
{
this.ThumbnailRefreshPeriod = ThumbnailConfig.ApplyRestrictions(this.ThumbnailRefreshPeriod, 300, 1000);
this.ThumbnailSize = new Size(ThumbnailConfig.ApplyRestrictions(this.ThumbnailSize.Width, this.ThumbnailMinimumSize.Width, this.ThumbnailMaximumSize.Width),
ThumbnailConfig.ApplyRestrictions(this.ThumbnailSize.Height, this.ThumbnailMinimumSize.Height, this.ThumbnailMaximumSize.Height));
this.ThumbnailOpacity = ThumbnailConfig.ApplyRestrictions((int)(this.ThumbnailOpacity * 100.00), 20, 100) / 100.00;
this.ThumbnailZoomFactor = ThumbnailConfig.ApplyRestrictions(this.ThumbnailZoomFactor, 2, 10);
this.ActiveClientHighlightThickness = ThumbnailConfig.ApplyRestrictions(this.ActiveClientHighlightThickness, 1, 6);
this.ThumbnailRefreshPeriod = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailRefreshPeriod, 300, 1000);
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);
}
private static int ApplyRestrictions(int value, int minimum, int maximum)

View File

@@ -3,10 +3,7 @@ using System.Windows.Forms;
namespace EveOPreview.Configuration
{
/// <summary>
/// Thumbnails Manager configuration
/// </summary>
public interface IThumbnailConfig
public interface IThumbnailConfiguration
{
bool MinimizeToTray { get; set; }
int ThumbnailRefreshPeriod { get; set; }
@@ -15,6 +12,7 @@ namespace EveOPreview.Configuration
bool EnableClientLayoutTracking { get; set; }
bool HideActiveClientThumbnail { get; set; }
bool MinimizeInactiveClients { get; set; }
bool ShowThumbnailsAlwaysOnTop { get; set; }
bool HideThumbnailsOnLostFocus { get; set; }
bool EnablePerClientThumbnailLayouts { get; set; }
@@ -23,6 +21,8 @@ namespace EveOPreview.Configuration
Size ThumbnailMinimumSize { get; set; }
Size ThumbnailMaximumSize { get; set; }
bool EnableThumbnailSnap { get; set; }
bool ThumbnailZoomEnabled { get; set; }
int ThumbnailZoomFactor { get; set; }
ZoomAnchor ThumbnailZoomAnchor { get; set; }
@@ -44,6 +44,11 @@ namespace EveOPreview.Configuration
Keys GetClientHotkey(string currentClient);
void SetClientHotkey(string currentClient, Keys hotkey);
bool IsPriorityClient(string currentClient);
bool IsThumbnailDisabled(string currentClient);
void ToggleThumbnail(string currentClient, bool isDisabled);
void ApplyRestrictions();
}
}

View File

@@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>EveOPreview</RootNamespace>
<AssemblyName>Eve-O Preview</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
@@ -79,13 +79,17 @@
<HintPath>..\packages\Costura.Fody.1.6.2\lib\dotnet\Costura.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="LightInject, Version=5.1.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LightInject.5.1.1\lib\net452\LightInject.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>R:\eve-o-preview\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
<Reference Include="LightInject">
<HintPath>..\packages\LightInject.5.1.2\lib\net452\LightInject.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="MediatR, Version=4.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MediatR.4.0.1\lib\net45\MediatR.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.11.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
@@ -107,53 +111,79 @@
<Compile Include="Configuration\AppConfig.cs" />
<Compile Include="Configuration\ConfigurationStorage.cs" />
<Compile Include="Configuration\IAppConfig.cs" />
<Compile Include="Configuration\IThumbnailConfig.cs" />
<Compile Include="Configuration\Interface\IThumbnailConfiguration.cs" />
<Compile Include="Configuration\ZoomAnchor.cs" />
<Compile Include="DwmAPI\DWM_BLURBEHIND.cs" />
<Compile Include="DwmAPI\DWM_THUMBNAIL_PROPERTIES.cs" />
<Compile Include="DwmAPI\DWM_TNP_CONSTANTS.cs" />
<Compile Include="DwmAPI\MARGINS.cs" />
<Compile Include="DwmAPI\RECT.cs" />
<Compile Include="Mediator\Handlers\Configuration\SaveConfigurationHandler.cs" />
<Compile Include="Mediator\Handlers\Thumbnails\ThumbnailFrameSettingsUpdatedHandler.cs" />
<Compile Include="Mediator\Handlers\Thumbnails\ThumbnailConfiguredSizeUpdatedHandler.cs" />
<Compile Include="Mediator\Handlers\Thumbnails\ThumbnailListUpdatedHandler.cs" />
<Compile Include="Mediator\Messages\Thumbnails\ThumbnailFrameSettingsUpdated.cs" />
<Compile Include="Mediator\Messages\Thumbnails\ThumbnailConfiguredSizeUpdated.cs" />
<Compile Include="Mediator\Messages\Thumbnails\ThumbnailListUpdated.cs" />
<Compile Include="Mediator\Handlers\Thumbnails\ThumbnailLocationUpdatedHandler.cs" />
<Compile Include="Mediator\Handlers\Thumbnails\ThumbnailActiveSizeUpdatedHandler.cs" />
<Compile Include="Mediator\Handlers\Services\StartStopServiceHandler.cs" />
<Compile Include="Mediator\Messages\Base\NotificationBase.cs" />
<Compile Include="Mediator\Messages\Configuration\SaveConfiguration.cs" />
<Compile Include="Mediator\Messages\Services\StartService.cs" />
<Compile Include="Mediator\Messages\Services\StopService.cs" />
<Compile Include="Mediator\Messages\Thumbnails\ThumbnailLocationUpdated.cs" />
<Compile Include="Mediator\Messages\Thumbnails\ThumbnailActiveSizeUpdated.cs" />
<Compile Include="Presenters\Interface\IMainFormPresenter.cs" />
<Compile Include="Services\Implementation\ProcessInfo.cs" />
<Compile Include="Services\Implementation\ProcessMonitor.cs" />
<Compile Include="Services\Interface\IProcessInfo.cs" />
<Compile Include="Services\Interface\IProcessMonitor.cs" />
<Compile Include="Services\Implementation\DwmThumbnail.cs" />
<Compile Include="Services\Interface\IDwmThumbnail.cs" />
<Compile Include="Services\Interface\InteropConstants.cs" />
<Compile Include="Services\Interop\DWM_BLURBEHIND.cs" />
<Compile Include="Services\Interop\DWM_THUMBNAIL_PROPERTIES.cs" />
<Compile Include="Services\Interop\DWM_TNP_CONSTANTS.cs" />
<Compile Include="Services\Interface\IWindowManager.cs" />
<Compile Include="Services\Interop\MARGINS.cs" />
<Compile Include="Services\Interop\RECT.cs" />
<Compile Include="Configuration\ClientLayout.cs" />
<Compile Include="ApplicationBase\IPresenter.cs" />
<Compile Include="Presentation\MainPresenter.cs" />
<Compile Include="Presentation\ViewCloseRequest.cs" />
<Compile Include="Presentation\ViewZoomAnchorConverter.cs" />
<Compile Include="UI\Interface\IThumbnailViewFactory.cs" />
<Compile Include="Presentation\IThumbnailManager.cs" />
<Compile Include="UI\Implementation\ThumbnailDescriptionView.cs" />
<Compile Include="UI\Factory\ThumbnailDescriptionViewFactory.cs" />
<Compile Include="UI\Interface\IMainView.cs" />
<Compile Include="Services\Implementation\WindowManager.cs" />
<Compile Include="Services\Interop\User32NativeMethods.cs" />
<Compile Include="Presenters\Implementation\MainFormPresenter.cs" />
<Compile Include="Presenters\Interface\ViewCloseRequest.cs" />
<Compile Include="Presenters\Implementation\ViewZoomAnchorConverter.cs" />
<Compile Include="Services\Interop\WINDOWPLACEMENT.cs" />
<Compile Include="View\Interface\IThumbnailViewFactory.cs" />
<Compile Include="Services\Interface\IThumbnailManager.cs" />
<Compile Include="View\Implementation\ThumbnailDescription.cs" />
<Compile Include="View\Interface\IMainFormView.cs" />
<Compile Include="ApplicationBase\IView.cs" />
<Compile Include="UI\Interface\IThumbnailDescriptionView.cs" />
<Compile Include="UI\Interface\IThumbnailDescriptionViewFactory.cs" />
<Compile Include="UI\Interface\ViewZoomAnchor.cs" />
<Compile Include="Configuration\ThumbnailConfig.cs" />
<Compile Include="View\Interface\IThumbnailDescription.cs" />
<Compile Include="View\Interface\ViewZoomAnchor.cs" />
<Compile Include="Configuration\Implementation\ThumbnailConfiguration.cs" />
<Compile Include="Hotkeys\HotkeyHandler.cs" />
<Compile Include="Hotkeys\HotkeyHandlerNativeMethods.cs" />
<Compile Include="UI\Implementation\MainForm.cs">
<Compile Include="View\Implementation\MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\Implementation\MainForm.Designer.cs">
<Compile Include="View\Implementation\MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="Configuration\IConfigurationStorage.cs" />
<Compile Include="UI\Interface\IThumbnailView.cs" />
<Compile Include="UI\Factory\ThumbnailViewFactory.cs" />
<Compile Include="Presentation\ThumbnailManager.cs" />
<Compile Include="UI\Implementation\ThumbnailOverlay.cs">
<Compile Include="View\Interface\IThumbnailView.cs" />
<Compile Include="View\Implementation\ThumbnailViewFactory.cs" />
<Compile Include="Services\Implementation\ThumbnailManager.cs" />
<Compile Include="View\Implementation\ThumbnailOverlay.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\Implementation\ThumbnailOverlay.Designer.cs">
<Compile Include="View\Implementation\ThumbnailOverlay.Designer.cs">
<DependentUpon>ThumbnailOverlay.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="UI\Implementation\MainForm.resx">
<EmbeddedResource Include="View\Implementation\MainForm.resx">
<SubType>Designer</SubType>
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\Implementation\ThumbnailOverlay.resx">
<EmbeddedResource Include="View\Implementation\ThumbnailOverlay.resx">
<DependentUpon>ThumbnailOverlay.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
@@ -161,7 +191,7 @@
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="UI\Implementation\ThumbnailView.resx">
<EmbeddedResource Include="View\Implementation\ThumbnailView.resx">
<SubType>Designer</SubType>
<DependentUpon>ThumbnailView.cs</DependentUpon>
</EmbeddedResource>
@@ -170,13 +200,13 @@
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<Compile Include="UI\Implementation\ThumbnailView.cs">
<Compile Include="View\Implementation\ThumbnailView.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\Implementation\ThumbnailView.Designer.cs">
<Compile Include="View\Implementation\ThumbnailView.Designer.cs">
<DependentUpon>ThumbnailView.cs</DependentUpon>
</Compile>
<Compile Include="DwmAPI\WindowManagerNativeMethods.cs" />
<Compile Include="Services\Interop\DwmApiNativeMethods.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
@@ -192,17 +222,15 @@
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Fody.2.2.0\build\netstandard1.2\Fody.targets" Condition="Exists('..\packages\Fody.2.2.0\build\netstandard1.2\Fody.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.2.2.0\build\netstandard1.2\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.2.2.0\build\netstandard1.2\Fody.targets'))" />
<Error Condition="!Exists('..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets'))" />
<Error Condition="!Exists('R:\eve-o-preview\packages\Fody.2.2.0\build\net452\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'R:\eve-o-preview\packages\Fody.2.2.0\build\net452\Fody.targets'))" />
<Error Condition="!Exists('..\packages\Fody.2.4.6\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.2.4.6\build\Fody.targets'))" />
</Target>
<Import Project="..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets" Condition="Exists('..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets')" />
<Import Project="R:\eve-o-preview\packages\Fody.2.2.0\build\net452\Fody.targets" Condition="Exists('R:\eve-o-preview\packages\Fody.2.2.0\build\net452\Fody.targets')" />
<Import Project="..\packages\Fody.2.4.6\build\Fody.targets" Condition="Exists('..\packages\Fody.2.4.6\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

@@ -1,15 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=configuration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=configuration_005Cimplementation/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=configuration_005Cinterface/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=gui/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=gui_005Cpresenter_005Cinterface/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=gui_005Cview/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=presentation/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=presentation_005Cinterface/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=thumbnail/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=thumbnail_005Cimplementation/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=thumbnail_005Cinterface/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=ui/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=ui_005Cimplementation/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=ui_005Cinterface/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@@ -2,7 +2,7 @@ using System;
using System.Windows.Forms;
using System.ComponentModel;
namespace EveOPreview.UI
namespace EveOPreview.UI.Hotkeys
{
class HotkeyHandler : IMessageFilter, IDisposable
{

View File

@@ -1,7 +1,7 @@
using System;
using System.Runtime.InteropServices;
namespace EveOPreview.UI
namespace EveOPreview.UI.Hotkeys
{
static class HotkeyHandlerNativeMethods
{

View File

@@ -0,0 +1,25 @@
using System.Threading;
using System.Threading.Tasks;
using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages;
using MediatR;
namespace EveOPreview.Mediator.Handlers.Configuration
{
sealed class SaveConfigurationHandler : IRequestHandler<SaveConfiguration>
{
private readonly IConfigurationStorage _storage;
public SaveConfigurationHandler(IConfigurationStorage storage)
{
this._storage = storage;
}
public Task Handle(SaveConfiguration message, CancellationToken cancellationToken)
{
this._storage.Save();
return Task.CompletedTask;
}
}
}

View File

@@ -0,0 +1,32 @@
using System.Threading;
using System.Threading.Tasks;
using EveOPreview.Mediator.Messages;
using EveOPreview.Services;
using MediatR;
namespace EveOPreview.Mediator.Handlers.Services
{
sealed class StartStopServiceHandler : IRequestHandler<StartService>, IRequestHandler<StopService>
{
private readonly IThumbnailManager _manager;
public StartStopServiceHandler(IThumbnailManager manager)
{
this._manager = manager;
}
public Task Handle(StartService message, CancellationToken cancellationToken)
{
this._manager.Start();
return Task.CompletedTask;
}
public Task Handle(StopService message, CancellationToken cancellationToken)
{
this._manager.Stop();
return Task.CompletedTask;
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,27 @@
using System.Threading;
using System.Threading.Tasks;
using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages;
using MediatR;
namespace EveOPreview.Mediator.Handlers.Thumbnails
{
sealed class ThumbnailLocationUpdatedHandler : INotificationHandler<ThumbnailLocationUpdated>
{
private readonly IMediator _mediator;
private readonly 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);
return this._mediator.Send(new SaveConfiguration(), cancellationToken);
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,21 @@
using System.Drawing;
using MediatR;
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;
}
public string ThumbnailName { get; }
public string ActiveClientName { get; }
public Point Location { get; }
}
}

View File

@@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
namespace EveOPreview.UI
{
public interface IThumbnailManager
{
void Activate();
void Deactivate();
void SetThumbnailState(IntPtr thumbnailId, bool hideAlways);
void SetThumbnailsSize(Size size);
void SetupThumbnailFrames();
Action<IList<IThumbnailView>> ThumbnailsAdded { get; set; }
Action<IList<IThumbnailView>> ThumbnailsUpdated { get; set; }
Action<IList<IThumbnailView>> ThumbnailsRemoved { get; set; }
Action<String, String, Point> ThumbnailPositionChanged { get; set; }
Action<Size> ThumbnailSizeChanged { get; set; }
}
}

View File

@@ -1,502 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Threading;
using EveOPreview.Configuration;
namespace EveOPreview.UI
{
public class ThumbnailManager : IThumbnailManager
{
#region Private constants
private const int WindowPositionThreshold = -5000;
private const int WindowSizeThreshold = -5000;
private const string ClientProcessName = "ExeFile";
private const string DefaultClientTitle = "EVE";
#endregion
#region Private fields
private readonly IThumbnailConfig _configuration;
private readonly DispatcherTimer _thumbnailUpdateTimer;
private readonly IThumbnailViewFactory _thumbnailViewFactory;
private readonly Dictionary<IntPtr, IThumbnailView> _thumbnailViews;
private IntPtr _activeClientHandle;
private string _activeClientTitle;
private bool _ignoreViewEvents;
private bool _isHoverEffectActive;
#endregion
public ThumbnailManager(IThumbnailConfig configuration, IThumbnailViewFactory factory)
{
this._configuration = configuration;
this._thumbnailViewFactory = factory;
this._activeClientHandle = (IntPtr)0;
this._activeClientTitle = ThumbnailManager.DefaultClientTitle;
this.EnableViewEvents();
this._isHoverEffectActive = false;
this._thumbnailViews = new Dictionary<IntPtr, IThumbnailView>();
// DispatcherTimer setup
this._thumbnailUpdateTimer = new DispatcherTimer();
this._thumbnailUpdateTimer.Tick += ThumbnailUpdateTimerTick;
this._thumbnailUpdateTimer.Interval = new TimeSpan(0, 0, 0, 0, configuration.ThumbnailRefreshPeriod);
}
public Action<IList<IThumbnailView>> ThumbnailsAdded { get; set; }
public Action<IList<IThumbnailView>> ThumbnailsUpdated { get; set; }
public Action<IList<IThumbnailView>> ThumbnailsRemoved { get; set; }
public Action<String, String, Point> ThumbnailPositionChanged { get; set; }
public Action<Size> ThumbnailSizeChanged { get; set; }
public void Activate()
{
this._thumbnailUpdateTimer.Start();
this.RefreshThumbnails();
}
public void Deactivate()
{
this._thumbnailUpdateTimer.Stop();
}
public void SetThumbnailState(IntPtr thumbnailId, bool hideAlways)
{
IThumbnailView thumbnail;
if (!this._thumbnailViews.TryGetValue(thumbnailId, out thumbnail))
{
return;
}
thumbnail.IsEnabled = !hideAlways;
}
public void SetThumbnailsSize(Size size)
{
this.DisableViewEvents();
foreach (KeyValuePair<IntPtr, IThumbnailView> entry in this._thumbnailViews)
{
entry.Value.ThumbnailSize = size;
entry.Value.Refresh(false);
}
this.ThumbnailSizeChanged?.Invoke(size);
this.EnableViewEvents();
}
private void RefreshThumbnails()
{
IntPtr foregroundWindowHandle = WindowManagerNativeMethods.GetForegroundWindow();
Boolean hideAllThumbnails = (this._configuration.HideThumbnailsOnLostFocus && this.IsNonClientWindowActive(foregroundWindowHandle)) || !WindowManagerNativeMethods.DwmIsCompositionEnabled();
this.DisableViewEvents();
// Hide, show, resize and move
foreach (KeyValuePair<IntPtr, IThumbnailView> entry in this._thumbnailViews)
{
IThumbnailView view = entry.Value;
if (hideAllThumbnails || !view.IsEnabled)
{
if (view.IsActive)
{
view.Hide();
}
continue;
}
if (this._configuration.HideActiveClientThumbnail && (view.Id == this._activeClientHandle))
{
if (view.IsActive)
{
view.Hide();
}
continue;
}
// No need to update Thumbnails while one of them is highlighted
if (!this._isHoverEffectActive)
{
// Do not even move thumbnails with default caption
if (this.IsManageableThumbnail(view))
{
view.ThumbnailLocation = this._configuration.GetThumbnailLocation(view.Title, this._activeClientTitle, view.ThumbnailLocation);
}
view.SetOpacity(this._configuration.ThumbnailOpacity);
view.SetTopMost(this._configuration.ShowThumbnailsAlwaysOnTop);
}
view.IsOverlayEnabled = this._configuration.ShowThumbnailOverlays;
view.SetHighlight(this._configuration.EnableActiveClientHighlight && (view.Id == this._activeClientHandle),
this._configuration.ActiveClientHighlightColor, this._configuration.ActiveClientHighlightThickness);
if (!view.IsActive)
{
view.Show();
}
else
{
view.Refresh(false);
}
}
this.EnableViewEvents();
}
public void SetupThumbnailFrames()
{
this.DisableViewEvents();
foreach (KeyValuePair<IntPtr, IThumbnailView> entry in this._thumbnailViews)
{
entry.Value.SetFrames(this._configuration.ShowThumbnailFrames);
}
this.EnableViewEvents();
}
private void ThumbnailUpdateTimerTick(object sender, EventArgs e)
{
this.UpdateThumbnailsList();
this.RefreshThumbnails();
}
private void EnableViewEvents()
{
this._ignoreViewEvents = false;
}
private void DisableViewEvents()
{
this._ignoreViewEvents = true;
}
private static Process[] GetClientProcesses()
{
return Process.GetProcessesByName(ThumbnailManager.ClientProcessName);
}
private void UpdateThumbnailsList()
{
Process[] clientProcesses = ThumbnailManager.GetClientProcesses();
List<IntPtr> processHandles = new List<IntPtr>(clientProcesses.Length);
IntPtr foregroundWindowHandle = WindowManagerNativeMethods.GetForegroundWindow();
List<IThumbnailView> viewsAdded = new List<IThumbnailView>();
List<IThumbnailView> viewsUpdated = new List<IThumbnailView>();
List<IThumbnailView> viewsRemoved = new List<IThumbnailView>();
foreach (Process process in clientProcesses)
{
IntPtr processHandle = process.MainWindowHandle;
string processTitle = process.MainWindowTitle;
processHandles.Add(processHandle);
IThumbnailView view;
this._thumbnailViews.TryGetValue(processHandle, out view);
if ((view == null) && (processTitle != ""))
{
view = this._thumbnailViewFactory.Create(processHandle, processTitle, this._configuration.ThumbnailSize);
view.IsEnabled = true;
view.IsOverlayEnabled = this._configuration.ShowThumbnailOverlays;
view.SetFrames(this._configuration.ShowThumbnailFrames);
// Max/Min size limitations should be set AFTER the frames are disabled
// Otherwise thumbnail window will be unnecessary resized
view.SetSizeLimitations(this._configuration.ThumbnailMinimumSize, this._configuration.ThumbnailMaximumSize);
view.SetTopMost(this._configuration.ShowThumbnailsAlwaysOnTop);
view.ThumbnailLocation = this.IsManageableThumbnail(view)
? this._configuration.GetThumbnailLocation(processTitle, this._activeClientTitle, view.ThumbnailLocation)
: this._configuration.GetDefaultThumbnailLocation();
this._thumbnailViews.Add(processHandle, view);
view.ThumbnailResized = this.ThumbnailViewResized;
view.ThumbnailMoved = this.ThumbnailViewMoved;
view.ThumbnailFocused = this.ThumbnailViewFocused;
view.ThumbnailLostFocus = this.ThumbnailViewLostFocus;
view.ThumbnailActivated = this.ThumbnailActivated;
view.ThumbnailDeactivated = this.ThumbnailDeactivated;
view.RegisterHotkey(this._configuration.GetClientHotkey(processTitle));
this.ApplyClientLayout(processHandle, processTitle);
viewsAdded.Add(view);
}
else if ((view != null) && (processTitle != view.Title)) // update thumbnail title
{
view.Title = processTitle;
view.RegisterHotkey(this._configuration.GetClientHotkey(processTitle));
this.ApplyClientLayout(processHandle, processTitle);
viewsUpdated.Add(view);
}
if (process.MainWindowHandle == foregroundWindowHandle)
{
this._activeClientHandle = process.MainWindowHandle;
this._activeClientTitle = process.MainWindowTitle;
}
}
// Cleanup
IList<IntPtr> obsoleteThumbnails = new List<IntPtr>();
foreach (IntPtr processHandle in this._thumbnailViews.Keys)
{
if (!processHandles.Contains(processHandle))
{
obsoleteThumbnails.Add(processHandle);
}
}
foreach (IntPtr processHandle in obsoleteThumbnails)
{
IThumbnailView view = this._thumbnailViews[processHandle];
this._thumbnailViews.Remove(processHandle);
view.UnregisterHotkey();
view.ThumbnailResized = null;
view.ThumbnailMoved = null;
view.ThumbnailFocused = null;
view.ThumbnailLostFocus = null;
view.ThumbnailActivated = null;
view.Close();
viewsRemoved.Add(view);
}
this.ThumbnailsAdded?.Invoke(viewsAdded);
this.ThumbnailsUpdated?.Invoke(viewsUpdated);
this.ThumbnailsRemoved?.Invoke(viewsRemoved);
}
private void ThumbnailViewFocused(IntPtr id)
{
if (this._isHoverEffectActive)
{
return;
}
this._isHoverEffectActive = true;
IThumbnailView view = this._thumbnailViews[id];
view.SetTopMost(true);
view.SetOpacity(1.0);
if (this._configuration.ThumbnailZoomEnabled)
{
this.ThumbnailZoomIn(view);
}
}
private void ThumbnailViewLostFocus(IntPtr id)
{
if (!this._isHoverEffectActive)
{
return;
}
IThumbnailView view = this._thumbnailViews[id];
if (this._configuration.ThumbnailZoomEnabled)
{
this.ThumbnailZoomOut(view);
}
view.SetOpacity(this._configuration.ThumbnailOpacity);
this._isHoverEffectActive = false;
}
private void ThumbnailActivated(IntPtr id)
{
IThumbnailView view;
if (this._thumbnailViews.TryGetValue(id, out view))
{
this._activeClientHandle = view.Id;
this._activeClientTitle = view.Title;
}
WindowManagerNativeMethods.SetForegroundWindow(id);
int style = WindowManagerNativeMethods.GetWindowLong(id, WindowManagerNativeMethods.GWL_STYLE);
// If the window was minimized then its thumbnail should be reset
if ((style & WindowManagerNativeMethods.WS_MINIMIZE) == WindowManagerNativeMethods.WS_MINIMIZE)
{
WindowManagerNativeMethods.ShowWindowAsync(id, WindowManagerNativeMethods.SW_SHOWNORMAL);
}
if (this._configuration.EnableClientLayoutTracking)
{
this.UpdateClientLayouts();
}
this.RefreshThumbnails();
view?.Refresh(true);
}
private void ThumbnailDeactivated(IntPtr id)
{
IThumbnailView view;
if (!this._thumbnailViews.TryGetValue(id, out view))
{
return;
}
WindowManagerNativeMethods.SendMessage(view.Id, WindowManagerNativeMethods.WM_SYSCOMMAND, WindowManagerNativeMethods.SC_MINIMIZE, 0);
this.RefreshThumbnails();
}
private void ThumbnailViewResized(IntPtr id)
{
if (this._ignoreViewEvents)
{
return;
}
IThumbnailView view = this._thumbnailViews[id];
this.SetThumbnailsSize(view.ThumbnailSize);
view.Refresh(false);
}
private void ThumbnailViewMoved(IntPtr id)
{
if (this._ignoreViewEvents)
{
return;
}
IThumbnailView view = this._thumbnailViews[id];
if (this.IsManageableThumbnail(view))
{
this.ThumbnailPositionChanged?.Invoke(view.Title, this._activeClientTitle, view.ThumbnailLocation);
}
view.Refresh(false);
}
private bool IsNonClientWindowActive(IntPtr windowHandle)
{
// We just don't know ATM
if (windowHandle == IntPtr.Zero)
{
return false;
}
foreach (KeyValuePair<IntPtr, IThumbnailView> entry in this._thumbnailViews)
{
IThumbnailView view = entry.Value;
if (view.IsKnownHandle(windowHandle))
{
return false;
}
}
return true;
}
private void ThumbnailZoomIn(IThumbnailView view)
{
this.DisableViewEvents();
view.ZoomIn(ViewZoomAnchorConverter.Convert(this._configuration.ThumbnailZoomAnchor), this._configuration.ThumbnailZoomFactor);
view.Refresh(false);
this.EnableViewEvents();
}
private void ThumbnailZoomOut(IThumbnailView view)
{
this.DisableViewEvents();
view.ZoomOut();
view.Refresh(false);
this.EnableViewEvents();
}
private void ApplyClientLayout(IntPtr clientHandle, string clientTitle)
{
ClientLayout clientLayout = this._configuration.GetClientLayout(clientTitle);
if (clientLayout == null)
{
return;
}
WindowManagerNativeMethods.MoveWindow(clientHandle, clientLayout.X, clientLayout.Y, clientLayout.Width, clientLayout.Height, true);
}
private void UpdateClientLayouts()
{
Process[] clientProcesses = ThumbnailManager.GetClientProcesses();
foreach (Process process in clientProcesses)
{
WindowManagerNativeMethods.GetWindowRect(process.MainWindowHandle, out RECT rect);
int width = Math.Abs(rect.Right - rect.Left);
int height = Math.Abs(rect.Bottom - rect.Top);
if (!this.IsValidWindowPosition(rect.Left, rect.Top, width, height))
{
continue;
}
ClientLayout layout = new ClientLayout();
layout.X = rect.Left;
layout.Y = rect.Top;
layout.Width = width;
layout.Height = height;
this._configuration.SetClientLayout(process.MainWindowTitle, layout);
}
}
// We should no manage some thumbnails (like thumbnail of the EVE client sitting on the login screen)
private bool IsManageableThumbnail(IThumbnailView view)
{
return view.Title != ThumbnailManager.DefaultClientTitle;
}
// Quick sanity check
// EVE Online client can create a window on a really weird position outside of the screen for some reason
// In this case we need to just skip such clients
private bool IsValidWindowPosition(int letf, int top, int width, int height)
{
return (letf >= ThumbnailManager.WindowPositionThreshold)
&& (top >= ThumbnailManager.WindowPositionThreshold)
&& (width >= ThumbnailManager.WindowSizeThreshold)
&& (height >= ThumbnailManager.WindowSizeThreshold);
}
}
}

View File

@@ -3,36 +3,38 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages;
using EveOPreview.View;
using MediatR;
namespace EveOPreview.UI
namespace EveOPreview.Presenters
{
public class MainPresenter : Presenter<IMainView>
public class MainFormPresenter : Presenter<IMainFormView>, IMainFormPresenter
{
#region Private constants
private const string ForumUrl = @"https://meta.eveonline.com/t/4202";
#endregion
#region Private fields
private readonly IThumbnailConfig _configuration;
private readonly IMediator _mediator;
private readonly IThumbnailConfiguration _configuration;
private readonly IConfigurationStorage _configurationStorage;
private readonly IThumbnailDescriptionViewFactory _thumbnailDescriptionViewFactory;
private readonly IDictionary<IntPtr, IThumbnailDescriptionView> _thumbnailDescriptionViews;
private readonly IThumbnailManager _thumbnailManager;
private readonly IDictionary<string, IThumbnailDescription> _descriptionsCache;
private bool _suppressSizeNotifications;
private bool _exitApplication;
#endregion
public MainPresenter(IApplicationController controller, IMainView view, IThumbnailConfig configuration, IConfigurationStorage configurationStorage,
IThumbnailManager thumbnailManager, IThumbnailDescriptionViewFactory thumbnailDescriptionViewFactory)
public MainFormPresenter(IApplicationController controller, IMainFormView view, IMediator mediator, IThumbnailConfiguration configuration, IConfigurationStorage configurationStorage)
: base(controller, view)
{
this._mediator = mediator;
this._configuration = configuration;
this._configurationStorage = configurationStorage;
this._thumbnailDescriptionViewFactory = thumbnailDescriptionViewFactory;
this._thumbnailManager = thumbnailManager;
this._descriptionsCache = new Dictionary<string, IThumbnailDescription>();
this._thumbnailDescriptionViews = new Dictionary<IntPtr, IThumbnailDescriptionView>();
this._suppressSizeNotifications = false;
this._exitApplication = false;
this.View.FormActivated = this.Activate;
@@ -43,26 +45,19 @@ namespace EveOPreview.UI
this.View.ThumbnailStateChanged = this.UpdateThumbnailState;
this.View.DocumentationLinkActivated = this.OpenDocumentationLink;
this.View.ApplicationExitRequested = this.ExitApplication;
this._thumbnailManager.ThumbnailsAdded = this.ThumbnailsAdded;
this._thumbnailManager.ThumbnailsUpdated = this.ThumbnailsUpdated;
this._thumbnailManager.ThumbnailsRemoved = this.ThumbnailsRemoved;
this._thumbnailManager.ThumbnailPositionChanged = this.ThumbnailPositionChanged;
this._thumbnailManager.ThumbnailSizeChanged = this.ThumbnailSizeChanged;
}
private void Activate()
{
this.LoadApplicationSettings();
this.View.SetDocumentationUrl(MainPresenter.ForumUrl);
this.View.SetDocumentationUrl(MainFormPresenter.ForumUrl);
this.View.SetVersionInfo(this.GetApplicationVersion());
if (this._configuration.MinimizeToTray)
{
this.View.Minimize();
}
this._thumbnailManager.Activate();
this._mediator.Send(new StartService());
}
private void Minimize()
@@ -79,7 +74,8 @@ namespace EveOPreview.UI
{
if (this._exitApplication || !this.View.MinimizeToTray)
{
this._thumbnailManager.Deactivate();
this._mediator.Send(new StopService()).Wait();
this._configurationStorage.Save();
request.Allow = true;
return;
@@ -89,10 +85,14 @@ namespace EveOPreview.UI
this.View.Minimize();
}
private void UpdateThumbnailsSize()
private async void UpdateThumbnailsSize()
{
this._thumbnailManager.SetThumbnailsSize(this.View.ThumbnailSize);
this.SaveApplicationSettings();
if (!this._suppressSizeNotifications)
{
await this._mediator.Publish(new ThumbnailConfiguredSizeUpdated());
}
}
private void LoadApplicationSettings()
@@ -105,6 +105,7 @@ namespace EveOPreview.UI
this.View.EnableClientLayoutTracking = this._configuration.EnableClientLayoutTracking;
this.View.HideActiveClientThumbnail = this._configuration.HideActiveClientThumbnail;
this.View.MinimizeInactiveClients = this._configuration.MinimizeInactiveClients;
this.View.ShowThumbnailsAlwaysOnTop = this._configuration.ShowThumbnailsAlwaysOnTop;
this.View.HideThumbnailsOnLostFocus = this._configuration.HideThumbnailsOnLostFocus;
this.View.EnablePerClientThumbnailLayouts = this._configuration.EnablePerClientThumbnailLayouts;
@@ -122,7 +123,7 @@ namespace EveOPreview.UI
this.View.ActiveClientHighlightColor = this._configuration.ActiveClientHighlightColor;
}
private void SaveApplicationSettings()
private async void SaveApplicationSettings()
{
this._configuration.MinimizeToTray = this.View.MinimizeToTray;
@@ -130,6 +131,7 @@ namespace EveOPreview.UI
this._configuration.EnableClientLayoutTracking = this.View.EnableClientLayoutTracking;
this._configuration.HideActiveClientThumbnail = this.View.HideActiveClientThumbnail;
this._configuration.MinimizeInactiveClients = this.View.MinimizeInactiveClients;
this._configuration.ShowThumbnailsAlwaysOnTop = this.View.ShowThumbnailsAlwaysOnTop;
this._configuration.HideThumbnailsOnLostFocus = this.View.HideThumbnailsOnLostFocus;
this._configuration.EnablePerClientThumbnailLayouts = this.View.EnablePerClientThumbnailLayouts;
@@ -141,7 +143,12 @@ namespace EveOPreview.UI
this._configuration.ThumbnailZoomAnchor = ViewZoomAnchorConverter.Convert(this.View.ThumbnailZoomAnchor);
this._configuration.ShowThumbnailOverlays = this.View.ShowThumbnailOverlays;
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());
}
this._configuration.EnableActiveClientHighlight = this.View.EnableActiveClientHighlight;
this._configuration.ActiveClientHighlightColor = this.View.ActiveClientHighlightColor;
@@ -149,92 +156,83 @@ namespace EveOPreview.UI
this.View.RefreshZoomSettings();
this._thumbnailManager.SetupThumbnailFrames();
await this._mediator.Send(new SaveConfiguration());
}
private void ThumbnailsAdded(IList<IThumbnailView> thumbnails)
{
this.View.AddThumbnails(this.GetThumbnailViews(thumbnails, false));
}
private void ThumbnailsUpdated(IList<IThumbnailView> thumbnails)
public void AddThumbnails(IList<string> thumbnailTitles)
{
this.View.UpdateThumbnails(this.GetThumbnailViews(thumbnails, false));
}
IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count);
private void ThumbnailsRemoved(IList<IThumbnailView> thumbnails)
{
this.View.RemoveThumbnails(this.GetThumbnailViews(thumbnails, true));
}
private IList<IThumbnailDescriptionView> GetThumbnailViews(IList<IThumbnailView> thumbnails, bool removeFromCache)
{
IList<IThumbnailDescriptionView> thumbnailViews = new List<IThumbnailDescriptionView>(thumbnails.Count);
// Time for some thread safety
lock (this._thumbnailDescriptionViews)
lock (this._descriptionsCache)
{
foreach (IThumbnailView thumbnail in thumbnails)
foreach (string title in thumbnailTitles)
{
IThumbnailDescriptionView thumbnailView;
bool foundInCache = this._thumbnailDescriptionViews.TryGetValue(thumbnail.Id, out thumbnailView);
IThumbnailDescription description = this.CreateThumbnailDescription(title);
this._descriptionsCache[title] = description;
if (!foundInCache)
{
if (removeFromCache)
{
// This item was not even cached
continue;
}
thumbnailView = this._thumbnailDescriptionViewFactory.Create(thumbnail.Id, thumbnail.Title, !thumbnail.IsEnabled);
this._thumbnailDescriptionViews.Add(thumbnail.Id, thumbnailView);
}
else
{
if (removeFromCache)
{
this._thumbnailDescriptionViews.Remove(thumbnail.Id);
}
else
{
thumbnailView.Title = thumbnail.Title;
}
}
thumbnailViews.Add(thumbnailView);
descriptions.Add(description);
}
}
return thumbnailViews;
this.View.AddThumbnails(descriptions);
}
private void ThumbnailPositionChanged(String thumbnailName, String activeClientName, Point location)
public void RemoveThumbnails(IList<string> thumbnailTitles)
{
this._configuration.SetThumbnailLocation(thumbnailName, activeClientName, location);
this._configurationStorage.Save();
IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count);
lock (this._descriptionsCache)
{
foreach (string title in thumbnailTitles)
{
if (!this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description))
{
continue;
}
this._descriptionsCache.Remove(title);
descriptions.Add(description);
}
}
this.View.RemoveThumbnails(descriptions);
}
private void ThumbnailSizeChanged(Size size)
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))
{
this._configuration.ToggleThumbnail(title, description.IsDisabled);
}
await this._mediator.Send(new SaveConfiguration());
}
public void UpdateThumbnailSize(Size size)
{
this._suppressSizeNotifications = true;
this.View.ThumbnailSize = size;
}
private void UpdateThumbnailState(IntPtr thumbnailId)
{
this._thumbnailManager.SetThumbnailState(thumbnailId, this._thumbnailDescriptionViews[thumbnailId].IsDisabled);
this._suppressSizeNotifications = false;
}
private void OpenDocumentationLink()
{
ProcessStartInfo processStartInfo = new ProcessStartInfo(new Uri(MainPresenter.ForumUrl).AbsoluteUri);
// TODO Move out to a separate service / presenter / message handler
ProcessStartInfo processStartInfo = new ProcessStartInfo(new Uri(MainFormPresenter.ForumUrl).AbsoluteUri);
Process.Start(processStartInfo);
}
private string GetApplicationVersion()
{
Version version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version;
return String.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Revision);
return $"{version.Major}.{version.Minor}.{version.Revision}";
}
private void ExitApplication()

View File

@@ -1,6 +1,6 @@
using EveOPreview.Configuration;
namespace EveOPreview.UI
namespace EveOPreview.View
{
static class ViewZoomAnchorConverter
{

View File

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

View File

@@ -1,4 +1,4 @@
namespace EveOPreview.UI
namespace EveOPreview.View
{
public class ViewCloseRequest
{

View File

@@ -2,25 +2,28 @@ using System;
using System.Threading;
using System.Windows.Forms;
using EveOPreview.Configuration;
using EveOPreview.Presenters;
using EveOPreview.Services;
using EveOPreview.UI;
using EveOPreview.View;
using MediatR;
namespace EveOPreview
{
static class Program
{
private static string MutexName = "EVE-O Preview Single Instance Mutex";
private static string ConfigParameterName = "--config:";
/// <summary>The main entry point for the application.</summary>
[STAThread]
static void Main(string[] args)
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
object token = Program.GetInstanceToken();
// If it was not possible to aquite the app token then another app instance is already running
// If it was not possible to aquire the app token then another app instance is already running
// Nothing to do here
if (token == null)
{
@@ -30,55 +33,23 @@ namespace EveOPreview
ExceptionHandler handler = new ExceptionHandler();
handler.SetupExceptionHandlers();
Program.InitializeWinFormsGui();
IApplicationController controller = Program.InitializeApplicationController();
Program.SetupApplicationConttroller(controller, Program.GetCustomConfigFile(args));
controller.Run<MainPresenter>();
}
private static string GetCustomConfigFile(string[] args)
{
// Parse startup parameters
// Simple approach is used because something like NParams would be an overkill here
string configFile = null;
foreach (string arg in args)
{
if ((arg.Length <= Program.ConfigParameterName.Length) || !arg.StartsWith(Program.ConfigParameterName, StringComparison.Ordinal))
{
continue;
}
configFile = arg.Substring(Program.ConfigParameterName.Length);
break;
}
if (string.IsNullOrEmpty(configFile))
{
return "";
}
// One more check to drop trailing "
if ((configFile.Length > 3) && (configFile[0] == '"') && (configFile[configFile.Length - 1] == '"'))
{
configFile = configFile.Substring(1, configFile.Length - 2);
}
return configFile;
Program.InitializeWinForms();
controller.Run<MainFormPresenter>();
}
private static object GetInstanceToken()
{
// The code might look overcomplicated here for a single Mutex operation
// Yet we had already experienced a Windows-level issue
// where .NET finalizer theread was literally paralyzed by
// where .NET finalizer thread was literally paralyzed by
// a failed Mutex operation. That did lead to weird OutOfMemory
// exceptions later
try
{
Mutex mutex = Mutex.OpenExisting(Program.MutexName);
// if that didn't fail then anotherinstance is already running
Mutex.OpenExisting(Program.MutexName);
// if that didn't fail then another instance is already running
return null;
}
catch (UnauthorizedAccessException)
@@ -87,13 +58,12 @@ namespace EveOPreview
}
catch (Exception)
{
bool result;
Mutex token = new Mutex(true, Program.MutexName, out result);
Mutex token = new Mutex(true, Program.MutexName, out var result);
return result ? token : null;
}
}
private static void InitializeWinFormsGui()
private static void InitializeWinForms()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
@@ -103,27 +73,37 @@ namespace EveOPreview
{
IIocContainer container = new LightInjectContainer();
// UI classes
IApplicationController controller = new ApplicationController(container)
.RegisterView<IMainView, MainForm>()
.RegisterView<IThumbnailView, ThumbnailView>()
.RegisterView<IThumbnailDescriptionView, ThumbnailDescriptionView>()
.RegisterInstance(new ApplicationContext());
// Singleton registration is used for services
// Low-level services
container.Register<IWindowManager>();
container.Register<IProcessMonitor>();
// MediatR
container.Register<IMediator, MediatR.Mediator>();
container.RegisterInstance<SingleInstanceFactory>(t => container.Resolve(t));
container.RegisterInstance<MultiInstanceFactory>(t => container.ResolveAll(t));
container.Register(typeof(INotificationHandler<>), typeof(Program).Assembly);
container.Register(typeof(IRequestHandler<>), typeof(Program).Assembly);
container.Register(typeof(IRequestHandler<,>), typeof(Program).Assembly);
// Configuration services
container.Register<IConfigurationStorage>();
container.Register<IAppConfig>();
container.Register<IThumbnailConfiguration>();
// Application services
controller.RegisterService<IThumbnailManager, ThumbnailManager>()
.RegisterService<IThumbnailViewFactory, ThumbnailViewFactory>()
.RegisterService<IThumbnailDescriptionViewFactory, ThumbnailDescriptionViewFactory>()
.RegisterService<IConfigurationStorage, ConfigurationStorage>()
.RegisterInstance<IAppConfig>(new AppConfig())
.RegisterInstance<IThumbnailConfig>(new ThumbnailConfig());
container.Register<IThumbnailManager>();
container.Register<IThumbnailViewFactory>();
container.Register<IThumbnailDescription>();
IApplicationController controller = new ApplicationController(container);
// UI classes
controller.RegisterView<IMainFormView, MainForm>()
.RegisterView<IThumbnailView, ThumbnailView>()
.RegisterInstance(new ApplicationContext());
return controller;
}
private static void SetupApplicationConttroller(IApplicationController controller, string configFile)
{
controller.Create<IAppConfig>().ConfigFileName = configFile;
}
}
}

View File

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

View File

@@ -0,0 +1,88 @@
using System;
using EveOPreview.Services.Interop;
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)
{
this._windowManager = windowManager;
this._handle = IntPtr.Zero;
}
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.opacity = 255;
this._properties.fVisible = true;
this._properties.fSourceClientAreaOnly = true;
if (!this._windowManager.IsCompositionEnabled)
{
return;
}
try
{
this._handle = DwmApiNativeMethods.DwmRegisterThumbnail(destination, source);
}
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
// lised in the process list yet it already cannot be used as
// a thumbnail source
this._handle = IntPtr.Zero;
}
}
public void Unregister()
{
if ((!this._windowManager.IsCompositionEnabled) || (this._handle == IntPtr.Zero))
{
return;
}
try
{
DwmApiNativeMethods.DwmUnregisterThumbnail(this._handle);
}
catch (ArgumentException)
{
}
}
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))
{
return;
}
try
{
DwmApiNativeMethods.DwmUpdateThumbnailProperties(this._handle, this._properties);
}
catch (ArgumentException)
{
//This exception will be thrown if the EVE client disappears while this method is running
}
}
}
}

View File

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

View File

@@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace EveOPreview.Services.Implementation
{
sealed class ProcessMonitor : IProcessMonitor
{
#region Private constants
private const string DefaultProcessName = "ExeFile";
#endregion
#region Private fields
private readonly IDictionary<IntPtr, string> _processCache;
#endregion
public ProcessMonitor()
{
this._processCache = new Dictionary<IntPtr, string>(512);
}
private bool IsMonitoredProcess(string processName)
{
// This is a possible extension point
return String.Equals(processName, ProcessMonitor.DefaultProcessName, StringComparison.OrdinalIgnoreCase);
}
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())
{
string processName = process.ProcessName;
if (!this.IsMonitoredProcess(processName))
{
continue;
}
IntPtr mainWindowHandle = process.MainWindowHandle;
if (mainWindowHandle == IntPtr.Zero)
{
continue; // No need to monitor non-visual processes
}
string mainWindowTitle = process.MainWindowTitle;
this._processCache.TryGetValue(mainWindowHandle, out string cachedTitle);
if (cachedTitle == null)
{
// This is a new process in the list
this._processCache.Add(mainWindowHandle, mainWindowTitle);
addedProcesses.Add(new ProcessInfo(mainWindowHandle, mainWindowTitle));
}
else
{
// This is an already known process
if (cachedTitle != mainWindowTitle)
{
this._processCache[mainWindowHandle] = mainWindowTitle;
updatedProcesses.Add((IProcessInfo)new ProcessInfo(mainWindowHandle, mainWindowTitle));
}
knownProcesses.Remove(mainWindowHandle);
}
}
foreach (IntPtr index in knownProcesses)
{
string title = this._processCache[index];
removedProcesses.Add(new ProcessInfo(index, title));
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

@@ -0,0 +1,667 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows.Threading;
using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages;
using EveOPreview.View;
using MediatR;
namespace EveOPreview.Services
{
class ThumbnailManager : IThumbnailManager
{
#region Private constants
private const int WindowPositionThresholdLow = -10_000;
private const int WindowPositionThresholdHigh = 31_000;
private const int WindowSizeThreshold = 10;
private const int ForcedRefreshCycleThreshold = 2;
private const int DefaultLocationChangeNotificationDelay = 2;
private const string DefaultClientTitle = "EVE";
#endregion
#region Private fields
private readonly IMediator _mediator;
private readonly IProcessMonitor _processMonitor;
private readonly IWindowManager _windowManager;
private readonly IThumbnailConfiguration _configuration;
private readonly DispatcherTimer _thumbnailUpdateTimer;
private readonly IThumbnailViewFactory _thumbnailViewFactory;
private readonly Dictionary<IntPtr, IThumbnailView> _thumbnailViews;
private (IntPtr Handle, string Title) _activeClient;
private readonly object _locationChangeNotificationSyncRoot;
private (IntPtr Handle, string Title, string ActiveClient, Point Location, int Delay) _enqueuedLocationChangeNotification;
private bool _ignoreViewEvents;
private bool _isHoverEffectActive;
private int _refreshCycleCount;
#endregion
public ThumbnailManager(IMediator mediator, IThumbnailConfiguration configuration, IProcessMonitor processMonitor, IWindowManager windowManager, IThumbnailViewFactory factory)
{
this._mediator = mediator;
this._processMonitor = processMonitor;
this._windowManager = windowManager;
this._configuration = configuration;
this._thumbnailViewFactory = factory;
this._activeClient = (IntPtr.Zero, ThumbnailManager.DefaultClientTitle);
this.EnableViewEvents();
this._isHoverEffectActive = false;
this._refreshCycleCount = 0;
this._locationChangeNotificationSyncRoot = new object();
this._enqueuedLocationChangeNotification = (IntPtr.Zero, null, null, Point.Empty, -1);
this._thumbnailViews = new Dictionary<IntPtr, IThumbnailView>();
// DispatcherTimer setup
this._thumbnailUpdateTimer = new DispatcherTimer();
this._thumbnailUpdateTimer.Tick += ThumbnailUpdateTimerTick;
this._thumbnailUpdateTimer.Interval = new TimeSpan(0, 0, 0, 0, configuration.ThumbnailRefreshPeriod);
}
public void Start()
{
this._thumbnailUpdateTimer.Start();
this.RefreshThumbnails();
}
public void Stop()
{
this._thumbnailUpdateTimer.Stop();
}
private void ThumbnailUpdateTimerTick(object sender, EventArgs e)
{
this.UpdateThumbnailsList();
this.RefreshThumbnails();
}
private async void UpdateThumbnailsList()
{
this._processMonitor.GetUpdatedProcesses(out ICollection<IProcessInfo> addedProcesses, out ICollection<IProcessInfo> updatedProcesses, out ICollection<IProcessInfo> removedProcesses);
List<string> viewsAdded = new List<string>();
List<string> viewsRemoved = new List<string>();
foreach (IProcessInfo process in addedProcesses)
{
IThumbnailView view = this._thumbnailViewFactory.Create(process.Handle, process.Title, this._configuration.ThumbnailSize);
view.IsOverlayEnabled = this._configuration.ShowThumbnailOverlays;
view.SetFrames(this._configuration.ShowThumbnailFrames);
// Max/Min size limitations should be set AFTER the frames are disabled
// Otherwise thumbnail window will be unnecessary resized
view.SetSizeLimitations(this._configuration.ThumbnailMinimumSize, this._configuration.ThumbnailMaximumSize);
view.SetTopMost(this._configuration.ShowThumbnailsAlwaysOnTop);
view.ThumbnailLocation = this.IsManageableThumbnail(view)
? this._configuration.GetThumbnailLocation(view.Title, this._activeClient.Title, view.ThumbnailLocation)
: this._configuration.GetDefaultThumbnailLocation();
this._thumbnailViews.Add(view.Id, view);
view.ThumbnailResized = this.ThumbnailViewResized;
view.ThumbnailMoved = this.ThumbnailViewMoved;
view.ThumbnailFocused = this.ThumbnailViewFocused;
view.ThumbnailLostFocus = this.ThumbnailViewLostFocus;
view.ThumbnailActivated = this.ThumbnailActivated;
view.ThumbnailDeactivated = this.ThumbnailDeactivated;
view.RegisterHotkey(this._configuration.GetClientHotkey(view.Title));
this.ApplyClientLayout(view.Id, view.Title);
// TODO Add extension filter here later
if (view.Title != ThumbnailManager.DefaultClientTitle)
{
viewsAdded.Add(view.Title);
}
}
foreach (IProcessInfo process in updatedProcesses)
{
this._thumbnailViews.TryGetValue(process.Handle, out IThumbnailView view);
if (view == null)
{
// Something went terribly wrong
continue;
}
if (process.Title != view.Title) // update thumbnail title
{
viewsRemoved.Add(view.Title);
view.Title = process.Title;
viewsAdded.Add(view.Title);
view.RegisterHotkey(this._configuration.GetClientHotkey(process.Title));
this.ApplyClientLayout(view.Id, view.Title);
}
}
foreach (IProcessInfo process in removedProcesses)
{
IThumbnailView view = this._thumbnailViews[process.Handle];
this._thumbnailViews.Remove(view.Id);
if (view.Title != ThumbnailManager.DefaultClientTitle)
{
viewsRemoved.Add(view.Title);
}
view.UnregisterHotkey();
view.ThumbnailResized = null;
view.ThumbnailMoved = null;
view.ThumbnailFocused = null;
view.ThumbnailLostFocus = null;
view.ThumbnailActivated = null;
view.Close();
}
if ((viewsAdded.Count > 0) || (viewsRemoved.Count > 0))
{
await this._mediator.Publish(new ThumbnailListUpdated(viewsAdded, viewsRemoved));
}
}
private void RefreshThumbnails()
{
// TODO Split this method
IntPtr foregroundWindowHandle = this._windowManager.GetForegroundWindowHandle();
string foregroundWindowTitle = null;
if (foregroundWindowHandle == this._activeClient.Handle)
{
foregroundWindowTitle = this._activeClient.Title;
}
else if (this._thumbnailViews.TryGetValue(foregroundWindowHandle, out IThumbnailView foregroundView))
{
// This code will work only on Alt+Tab switch between clients
foregroundWindowTitle = foregroundView.Title;
}
// No need to minimize EVE clients when switching out to non-EVE window (like thumbnail)
if (!string.IsNullOrEmpty(foregroundWindowTitle))
{
this.SwitchActiveClient(foregroundWindowHandle, foregroundWindowTitle);
}
bool hideAllThumbnails = this._configuration.HideThumbnailsOnLostFocus && !(string.IsNullOrEmpty(foregroundWindowTitle) || this.IsClientWindowActive(foregroundWindowHandle));
this._refreshCycleCount++;
bool forceRefresh;
if (this._refreshCycleCount >= ThumbnailManager.ForcedRefreshCycleThreshold)
{
this._refreshCycleCount = 0;
forceRefresh = true;
}
else
{
forceRefresh = false;
}
this.DisableViewEvents();
// Snap thumbnail
// No need to update Thumbnails while one of them is highlighted
if ((!this._isHoverEffectActive) && this.TryDequeueLocationChange(out var locationChange))
{
if ((locationChange.ActiveClient == this._activeClient.Title) && this._thumbnailViews.TryGetValue(locationChange.Handle, out var view))
{
this.SnapThumbnailView(view);
this.RaiseThumbnailLocationUpdatedNotification(view.Title, this._activeClient.Title, view.ThumbnailLocation);
}
else
{
this.RaiseThumbnailLocationUpdatedNotification(locationChange.Title, locationChange.ActiveClient, locationChange.Location);
}
}
// Hide, show, resize and move
foreach (KeyValuePair<IntPtr, IThumbnailView> entry in this._thumbnailViews)
{
IThumbnailView view = entry.Value;
if (hideAllThumbnails || this._configuration.IsThumbnailDisabled(view.Title))
{
if (view.IsActive)
{
view.Hide();
}
continue;
}
if (this._configuration.HideActiveClientThumbnail && (view.Id == this._activeClient.Handle))
{
if (view.IsActive)
{
view.Hide();
}
continue;
}
// No need to update Thumbnails while one of them is highlighted
if (!this._isHoverEffectActive)
{
// Do not even move thumbnails with default caption
if (this.IsManageableThumbnail(view))
{
view.ThumbnailLocation = this._configuration.GetThumbnailLocation(view.Title, this._activeClient.Title, view.ThumbnailLocation);
}
view.SetOpacity(this._configuration.ThumbnailOpacity);
view.SetTopMost(this._configuration.ShowThumbnailsAlwaysOnTop);
}
view.IsOverlayEnabled = this._configuration.ShowThumbnailOverlays;
view.SetHighlight(this._configuration.EnableActiveClientHighlight && (view.Id == this._activeClient.Handle),
this._configuration.ActiveClientHighlightColor, this._configuration.ActiveClientHighlightThickness);
if (!view.IsActive)
{
view.Show();
}
else
{
view.Refresh(forceRefresh);
}
}
this.EnableViewEvents();
}
public void UpdateThumbnailsSize()
{
this.SetThumbnailsSize(this._configuration.ThumbnailSize);
}
private void SetThumbnailsSize(Size size)
{
this.DisableViewEvents();
foreach (KeyValuePair<IntPtr, IThumbnailView> entry in this._thumbnailViews)
{
entry.Value.ThumbnailSize = size;
entry.Value.Refresh(false);
}
this.EnableViewEvents();
}
public void UpdateThumbnailFrames()
{
this.DisableViewEvents();
foreach (KeyValuePair<IntPtr, IThumbnailView> entry in this._thumbnailViews)
{
entry.Value.SetFrames(this._configuration.ShowThumbnailFrames);
}
this.EnableViewEvents();
}
private void EnableViewEvents()
{
this._ignoreViewEvents = false;
}
private void DisableViewEvents()
{
this._ignoreViewEvents = true;
}
private void SwitchActiveClient(IntPtr foregroungClientHandle, string foregroundClientTitle)
{
// Check if any actions are needed
if (this._activeClient.Handle == foregroungClientHandle)
{
return;
}
// Minimize the currently active client if needed
if (this._configuration.MinimizeInactiveClients && !this._configuration.IsPriorityClient(this._activeClient.Title))
{
this._windowManager.MinimizeWindow(this._activeClient.Handle, false);
}
this._activeClient = (foregroungClientHandle, foregroundClientTitle);
}
private void ThumbnailViewFocused(IntPtr id)
{
if (this._isHoverEffectActive)
{
return;
}
this._isHoverEffectActive = true;
IThumbnailView view = this._thumbnailViews[id];
view.SetTopMost(true);
view.SetOpacity(1.0);
if (this._configuration.ThumbnailZoomEnabled)
{
this.ThumbnailZoomIn(view);
}
}
private void ThumbnailViewLostFocus(IntPtr id)
{
if (!this._isHoverEffectActive)
{
return;
}
IThumbnailView view = this._thumbnailViews[id];
if (this._configuration.ThumbnailZoomEnabled)
{
this.ThumbnailZoomOut(view);
}
view.SetOpacity(this._configuration.ThumbnailOpacity);
this._isHoverEffectActive = false;
}
private void ThumbnailActivated(IntPtr id)
{
// View is always available because this method is actually being called by
// a view callback
IThumbnailView view = this._thumbnailViews[id];
Task.Run(() => this._windowManager.ActivateWindow(view.Id));
this.UpdateClientLayouts();
}
private void ThumbnailDeactivated(IntPtr id)
{
if (!this._thumbnailViews.TryGetValue(id, out IThumbnailView view))
{
return;
}
this._windowManager.MinimizeWindow(view.Id, true);
this.RefreshThumbnails();
}
private async void ThumbnailViewResized(IntPtr id)
{
if (this._ignoreViewEvents)
{
return;
}
IThumbnailView view = this._thumbnailViews[id];
this.SetThumbnailsSize(view.ThumbnailSize);
view.Refresh(false);
await this._mediator.Publish(new ThumbnailActiveSizeUpdated(view.ThumbnailSize));
}
private void ThumbnailViewMoved(IntPtr id)
{
if (this._ignoreViewEvents)
{
return;
}
IThumbnailView view = this._thumbnailViews[id];
view.Refresh(false);
this.EnqueueLocationChange(view);
}
private bool IsClientWindowActive(IntPtr windowHandle)
{
if (windowHandle == IntPtr.Zero)
{
return false;
}
foreach (KeyValuePair<IntPtr, IThumbnailView> entry in this._thumbnailViews)
{
IThumbnailView view = entry.Value;
if (view.IsKnownHandle(windowHandle))
{
return true;
}
}
return false;
}
private void ThumbnailZoomIn(IThumbnailView view)
{
this.DisableViewEvents();
view.ZoomIn(ViewZoomAnchorConverter.Convert(this._configuration.ThumbnailZoomAnchor), this._configuration.ThumbnailZoomFactor);
view.Refresh(false);
this.EnableViewEvents();
}
private void ThumbnailZoomOut(IThumbnailView view)
{
this.DisableViewEvents();
view.ZoomOut();
view.Refresh(false);
this.EnableViewEvents();
}
private void SnapThumbnailView(IThumbnailView view)
{
// Check if this feature is enabled
if (!this._configuration.EnableThumbnailSnap)
{
return;
}
// Only borderless thumbnails can be docked
if (this._configuration.ShowThumbnailFrames)
{
return;
}
int width = this._configuration.ThumbnailSize.Width;
int height = this._configuration.ThumbnailSize.Height;
// TODO Extract method
int baseX = view.ThumbnailLocation.X;
int baseY = view.ThumbnailLocation.Y;
Point[] viewPoints = { new Point(baseX, baseY), new Point(baseX + width, baseY), new Point(baseX, baseY + height), new Point(baseX + width, baseY + height) };
// TODO Extract constants
int thresholdX = Math.Max(20, width / 10);
int thresholdY = Math.Max(20, height / 10);
foreach (var entry in this._thumbnailViews)
{
IThumbnailView testView = entry.Value;
if (view.Id == testView.Id)
{
continue;
}
int testX = testView.ThumbnailLocation.X;
int testY = testView.ThumbnailLocation.Y;
Point[] testPoints = { new Point(testX, testY), new Point(testX + width, testY), new Point(testX, testY + height), new Point(testX + width, testY + height) };
var delta = ThumbnailManager.TestViewPoints(viewPoints, testPoints, thresholdX, thresholdY);
if ((delta.X == 0) && (delta.Y == 0))
{
continue;
}
view.ThumbnailLocation = new Point(view.ThumbnailLocation.X + delta.X, view.ThumbnailLocation.Y + delta.Y);
this._configuration.SetThumbnailLocation(view.Title, this._activeClient.Title, view.ThumbnailLocation);
break;
}
}
private static (int X, int Y) TestViewPoints(Point[] viewPoints, Point[] testPoints, int thresholdX, int thresholdY)
{
// Point combinations that we need to check
// No need to check all 4x4 combinations
(int ViewOffset, int TestOffset)[] testOffsets =
{ ( 0, 3 ), ( 0, 2 ), ( 1, 2 ),
( 0, 1 ), ( 0, 0 ), ( 1, 0 ),
( 2, 1 ), ( 2, 0 ), ( 3, 0 )};
foreach (var testOffset in testOffsets)
{
Point viewPoint = viewPoints[testOffset.ViewOffset];
Point testPoint = testPoints[testOffset.TestOffset];
int deltaX = testPoint.X - viewPoint.X;
int deltaY = testPoint.Y - viewPoint.Y;
if ((Math.Abs(deltaX) <= thresholdX) && (Math.Abs(deltaY) <= thresholdY))
{
return (deltaX, deltaY);
}
}
return (0, 0);
}
private void ApplyClientLayout(IntPtr clientHandle, string clientTitle)
{
ClientLayout clientLayout = this._configuration.GetClientLayout(clientTitle);
if (clientLayout == null)
{
return;
}
this._windowManager.MoveWindow(clientHandle, clientLayout.X, clientLayout.Y, clientLayout.Width, clientLayout.Height);
}
private void UpdateClientLayouts()
{
if (!this._configuration.EnableClientLayoutTracking)
{
return;
}
foreach (KeyValuePair<IntPtr, IThumbnailView> entry in this._thumbnailViews)
{
IThumbnailView view = entry.Value;
(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);
if (!this.IsValidWindowPosition(position.Left, position.Top, width, height))
{
continue;
}
this._configuration.SetClientLayout(view.Title, new ClientLayout(position.Left, position.Top, width, height));
}
}
private void EnqueueLocationChange(IThumbnailView view)
{
string activeClientTitle = this._activeClient.Title;
// TODO ??
this._configuration.SetThumbnailLocation(view.Title, activeClientTitle, view.ThumbnailLocation);
lock (this._locationChangeNotificationSyncRoot)
{
if (this._enqueuedLocationChangeNotification.Handle == IntPtr.Zero)
{
this._enqueuedLocationChangeNotification = (view.Id, view.Title, activeClientTitle, view.ThumbnailLocation, ThumbnailManager.DefaultLocationChangeNotificationDelay);
return;
}
// Reset the delay and exit
if ((this._enqueuedLocationChangeNotification.Handle == view.Id) &&
(this._enqueuedLocationChangeNotification.ActiveClient == activeClientTitle))
{
this._enqueuedLocationChangeNotification.Delay = ThumbnailManager.DefaultLocationChangeNotificationDelay;
return;
}
this.RaiseThumbnailLocationUpdatedNotification(this._enqueuedLocationChangeNotification.Title, activeClientTitle, this._enqueuedLocationChangeNotification.Location);
this._enqueuedLocationChangeNotification = (view.Id, view.Title, activeClientTitle, view.ThumbnailLocation, ThumbnailManager.DefaultLocationChangeNotificationDelay);
}
}
private bool TryDequeueLocationChange(out (IntPtr Handle, string Title, string ActiveClient, Point Location) change)
{
lock (this._locationChangeNotificationSyncRoot)
{
change = (IntPtr.Zero, null, null, Point.Empty);
if (this._enqueuedLocationChangeNotification.Handle == IntPtr.Zero)
{
return false;
}
this._enqueuedLocationChangeNotification.Delay--;
if (this._enqueuedLocationChangeNotification.Delay > 0)
{
return false;
}
change = (this._enqueuedLocationChangeNotification.Handle, this._enqueuedLocationChangeNotification.Title, this._enqueuedLocationChangeNotification.ActiveClient, this._enqueuedLocationChangeNotification.Location);
this._enqueuedLocationChangeNotification = (IntPtr.Zero, null, null, Point.Empty, -1);
return true;
}
}
private async void RaiseThumbnailLocationUpdatedNotification(string title, string activeClient, Point location)
{
if (string.IsNullOrEmpty(title) || (title == ThumbnailManager.DefaultClientTitle))
{
return;
}
await this._mediator.Send(new SaveConfiguration());
}
// We shouldn't manage some thumbnails (like thumbnail of the EVE client sitting on the login screen)
// TODO Move to a service (?)
private bool IsManageableThumbnail(IThumbnailView view)
{
return view.Title != ThumbnailManager.DefaultClientTitle;
}
// Quick sanity check that the window is not minimized
private bool IsValidWindowPosition(int letf, int top, int width, int height)
{
return (letf > ThumbnailManager.WindowPositionThresholdLow) && (letf < ThumbnailManager.WindowPositionThresholdHigh)
&& (top > ThumbnailManager.WindowPositionThresholdLow) && (top < ThumbnailManager.WindowPositionThresholdHigh)
&& (width > ThumbnailManager.WindowSizeThreshold) && (height > ThumbnailManager.WindowSizeThreshold);
}
}
}

View File

@@ -0,0 +1,74 @@
using System;
using System.Runtime.InteropServices;
using EveOPreview.Services.Interop;
namespace EveOPreview.Services.Implementation
{
class WindowManager : IWindowManager
{
public WindowManager()
{
this.IsCompositionEnabled = DwmApiNativeMethods.DwmIsCompositionEnabled();
}
public bool IsCompositionEnabled { get; }
public IntPtr GetForegroundWindowHandle()
{
return User32NativeMethods.GetForegroundWindow();
}
public void ActivateWindow(IntPtr handle)
{
User32NativeMethods.SetForegroundWindow(handle);
int style = User32NativeMethods.GetWindowLong(handle, InteropConstants.GWL_STYLE);
if ((style & InteropConstants.WS_MINIMIZE) == InteropConstants.WS_MINIMIZE)
{
User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_SHOWNORMAL);
}
}
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);
param.showCmd = WINDOWPLACEMENT.SW_MINIMIZE;
User32NativeMethods.SetWindowPlacement(handle, ref param);
}
}
public void MoveWindow(IntPtr handle, int left, int top, int width, int height)
{
User32NativeMethods.MoveWindow(handle, left, top, width, height, true);
}
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 IsWindowMinimized(IntPtr handle)
{
return User32NativeMethods.IsIconic(handle);
}
public IDwmThumbnail RegisterThumbnail(IntPtr destination, IntPtr source)
{
IDwmThumbnail thumbnail = new DwmThumbnail(this);
thumbnail.Register(destination, source);
return thumbnail;
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
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 Update();
}
}

View File

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

View File

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

View File

@@ -0,0 +1,11 @@
namespace EveOPreview.Services
{
public interface IThumbnailManager
{
void Start();
void Stop();
void UpdateThumbnailsSize();
void UpdateThumbnailFrames();
}
}

View File

@@ -0,0 +1,20 @@
using System;
namespace EveOPreview.Services
{
public interface IWindowManager
{
bool IsCompositionEnabled { get; }
IntPtr GetForegroundWindowHandle();
void ActivateWindow(IntPtr handle);
void MinimizeWindow(IntPtr handle, bool enableAnimation);
void MoveWindow(IntPtr handle, int left, int top, int width, int height);
(int Left, int Top, int Right, int Bottom) GetWindowPosition(IntPtr handle);
bool IsWindowMinimized(IntPtr handle);
IDwmThumbnail RegisterThumbnail(IntPtr destination, IntPtr source);
}
}

View File

@@ -1,66 +1,9 @@
using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System;
namespace EveOPreview
namespace EveOPreview.Services
{
// Desktop Windows Manager APIs
static class WindowManagerNativeMethods
public static class InteropConstants
{
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr window);
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmEnableBlurBehindWindow(IntPtr hWnd, DWM_BLURBEHIND pBlurBehind);
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, MARGINS pMargins);
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern bool DwmIsCompositionEnabled();
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmGetColorizationColor(
out int pcrColorization,
[MarshalAs(UnmanagedType.Bool)]out bool pfOpaqueBlend);
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmEnableComposition(bool bEnable);
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern IntPtr DwmRegisterThumbnail(IntPtr dest, IntPtr source);
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmUnregisterThumbnail(IntPtr hThumbnail);
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmUpdateThumbnailProperties(IntPtr hThumbnail, DWM_THUMBNAIL_PROPERTIES props);
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmQueryThumbnailSourceSize(IntPtr hThumbnail, out Size size);
public const int SW_SHOWNORMAL = 1;
public const int SW_SHOWMINIMIZED = 2;
public const int SW_SHOWMAXIMIZED = 3;
[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HTCAPTION = 0x2;
[DllImport("User32.dll")]
public static extern bool ReleaseCapture();
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImport("user32.dll", SetLastError = true)]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
public const int GWL_ID = (-12);
public const int GWL_STYLE = (-16);
public const int GWL_EXSTYLE = (-20);
@@ -129,10 +72,11 @@ namespace EveOPreview
public const int SIZE_MAXSHOW = 3;
public const int SIZE_MAXHIDE = 4;
[DllImport("user32.dll")]
public static extern int GetWindowRect(IntPtr hwnd, out RECT rect);
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HTCAPTION = 0x2;
[DllImport("user32.dll")]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
public const int SW_SHOWNORMAL = 1;
public const int SW_SHOWMINIMIZED = 2;
public const int SW_SHOWMAXIMIZED = 3;
}
}

View File

@@ -1,7 +1,7 @@
using System;
using System.Runtime.InteropServices;
namespace EveOPreview
namespace EveOPreview.Services.Interop
{
[StructLayout(LayoutKind.Sequential)]
class DWM_BLURBEHIND

View File

@@ -1,6 +1,6 @@
using System.Runtime.InteropServices;
namespace EveOPreview
namespace EveOPreview.Services.Interop
{
[StructLayout(LayoutKind.Sequential)]
class DWM_THUMBNAIL_PROPERTIES

View File

@@ -1,4 +1,4 @@
namespace EveOPreview
namespace EveOPreview.Services.Interop
{
static class DWM_TNP_CONSTANTS
{

View File

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

View File

@@ -1,6 +1,6 @@
using System.Runtime.InteropServices;
namespace EveOPreview
namespace EveOPreview.Services.Interop
{
[StructLayout(LayoutKind.Sequential)]
class MARGINS

View File

@@ -1,6 +1,6 @@
using System.Runtime.InteropServices;
namespace EveOPreview
namespace EveOPreview.Services.Interop
{
[StructLayout(LayoutKind.Sequential)]
struct RECT

View File

@@ -0,0 +1,46 @@
using System;
using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop
{
static class User32NativeMethods
{
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr window);
[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("User32.dll")]
public static extern bool ReleaseCapture();
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImport("user32.dll", SetLastError = true)]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
public static extern int GetWindowRect(IntPtr hwnd, out RECT rect);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll")]
public static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll")]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern bool IsZoomed(IntPtr hWnd);
}
}

View File

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

View File

@@ -1,25 +0,0 @@
using System;
namespace EveOPreview.UI
{
public class ThumbnailDescriptionViewFactory : IThumbnailDescriptionViewFactory
{
private readonly IApplicationController _controller;
public ThumbnailDescriptionViewFactory(IApplicationController controller)
{
this._controller = controller;
}
public IThumbnailDescriptionView Create(IntPtr id, string title, bool isDisabled)
{
IThumbnailDescriptionView view = this._controller.Create<IThumbnailDescriptionView>();
view.Id = id;
view.Title = title;
view.IsDisabled = isDisabled;
return view;
}
}
}

View File

@@ -1,25 +0,0 @@
using System;
namespace EveOPreview.UI
{
public class ThumbnailDescriptionView : IThumbnailDescriptionView
{
public IntPtr Id { get; set; }
public string Title { get; set; }
public bool IsDisabled { get; set; }
public void Show()
{
}
public void Hide()
{
}
public void Close()
{
}
}
}

View File

@@ -1,11 +0,0 @@
using System;
namespace EveOPreview.UI
{
public interface IThumbnailDescriptionView : IView
{
IntPtr Id { get; set; }
string Title { get; set; }
bool IsDisabled { get; set; }
}
}

View File

@@ -1,9 +0,0 @@
using System;
namespace EveOPreview.UI
{
public interface IThumbnailDescriptionViewFactory
{
IThumbnailDescriptionView Create(IntPtr id, string title, bool isDisabled);
}
}

View File

@@ -1,6 +1,6 @@
using System.Windows.Forms;
namespace EveOPreview.UI
namespace EveOPreview.View
{
partial class MainForm
{
@@ -57,6 +57,7 @@ namespace EveOPreview.UI
System.Windows.Forms.Label DescriptionLabel;
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
System.Windows.Forms.Label NameLabel;
this.MinimizeInactiveClientsCheckBox = new System.Windows.Forms.CheckBox();
this.EnableClientLayoutTrackingCheckBox = new System.Windows.Forms.CheckBox();
this.HideActiveClientThumbnailCheckBox = new System.Windows.Forms.CheckBox();
this.ShowThumbnailsAlwaysOnTopCheckBox = new System.Windows.Forms.CheckBox();
@@ -138,14 +139,14 @@ namespace EveOPreview.UI
// RestoreWindowMenuItem
//
RestoreWindowMenuItem.Name = "RestoreWindowMenuItem";
RestoreWindowMenuItem.Size = new System.Drawing.Size(151, 22);
RestoreWindowMenuItem.Size = new System.Drawing.Size(199, 30);
RestoreWindowMenuItem.Text = "Restore";
RestoreWindowMenuItem.Click += new System.EventHandler(this.RestoreMainForm_Handler);
//
// ExitMenuItem
//
ExitMenuItem.Name = "ExitMenuItem";
ExitMenuItem.Size = new System.Drawing.Size(151, 22);
ExitMenuItem.Size = new System.Drawing.Size(199, 30);
ExitMenuItem.Text = "Exit";
ExitMenuItem.Click += new System.EventHandler(this.ExitMenuItemClick_Handler);
//
@@ -153,13 +154,13 @@ namespace EveOPreview.UI
//
TitleMenuItem.Enabled = false;
TitleMenuItem.Name = "TitleMenuItem";
TitleMenuItem.Size = new System.Drawing.Size(151, 22);
TitleMenuItem.Size = new System.Drawing.Size(199, 30);
TitleMenuItem.Text = "EVE-O Preview";
//
// SeparatorMenuItem
//
SeparatorMenuItem.Name = "SeparatorMenuItem";
SeparatorMenuItem.Size = new System.Drawing.Size(148, 6);
SeparatorMenuItem.Size = new System.Drawing.Size(196, 6);
//
// ContentTabControl
//
@@ -174,10 +175,11 @@ namespace EveOPreview.UI
ContentTabControl.DrawMode = System.Windows.Forms.TabDrawMode.OwnerDrawFixed;
ContentTabControl.ItemSize = new System.Drawing.Size(35, 120);
ContentTabControl.Location = new System.Drawing.Point(0, 0);
ContentTabControl.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
ContentTabControl.Multiline = true;
ContentTabControl.Name = "ContentTabControl";
ContentTabControl.SelectedIndex = 0;
ContentTabControl.Size = new System.Drawing.Size(390, 218);
ContentTabControl.Size = new System.Drawing.Size(585, 335);
ContentTabControl.SizeMode = System.Windows.Forms.TabSizeMode.Fixed;
ContentTabControl.TabIndex = 6;
ContentTabControl.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.ContentTabControl_DrawItem);
@@ -187,15 +189,17 @@ namespace EveOPreview.UI
GeneralTabPage.BackColor = System.Drawing.SystemColors.Control;
GeneralTabPage.Controls.Add(GeneralSettingsPanel);
GeneralTabPage.Location = new System.Drawing.Point(124, 4);
GeneralTabPage.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
GeneralTabPage.Name = "GeneralTabPage";
GeneralTabPage.Padding = new System.Windows.Forms.Padding(3);
GeneralTabPage.Size = new System.Drawing.Size(262, 210);
GeneralTabPage.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5);
GeneralTabPage.Size = new System.Drawing.Size(457, 327);
GeneralTabPage.TabIndex = 0;
GeneralTabPage.Text = "General";
//
// GeneralSettingsPanel
//
GeneralSettingsPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
GeneralSettingsPanel.Controls.Add(this.MinimizeInactiveClientsCheckBox);
GeneralSettingsPanel.Controls.Add(this.EnableClientLayoutTrackingCheckBox);
GeneralSettingsPanel.Controls.Add(this.HideActiveClientThumbnailCheckBox);
GeneralSettingsPanel.Controls.Add(this.ShowThumbnailsAlwaysOnTopCheckBox);
@@ -203,17 +207,31 @@ namespace EveOPreview.UI
GeneralSettingsPanel.Controls.Add(this.EnablePerClientThumbnailsLayoutsCheckBox);
GeneralSettingsPanel.Controls.Add(this.MinimizeToTrayCheckBox);
GeneralSettingsPanel.Dock = System.Windows.Forms.DockStyle.Fill;
GeneralSettingsPanel.Location = new System.Drawing.Point(3, 3);
GeneralSettingsPanel.Location = new System.Drawing.Point(4, 5);
GeneralSettingsPanel.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
GeneralSettingsPanel.Name = "GeneralSettingsPanel";
GeneralSettingsPanel.Size = new System.Drawing.Size(256, 204);
GeneralSettingsPanel.Size = new System.Drawing.Size(449, 317);
GeneralSettingsPanel.TabIndex = 18;
//
// MinimizeInactiveClientsCheckBox
//
this.MinimizeInactiveClientsCheckBox.AutoSize = true;
this.MinimizeInactiveClientsCheckBox.Location = new System.Drawing.Point(12, 122);
this.MinimizeInactiveClientsCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.MinimizeInactiveClientsCheckBox.Name = "MinimizeInactiveClientsCheckBox";
this.MinimizeInactiveClientsCheckBox.Size = new System.Drawing.Size(239, 24);
this.MinimizeInactiveClientsCheckBox.TabIndex = 24;
this.MinimizeInactiveClientsCheckBox.Text = "Minimize inactive EVE clients";
this.MinimizeInactiveClientsCheckBox.UseVisualStyleBackColor = true;
this.MinimizeInactiveClientsCheckBox.CheckedChanged += new System.EventHandler(this.OptionChanged_Handler);
//
// EnableClientLayoutTrackingCheckBox
//
this.EnableClientLayoutTrackingCheckBox.AutoSize = true;
this.EnableClientLayoutTrackingCheckBox.Location = new System.Drawing.Point(8, 31);
this.EnableClientLayoutTrackingCheckBox.Location = new System.Drawing.Point(12, 48);
this.EnableClientLayoutTrackingCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.EnableClientLayoutTrackingCheckBox.Name = "EnableClientLayoutTrackingCheckBox";
this.EnableClientLayoutTrackingCheckBox.Size = new System.Drawing.Size(127, 17);
this.EnableClientLayoutTrackingCheckBox.Size = new System.Drawing.Size(182, 24);
this.EnableClientLayoutTrackingCheckBox.TabIndex = 19;
this.EnableClientLayoutTrackingCheckBox.Text = "Track client locations";
this.EnableClientLayoutTrackingCheckBox.UseVisualStyleBackColor = true;
@@ -224,9 +242,10 @@ namespace EveOPreview.UI
this.HideActiveClientThumbnailCheckBox.AutoSize = true;
this.HideActiveClientThumbnailCheckBox.Checked = true;
this.HideActiveClientThumbnailCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.HideActiveClientThumbnailCheckBox.Location = new System.Drawing.Point(8, 55);
this.HideActiveClientThumbnailCheckBox.Location = new System.Drawing.Point(12, 85);
this.HideActiveClientThumbnailCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.HideActiveClientThumbnailCheckBox.Name = "HideActiveClientThumbnailCheckBox";
this.HideActiveClientThumbnailCheckBox.Size = new System.Drawing.Size(184, 17);
this.HideActiveClientThumbnailCheckBox.Size = new System.Drawing.Size(266, 24);
this.HideActiveClientThumbnailCheckBox.TabIndex = 20;
this.HideActiveClientThumbnailCheckBox.Text = "Hide preview of active EVE client";
this.HideActiveClientThumbnailCheckBox.UseVisualStyleBackColor = true;
@@ -237,10 +256,11 @@ namespace EveOPreview.UI
this.ShowThumbnailsAlwaysOnTopCheckBox.AutoSize = true;
this.ShowThumbnailsAlwaysOnTopCheckBox.Checked = true;
this.ShowThumbnailsAlwaysOnTopCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.ShowThumbnailsAlwaysOnTopCheckBox.Location = new System.Drawing.Point(8, 79);
this.ShowThumbnailsAlwaysOnTopCheckBox.Location = new System.Drawing.Point(12, 159);
this.ShowThumbnailsAlwaysOnTopCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ShowThumbnailsAlwaysOnTopCheckBox.Name = "ShowThumbnailsAlwaysOnTopCheckBox";
this.ShowThumbnailsAlwaysOnTopCheckBox.RightToLeft = System.Windows.Forms.RightToLeft.No;
this.ShowThumbnailsAlwaysOnTopCheckBox.Size = new System.Drawing.Size(137, 17);
this.ShowThumbnailsAlwaysOnTopCheckBox.Size = new System.Drawing.Size(197, 24);
this.ShowThumbnailsAlwaysOnTopCheckBox.TabIndex = 21;
this.ShowThumbnailsAlwaysOnTopCheckBox.Text = "Previews always on top";
this.ShowThumbnailsAlwaysOnTopCheckBox.UseVisualStyleBackColor = true;
@@ -251,9 +271,10 @@ namespace EveOPreview.UI
this.HideThumbnailsOnLostFocusCheckBox.AutoSize = true;
this.HideThumbnailsOnLostFocusCheckBox.Checked = true;
this.HideThumbnailsOnLostFocusCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.HideThumbnailsOnLostFocusCheckBox.Location = new System.Drawing.Point(8, 103);
this.HideThumbnailsOnLostFocusCheckBox.Location = new System.Drawing.Point(12, 196);
this.HideThumbnailsOnLostFocusCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.HideThumbnailsOnLostFocusCheckBox.Name = "HideThumbnailsOnLostFocusCheckBox";
this.HideThumbnailsOnLostFocusCheckBox.Size = new System.Drawing.Size(234, 17);
this.HideThumbnailsOnLostFocusCheckBox.Size = new System.Drawing.Size(340, 24);
this.HideThumbnailsOnLostFocusCheckBox.TabIndex = 22;
this.HideThumbnailsOnLostFocusCheckBox.Text = "Hide previews when EVE client is not active";
this.HideThumbnailsOnLostFocusCheckBox.UseVisualStyleBackColor = true;
@@ -264,9 +285,10 @@ namespace EveOPreview.UI
this.EnablePerClientThumbnailsLayoutsCheckBox.AutoSize = true;
this.EnablePerClientThumbnailsLayoutsCheckBox.Checked = true;
this.EnablePerClientThumbnailsLayoutsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.EnablePerClientThumbnailsLayoutsCheckBox.Location = new System.Drawing.Point(8, 127);
this.EnablePerClientThumbnailsLayoutsCheckBox.Location = new System.Drawing.Point(12, 233);
this.EnablePerClientThumbnailsLayoutsCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.EnablePerClientThumbnailsLayoutsCheckBox.Name = "EnablePerClientThumbnailsLayoutsCheckBox";
this.EnablePerClientThumbnailsLayoutsCheckBox.Size = new System.Drawing.Size(185, 17);
this.EnablePerClientThumbnailsLayoutsCheckBox.Size = new System.Drawing.Size(272, 24);
this.EnablePerClientThumbnailsLayoutsCheckBox.TabIndex = 23;
this.EnablePerClientThumbnailsLayoutsCheckBox.Text = "Unique layout for each EVE client";
this.EnablePerClientThumbnailsLayoutsCheckBox.UseVisualStyleBackColor = true;
@@ -275,9 +297,10 @@ namespace EveOPreview.UI
// MinimizeToTrayCheckBox
//
this.MinimizeToTrayCheckBox.AutoSize = true;
this.MinimizeToTrayCheckBox.Location = new System.Drawing.Point(8, 7);
this.MinimizeToTrayCheckBox.Location = new System.Drawing.Point(12, 11);
this.MinimizeToTrayCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.MinimizeToTrayCheckBox.Name = "MinimizeToTrayCheckBox";
this.MinimizeToTrayCheckBox.Size = new System.Drawing.Size(139, 17);
this.MinimizeToTrayCheckBox.Size = new System.Drawing.Size(205, 24);
this.MinimizeToTrayCheckBox.TabIndex = 18;
this.MinimizeToTrayCheckBox.Text = "Minimize to System Tray";
this.MinimizeToTrayCheckBox.UseVisualStyleBackColor = true;
@@ -288,9 +311,10 @@ namespace EveOPreview.UI
ThumbnailTabPage.BackColor = System.Drawing.SystemColors.Control;
ThumbnailTabPage.Controls.Add(ThumbnailSettingsPanel);
ThumbnailTabPage.Location = new System.Drawing.Point(124, 4);
ThumbnailTabPage.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
ThumbnailTabPage.Name = "ThumbnailTabPage";
ThumbnailTabPage.Padding = new System.Windows.Forms.Padding(3);
ThumbnailTabPage.Size = new System.Drawing.Size(262, 210);
ThumbnailTabPage.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5);
ThumbnailTabPage.Size = new System.Drawing.Size(457, 327);
ThumbnailTabPage.TabIndex = 1;
ThumbnailTabPage.Text = "Thumbnail";
//
@@ -304,26 +328,29 @@ namespace EveOPreview.UI
ThumbnailSettingsPanel.Controls.Add(this.ThumbnailOpacityTrackBar);
ThumbnailSettingsPanel.Controls.Add(OpacityLabel);
ThumbnailSettingsPanel.Dock = System.Windows.Forms.DockStyle.Fill;
ThumbnailSettingsPanel.Location = new System.Drawing.Point(3, 3);
ThumbnailSettingsPanel.Location = new System.Drawing.Point(4, 5);
ThumbnailSettingsPanel.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
ThumbnailSettingsPanel.Name = "ThumbnailSettingsPanel";
ThumbnailSettingsPanel.Size = new System.Drawing.Size(256, 204);
ThumbnailSettingsPanel.Size = new System.Drawing.Size(449, 317);
ThumbnailSettingsPanel.TabIndex = 19;
//
// HeigthLabel
//
HeigthLabel.AutoSize = true;
HeigthLabel.Location = new System.Drawing.Point(8, 57);
HeigthLabel.Location = new System.Drawing.Point(12, 88);
HeigthLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
HeigthLabel.Name = "HeigthLabel";
HeigthLabel.Size = new System.Drawing.Size(90, 13);
HeigthLabel.Size = new System.Drawing.Size(133, 20);
HeigthLabel.TabIndex = 24;
HeigthLabel.Text = "Thumbnail Heigth";
//
// WidthLabel
//
WidthLabel.AutoSize = true;
WidthLabel.Location = new System.Drawing.Point(8, 33);
WidthLabel.Location = new System.Drawing.Point(12, 51);
WidthLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
WidthLabel.Name = "WidthLabel";
WidthLabel.Size = new System.Drawing.Size(87, 13);
WidthLabel.Size = new System.Drawing.Size(127, 20);
WidthLabel.TabIndex = 23;
WidthLabel.Text = "Thumbnail Width";
//
@@ -337,14 +364,15 @@ namespace EveOPreview.UI
0,
0,
0});
this.ThumbnailsWidthNumericEdit.Location = new System.Drawing.Point(105, 31);
this.ThumbnailsWidthNumericEdit.Location = new System.Drawing.Point(158, 48);
this.ThumbnailsWidthNumericEdit.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ThumbnailsWidthNumericEdit.Maximum = new decimal(new int[] {
999999,
0,
0,
0});
this.ThumbnailsWidthNumericEdit.Name = "ThumbnailsWidthNumericEdit";
this.ThumbnailsWidthNumericEdit.Size = new System.Drawing.Size(48, 20);
this.ThumbnailsWidthNumericEdit.Size = new System.Drawing.Size(72, 26);
this.ThumbnailsWidthNumericEdit.TabIndex = 21;
this.ThumbnailsWidthNumericEdit.Value = new decimal(new int[] {
100,
@@ -363,14 +391,15 @@ namespace EveOPreview.UI
0,
0,
0});
this.ThumbnailsHeightNumericEdit.Location = new System.Drawing.Point(105, 55);
this.ThumbnailsHeightNumericEdit.Location = new System.Drawing.Point(158, 85);
this.ThumbnailsHeightNumericEdit.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ThumbnailsHeightNumericEdit.Maximum = new decimal(new int[] {
99999999,
0,
0,
0});
this.ThumbnailsHeightNumericEdit.Name = "ThumbnailsHeightNumericEdit";
this.ThumbnailsHeightNumericEdit.Size = new System.Drawing.Size(48, 20);
this.ThumbnailsHeightNumericEdit.Size = new System.Drawing.Size(72, 26);
this.ThumbnailsHeightNumericEdit.TabIndex = 22;
this.ThumbnailsHeightNumericEdit.Value = new decimal(new int[] {
70,
@@ -383,11 +412,12 @@ namespace EveOPreview.UI
//
this.ThumbnailOpacityTrackBar.AutoSize = false;
this.ThumbnailOpacityTrackBar.LargeChange = 10;
this.ThumbnailOpacityTrackBar.Location = new System.Drawing.Point(61, 6);
this.ThumbnailOpacityTrackBar.Location = new System.Drawing.Point(92, 9);
this.ThumbnailOpacityTrackBar.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ThumbnailOpacityTrackBar.Maximum = 100;
this.ThumbnailOpacityTrackBar.Minimum = 20;
this.ThumbnailOpacityTrackBar.Name = "ThumbnailOpacityTrackBar";
this.ThumbnailOpacityTrackBar.Size = new System.Drawing.Size(191, 22);
this.ThumbnailOpacityTrackBar.Size = new System.Drawing.Size(286, 34);
this.ThumbnailOpacityTrackBar.TabIndex = 20;
this.ThumbnailOpacityTrackBar.TickFrequency = 10;
this.ThumbnailOpacityTrackBar.Value = 20;
@@ -396,9 +426,10 @@ namespace EveOPreview.UI
// OpacityLabel
//
OpacityLabel.AutoSize = true;
OpacityLabel.Location = new System.Drawing.Point(8, 9);
OpacityLabel.Location = new System.Drawing.Point(12, 14);
OpacityLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
OpacityLabel.Name = "OpacityLabel";
OpacityLabel.Size = new System.Drawing.Size(43, 13);
OpacityLabel.Size = new System.Drawing.Size(62, 20);
OpacityLabel.TabIndex = 19;
OpacityLabel.Text = "Opacity";
//
@@ -407,8 +438,9 @@ namespace EveOPreview.UI
this.ZoomTabPage.BackColor = System.Drawing.SystemColors.Control;
this.ZoomTabPage.Controls.Add(ZoomSettingsPanel);
this.ZoomTabPage.Location = new System.Drawing.Point(124, 4);
this.ZoomTabPage.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ZoomTabPage.Name = "ZoomTabPage";
this.ZoomTabPage.Size = new System.Drawing.Size(262, 210);
this.ZoomTabPage.Size = new System.Drawing.Size(457, 327);
this.ZoomTabPage.TabIndex = 2;
this.ZoomTabPage.Text = "Zoom";
//
@@ -422,16 +454,18 @@ namespace EveOPreview.UI
ZoomSettingsPanel.Controls.Add(this.ThumbnailZoomFactorNumericEdit);
ZoomSettingsPanel.Dock = System.Windows.Forms.DockStyle.Fill;
ZoomSettingsPanel.Location = new System.Drawing.Point(0, 0);
ZoomSettingsPanel.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
ZoomSettingsPanel.Name = "ZoomSettingsPanel";
ZoomSettingsPanel.Size = new System.Drawing.Size(262, 210);
ZoomSettingsPanel.Size = new System.Drawing.Size(457, 327);
ZoomSettingsPanel.TabIndex = 36;
//
// ZoomFactorLabel
//
ZoomFactorLabel.AutoSize = true;
ZoomFactorLabel.Location = new System.Drawing.Point(8, 33);
ZoomFactorLabel.Location = new System.Drawing.Point(12, 51);
ZoomFactorLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
ZoomFactorLabel.Name = "ZoomFactorLabel";
ZoomFactorLabel.Size = new System.Drawing.Size(67, 13);
ZoomFactorLabel.Size = new System.Drawing.Size(100, 20);
ZoomFactorLabel.TabIndex = 39;
ZoomFactorLabel.Text = "Zoom Factor";
//
@@ -447,17 +481,19 @@ namespace EveOPreview.UI
this.ZoomAnchorPanel.Controls.Add(this.ZoomAanchorSRadioButton);
this.ZoomAnchorPanel.Controls.Add(this.ZoomAanchorERadioButton);
this.ZoomAnchorPanel.Controls.Add(this.ZoomAanchorSWRadioButton);
this.ZoomAnchorPanel.Location = new System.Drawing.Point(81, 54);
this.ZoomAnchorPanel.Location = new System.Drawing.Point(122, 83);
this.ZoomAnchorPanel.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ZoomAnchorPanel.Name = "ZoomAnchorPanel";
this.ZoomAnchorPanel.Size = new System.Drawing.Size(77, 73);
this.ZoomAnchorPanel.Size = new System.Drawing.Size(114, 111);
this.ZoomAnchorPanel.TabIndex = 38;
//
// ZoomAanchorNWRadioButton
//
this.ZoomAanchorNWRadioButton.AutoSize = true;
this.ZoomAanchorNWRadioButton.Location = new System.Drawing.Point(3, 3);
this.ZoomAanchorNWRadioButton.Location = new System.Drawing.Point(4, 5);
this.ZoomAanchorNWRadioButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ZoomAanchorNWRadioButton.Name = "ZoomAanchorNWRadioButton";
this.ZoomAanchorNWRadioButton.Size = new System.Drawing.Size(14, 13);
this.ZoomAanchorNWRadioButton.Size = new System.Drawing.Size(21, 20);
this.ZoomAanchorNWRadioButton.TabIndex = 0;
this.ZoomAanchorNWRadioButton.TabStop = true;
this.ZoomAanchorNWRadioButton.UseVisualStyleBackColor = true;
@@ -466,9 +502,10 @@ namespace EveOPreview.UI
// ZoomAanchorNRadioButton
//
this.ZoomAanchorNRadioButton.AutoSize = true;
this.ZoomAanchorNRadioButton.Location = new System.Drawing.Point(31, 3);
this.ZoomAanchorNRadioButton.Location = new System.Drawing.Point(46, 5);
this.ZoomAanchorNRadioButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ZoomAanchorNRadioButton.Name = "ZoomAanchorNRadioButton";
this.ZoomAanchorNRadioButton.Size = new System.Drawing.Size(14, 13);
this.ZoomAanchorNRadioButton.Size = new System.Drawing.Size(21, 20);
this.ZoomAanchorNRadioButton.TabIndex = 1;
this.ZoomAanchorNRadioButton.TabStop = true;
this.ZoomAanchorNRadioButton.UseVisualStyleBackColor = true;
@@ -477,9 +514,10 @@ namespace EveOPreview.UI
// ZoomAanchorNERadioButton
//
this.ZoomAanchorNERadioButton.AutoSize = true;
this.ZoomAanchorNERadioButton.Location = new System.Drawing.Point(59, 3);
this.ZoomAanchorNERadioButton.Location = new System.Drawing.Point(88, 5);
this.ZoomAanchorNERadioButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ZoomAanchorNERadioButton.Name = "ZoomAanchorNERadioButton";
this.ZoomAanchorNERadioButton.Size = new System.Drawing.Size(14, 13);
this.ZoomAanchorNERadioButton.Size = new System.Drawing.Size(21, 20);
this.ZoomAanchorNERadioButton.TabIndex = 2;
this.ZoomAanchorNERadioButton.TabStop = true;
this.ZoomAanchorNERadioButton.UseVisualStyleBackColor = true;
@@ -488,9 +526,10 @@ namespace EveOPreview.UI
// ZoomAanchorWRadioButton
//
this.ZoomAanchorWRadioButton.AutoSize = true;
this.ZoomAanchorWRadioButton.Location = new System.Drawing.Point(3, 29);
this.ZoomAanchorWRadioButton.Location = new System.Drawing.Point(4, 45);
this.ZoomAanchorWRadioButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ZoomAanchorWRadioButton.Name = "ZoomAanchorWRadioButton";
this.ZoomAanchorWRadioButton.Size = new System.Drawing.Size(14, 13);
this.ZoomAanchorWRadioButton.Size = new System.Drawing.Size(21, 20);
this.ZoomAanchorWRadioButton.TabIndex = 3;
this.ZoomAanchorWRadioButton.TabStop = true;
this.ZoomAanchorWRadioButton.UseVisualStyleBackColor = true;
@@ -499,9 +538,10 @@ namespace EveOPreview.UI
// ZoomAanchorSERadioButton
//
this.ZoomAanchorSERadioButton.AutoSize = true;
this.ZoomAanchorSERadioButton.Location = new System.Drawing.Point(59, 55);
this.ZoomAanchorSERadioButton.Location = new System.Drawing.Point(88, 85);
this.ZoomAanchorSERadioButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ZoomAanchorSERadioButton.Name = "ZoomAanchorSERadioButton";
this.ZoomAanchorSERadioButton.Size = new System.Drawing.Size(14, 13);
this.ZoomAanchorSERadioButton.Size = new System.Drawing.Size(21, 20);
this.ZoomAanchorSERadioButton.TabIndex = 8;
this.ZoomAanchorSERadioButton.TabStop = true;
this.ZoomAanchorSERadioButton.UseVisualStyleBackColor = true;
@@ -510,9 +550,10 @@ namespace EveOPreview.UI
// ZoomAanchorCRadioButton
//
this.ZoomAanchorCRadioButton.AutoSize = true;
this.ZoomAanchorCRadioButton.Location = new System.Drawing.Point(31, 29);
this.ZoomAanchorCRadioButton.Location = new System.Drawing.Point(46, 45);
this.ZoomAanchorCRadioButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ZoomAanchorCRadioButton.Name = "ZoomAanchorCRadioButton";
this.ZoomAanchorCRadioButton.Size = new System.Drawing.Size(14, 13);
this.ZoomAanchorCRadioButton.Size = new System.Drawing.Size(21, 20);
this.ZoomAanchorCRadioButton.TabIndex = 4;
this.ZoomAanchorCRadioButton.TabStop = true;
this.ZoomAanchorCRadioButton.UseVisualStyleBackColor = true;
@@ -521,9 +562,10 @@ namespace EveOPreview.UI
// ZoomAanchorSRadioButton
//
this.ZoomAanchorSRadioButton.AutoSize = true;
this.ZoomAanchorSRadioButton.Location = new System.Drawing.Point(31, 55);
this.ZoomAanchorSRadioButton.Location = new System.Drawing.Point(46, 85);
this.ZoomAanchorSRadioButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ZoomAanchorSRadioButton.Name = "ZoomAanchorSRadioButton";
this.ZoomAanchorSRadioButton.Size = new System.Drawing.Size(14, 13);
this.ZoomAanchorSRadioButton.Size = new System.Drawing.Size(21, 20);
this.ZoomAanchorSRadioButton.TabIndex = 7;
this.ZoomAanchorSRadioButton.TabStop = true;
this.ZoomAanchorSRadioButton.UseVisualStyleBackColor = true;
@@ -532,9 +574,10 @@ namespace EveOPreview.UI
// ZoomAanchorERadioButton
//
this.ZoomAanchorERadioButton.AutoSize = true;
this.ZoomAanchorERadioButton.Location = new System.Drawing.Point(59, 29);
this.ZoomAanchorERadioButton.Location = new System.Drawing.Point(88, 45);
this.ZoomAanchorERadioButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ZoomAanchorERadioButton.Name = "ZoomAanchorERadioButton";
this.ZoomAanchorERadioButton.Size = new System.Drawing.Size(14, 13);
this.ZoomAanchorERadioButton.Size = new System.Drawing.Size(21, 20);
this.ZoomAanchorERadioButton.TabIndex = 5;
this.ZoomAanchorERadioButton.TabStop = true;
this.ZoomAanchorERadioButton.UseVisualStyleBackColor = true;
@@ -543,9 +586,10 @@ namespace EveOPreview.UI
// ZoomAanchorSWRadioButton
//
this.ZoomAanchorSWRadioButton.AutoSize = true;
this.ZoomAanchorSWRadioButton.Location = new System.Drawing.Point(3, 55);
this.ZoomAanchorSWRadioButton.Location = new System.Drawing.Point(4, 85);
this.ZoomAanchorSWRadioButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ZoomAanchorSWRadioButton.Name = "ZoomAanchorSWRadioButton";
this.ZoomAanchorSWRadioButton.Size = new System.Drawing.Size(14, 13);
this.ZoomAanchorSWRadioButton.Size = new System.Drawing.Size(21, 20);
this.ZoomAanchorSWRadioButton.TabIndex = 6;
this.ZoomAanchorSWRadioButton.TabStop = true;
this.ZoomAanchorSWRadioButton.UseVisualStyleBackColor = true;
@@ -554,9 +598,10 @@ namespace EveOPreview.UI
// ZoomAnchorLabel
//
ZoomAnchorLabel.AutoSize = true;
ZoomAnchorLabel.Location = new System.Drawing.Point(8, 57);
ZoomAnchorLabel.Location = new System.Drawing.Point(12, 88);
ZoomAnchorLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
ZoomAnchorLabel.Name = "ZoomAnchorLabel";
ZoomAnchorLabel.Size = new System.Drawing.Size(41, 13);
ZoomAnchorLabel.Size = new System.Drawing.Size(60, 20);
ZoomAnchorLabel.TabIndex = 40;
ZoomAnchorLabel.Text = "Anchor";
//
@@ -565,10 +610,11 @@ namespace EveOPreview.UI
this.EnableThumbnailZoomCheckBox.AutoSize = true;
this.EnableThumbnailZoomCheckBox.Checked = true;
this.EnableThumbnailZoomCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.EnableThumbnailZoomCheckBox.Location = new System.Drawing.Point(8, 7);
this.EnableThumbnailZoomCheckBox.Location = new System.Drawing.Point(12, 11);
this.EnableThumbnailZoomCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.EnableThumbnailZoomCheckBox.Name = "EnableThumbnailZoomCheckBox";
this.EnableThumbnailZoomCheckBox.RightToLeft = System.Windows.Forms.RightToLeft.No;
this.EnableThumbnailZoomCheckBox.Size = new System.Drawing.Size(98, 17);
this.EnableThumbnailZoomCheckBox.Size = new System.Drawing.Size(141, 24);
this.EnableThumbnailZoomCheckBox.TabIndex = 36;
this.EnableThumbnailZoomCheckBox.Text = "Zoom on hover";
this.EnableThumbnailZoomCheckBox.UseVisualStyleBackColor = true;
@@ -578,7 +624,8 @@ namespace EveOPreview.UI
//
this.ThumbnailZoomFactorNumericEdit.BackColor = System.Drawing.SystemColors.Window;
this.ThumbnailZoomFactorNumericEdit.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.ThumbnailZoomFactorNumericEdit.Location = new System.Drawing.Point(81, 31);
this.ThumbnailZoomFactorNumericEdit.Location = new System.Drawing.Point(122, 48);
this.ThumbnailZoomFactorNumericEdit.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ThumbnailZoomFactorNumericEdit.Maximum = new decimal(new int[] {
10,
0,
@@ -590,7 +637,7 @@ namespace EveOPreview.UI
0,
0});
this.ThumbnailZoomFactorNumericEdit.Name = "ThumbnailZoomFactorNumericEdit";
this.ThumbnailZoomFactorNumericEdit.Size = new System.Drawing.Size(38, 20);
this.ThumbnailZoomFactorNumericEdit.Size = new System.Drawing.Size(57, 26);
this.ThumbnailZoomFactorNumericEdit.TabIndex = 37;
this.ThumbnailZoomFactorNumericEdit.Value = new decimal(new int[] {
2,
@@ -604,8 +651,9 @@ namespace EveOPreview.UI
OverlayTabPage.BackColor = System.Drawing.SystemColors.Control;
OverlayTabPage.Controls.Add(OverlaySettingsPanel);
OverlayTabPage.Location = new System.Drawing.Point(124, 4);
OverlayTabPage.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
OverlayTabPage.Name = "OverlayTabPage";
OverlayTabPage.Size = new System.Drawing.Size(262, 210);
OverlayTabPage.Size = new System.Drawing.Size(457, 327);
OverlayTabPage.TabIndex = 3;
OverlayTabPage.Text = "Overlay";
//
@@ -619,25 +667,28 @@ namespace EveOPreview.UI
OverlaySettingsPanel.Controls.Add(this.ShowThumbnailFramesCheckBox);
OverlaySettingsPanel.Dock = System.Windows.Forms.DockStyle.Fill;
OverlaySettingsPanel.Location = new System.Drawing.Point(0, 0);
OverlaySettingsPanel.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
OverlaySettingsPanel.Name = "OverlaySettingsPanel";
OverlaySettingsPanel.Size = new System.Drawing.Size(262, 210);
OverlaySettingsPanel.Size = new System.Drawing.Size(457, 327);
OverlaySettingsPanel.TabIndex = 25;
//
// HighlightColorLabel
//
this.HighlightColorLabel.AutoSize = true;
this.HighlightColorLabel.Location = new System.Drawing.Point(5, 78);
this.HighlightColorLabel.Location = new System.Drawing.Point(8, 120);
this.HighlightColorLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.HighlightColorLabel.Name = "HighlightColorLabel";
this.HighlightColorLabel.Size = new System.Drawing.Size(31, 13);
this.HighlightColorLabel.Size = new System.Drawing.Size(46, 20);
this.HighlightColorLabel.TabIndex = 29;
this.HighlightColorLabel.Text = "Color";
//
// ActiveClientHighlightColorButton
//
this.ActiveClientHighlightColorButton.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.ActiveClientHighlightColorButton.Location = new System.Drawing.Point(42, 77);
this.ActiveClientHighlightColorButton.Location = new System.Drawing.Point(63, 118);
this.ActiveClientHighlightColorButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ActiveClientHighlightColorButton.Name = "ActiveClientHighlightColorButton";
this.ActiveClientHighlightColorButton.Size = new System.Drawing.Size(93, 17);
this.ActiveClientHighlightColorButton.Size = new System.Drawing.Size(138, 25);
this.ActiveClientHighlightColorButton.TabIndex = 28;
this.ActiveClientHighlightColorButton.Click += new System.EventHandler(this.ActiveClientHighlightColorButton_Click);
//
@@ -646,10 +697,11 @@ namespace EveOPreview.UI
this.EnableActiveClientHighlightCheckBox.AutoSize = true;
this.EnableActiveClientHighlightCheckBox.Checked = true;
this.EnableActiveClientHighlightCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.EnableActiveClientHighlightCheckBox.Location = new System.Drawing.Point(8, 55);
this.EnableActiveClientHighlightCheckBox.Location = new System.Drawing.Point(12, 85);
this.EnableActiveClientHighlightCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.EnableActiveClientHighlightCheckBox.Name = "EnableActiveClientHighlightCheckBox";
this.EnableActiveClientHighlightCheckBox.RightToLeft = System.Windows.Forms.RightToLeft.No;
this.EnableActiveClientHighlightCheckBox.Size = new System.Drawing.Size(127, 17);
this.EnableActiveClientHighlightCheckBox.Size = new System.Drawing.Size(183, 24);
this.EnableActiveClientHighlightCheckBox.TabIndex = 27;
this.EnableActiveClientHighlightCheckBox.Text = "Highlight active client";
this.EnableActiveClientHighlightCheckBox.UseVisualStyleBackColor = true;
@@ -660,10 +712,11 @@ namespace EveOPreview.UI
this.ShowThumbnailOverlaysCheckBox.AutoSize = true;
this.ShowThumbnailOverlaysCheckBox.Checked = true;
this.ShowThumbnailOverlaysCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.ShowThumbnailOverlaysCheckBox.Location = new System.Drawing.Point(8, 7);
this.ShowThumbnailOverlaysCheckBox.Location = new System.Drawing.Point(12, 11);
this.ShowThumbnailOverlaysCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ShowThumbnailOverlaysCheckBox.Name = "ShowThumbnailOverlaysCheckBox";
this.ShowThumbnailOverlaysCheckBox.RightToLeft = System.Windows.Forms.RightToLeft.No;
this.ShowThumbnailOverlaysCheckBox.Size = new System.Drawing.Size(90, 17);
this.ShowThumbnailOverlaysCheckBox.Size = new System.Drawing.Size(128, 24);
this.ShowThumbnailOverlaysCheckBox.TabIndex = 25;
this.ShowThumbnailOverlaysCheckBox.Text = "Show overlay";
this.ShowThumbnailOverlaysCheckBox.UseVisualStyleBackColor = true;
@@ -674,10 +727,11 @@ namespace EveOPreview.UI
this.ShowThumbnailFramesCheckBox.AutoSize = true;
this.ShowThumbnailFramesCheckBox.Checked = true;
this.ShowThumbnailFramesCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.ShowThumbnailFramesCheckBox.Location = new System.Drawing.Point(8, 31);
this.ShowThumbnailFramesCheckBox.Location = new System.Drawing.Point(12, 48);
this.ShowThumbnailFramesCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ShowThumbnailFramesCheckBox.Name = "ShowThumbnailFramesCheckBox";
this.ShowThumbnailFramesCheckBox.RightToLeft = System.Windows.Forms.RightToLeft.No;
this.ShowThumbnailFramesCheckBox.Size = new System.Drawing.Size(87, 17);
this.ShowThumbnailFramesCheckBox.Size = new System.Drawing.Size(128, 24);
this.ShowThumbnailFramesCheckBox.TabIndex = 26;
this.ShowThumbnailFramesCheckBox.Text = "Show frames";
this.ShowThumbnailFramesCheckBox.UseVisualStyleBackColor = true;
@@ -688,8 +742,9 @@ namespace EveOPreview.UI
ClientsTabPage.BackColor = System.Drawing.SystemColors.Control;
ClientsTabPage.Controls.Add(ClientsPanel);
ClientsTabPage.Location = new System.Drawing.Point(124, 4);
ClientsTabPage.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
ClientsTabPage.Name = "ClientsTabPage";
ClientsTabPage.Size = new System.Drawing.Size(262, 210);
ClientsTabPage.Size = new System.Drawing.Size(457, 327);
ClientsTabPage.TabIndex = 4;
ClientsTabPage.Text = "Active Clients";
//
@@ -700,29 +755,33 @@ namespace EveOPreview.UI
ClientsPanel.Controls.Add(ThumbnailsListLabel);
ClientsPanel.Dock = System.Windows.Forms.DockStyle.Fill;
ClientsPanel.Location = new System.Drawing.Point(0, 0);
ClientsPanel.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
ClientsPanel.Name = "ClientsPanel";
ClientsPanel.Size = new System.Drawing.Size(262, 210);
ClientsPanel.Size = new System.Drawing.Size(457, 327);
ClientsPanel.TabIndex = 32;
//
// ThumbnailsList
//
this.ThumbnailsList.BackColor = System.Drawing.SystemColors.Window;
this.ThumbnailsList.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.ThumbnailsList.CheckOnClick = true;
this.ThumbnailsList.Dock = System.Windows.Forms.DockStyle.Bottom;
this.ThumbnailsList.FormattingEnabled = true;
this.ThumbnailsList.IntegralHeight = false;
this.ThumbnailsList.Location = new System.Drawing.Point(0, 28);
this.ThumbnailsList.Location = new System.Drawing.Point(0, 49);
this.ThumbnailsList.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ThumbnailsList.Name = "ThumbnailsList";
this.ThumbnailsList.Size = new System.Drawing.Size(260, 180);
this.ThumbnailsList.Size = new System.Drawing.Size(455, 276);
this.ThumbnailsList.TabIndex = 34;
this.ThumbnailsList.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.ThumbnailsList_ItemCheck_Handler);
//
// ThumbnailsListLabel
//
ThumbnailsListLabel.AutoSize = true;
ThumbnailsListLabel.Location = new System.Drawing.Point(8, 9);
ThumbnailsListLabel.Location = new System.Drawing.Point(12, 14);
ThumbnailsListLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
ThumbnailsListLabel.Name = "ThumbnailsListLabel";
ThumbnailsListLabel.Size = new System.Drawing.Size(162, 13);
ThumbnailsListLabel.Size = new System.Drawing.Size(238, 20);
ThumbnailsListLabel.TabIndex = 33;
ThumbnailsListLabel.Text = "Thumbnails (check to force hide)";
//
@@ -731,8 +790,9 @@ namespace EveOPreview.UI
AboutTabPage.BackColor = System.Drawing.SystemColors.Control;
AboutTabPage.Controls.Add(AboutPanel);
AboutTabPage.Location = new System.Drawing.Point(124, 4);
AboutTabPage.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
AboutTabPage.Name = "AboutTabPage";
AboutTabPage.Size = new System.Drawing.Size(262, 210);
AboutTabPage.Size = new System.Drawing.Size(457, 327);
AboutTabPage.TabIndex = 5;
AboutTabPage.Text = "About";
//
@@ -746,26 +806,29 @@ namespace EveOPreview.UI
AboutPanel.Controls.Add(this.DocumentationLink);
AboutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
AboutPanel.Location = new System.Drawing.Point(0, 0);
AboutPanel.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
AboutPanel.Name = "AboutPanel";
AboutPanel.Size = new System.Drawing.Size(262, 210);
AboutPanel.Size = new System.Drawing.Size(457, 327);
AboutPanel.TabIndex = 2;
//
// DocumentationLinkLabel
//
DocumentationLinkLabel.AutoSize = true;
DocumentationLinkLabel.Location = new System.Drawing.Point(0, 157);
DocumentationLinkLabel.Location = new System.Drawing.Point(0, 242);
DocumentationLinkLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
DocumentationLinkLabel.Name = "DocumentationLinkLabel";
DocumentationLinkLabel.Padding = new System.Windows.Forms.Padding(8, 3, 8, 3);
DocumentationLinkLabel.Size = new System.Drawing.Size(222, 19);
DocumentationLinkLabel.Padding = new System.Windows.Forms.Padding(12, 5, 12, 5);
DocumentationLinkLabel.Size = new System.Drawing.Size(336, 30);
DocumentationLinkLabel.TabIndex = 6;
DocumentationLinkLabel.Text = "For more information visit our forum thread:";
//
// DescriptionLabel
//
DescriptionLabel.Location = new System.Drawing.Point(0, 41);
DescriptionLabel.Location = new System.Drawing.Point(0, 63);
DescriptionLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
DescriptionLabel.Name = "DescriptionLabel";
DescriptionLabel.Padding = new System.Windows.Forms.Padding(8, 3, 8, 3);
DescriptionLabel.Size = new System.Drawing.Size(261, 116);
DescriptionLabel.Padding = new System.Windows.Forms.Padding(12, 5, 12, 5);
DescriptionLabel.Size = new System.Drawing.Size(392, 178);
DescriptionLabel.TabIndex = 5;
DescriptionLabel.Text = resources.GetString("DescriptionLabel.Text");
//
@@ -773,9 +836,10 @@ namespace EveOPreview.UI
//
this.VersionLabel.AutoSize = true;
this.VersionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.VersionLabel.Location = new System.Drawing.Point(133, 9);
this.VersionLabel.Location = new System.Drawing.Point(200, 14);
this.VersionLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.VersionLabel.Name = "VersionLabel";
this.VersionLabel.Size = new System.Drawing.Size(49, 20);
this.VersionLabel.Size = new System.Drawing.Size(69, 29);
this.VersionLabel.TabIndex = 4;
this.VersionLabel.Text = "1.0.0";
//
@@ -783,19 +847,20 @@ namespace EveOPreview.UI
//
NameLabel.AutoSize = true;
NameLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
NameLabel.Location = new System.Drawing.Point(4, 9);
NameLabel.Location = new System.Drawing.Point(6, 14);
NameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
NameLabel.Name = "NameLabel";
NameLabel.Size = new System.Drawing.Size(130, 20);
NameLabel.Size = new System.Drawing.Size(193, 29);
NameLabel.TabIndex = 3;
NameLabel.Text = "EVE-O Preview";
//
// DocumentationLink
//
this.DocumentationLink.Location = new System.Drawing.Point(0, 173);
this.DocumentationLink.Margin = new System.Windows.Forms.Padding(30, 3, 3, 3);
this.DocumentationLink.Location = new System.Drawing.Point(0, 266);
this.DocumentationLink.Margin = new System.Windows.Forms.Padding(45, 5, 4, 5);
this.DocumentationLink.Name = "DocumentationLink";
this.DocumentationLink.Padding = new System.Windows.Forms.Padding(8, 3, 8, 3);
this.DocumentationLink.Size = new System.Drawing.Size(262, 33);
this.DocumentationLink.Padding = new System.Windows.Forms.Padding(12, 5, 12, 5);
this.DocumentationLink.Size = new System.Drawing.Size(393, 51);
this.DocumentationLink.TabIndex = 2;
this.DocumentationLink.TabStop = true;
this.DocumentationLink.Text = "to be set from prresenter to be set from prresenter to be set from prresenter to " +
@@ -812,20 +877,21 @@ namespace EveOPreview.UI
//
// TrayMenu
//
this.TrayMenu.ImageScalingSize = new System.Drawing.Size(24, 24);
this.TrayMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
TitleMenuItem,
RestoreWindowMenuItem,
SeparatorMenuItem,
ExitMenuItem});
this.TrayMenu.Name = "contextMenuStrip1";
this.TrayMenu.Size = new System.Drawing.Size(152, 76);
this.TrayMenu.Size = new System.Drawing.Size(200, 100);
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Control;
this.ClientSize = new System.Drawing.Size(390, 218);
this.ClientSize = new System.Drawing.Size(585, 335);
this.Controls.Add(ContentTabControl);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
@@ -900,5 +966,6 @@ namespace EveOPreview.UI
private CheckedListBox ThumbnailsList;
private LinkLabel DocumentationLink;
private Label VersionLabel;
private CheckBox MinimizeInactiveClientsCheckBox;
}
}

View File

@@ -3,9 +3,9 @@ using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace EveOPreview.UI
namespace EveOPreview.View
{
public partial class MainForm : Form, IMainView
public partial class MainForm : Form, IMainFormView
{
#region Private fields
private readonly ApplicationContext _context;
@@ -69,6 +69,12 @@ namespace EveOPreview.UI
set => this.HideActiveClientThumbnailCheckBox.Checked = value;
}
public bool MinimizeInactiveClients
{
get => this.MinimizeInactiveClientsCheckBox.Checked;
set => this.MinimizeInactiveClientsCheckBox.Checked = value;
}
public bool ShowThumbnailsAlwaysOnTop
{
get => this.ShowThumbnailsAlwaysOnTopCheckBox.Checked;
@@ -205,42 +211,23 @@ namespace EveOPreview.UI
this.DocumentationLink.Text = url;
}
public void AddThumbnails(IList<IThumbnailDescriptionView> thumbnails)
public void AddThumbnails(IList<IThumbnailDescription> thumbnails)
{
if (thumbnails.Count == 0)
{
return;
}
this.ThumbnailsList.BeginUpdate();
foreach (IThumbnailDescriptionView view in thumbnails)
foreach (IThumbnailDescription view in thumbnails)
{
this.ThumbnailsList.Items.Add(view);
this.ThumbnailsList.SetItemChecked(this.ThumbnailsList.Items.Add(view), view.IsDisabled);
}
this.ThumbnailsList.EndUpdate();
}
public void UpdateThumbnails(IList<IThumbnailDescriptionView> thumbnails)
public void RemoveThumbnails(IList<IThumbnailDescription> thumbnails)
{
// Just trigger redraw
if (thumbnails.Count > 0)
{
this.ThumbnailsList.Invalidate();
}
}
public void RemoveThumbnails(IList<IThumbnailDescriptionView> thumbnails)
{
if (thumbnails.Count == 0)
{
return;
}
this.ThumbnailsList.BeginUpdate();
foreach (IThumbnailDescriptionView view in thumbnails)
foreach (IThumbnailDescription view in thumbnails)
{
this.ThumbnailsList.Items.Remove(view);
}
@@ -267,7 +254,7 @@ namespace EveOPreview.UI
public Action ThumbnailsSizeChanged { get; set; }
public Action<IntPtr> ThumbnailStateChanged { get; set; }
public Action<string> ThumbnailStateChanged { get; set; }
public Action DocumentationLinkActivated { get; set; }
@@ -287,7 +274,7 @@ namespace EveOPreview.UI
graphics.FillRectangle(backgroundBrush, e.Bounds);
// Use our own font
Font font = new Font("Arial", this.Font.Size * 1.2f, FontStyle.Bold, GraphicsUnit.Pixel);
Font font = new Font("Arial", this.Font.Size * 1.5f, FontStyle.Bold, GraphicsUnit.Pixel);
// Draw string and center the text
StringFormat stringFlags = new StringFormat();
@@ -344,14 +331,14 @@ namespace EveOPreview.UI
private void ThumbnailsList_ItemCheck_Handler(object sender, ItemCheckEventArgs e)
{
IThumbnailDescriptionView selectedItem = this.ThumbnailsList.Items[e.Index] as IThumbnailDescriptionView;
if (selectedItem == null)
if (!(this.ThumbnailsList.Items[e.Index] is IThumbnailDescription selectedItem))
{
return;
}
selectedItem.IsDisabled = (e.NewValue == CheckState.Checked);
this.ThumbnailStateChanged?.Invoke(selectedItem.Id);
this.ThumbnailStateChanged?.Invoke(selectedItem.Title);
}
private void DocumentationLinkClicked_Handler(object sender, LinkLabelLinkClickedEventArgs e)

View File

@@ -132,63 +132,210 @@
<metadata name="ContentTabControl.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="ContentTabControl.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="GeneralTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="GeneralTabPage.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="GeneralSettingsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="GeneralSettingsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="MinimizeInactiveClientsCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="EnableClientLayoutTrackingCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="HideActiveClientThumbnailCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ShowThumbnailsAlwaysOnTopCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="HideThumbnailsOnLostFocusCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="EnablePerClientThumbnailsLayoutsCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="MinimizeToTrayCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ThumbnailTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="ThumbnailTabPage.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ThumbnailSettingsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="ThumbnailSettingsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="HeigthLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="HeigthLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="WidthLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="WidthLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ThumbnailsWidthNumericEdit.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ThumbnailsHeightNumericEdit.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ThumbnailOpacityTrackBar.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="OpacityLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="OpacityLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ZoomTabPage.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ZoomSettingsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="ZoomSettingsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ZoomFactorLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="ZoomFactorLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ZoomAnchorPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ZoomAanchorNWRadioButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ZoomAanchorNRadioButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ZoomAanchorNERadioButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ZoomAanchorWRadioButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ZoomAanchorSERadioButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ZoomAanchorCRadioButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ZoomAanchorSRadioButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ZoomAanchorERadioButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ZoomAanchorSWRadioButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ZoomAnchorLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="ZoomAnchorLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="EnableThumbnailZoomCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ThumbnailZoomFactorNumericEdit.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="OverlayTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="OverlayTabPage.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="OverlaySettingsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="OverlaySettingsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="HighlightColorLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ActiveClientHighlightColorButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="EnableActiveClientHighlightCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ShowThumbnailOverlaysCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ShowThumbnailFramesCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ClientsTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="ClientsTabPage.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ClientsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="ClientsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ThumbnailsList.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ThumbnailsListLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="ThumbnailsListLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="AboutTabPage.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="AboutTabPage.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="AboutPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="AboutPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="DocumentationLinkLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="DocumentationLinkLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="DescriptionLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="DescriptionLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<data name="DescriptionLabel.Text" xml:space="preserve">
<value>An advanced task switcher for EVE Online clients.
@@ -198,9 +345,18 @@ The program does NOT
- broadcast any keyboard or mouse events
- anyhow interact with EVE Online except of bringing its main window to foreground or resizing it</value>
</data>
<metadata name="VersionLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="NameLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="NameLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="DocumentationLink.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="NotifyIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
@@ -746,6 +902,9 @@ The program does NOT
Af//4AAAAAAH///wAAAAAA////gAAAAAH////gAAAAB/////AAAAAP/////AAAAD/////+AAAAf//w==
</value>
</data>
<metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>36</value>
</metadata>

View File

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

View File

@@ -1,4 +1,4 @@
namespace EveOPreview.UI
namespace EveOPreview.View
{
partial class ThumbnailOverlay
{

View File

@@ -1,7 +1,8 @@
using System;
using System.Windows.Forms;
using EveOPreview.Services;
namespace EveOPreview.UI
namespace EveOPreview.View
{
public partial class ThumbnailOverlay : Form
{
@@ -37,7 +38,7 @@ namespace EveOPreview.UI
get
{
var Params = base.CreateParams;
Params.ExStyle |= (int)WindowManagerNativeMethods.WS_EX_TOOLWINDOW;
Params.ExStyle |= (int)InteropConstants.WS_EX_TOOLWINDOW;
return Params;
}
}

View File

@@ -1,4 +1,4 @@
namespace EveOPreview.UI
namespace EveOPreview.View
{
partial class ThumbnailView
{
@@ -21,6 +21,7 @@ namespace EveOPreview.UI
this.AccessibleRole = System.Windows.Forms.AccessibleRole.None;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Black;
this.ClientSize = new System.Drawing.Size(153, 89);
this.ControlBox = false;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;

View File

@@ -2,27 +2,28 @@ using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using EveOPreview.Services;
using EveOPreview.UI.Hotkeys;
namespace EveOPreview.UI
namespace EveOPreview.View
{
public partial class ThumbnailView : Form, IThumbnailView
{
#region Private fields
private readonly IWindowManager _windowManager;
private readonly ThumbnailOverlay _overlay;
private IDwmThumbnail _thumbnail;
// Part of the logic (namely current size / position management)
// was moved to the view due to the performance reasons
private bool _isThumbnailSetUp;
private bool _isOverlayVisible;
private bool _isTopMost;
private bool _isPositionChanged;
private bool _isLocationChanged;
private bool _isSizeChanged;
private bool _isCustomMouseModeActive;
private bool _isHighlightEnabled;
private int _highlightWidth;
private DateTime _suppressResizeEventsTimestamp;
private DWM_THUMBNAIL_PROPERTIES _thumbnail;
private IntPtr _thumbnailHandle;
private Size _baseZoomSize;
private Point _baseZoomLocation;
private Point _baseMousePosition;
@@ -31,17 +32,17 @@ namespace EveOPreview.UI
private HotkeyHandler _hotkeyHandler;
#endregion
public ThumbnailView()
public ThumbnailView(IWindowManager windowManager)
{
this.IsEnabled = true;
this._windowManager = windowManager;
this.IsActive = false;
this.IsOverlayEnabled = false;
this._isThumbnailSetUp = false;
this._isOverlayVisible = false;
this._isTopMost = false;
this._isPositionChanged = true;
this._isLocationChanged = true;
this._isSizeChanged = true;
this._isCustomMouseModeActive = false;
@@ -66,8 +67,6 @@ namespace EveOPreview.UI
}
}
public bool IsEnabled { get; set; }
public bool IsActive { get; set; }
public bool IsOverlayEnabled { get; set; }
@@ -107,7 +106,7 @@ namespace EveOPreview.UI
{
base.Show();
this._isPositionChanged = true;
this._isLocationChanged = true;
this._isSizeChanged = true;
this._isOverlayVisible = false;
@@ -128,9 +127,7 @@ namespace EveOPreview.UI
public new void Close()
{
this.IsActive = false;
this.UnregisterThumbnail(this._thumbnailHandle);
this._thumbnail?.Unregister();
this._overlay.Close();
base.Close();
}
@@ -309,56 +306,26 @@ namespace EveOPreview.UI
public void Refresh(bool forceRefresh)
{
// To prevent flickering the old broken thumbnail is removed AFTER the new shiny one is created
IntPtr obsoleteThumbnailHanlde = forceRefresh ? this._thumbnailHandle : IntPtr.Zero;
IDwmThumbnail obsoleteThumbnail = forceRefresh ? this._thumbnail : null;
if ((this._isThumbnailSetUp == false) || forceRefresh)
if ((this._thumbnail == null) || forceRefresh)
{
this.RegisterThumbnail();
}
bool sizeChanged = this._isSizeChanged || forceRefresh;
bool locationChanged = this._isPositionChanged || forceRefresh;
bool locationChanged = this._isLocationChanged || forceRefresh;
if (sizeChanged)
{
// This approach would work only for square-shaped thumbnail window
// To get PROPER results we have to do some crazy math
//int delta = this._isHighlightEnabled ? this._highlightWidth : 0;
//this._thumbnail.rcDestination = new RECT(0 + delta, 0 + delta, this.ClientSize.Width - delta, this.ClientSize.Height - delta);
if (this._isHighlightEnabled)
{
int baseWidth = this.ClientSize.Width;
int baseHeight = this.ClientSize.Height;
double baseAspectRatio = ((double)baseWidth) / baseHeight;
this.RecalculateThumbnailSize();
int actualHeight = baseHeight - 2 * this._highlightWidth;
double desiredWidth = actualHeight * baseAspectRatio;
int actualWidth = (int)Math.Round(desiredWidth, MidpointRounding.AwayFromZero);
int highlightWidthLeft = (baseWidth - actualWidth) / 2;
int highlightWidthRight = baseWidth - actualWidth - highlightWidthLeft;
this.UpdateThumbnail();
this._thumbnail.rcDestination = new RECT(0 + highlightWidthLeft, 0 + this._highlightWidth, baseWidth - highlightWidthRight, baseHeight - this._highlightWidth);
}
else
{
//No highlighting enables, so no odd math required
this._thumbnail.rcDestination = new RECT(0, 0, this.ClientSize.Width, this.ClientSize.Height);
}
try
{
WindowManagerNativeMethods.DwmUpdateThumbnailProperties(this._thumbnailHandle, this._thumbnail);
}
catch (ArgumentException)
{
//This exception will be thrown if the EVE client disappears while this method is running
}
this._isSizeChanged = false;
}
if (obsoleteThumbnailHanlde != IntPtr.Zero)
{
this.UnregisterThumbnail(obsoleteThumbnailHanlde);
}
obsoleteThumbnail?.Unregister();
this._overlay.EnableOverlayLabel(this.IsOverlayEnabled);
@@ -385,26 +352,52 @@ namespace EveOPreview.UI
overlayLocation.X += borderWidth;
overlayLocation.Y += (this.Size.Height - this.ClientSize.Height) - borderWidth;
this._isPositionChanged = false;
this._isLocationChanged = false;
this._overlay.Size = overlaySize;
this._overlay.Location = overlayLocation;
this._overlay.Refresh();
}
private void RecalculateThumbnailSize()
{
// This approach would work only for square-shaped thumbnail window
// To get PROPER results we have to do some crazy math
//int delta = this._isHighlightEnabled ? this._highlightWidth : 0;
//this._thumbnail.rcDestination = new RECT(0 + delta, 0 + delta, this.ClientSize.Width - delta, this.ClientSize.Height - delta);
if (!this._isHighlightEnabled)
{
//No highlighting enabled, so no odd math required
this._thumbnail.Move(0, 0, this.ClientSize.Width, this.ClientSize.Height);
return;
}
int baseWidth = this.ClientSize.Width;
int baseHeight = this.ClientSize.Height;
double baseAspectRatio = ((double)baseWidth) / baseHeight;
int actualHeight = baseHeight - 2 * this._highlightWidth;
double desiredWidth = actualHeight * baseAspectRatio;
int actualWidth = (int)Math.Round(desiredWidth, MidpointRounding.AwayFromZero);
int highlightWidthLeft = (baseWidth - actualWidth) / 2;
int highlightWidthRight = baseWidth - actualWidth - highlightWidthLeft;
this._thumbnail.Move(0 + highlightWidthLeft, 0 + this._highlightWidth, baseWidth - highlightWidthRight, baseHeight - this._highlightWidth);
}
#region GUI events
protected override CreateParams CreateParams
{
get
{
var Params = base.CreateParams;
Params.ExStyle |= (int)WindowManagerNativeMethods.WS_EX_TOOLWINDOW;
Params.ExStyle |= (int)InteropConstants.WS_EX_TOOLWINDOW;
return Params;
}
}
private void Move_Handler(object sender, EventArgs e)
{
this._isPositionChanged = true;
this._isLocationChanged = true;
this.ThumbnailMoved?.Invoke(this.Id);
}
@@ -480,29 +473,12 @@ namespace EveOPreview.UI
#region Thumbnail management
private void RegisterThumbnail()
{
this._thumbnailHandle = WindowManagerNativeMethods.DwmRegisterThumbnail(this.Handle, this.Id);
this._thumbnail = new DWM_THUMBNAIL_PROPERTIES();
this._thumbnail.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._thumbnail.opacity = 255;
this._thumbnail.fVisible = true;
this._thumbnail.fSourceClientAreaOnly = true;
this._isThumbnailSetUp = true;
this._thumbnail = this._windowManager.RegisterThumbnail(this.Handle, this.Id);
}
private void UnregisterThumbnail(IntPtr thumbnailHandle)
private void UpdateThumbnail()
{
try
{
WindowManagerNativeMethods.DwmUnregisterThumbnail(thumbnailHandle);
}
catch (ArgumentException)
{
}
this._thumbnail.Update();
}
#endregion

View File

@@ -1,9 +1,9 @@
using System;
using System.Drawing;
namespace EveOPreview.UI
namespace EveOPreview.View
{
public class ThumbnailViewFactory : IThumbnailViewFactory
sealed class ThumbnailViewFactory : IThumbnailViewFactory
{
private readonly IApplicationController _controller;

View File

@@ -1,14 +1,15 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using EveOPreview.UI;
namespace EveOPreview.UI
namespace EveOPreview.View
{
/// <summary>
/// Main view interface
/// Presenter uses it to access GUI properties
/// </summary>
public interface IMainView : IView
public interface IMainFormView : IView
{
bool MinimizeToTray { get; set; }
@@ -16,6 +17,7 @@ namespace EveOPreview.UI
bool EnableClientLayoutTracking { get; set; }
bool HideActiveClientThumbnail { get; set; }
bool MinimizeInactiveClients { get; set; }
bool ShowThumbnailsAlwaysOnTop { get; set; }
bool HideThumbnailsOnLostFocus { get; set; }
bool EnablePerClientThumbnailLayouts { get; set; }
@@ -38,9 +40,8 @@ namespace EveOPreview.UI
void Minimize();
void AddThumbnails(IList<IThumbnailDescriptionView> thumbnails);
void UpdateThumbnails(IList<IThumbnailDescriptionView> thumbnails);
void RemoveThumbnails(IList<IThumbnailDescriptionView> thumbnails);
void AddThumbnails(IList<IThumbnailDescription> thumbnails);
void RemoveThumbnails(IList<IThumbnailDescription> thumbnails);
void RefreshZoomSettings();
Action ApplicationExitRequested { get; set; }
@@ -49,7 +50,7 @@ namespace EveOPreview.UI
Action<ViewCloseRequest> FormCloseRequested { get; set; }
Action ApplicationSettingsChanged { get; set; }
Action ThumbnailsSizeChanged { get; set; }
Action<IntPtr> ThumbnailStateChanged { get; set; }
Action<string> ThumbnailStateChanged { get; set; }
Action DocumentationLinkActivated { get; set; }
}
}

View File

@@ -0,0 +1,8 @@
namespace EveOPreview.View
{
public interface IThumbnailDescription
{
string Title { get; set; }
bool IsDisabled { get; set; }
}
}

View File

@@ -2,14 +2,13 @@
using System.Drawing;
using System.Windows.Forms;
namespace EveOPreview.UI
namespace EveOPreview.View
{
public interface IThumbnailView : IView
{
IntPtr Id { get; set; }
string Title { get; set; }
bool IsEnabled { get; set; }
bool IsActive { get; set; }
Point ThumbnailLocation { get; set; }
Size ThumbnailSize { get; set; }

View File

@@ -1,7 +1,7 @@
using System;
using System.Drawing;
namespace EveOPreview.UI
namespace EveOPreview.View
{
public interface IThumbnailViewFactory
{

View File

@@ -1,4 +1,4 @@
namespace EveOPreview.UI
namespace EveOPreview.View
{
public enum ViewZoomAnchor
{

View File

@@ -1,3 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup></configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7"/></startup></configuration>

View File

@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Costura.Fody" version="1.6.2" targetFramework="net46" developmentDependency="true" />
<package id="Fody" version="2.2.0" targetFramework="net452" developmentDependency="true" />
<package id="LightInject" version="5.1.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net452" />
<package id="Fody" version="2.4.6" targetFramework="net47" developmentDependency="true" />
<package id="LightInject" version="5.1.2" targetFramework="net452" requireReinstallation="true" />
<package id="MediatR" version="4.0.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="11.0.1" targetFramework="net46" />
</packages>

View File

@@ -18,9 +18,8 @@ If you have find out that some of the features or their combination of EVE-O Pre
# System Requirements
* Windows Vista, Windows 7, Windows 8/8.1, Windows 10
* Windows Aero Enabled
* Microsoft .NET Framework 4.5+
* Microsoft .NET Framework 4.7+
* EVE clients Display Mode should be set to **Fixed Window** or **Window Mode**. **Fullscreen** mode is not supported.
# How To Install & Use
@@ -47,12 +46,6 @@ CCP Grimmi wrote:
# Application Options
## Startup Parameters
| Parameter | Description |
| --- | --- |
| **config** | This option allows to start the application with a custom configuration file. If the provided file doesn't exists it will be created with default values.<br />For example **"Eve-O&nbsp;Preview.exe"&nbsp;--config:TestSetup.json** |
## Application Options Available Via GUI
| Tab | Option | Description |
@@ -60,6 +53,7 @@ CCP Grimmi wrote:
| **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 ) |
@@ -69,8 +63,8 @@ CCP Grimmi wrote:
| **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 cliet should be displayed on the thumbnail |
| Overlay | Show frames | Determines whether thumbnails should be displayd with window caption and borders |
| **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 |
@@ -89,19 +83,21 @@ Mouse gestures are applied to the thumbnail window currently being hovered over.
## Configuration File-Only Options
Some of the application options are not exposed in the GUI. They can be ajusted directly in the configuration file.
Some of the application options are not exposed in the GUI. They can be adjusted directly in the configuration file.
**Note:** Do any changes to the configuration file only while the EVE-O Preview itself is closed. Otherwise the changes you made might be lost.
| 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** |
| **ThumbnailMinimumSize** | Minimum thumbnail size that can be set either via GUI or by resizing a thumbnail window. Value is witten 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 witten in the form "width, height"<br />The default value is **"640, 400"**.<br />For example: **"ThumbnailMaximumSize": "640, 400"** |
| **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"** |
## Hotkey Setup
It is possible to set a key kombinations to immediately jump to cetrain EVE window. However currently EVE-O Preview doesn't provide any GUI to set the these hotkeys. It should be done via editind the configuration file directly. Don't forget to make a backup copy of the file before editing it.
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.
**Note**: Don't forget to make a backup copy of the file before editing it.