Merge branch 'develop' into beta

This commit is contained in:
Anton Kasyanov
2019-05-05 02:31:26 +03:00
20 changed files with 573 additions and 119 deletions

View File

@@ -24,6 +24,8 @@ namespace EveOPreview.Configuration.Implementation
this.MinimizeToTray = false; this.MinimizeToTray = false;
this.ThumbnailRefreshPeriod = 500; this.ThumbnailRefreshPeriod = 500;
this.EnableCompatibilityMode = false;
this.ThumbnailOpacity = 0.5; this.ThumbnailOpacity = 0.5;
this.EnableClientLayoutTracking = false; this.EnableClientLayoutTracking = false;
@@ -54,6 +56,9 @@ namespace EveOPreview.Configuration.Implementation
public bool MinimizeToTray { get; set; } public bool MinimizeToTray { get; set; }
public int ThumbnailRefreshPeriod { get; set; } public int ThumbnailRefreshPeriod { get; set; }
[JsonProperty("CompatibilityMode")]
public bool EnableCompatibilityMode { get; set; }
[JsonProperty("ThumbnailsOpacity")] [JsonProperty("ThumbnailsOpacity")]
public double ThumbnailOpacity { get; set; } public double ThumbnailOpacity { get; set; }

View File

@@ -8,6 +8,8 @@ namespace EveOPreview.Configuration
bool MinimizeToTray { get; set; } bool MinimizeToTray { get; set; }
int ThumbnailRefreshPeriod { get; set; } int ThumbnailRefreshPeriod { get; set; }
bool EnableCompatibilityMode { get; set; }
double ThumbnailOpacity { get; set; } double ThumbnailOpacity { get; set; }
bool EnableClientLayoutTracking { get; set; } bool EnableClientLayoutTracking { get; set; }

View File

@@ -147,6 +147,7 @@
<Compile Include="Services\Interop\DWM_THUMBNAIL_PROPERTIES.cs" /> <Compile Include="Services\Interop\DWM_THUMBNAIL_PROPERTIES.cs" />
<Compile Include="Services\Interop\DWM_TNP_CONSTANTS.cs" /> <Compile Include="Services\Interop\DWM_TNP_CONSTANTS.cs" />
<Compile Include="Services\Interface\IWindowManager.cs" /> <Compile Include="Services\Interface\IWindowManager.cs" />
<Compile Include="Services\Interop\Gdi32NativeMethods.cs" />
<Compile Include="Services\Interop\MARGINS.cs" /> <Compile Include="Services\Interop\MARGINS.cs" />
<Compile Include="Services\Interop\RECT.cs" /> <Compile Include="Services\Interop\RECT.cs" />
<Compile Include="Configuration\Interface\ClientLayout.cs" /> <Compile Include="Configuration\Interface\ClientLayout.cs" />
@@ -157,6 +158,15 @@
<Compile Include="Presenters\Interface\ViewCloseRequest.cs" /> <Compile Include="Presenters\Interface\ViewCloseRequest.cs" />
<Compile Include="Presenters\Implementation\ViewZoomAnchorConverter.cs" /> <Compile Include="Presenters\Implementation\ViewZoomAnchorConverter.cs" />
<Compile Include="Services\Interop\WINDOWPLACEMENT.cs" /> <Compile Include="Services\Interop\WINDOWPLACEMENT.cs" />
<Compile Include="View\Implementation\LiveThumbnailView.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="View\Implementation\StaticThumbnailImage.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="View\Implementation\StaticThumbnailView.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="View\Interface\IThumbnailViewFactory.cs" /> <Compile Include="View\Interface\IThumbnailViewFactory.cs" />
<Compile Include="Services\Interface\IThumbnailManager.cs" /> <Compile Include="Services\Interface\IThumbnailManager.cs" />
<Compile Include="View\Implementation\ThumbnailDescription.cs" /> <Compile Include="View\Implementation\ThumbnailDescription.cs" />
@@ -212,7 +222,7 @@
<Compile Include="View\Implementation\ThumbnailView.Designer.cs"> <Compile Include="View\Implementation\ThumbnailView.Designer.cs">
<DependentUpon>ThumbnailView.cs</DependentUpon> <DependentUpon>ThumbnailView.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Services\Interop\DwmApiNativeMethods.cs" /> <Compile Include="Services\Interop\DwmNativeMethods.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="app.config" /> <None Include="app.config" />

View File

@@ -11,14 +11,16 @@ namespace EveOPreview
{ {
static class Program static class Program
{ {
private static string MutexName = "EVE-O Preview Single Instance Mutex"; private static string MUTEX_NAME = "EVE-O Preview Single Instance Mutex";
private static Mutex _singleInstanceMutex;
/// <summary>The main entry point for the application.</summary> /// <summary>The main entry point for the application.</summary>
[STAThread] [STAThread]
static void Main() static void Main()
{ {
#if DEBUG #if DEBUG
var expirationDate = new DateTime(2019, 5, 1); var expirationDate = new DateTime(2019, 5, 15);
if (DateTime.Today >= expirationDate) if (DateTime.Today >= expirationDate)
{ {
MessageBox.Show(@"This Beta version is expired. Please download a new build at https://github.com/Phrynohyas/eve-o-preview/releases", @"EVE-O Preview", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); MessageBox.Show(@"This Beta version is expired. Please download a new build at https://github.com/Phrynohyas/eve-o-preview/releases", @"EVE-O Preview", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
@@ -28,11 +30,11 @@ namespace EveOPreview
// The very usual Mutex-based single-instance screening // The very usual Mutex-based single-instance screening
// 'token' variable is used to store reference to the instance Mutex // 'token' variable is used to store reference to the instance Mutex
// during the app lifetime // during the app lifetime
object token = Program.GetInstanceToken(); Program._singleInstanceMutex = Program.GetInstanceToken();
// If it was not possible to acquire the app token then another app instance is already running // If it was not possible to acquire the app token then another app instance is already running
// Nothing to do here // Nothing to do here
if (token == null) if (Program._singleInstanceMutex == null)
{ {
return; return;
} }
@@ -46,7 +48,7 @@ namespace EveOPreview
controller.Run<MainFormPresenter>(); controller.Run<MainFormPresenter>();
} }
private static object GetInstanceToken() private static Mutex GetInstanceToken()
{ {
// The code might look overcomplicated here for a single Mutex operation // The code might look overcomplicated here for a single Mutex operation
// Yet we had already experienced a Windows-level issue // Yet we had already experienced a Windows-level issue
@@ -55,7 +57,7 @@ namespace EveOPreview
// exceptions later // exceptions later
try try
{ {
Mutex.OpenExisting(Program.MutexName); Mutex.OpenExisting(Program.MUTEX_NAME);
// if that didn't fail then another instance is already running // if that didn't fail then another instance is already running
return null; return null;
} }
@@ -65,7 +67,7 @@ namespace EveOPreview
} }
catch (Exception) catch (Exception)
{ {
Mutex token = new Mutex(true, Program.MutexName, out var result); Mutex token = new Mutex(true, Program.MUTEX_NAME, out var result);
return result ? token : null; return result ? token : null;
} }
} }
@@ -105,9 +107,11 @@ namespace EveOPreview
IApplicationController controller = new ApplicationController(container); IApplicationController controller = new ApplicationController(container);
// UI classes // UI classes
controller.RegisterView<IMainFormView, MainForm>() controller.RegisterView<StaticThumbnailView, StaticThumbnailView>();
.RegisterView<IThumbnailView, ThumbnailView>() controller.RegisterView<LiveThumbnailView, LiveThumbnailView>();
.RegisterInstance(new ApplicationContext());
controller.RegisterView<IMainFormView, MainForm>();
controller.RegisterInstance(new ApplicationContext());
return controller; return controller;
} }

View File

@@ -36,7 +36,7 @@ namespace EveOPreview.Services.Implementation
try try
{ {
this._handle = DwmApiNativeMethods.DwmRegisterThumbnail(destination, source); this._handle = DwmNativeMethods.DwmRegisterThumbnail(destination, source);
} }
catch (ArgumentException) catch (ArgumentException)
{ {
@@ -63,7 +63,7 @@ namespace EveOPreview.Services.Implementation
try try
{ {
DwmApiNativeMethods.DwmUnregisterThumbnail(this._handle); DwmNativeMethods.DwmUnregisterThumbnail(this._handle);
} }
catch (ArgumentException) catch (ArgumentException)
{ {
@@ -88,7 +88,7 @@ namespace EveOPreview.Services.Implementation
try try
{ {
DwmApiNativeMethods.DwmUpdateThumbnailProperties(this._handle, this._properties); DwmNativeMethods.DwmUpdateThumbnailProperties(this._handle, this._properties);
} }
catch (ArgumentException) catch (ArgumentException)
{ {

View File

@@ -10,7 +10,7 @@ using MediatR;
namespace EveOPreview.Services namespace EveOPreview.Services
{ {
class ThumbnailManager : IThumbnailManager sealed class ThumbnailManager : IThumbnailManager
{ {
#region Private constants #region Private constants
private const int WINDOW_POSITION_THRESHOLD_LOW = -10_000; private const int WINDOW_POSITION_THRESHOLD_LOW = -10_000;

View File

@@ -1,14 +1,19 @@
using System; using System;
using System.Drawing;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using EveOPreview.Services.Interop; using EveOPreview.Services.Interop;
namespace EveOPreview.Services.Implementation namespace EveOPreview.Services.Implementation
{ {
class WindowManager : IWindowManager sealed class WindowManager : IWindowManager
{ {
#region Private constants
private const int WINDOW_SIZE_THRESHOLD = 300;
#endregion
public WindowManager() public WindowManager()
{ {
this.IsCompositionEnabled = DwmApiNativeMethods.DwmIsCompositionEnabled(); this.IsCompositionEnabled = DwmNativeMethods.DwmIsCompositionEnabled();
} }
public bool IsCompositionEnabled { get; } public bool IsCompositionEnabled { get; }
@@ -63,12 +68,42 @@ namespace EveOPreview.Services.Implementation
return User32NativeMethods.IsIconic(handle); return User32NativeMethods.IsIconic(handle);
} }
public IDwmThumbnail RegisterThumbnail(IntPtr destination, IntPtr source) public IDwmThumbnail GetLiveThumbnail(IntPtr destination, IntPtr source)
{ {
IDwmThumbnail thumbnail = new DwmThumbnail(this); IDwmThumbnail thumbnail = new DwmThumbnail(this);
thumbnail.Register(destination, source); thumbnail.Register(destination, source);
return thumbnail; return thumbnail;
} }
public Image GetStaticThumbnail(IntPtr source)
{
var sourceContext = User32NativeMethods.GetDC(source);
User32NativeMethods.GetClientRect(source, out RECT windowRect);
var width = windowRect.Right - windowRect.Left;
var height = windowRect.Bottom - windowRect.Top;
// Check if there is anything to make thumbnail of
if ((width < WINDOW_SIZE_THRESHOLD) || (height < WINDOW_SIZE_THRESHOLD))
{
return null;
}
var destContext = Gdi32NativeMethods.CreateCompatibleDC(sourceContext);
var bitmap = Gdi32NativeMethods.CreateCompatibleBitmap(sourceContext, width, height);
var oldBitmap = Gdi32NativeMethods.SelectObject(destContext, bitmap);
Gdi32NativeMethods.BitBlt(destContext, 0, 0, width, height, sourceContext, 0, 0, Gdi32NativeMethods.SRCCOPY);
Gdi32NativeMethods.SelectObject(destContext, oldBitmap);
Gdi32NativeMethods.DeleteDC(destContext);
User32NativeMethods.ReleaseDC(source, sourceContext);
Image image = Image.FromHbitmap(bitmap);
Gdi32NativeMethods.DeleteObject(bitmap);
return image;
}
} }
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Drawing;
namespace EveOPreview.Services namespace EveOPreview.Services
{ {
@@ -15,6 +16,7 @@ namespace EveOPreview.Services
(int Left, int Top, int Right, int Bottom) GetWindowPosition(IntPtr handle); (int Left, int Top, int Right, int Bottom) GetWindowPosition(IntPtr handle);
bool IsWindowMinimized(IntPtr handle); bool IsWindowMinimized(IntPtr handle);
IDwmThumbnail RegisterThumbnail(IntPtr destination, IntPtr source); IDwmThumbnail GetLiveThumbnail(IntPtr destination, IntPtr source);
Image GetStaticThumbnail(IntPtr source);
} }
} }

View File

@@ -4,7 +4,7 @@ using System.Drawing;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop
{ {
static class DwmApiNativeMethods static class DwmNativeMethods
{ {
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmEnableBlurBehindWindow(IntPtr hWnd, DWM_BLURBEHIND pBlurBehind); public static extern void DwmEnableBlurBehindWindow(IntPtr hWnd, DWM_BLURBEHIND pBlurBehind);

View File

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

View File

@@ -24,7 +24,10 @@ namespace EveOPreview.Services.Interop
public static extern int GetWindowLong(IntPtr hWnd, int nIndex); public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern int GetWindowRect(IntPtr hwnd, out RECT rect); public static extern int GetWindowRect(IntPtr hWnd, out RECT rect);
[DllImport("user32.dll")]
public static extern bool GetClientRect(IntPtr hWnd, out RECT rect);
[DllImport("user32.dll", SetLastError = true)] [DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
@@ -42,5 +45,14 @@ namespace EveOPreview.Services.Interop
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool IsZoomed(IntPtr hWnd); public static extern bool IsZoomed(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hdc);
} }
} }

View File

@@ -0,0 +1,48 @@
using System;
using EveOPreview.Services;
namespace EveOPreview.View
{
sealed class LiveThumbnailView : ThumbnailView
{
#region Private fields
private IDwmThumbnail _thumbnail;
#endregion
public LiveThumbnailView(IWindowManager windowManager)
: base(windowManager)
{
}
public override void Close()
{
this._thumbnail?.Unregister();
base.Close();
}
protected override void RefreshThumbnail(bool forceRefresh)
{
// To prevent flickering the old broken thumbnail is removed AFTER the new shiny one is created
IDwmThumbnail obsoleteThumbnail = forceRefresh ? this._thumbnail : null;
if ((this._thumbnail == null) || forceRefresh)
{
this.RegisterThumbnail();
}
obsoleteThumbnail?.Unregister();
}
protected override void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop, int highlightWidthRight, int highlightWidthBottom, int highlightWidthLeft)
{
this._thumbnail.Move(0 + highlightWidthLeft, 0 + highlightWidthTop, baseWidth - highlightWidthRight, baseHeight - highlightWidthBottom);
this._thumbnail.Update();
}
private void RegisterThumbnail()
{
this._thumbnail = this.WindowManager.GetLiveThumbnail(this.Handle, this.Id);
this._thumbnail.Update();
}
}
}

View File

@@ -141,12 +141,72 @@
<metadata name="GeneralTabPage.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="GeneralTabPage.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </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="ZoomTabPage.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="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="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="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"> <metadata name="GeneralSettingsPanel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</metadata> </metadata>
<metadata name="GeneralSettingsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="GeneralSettingsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </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="MinimizeInactiveClientsCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="MinimizeInactiveClientsCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
@@ -180,6 +240,39 @@
<metadata name="ThumbnailSettingsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="ThumbnailSettingsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </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="HeigthLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="HeigthLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</metadata> </metadata>
@@ -216,6 +309,12 @@
<metadata name="ZoomSettingsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="ZoomSettingsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </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"> <metadata name="ZoomFactorLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</metadata> </metadata>
@@ -225,6 +324,54 @@
<metadata name="ZoomAnchorPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="ZoomAnchorPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </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="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="ZoomAanchorNWRadioButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="ZoomAanchorNWRadioButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
@@ -276,6 +423,27 @@
<metadata name="OverlaySettingsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="OverlaySettingsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </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="HighlightColorLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="HighlightColorLabel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
@@ -303,6 +471,21 @@
<metadata name="ClientsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="ClientsPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </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="ThumbnailsList.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="ThumbnailsList.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
@@ -324,6 +507,36 @@
<metadata name="AboutPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="AboutPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </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>
<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="DocumentationLinkLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="DocumentationLinkLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</metadata> </metadata>

View File

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

View File

@@ -0,0 +1,49 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using EveOPreview.Services;
namespace EveOPreview.View
{
sealed class StaticThumbnailView : ThumbnailView
{
#region Private fields
private readonly PictureBox _thumbnail;
#endregion
public StaticThumbnailView(IWindowManager windowManager)
: base(windowManager)
{
this._thumbnail = new StaticThumbnailImage
{
TabStop = false,
SizeMode = PictureBoxSizeMode.StretchImage,
Location = new Point(0, 0),
Size = new Size(this.ClientSize.Width, this.ClientSize.Height)
};
this.Controls.Add(this._thumbnail);
}
protected override void RefreshThumbnail(bool forceRefresh)
{
if (!forceRefresh)
{
return;
}
var thumbnail = this.WindowManager.GetStaticThumbnail(this.Id);
if (thumbnail != null)
{
var oldImage = this._thumbnail.Image;
this._thumbnail.Image = thumbnail;
oldImage?.Dispose();
}
}
protected override void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop, int highlightWidthRight, int highlightWidthBottom, int highlightWidthLeft)
{
this._thumbnail.Location = new Point(0 + highlightWidthLeft, 0 + highlightWidthTop);
this._thumbnail.Size = new Size(baseWidth - highlightWidthLeft - highlightWidthRight, baseHeight - highlightWidthTop - highlightWidthBottom);
}
}
}

View File

@@ -19,11 +19,12 @@ namespace EveOPreview.View
// ThumbnailView // ThumbnailView
// //
this.AccessibleRole = System.Windows.Forms.AccessibleRole.None; this.AccessibleRole = System.Windows.Forms.AccessibleRole.None;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackColor = System.Drawing.Color.Black; this.BackColor = System.Drawing.Color.Black;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.ClientSize = new System.Drawing.Size(153, 89); this.ClientSize = new System.Drawing.Size(153, 89);
this.ControlBox = false; this.ControlBox = false;
this.DoubleBuffered = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
this.MaximizeBox = false; this.MaximizeBox = false;
this.MinimizeBox = false; this.MinimizeBox = false;

View File

@@ -7,26 +7,32 @@ using EveOPreview.UI.Hotkeys;
namespace EveOPreview.View namespace EveOPreview.View
{ {
public partial class ThumbnailView : Form, IThumbnailView public abstract partial class ThumbnailView : Form, IThumbnailView
{ {
#region Private constants #region Private constants
private const int RESIZE_EVENT_TIMEOUT = 500; private const int RESIZE_EVENT_TIMEOUT = 500;
f private const double OPACITY_THRESHOLD = 0.9;
private const double OPACITY_EPSILON = 0.1;
#endregion #endregion
#region Private fields #region Private fields
private readonly IWindowManager _windowManager;
private readonly ThumbnailOverlay _overlay; private readonly ThumbnailOverlay _overlay;
private IDwmThumbnail _thumbnail;
// Part of the logic (namely current size / position management) // Part of the logic (namely current size / position management)
// was moved to the view due to the performance reasons // was moved to the view due to the performance reasons
private bool _isOverlayVisible; private bool _isOverlayVisible;
private bool _isTopMost; private bool _isTopMost;
private bool _isHighlightEnabled;
private bool _isHighlightRequested;
private int _highlightWidth;
private bool _isLocationChanged; private bool _isLocationChanged;
private bool _isSizeChanged; private bool _isSizeChanged;
private bool _isCustomMouseModeActive; private bool _isCustomMouseModeActive;
private bool _isHighlightEnabled;
private int _highlightWidth; private double _opacity;
private DateTime _suppressResizeEventsTimestamp; private DateTime _suppressResizeEventsTimestamp;
private Size _baseZoomSize; private Size _baseZoomSize;
private Point _baseZoomLocation; private Point _baseZoomLocation;
@@ -36,29 +42,34 @@ namespace EveOPreview.View
private HotkeyHandler _hotkeyHandler; private HotkeyHandler _hotkeyHandler;
#endregion #endregion
public ThumbnailView(IWindowManager windowManager) protected ThumbnailView(IWindowManager windowManager)
{ {
this.SuppressResizeEvent(); this.SuppressResizeEvent();
this._windowManager = windowManager; this.WindowManager = windowManager;
this.IsActive = false; this.IsActive = false;
this.IsOverlayEnabled = false; this.IsOverlayEnabled = false;
this._isOverlayVisible = false; this._isOverlayVisible = false;
this._isTopMost = false; this._isTopMost = false;
this._isHighlightEnabled = false;
this._isHighlightRequested = false;
this._isLocationChanged = true; this._isLocationChanged = true;
this._isSizeChanged = true; this._isSizeChanged = true;
this._isCustomMouseModeActive = false; this._isCustomMouseModeActive = false;
this._isHighlightEnabled = false; this._opacity = 1.0;
InitializeComponent(); InitializeComponent();
this._overlay = new ThumbnailOverlay(this, this.MouseDown_Handler); this._overlay = new ThumbnailOverlay(this, this.MouseDown_Handler);
} }
protected IWindowManager WindowManager { get; }
public IntPtr Id { get; set; } public IntPtr Id { get; set; }
public string Title public string Title
@@ -131,12 +142,11 @@ namespace EveOPreview.View
base.Hide(); base.Hide();
} }
public new void Close() public new virtual void Close()
{ {
this.SuppressResizeEvent(); this.SuppressResizeEvent();
this.IsActive = false; this.IsActive = false;
this._thumbnail?.Unregister();
this._overlay.Close(); this._overlay.Close();
base.Close(); base.Close();
} }
@@ -154,6 +164,18 @@ namespace EveOPreview.View
} }
public void SetOpacity(double opacity) public void SetOpacity(double opacity)
{
if (opacity >= OPACITY_THRESHOLD)
{
opacity = 1.0;
}
if (Math.Abs(opacity - this._opacity) < OPACITY_EPSILON)
{
return;
}
try
{ {
this.Opacity = opacity; this.Opacity = opacity;
@@ -161,7 +183,15 @@ namespace EveOPreview.View
// Of the thumbnail's opacity is almost full then set the overlay's one to // Of the thumbnail's opacity is almost full then set the overlay's one to
// full. Otherwise set it to half of the thumbnail opacity // full. Otherwise set it to half of the thumbnail opacity
// Opacity value is stored even if the overlay is not displayed atm // Opacity value is stored even if the overlay is not displayed atm
this._overlay.Opacity = this.Opacity > 0.9 ? 1.0 : 1.0 - (1.0 - this.Opacity) / 2; this._overlay.Opacity = opacity > 0.8 ? 1.0 : 1.0 - (1.0 - opacity) / 2;
this._opacity = opacity;
}
catch (Win32Exception)
{
// Something went wrong in WinForms internals
// Opacity will be updated in the next cycle
}
} }
public void SetFrames(bool enable) public void SetFrames(bool enable)
@@ -177,9 +207,6 @@ namespace EveOPreview.View
this.SuppressResizeEvent(); this.SuppressResizeEvent();
this.FormBorderStyle = style; this.FormBorderStyle = style;
// Notify about possible contents position change
this._isSizeChanged = true;
} }
public void SetTopMost(bool enableTopmost) public void SetTopMost(bool enableTopmost)
@@ -198,20 +225,20 @@ namespace EveOPreview.View
public void SetHighlight(bool enabled, Color color, int width) public void SetHighlight(bool enabled, Color color, int width)
{ {
if (this._isHighlightEnabled == enabled) if (this._isHighlightRequested == enabled)
{ {
return; return;
} }
if (enabled) if (enabled)
{ {
this._isHighlightEnabled = true; this._isHighlightRequested = true;
this._highlightWidth = width; this._highlightWidth = width;
this.BackColor = color; this.BackColor = color;
} }
else else
{ {
this._isHighlightEnabled = false; this._isHighlightRequested = false;
this.BackColor = SystemColors.Control; this.BackColor = SystemColors.Control;
} }
@@ -305,69 +332,31 @@ namespace EveOPreview.View
public void Refresh(bool forceRefresh) public void Refresh(bool forceRefresh)
{ {
// To prevent flickering the old broken thumbnail is removed AFTER the new shiny one is created this.RefreshThumbnail(forceRefresh);
IDwmThumbnail obsoleteThumbnail = forceRefresh ? this._thumbnail : null; this.HighlightThumbnail(forceRefresh || this._isSizeChanged);
this.RefreshOverlay(forceRefresh || this._isSizeChanged || this._isLocationChanged);
if ((this._thumbnail == null) || forceRefresh)
{
this.RegisterThumbnail();
}
bool sizeChanged = this._isSizeChanged || forceRefresh;
bool locationChanged = this._isLocationChanged || forceRefresh;
if (sizeChanged)
{
this.RecalculateThumbnailSize();
this.UpdateThumbnail();
this._isSizeChanged = false; this._isSizeChanged = false;
} }
obsoleteThumbnail?.Unregister(); protected abstract void RefreshThumbnail(bool forceRefresh);
this._overlay.EnableOverlayLabel(this.IsOverlayEnabled); protected abstract void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop, int highlightWidthRight, int highlightWidthBottom, int highlightWidthLeft);
if (!this._isOverlayVisible) private void HighlightThumbnail(bool forceRefresh)
{ {
// One-time action to show the Overlay before it is set up if (!forceRefresh && (this._isHighlightRequested == this._isHighlightEnabled))
// Otherwise its position won't be set
this._overlay.Show();
this._isOverlayVisible = true;
}
else
{ {
if (!(sizeChanged || locationChanged)) // Nothing to do here
{
// No need to adjust in the overlay location if it is already visible and properly set
return; return;
} }
}
Size overlaySize = this.ClientSize; this._isHighlightEnabled = this._isHighlightRequested;
Point overlayLocation = this.Location;
int borderWidth = (this.Size.Width - this.ClientSize.Width) / 2; if (!this._isHighlightRequested)
overlayLocation.X += borderWidth;
overlayLocation.Y += (this.Size.Height - this.ClientSize.Height) - borderWidth;
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 //No highlighting enabled, so no math required
// To get PROPER results we have to do some crazy math this.ResizeThumbnail(this.ClientSize.Width, this.ClientSize.Height, 0, 0, 0, 0);
//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; return;
} }
@@ -381,7 +370,38 @@ namespace EveOPreview.View
int highlightWidthLeft = (baseWidth - actualWidth) / 2; int highlightWidthLeft = (baseWidth - actualWidth) / 2;
int highlightWidthRight = baseWidth - actualWidth - highlightWidthLeft; int highlightWidthRight = baseWidth - actualWidth - highlightWidthLeft;
this._thumbnail.Move(0 + highlightWidthLeft, 0 + this._highlightWidth, baseWidth - highlightWidthRight, baseHeight - this._highlightWidth); this.ResizeThumbnail(this.ClientSize.Width, this.ClientSize.Height, this._highlightWidth, highlightWidthRight, this._highlightWidth, highlightWidthLeft);
}
private void RefreshOverlay(bool forceRefresh)
{
if (this._isOverlayVisible && !forceRefresh)
{
// No need to update anything. Everything is already set up
return;
}
this._overlay.EnableOverlayLabel(this.IsOverlayEnabled);
if (!this._isOverlayVisible)
{
// One-time action to show the Overlay before it is set up
// Otherwise its position won't be set
this._overlay.Show();
this._isOverlayVisible = true;
}
Size overlaySize = this.ClientSize;
Point overlayLocation = this.Location;
int borderWidth = (this.Size.Width - this.ClientSize.Width) / 2;
overlayLocation.X += borderWidth;
overlayLocation.Y += (this.Size.Height - this.ClientSize.Height) - borderWidth;
this._isLocationChanged = false;
this._overlay.Size = overlaySize;
this._overlay.Location = overlayLocation;
this._overlay.Refresh();
} }
private void SuppressResizeEvent() private void SuppressResizeEvent()
@@ -482,18 +502,6 @@ namespace EveOPreview.View
} }
#endregion #endregion
#region Thumbnail management
private void RegisterThumbnail()
{
this._thumbnail = this._windowManager.RegisterThumbnail(this.Handle, this.Id);
}
private void UpdateThumbnail()
{
this._thumbnail.Update();
}
#endregion
#region Custom Mouse mode #region Custom Mouse mode
// This pair of methods saves/restores certain window properties // This pair of methods saves/restores certain window properties
// Methods are used to remove the 'Zoom' effect (if any) when the // Methods are used to remove the 'Zoom' effect (if any) when the

View File

@@ -1,20 +1,25 @@
using System; using System;
using System.Drawing; using System.Drawing;
using EveOPreview.Configuration;
namespace EveOPreview.View namespace EveOPreview.View
{ {
sealed class ThumbnailViewFactory : IThumbnailViewFactory sealed class ThumbnailViewFactory : IThumbnailViewFactory
{ {
private readonly IApplicationController _controller; private readonly IApplicationController _controller;
private readonly bool _isCompatibilityModeEnabled;
public ThumbnailViewFactory(IApplicationController controller) public ThumbnailViewFactory(IApplicationController controller, IThumbnailConfiguration configuration)
{ {
this._controller = controller; this._controller = controller;
this._isCompatibilityModeEnabled = configuration.EnableCompatibilityMode;
} }
public IThumbnailView Create(IntPtr id, string title, Size size) public IThumbnailView Create(IntPtr id, string title, Size size)
{ {
IThumbnailView view = this._controller.Create<IThumbnailView>(); IThumbnailView view = this._isCompatibilityModeEnabled
? (IThumbnailView)this._controller.Create<StaticThumbnailView>()
: (IThumbnailView)this._controller.Create<LiveThumbnailView>();
view.Id = id; view.Id = id;
view.Title = title; view.Title = title;

View File

@@ -74,8 +74,8 @@
--> -->
<asmv3:application> <asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True/PM</dpiAware> <dpiAware>True</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness> <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitor</dpiAwareness>
</asmv3:windowsSettings> </asmv3:windowsSettings>
</asmv3:application> </asmv3:application>

View File

@@ -91,6 +91,7 @@ Some of the application options are not exposed in the GUI. They can be adjusted
| Option | Description | | 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** | | **ActiveClientHighlightThickness** | Thickness of the border used to highlight the active client's thumbnail.<br />Allowed values are **1**...**6**.<br />The default value is **3**<br />For example: **"ActiveClientHighlightThickness": 3** |
| **CompatibilityMode** | Enables the alternative render mode (see below)<br />The default value is **false**<br />For example: **"CompatibilityMode": true** |
| **EnableThumbnailSnap** | Allows to disable thumbnails snap feature by setting its value to **false**<br />The default value is **true**<br />For example: **"EnableThumbnailSnap": true** | | **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" ]** | | **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"** | | **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"** |
@@ -124,6 +125,14 @@ The following hotkey is described as `modifier+key` where `modifier` can be **Co
**Note:** Do not set hotkeys to use the key combinations already used by EVE. It won't work as "_I set hotkey for my DPS char to F1 and when I'll press F1 it will automatically open the DPS char's window and activate guns_". Key combination will be swallowed by EVE-O Preview and NOT retranslated to EVE window. So it will be only "_it will automatically open the DPS char's window_". **Note:** Do not set hotkeys to use the key combinations already used by EVE. It won't work as "_I set hotkey for my DPS char to F1 and when I'll press F1 it will automatically open the DPS char's window and activate guns_". Key combination will be swallowed by EVE-O Preview and NOT retranslated to EVE window. So it will be only "_it will automatically open the DPS char's window_".
## Compatibility Mode
This setting allows to enable an alternate thumbnail render. This render doesn't use advanced DWM API to create live previews. Instead it is a screenshot-based render with the following pros and cons:
* `+` Doesn't require Aero to work
* `+` Should work even in remote desktop environments
* `-` Consumes significantly more memory. In the testing environment EVE-O Preview did consume around 180 MB to manage 3 thumbnails using this render. At the same time the primary render did consume around 50 MB when run in the same environment.
* `-` Thumbnail images are refreshed at 1 FPS rate
* `-` Possible short mouse cursor freezes
--- ---