Thumbnail management code cleanup
This commit is contained in:
11
Eve-O-Preview/Configuration/WindowProperties.cs
Normal file
11
Eve-O-Preview/Configuration/WindowProperties.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
namespace EveOPreview
|
||||||
|
{
|
||||||
|
public class WindowProperties
|
||||||
|
{
|
||||||
|
public int X { get; set; }
|
||||||
|
public int Y { get; set; }
|
||||||
|
|
||||||
|
public int Width { get; set; }
|
||||||
|
public int Height { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -116,22 +116,22 @@
|
|||||||
<Compile Include="DwmAPI\DWM_TNP_CONSTANTS.cs" />
|
<Compile Include="DwmAPI\DWM_TNP_CONSTANTS.cs" />
|
||||||
<Compile Include="DwmAPI\MARGINS.cs" />
|
<Compile Include="DwmAPI\MARGINS.cs" />
|
||||||
<Compile Include="DwmAPI\RECT.cs" />
|
<Compile Include="DwmAPI\RECT.cs" />
|
||||||
<Compile Include="GUI\ClientLocation.cs" />
|
<Compile Include="Configuration\WindowProperties.cs" />
|
||||||
<Compile Include="ApplicationBase\IPresenter.cs" />
|
<Compile Include="ApplicationBase\IPresenter.cs" />
|
||||||
<Compile Include="Presentation\MainPresenter.cs" />
|
<Compile Include="Presentation\MainPresenter.cs" />
|
||||||
<Compile Include="Presentation\ViewCloseRequest.cs" />
|
<Compile Include="Presentation\ViewCloseRequest.cs" />
|
||||||
<Compile Include="Thumbnail\Interface\IThumbnailFactory.cs" />
|
<Compile Include="UI\Interface\IThumbnailViewFactory.cs" />
|
||||||
<Compile Include="Thumbnail\Interface\IThumbnailManager.cs" />
|
<Compile Include="Presentation\IThumbnailManager.cs" />
|
||||||
<Compile Include="UI\Implementation\ThumbnailDescriptionView.cs" />
|
<Compile Include="UI\Implementation\ThumbnailDescriptionView.cs" />
|
||||||
<Compile Include="UI\Implementation\ThumbnailDescriptionViewFactory.cs" />
|
<Compile Include="UI\Factory\ThumbnailDescriptionViewFactory.cs" />
|
||||||
<Compile Include="UI\Interface\IMainView.cs" />
|
<Compile Include="UI\Interface\IMainView.cs" />
|
||||||
<Compile Include="ApplicationBase\IView.cs" />
|
<Compile Include="ApplicationBase\IView.cs" />
|
||||||
<Compile Include="UI\Interface\IThumbnailDescriptionView.cs" />
|
<Compile Include="UI\Interface\IThumbnailDescriptionView.cs" />
|
||||||
<Compile Include="UI\Interface\IThumbnailDescriptionViewFactory.cs" />
|
<Compile Include="UI\Interface\IThumbnailDescriptionViewFactory.cs" />
|
||||||
<Compile Include="UI\Interface\ZoomAnchor.cs" />
|
<Compile Include="UI\Interface\ZoomAnchor.cs" />
|
||||||
<Compile Include="Configuration\Configuration.cs" />
|
<Compile Include="Configuration\Configuration.cs" />
|
||||||
<Compile Include="Hotkeys\Hotkey.cs" />
|
<None Include="Hotkeys\Hotkey.cs" />
|
||||||
<Compile Include="Hotkeys\HotkeyNativeMethods.cs" />
|
<None Include="Hotkeys\HotkeyNativeMethods.cs" />
|
||||||
<Compile Include="UI\Implementation\MainForm.cs">
|
<Compile Include="UI\Implementation\MainForm.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -139,13 +139,13 @@
|
|||||||
<DependentUpon>MainForm.cs</DependentUpon>
|
<DependentUpon>MainForm.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Configuration\ConfigurationStorage.cs" />
|
<Compile Include="Configuration\ConfigurationStorage.cs" />
|
||||||
<Compile Include="Thumbnail\Interface\IThumbnail.cs" />
|
<Compile Include="UI\Interface\IThumbnailView.cs" />
|
||||||
<Compile Include="Thumbnail\Implementation\ThumbnailFactory.cs" />
|
<Compile Include="UI\Factory\ThumbnailViewFactory.cs" />
|
||||||
<Compile Include="Thumbnail\Implementation\ThumbnailManager.cs" />
|
<Compile Include="Presentation\ThumbnailManager.cs" />
|
||||||
<Compile Include="Thumbnail\Implementation\ThumbnailOverlay.cs">
|
<Compile Include="UI\Implementation\ThumbnailOverlay.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Thumbnail\Implementation\ThumbnailOverlay.Designer.cs">
|
<Compile Include="UI\Implementation\ThumbnailOverlay.Designer.cs">
|
||||||
<DependentUpon>ThumbnailOverlay.cs</DependentUpon>
|
<DependentUpon>ThumbnailOverlay.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<DependentUpon>MainForm.cs</DependentUpon>
|
<DependentUpon>MainForm.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Thumbnail\Implementation\ThumbnailOverlay.resx">
|
<EmbeddedResource Include="UI\Implementation\ThumbnailOverlay.resx">
|
||||||
<DependentUpon>ThumbnailOverlay.cs</DependentUpon>
|
<DependentUpon>ThumbnailOverlay.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Properties\Resources.resx">
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
@@ -162,9 +162,9 @@
|
|||||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Thumbnail\Implementation\ThumbnailWindow.resx">
|
<EmbeddedResource Include="UI\Implementation\ThumbnailView.resx">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<DependentUpon>ThumbnailWindow.cs</DependentUpon>
|
<DependentUpon>ThumbnailView.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<Compile Include="Properties\Resources.Designer.cs">
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
@@ -184,11 +184,11 @@
|
|||||||
<DependentUpon>Settings.settings</DependentUpon>
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Thumbnail\Implementation\ThumbnailWindow.cs">
|
<Compile Include="UI\Implementation\ThumbnailView.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Thumbnail\Implementation\ThumbnailWindow.Designer.cs">
|
<Compile Include="UI\Implementation\ThumbnailView.Designer.cs">
|
||||||
<DependentUpon>ThumbnailWindow.cs</DependentUpon>
|
<DependentUpon>ThumbnailView.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="DwmAPI\DwmApiNativeMethods.cs" />
|
<Compile Include="DwmAPI\DwmApiNativeMethods.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -220,7 +220,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="icon.ico" />
|
<Content Include="icon.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup>
|
||||||
|
<Folder Include="GUI\" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
@@ -1,10 +0,0 @@
|
|||||||
namespace EveOPreview
|
|
||||||
{
|
|
||||||
public struct ClientLocation
|
|
||||||
{
|
|
||||||
public int X;
|
|
||||||
public int Y;
|
|
||||||
public int Width;
|
|
||||||
public int Height;
|
|
||||||
}
|
|
||||||
}
|
|
21
Eve-O-Preview/Presentation/IThumbnailManager.cs
Normal file
21
Eve-O-Preview/Presentation/IThumbnailManager.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace EveOPreview.UI
|
||||||
|
{
|
||||||
|
public interface IThumbnailManager
|
||||||
|
{
|
||||||
|
void Activate();
|
||||||
|
|
||||||
|
void SetThumbnailState(IntPtr thumbnailId, bool hideAlways);
|
||||||
|
void SetThumbnailsSize(Size size);
|
||||||
|
void RefreshThumbnails();
|
||||||
|
void SetupThumbnailFrames();
|
||||||
|
|
||||||
|
event Action<IList<IThumbnailView>> ThumbnailsAdded;
|
||||||
|
event Action<IList<IThumbnailView>> ThumbnailsUpdated;
|
||||||
|
event Action<IList<IThumbnailView>> ThumbnailsRemoved;
|
||||||
|
event Action<Size> ThumbnailSizeChanged;
|
||||||
|
}
|
||||||
|
}
|
@@ -2,7 +2,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using EveOPreview.Thumbnails;
|
|
||||||
|
|
||||||
namespace EveOPreview.UI
|
namespace EveOPreview.UI
|
||||||
{
|
{
|
||||||
@@ -78,7 +77,7 @@ namespace EveOPreview.UI
|
|||||||
|
|
||||||
private void UpdateThumbnailsSize()
|
private void UpdateThumbnailsSize()
|
||||||
{
|
{
|
||||||
this._manager.SyncPreviewSize(new Size(this.View.ThumbnailsWidth, this.View.ThumbnailsHeight));
|
this._manager.SetThumbnailsSize(new Size(this.View.ThumbnailsWidth, this.View.ThumbnailsHeight));
|
||||||
this.SaveApplicationSettings();
|
this.SaveApplicationSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,29 +133,29 @@ namespace EveOPreview.UI
|
|||||||
this._manager.RefreshThumbnails();
|
this._manager.RefreshThumbnails();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThumbnailsAdded(IList<IThumbnail> thumbnails)
|
private void ThumbnailsAdded(IList<IThumbnailView> thumbnails)
|
||||||
{
|
{
|
||||||
this.View.AddThumbnails(this.GetThumbnailViews(thumbnails, false));
|
this.View.AddThumbnails(this.GetThumbnailViews(thumbnails, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThumbnailsUpdated(IList<IThumbnail> thumbnails)
|
private void ThumbnailsUpdated(IList<IThumbnailView> thumbnails)
|
||||||
{
|
{
|
||||||
this.View.UpdateThumbnails(this.GetThumbnailViews(thumbnails, false));
|
this.View.UpdateThumbnails(this.GetThumbnailViews(thumbnails, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThumbnailsRemoved(IList<IThumbnail> thumbnails)
|
private void ThumbnailsRemoved(IList<IThumbnailView> thumbnails)
|
||||||
{
|
{
|
||||||
this.View.RemoveThumbnails(this.GetThumbnailViews(thumbnails, true));
|
this.View.RemoveThumbnails(this.GetThumbnailViews(thumbnails, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
private IList<IThumbnailDescriptionView> GetThumbnailViews(IList<IThumbnail> thumbnails, bool removeFromCache)
|
private IList<IThumbnailDescriptionView> GetThumbnailViews(IList<IThumbnailView> thumbnails, bool removeFromCache)
|
||||||
{
|
{
|
||||||
IList<IThumbnailDescriptionView> thumbnailViews = new List<IThumbnailDescriptionView>(thumbnails.Count);
|
IList<IThumbnailDescriptionView> thumbnailViews = new List<IThumbnailDescriptionView>(thumbnails.Count);
|
||||||
|
|
||||||
// Time for some thread safety
|
// Time for some thread safety
|
||||||
lock (this._thumbnailViews)
|
lock (this._thumbnailViews)
|
||||||
{
|
{
|
||||||
foreach (IThumbnail thumbnail in thumbnails)
|
foreach (IThumbnailView thumbnail in thumbnails)
|
||||||
{
|
{
|
||||||
IThumbnailDescriptionView thumbnailView;
|
IThumbnailDescriptionView thumbnailView;
|
||||||
bool foundInCache = this._thumbnailViews.TryGetValue(thumbnail.Id, out thumbnailView);
|
bool foundInCache = this._thumbnailViews.TryGetValue(thumbnail.Id, out thumbnailView);
|
||||||
@@ -169,7 +168,7 @@ namespace EveOPreview.UI
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
thumbnailView = this._thumbnailDescriptionViewFactory.Create(thumbnail.Id, thumbnail.GetLabel());
|
thumbnailView = this._thumbnailDescriptionViewFactory.Create(thumbnail.Id, thumbnail.Title, !thumbnail.IsEnabled);
|
||||||
this._thumbnailViews.Add(thumbnail.Id, thumbnailView);
|
this._thumbnailViews.Add(thumbnail.Id, thumbnailView);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -180,7 +179,7 @@ namespace EveOPreview.UI
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
thumbnailView.Title = thumbnail.GetLabel();
|
thumbnailView.Title = thumbnail.Title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,9 +195,9 @@ namespace EveOPreview.UI
|
|||||||
this.View.UpdateThumbnailsSizeView(size);
|
this.View.UpdateThumbnailsSizeView(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateThumbnailState(IntPtr thumbnailId, bool hideAlways)
|
private void UpdateThumbnailState(IntPtr thumbnailId)
|
||||||
{
|
{
|
||||||
this._manager.SetThumbnailState(thumbnailId, hideAlways);
|
this._manager.SetThumbnailState(thumbnailId, this._thumbnailViews[thumbnailId].IsDisabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenForumUrlLink()
|
private void OpenForumUrlLink()
|
||||||
|
746
Eve-O-Preview/Presentation/ThumbnailManager.cs
Normal file
746
Eve-O-Preview/Presentation/ThumbnailManager.cs
Normal file
@@ -0,0 +1,746 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace EveOPreview.UI
|
||||||
|
{
|
||||||
|
public class ThumbnailManager : IThumbnailManager
|
||||||
|
{
|
||||||
|
private const string ClientProcessName = "ExeFile";
|
||||||
|
private const string DefaultThumbnailTitle = "...";
|
||||||
|
|
||||||
|
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;
|
||||||
|
private Size _thumbnailBaseSize;
|
||||||
|
private Point _thumbnailBaseLocation;
|
||||||
|
|
||||||
|
// TODO To be moved into a separate class
|
||||||
|
private readonly Dictionary<string, Dictionary<string, Point>> _uniqueLayouts;
|
||||||
|
private readonly Dictionary<string, Point> _flatLayout;
|
||||||
|
private readonly Dictionary<string, string> _flatLayoutShortcuts;
|
||||||
|
private readonly Dictionary<string, WindowProperties> _clientLayout;
|
||||||
|
|
||||||
|
// TODO To be removed
|
||||||
|
private readonly Dictionary<string, string> _xmlBadToOkChars;
|
||||||
|
|
||||||
|
// TODO Drop dependency on the configuration object
|
||||||
|
public ThumbnailManager(IThumbnailViewFactory factory)
|
||||||
|
{
|
||||||
|
this._thumbnailViewFactory = factory;
|
||||||
|
|
||||||
|
this._activeClientHandle = (IntPtr)0;
|
||||||
|
this._activeClientTitle = "";
|
||||||
|
|
||||||
|
this._ignoreViewEvents = false;
|
||||||
|
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, 500); // TODO Make it configurable
|
||||||
|
|
||||||
|
// TODO Move mayouts stuff out
|
||||||
|
_uniqueLayouts = new Dictionary<string, Dictionary<string, Point>>();
|
||||||
|
_flatLayout = new Dictionary<string, Point>();
|
||||||
|
_flatLayoutShortcuts = new Dictionary<string, string>();
|
||||||
|
_clientLayout = new Dictionary<string, WindowProperties>();
|
||||||
|
|
||||||
|
// TODO To be removed
|
||||||
|
_xmlBadToOkChars = new Dictionary<string, string>();
|
||||||
|
_xmlBadToOkChars["<"] = "---lt---";
|
||||||
|
_xmlBadToOkChars["&"] = "---amp---";
|
||||||
|
_xmlBadToOkChars[">"] = "---gt---";
|
||||||
|
_xmlBadToOkChars["\""] = "---quot---";
|
||||||
|
_xmlBadToOkChars["\'"] = "---apos---";
|
||||||
|
_xmlBadToOkChars[","] = "---comma---";
|
||||||
|
_xmlBadToOkChars["."] = "---dot---";
|
||||||
|
}
|
||||||
|
|
||||||
|
public event Action<IList<IThumbnailView>> ThumbnailsAdded;
|
||||||
|
public event Action<IList<IThumbnailView>> ThumbnailsUpdated;
|
||||||
|
public event Action<IList<IThumbnailView>> ThumbnailsRemoved;
|
||||||
|
public event Action<Size> ThumbnailSizeChanged;
|
||||||
|
|
||||||
|
public void Activate()
|
||||||
|
{
|
||||||
|
this.LoadLayout();
|
||||||
|
|
||||||
|
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._ignoreViewEvents = true;
|
||||||
|
|
||||||
|
foreach (KeyValuePair<IntPtr, IThumbnailView> entry in this._thumbnailViews)
|
||||||
|
{
|
||||||
|
entry.Value.Size = size;
|
||||||
|
entry.Value.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ThumbnailSizeChanged?.Invoke(size);
|
||||||
|
|
||||||
|
this._ignoreViewEvents = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Drop dependency on the configuration object
|
||||||
|
public void RefreshThumbnails()
|
||||||
|
{
|
||||||
|
IntPtr foregroundWindowHandle = DwmApiNativeMethods.GetForegroundWindow();
|
||||||
|
Boolean hideAllThumbnails = (Properties.Settings.Default.hide_all && !this.IsClientWindowActive(foregroundWindowHandle)) || !DwmApiNativeMethods.DwmIsCompositionEnabled();
|
||||||
|
|
||||||
|
this._ignoreViewEvents = true;
|
||||||
|
|
||||||
|
// 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 (view.Id == this._activeClientHandle && Properties.Settings.Default.hide_active)
|
||||||
|
{
|
||||||
|
if (view.IsActive)
|
||||||
|
{
|
||||||
|
view.Hide();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Properties.Settings.Default.unique_layout)
|
||||||
|
{
|
||||||
|
this.ApplyPerClientLayout(view, this._activeClientTitle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.ApplyFlatLayout(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
view.IsOverlayEnabled = Properties.Settings.Default.show_overlay;
|
||||||
|
if (!this._isHoverEffectActive)
|
||||||
|
{
|
||||||
|
view.SetOpacity(Properties.Settings.Default.opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!view.IsActive)
|
||||||
|
{
|
||||||
|
view.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._ignoreViewEvents = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetupThumbnailFrames()
|
||||||
|
{
|
||||||
|
// TODO Drop config dependency
|
||||||
|
this._ignoreViewEvents = true;
|
||||||
|
|
||||||
|
foreach (KeyValuePair<IntPtr, IThumbnailView> entry in this._thumbnailViews)
|
||||||
|
{
|
||||||
|
entry.Value.SetWindowFrames(Properties.Settings.Default.show_thumb_frames);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._ignoreViewEvents = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThumbnailUpdateTimerTick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.UpdateThumbnailsList();
|
||||||
|
this.RefreshThumbnails();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Process[] GetClientProcesses()
|
||||||
|
{
|
||||||
|
return Process.GetProcessesByName(ThumbnailManager.ClientProcessName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateThumbnailsList()
|
||||||
|
{
|
||||||
|
Process[] clientProcesses = this.GetClientProcesses();
|
||||||
|
List<IntPtr> processHandles = new List<IntPtr>(clientProcesses.Length);
|
||||||
|
|
||||||
|
IntPtr foregroundWindowHandle = DwmApiNativeMethods.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 != ""))
|
||||||
|
{
|
||||||
|
Size thumbnailSize = new Size();
|
||||||
|
thumbnailSize.Width = (int)Properties.Settings.Default.sync_resize_x;
|
||||||
|
thumbnailSize.Height = (int)Properties.Settings.Default.sync_resize_y;
|
||||||
|
|
||||||
|
view = this._thumbnailViewFactory.Create(processHandle, ThumbnailManager.DefaultThumbnailTitle, thumbnailSize);
|
||||||
|
view.IsEnabled = true;
|
||||||
|
view.IsOverlayEnabled = Properties.Settings.Default.show_overlay;
|
||||||
|
view.SetTopMost(Properties.Settings.Default.always_on_top);
|
||||||
|
view.SetWindowFrames(Properties.Settings.Default.show_thumb_frames);
|
||||||
|
|
||||||
|
view.ThumbnailResized += ThumbnailViewResized;
|
||||||
|
view.ThumbnailMoved += ThumbnailViewMoved;
|
||||||
|
view.ThumbnailFocused += ThumbnailViewFocused;
|
||||||
|
view.ThumbnailLostFocus += ThumbnailViewLostFocus;
|
||||||
|
view.ThumbnailActivated += ThumbnailActivated;
|
||||||
|
|
||||||
|
this._thumbnailViews.Add(processHandle, view);
|
||||||
|
|
||||||
|
this.SetupClientWindow(processHandle, processTitle);
|
||||||
|
|
||||||
|
viewsAdded.Add(view);
|
||||||
|
}
|
||||||
|
else if ((view != null) && (processTitle != view.Title)) // update thumbnail title
|
||||||
|
{
|
||||||
|
view.Title = processTitle;
|
||||||
|
|
||||||
|
// TODO Shortcuts should be handled at manager level
|
||||||
|
//string value;
|
||||||
|
//if (_flatLayoutShortcuts.TryGetValue(processTitle, out value))
|
||||||
|
//{
|
||||||
|
// view.RegisterShortcut(value);
|
||||||
|
//}
|
||||||
|
|
||||||
|
this.SetupClientWindow(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 _thumbnailViews.Keys)
|
||||||
|
{
|
||||||
|
if (!processHandles.Contains(processHandle))
|
||||||
|
{
|
||||||
|
obsoleteThumbnails.Add(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (IntPtr processHandle in obsoleteThumbnails)
|
||||||
|
{
|
||||||
|
IThumbnailView view = this._thumbnailViews[processHandle];
|
||||||
|
|
||||||
|
_thumbnailViews.Remove(processHandle);
|
||||||
|
|
||||||
|
// TODO Remove hotkey here
|
||||||
|
view.ThumbnailResized -= ThumbnailViewResized;
|
||||||
|
view.ThumbnailMoved -= ThumbnailViewMoved;
|
||||||
|
view.ThumbnailFocused -= ThumbnailViewFocused;
|
||||||
|
view.ThumbnailLostFocus -= ThumbnailViewLostFocus;
|
||||||
|
view.ThumbnailActivated -= ThumbnailActivated;
|
||||||
|
|
||||||
|
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];
|
||||||
|
|
||||||
|
this.ThumbnailZoomIn(view);
|
||||||
|
view.SetTopMost(true);
|
||||||
|
|
||||||
|
view.SetOpacity(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThumbnailViewLostFocus(IntPtr id)
|
||||||
|
{
|
||||||
|
if (!this._isHoverEffectActive)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IThumbnailView view = this._thumbnailViews[id];
|
||||||
|
|
||||||
|
this.ThumbnailZoomOut(view);
|
||||||
|
|
||||||
|
view.SetOpacity(Properties.Settings.Default.opacity);
|
||||||
|
|
||||||
|
this._isHoverEffectActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThumbnailActivated(IntPtr id)
|
||||||
|
{
|
||||||
|
DwmApiNativeMethods.SetForegroundWindow(id);
|
||||||
|
|
||||||
|
int style = DwmApiNativeMethods.GetWindowLong(id, DwmApiNativeMethods.GWL_STYLE);
|
||||||
|
if ((style & DwmApiNativeMethods.WS_MINIMIZE) == DwmApiNativeMethods.WS_MINIMIZE)
|
||||||
|
{
|
||||||
|
DwmApiNativeMethods.ShowWindowAsync(id, DwmApiNativeMethods.SW_SHOWNORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.UpdateClientLocation();
|
||||||
|
|
||||||
|
this.SaveLayout(); // Stores info about client window locations
|
||||||
|
|
||||||
|
foreach (KeyValuePair<IntPtr, IThumbnailView> entry in this._thumbnailViews)
|
||||||
|
{
|
||||||
|
IThumbnailView view = entry.Value;
|
||||||
|
view.SetTopMost(Properties.Settings.Default.always_on_top);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThumbnailViewResized(IntPtr id)
|
||||||
|
{
|
||||||
|
if (this._ignoreViewEvents)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IThumbnailView view = this._thumbnailViews[id];
|
||||||
|
|
||||||
|
this.SetThumbnailsSize(view.Size);
|
||||||
|
|
||||||
|
view.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThumbnailViewMoved(IntPtr id)
|
||||||
|
{
|
||||||
|
if (this._ignoreViewEvents)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IThumbnailView view = this._thumbnailViews[id];
|
||||||
|
|
||||||
|
this.UpdateThumbnailPosition(view.Title, view.Location);
|
||||||
|
|
||||||
|
view.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupClientWindow(IntPtr clientHandle, string clientTitle)
|
||||||
|
{
|
||||||
|
if (!Properties.Settings.Default.track_client_windows)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowProperties windowProperties;
|
||||||
|
if (!this._clientLayout.TryGetValue(clientTitle, out windowProperties))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DwmApiNativeMethods.MoveWindow(clientHandle, windowProperties.X, windowProperties.Y, windowProperties.Width, windowProperties.Height, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsClientWindowActive(IntPtr windowHandle)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<IntPtr, IThumbnailView> entry in _thumbnailViews)
|
||||||
|
{
|
||||||
|
if (entry.Value.IsKnownHandle(windowHandle))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateThumbnailPosition(string title, Point position)
|
||||||
|
{
|
||||||
|
if (Properties.Settings.Default.unique_layout)
|
||||||
|
{
|
||||||
|
Dictionary<string, Point> layout;
|
||||||
|
if (_uniqueLayouts.TryGetValue(_activeClientTitle, out layout))
|
||||||
|
{
|
||||||
|
layout[title] = position;
|
||||||
|
}
|
||||||
|
else if (_activeClientTitle == "")
|
||||||
|
{
|
||||||
|
_uniqueLayouts[_activeClientTitle] = new Dictionary<string, Point>();
|
||||||
|
_uniqueLayouts[_activeClientTitle][title] = position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_flatLayout[title] = position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThumbnailZoomIn(IThumbnailView view)
|
||||||
|
{
|
||||||
|
// TODO Use global settings object
|
||||||
|
float zoomFactor = Properties.Settings.Default.zoom_amount;
|
||||||
|
|
||||||
|
this._thumbnailBaseSize = view.Size;
|
||||||
|
this._thumbnailBaseLocation = view.Location;
|
||||||
|
|
||||||
|
this._ignoreViewEvents = true;
|
||||||
|
view.Size = new Size((int)(zoomFactor * view.Size.Width), (int)(zoomFactor * view.Size.Height));
|
||||||
|
|
||||||
|
int locationX = view.Location.X;
|
||||||
|
int locationY = view.Location.Y;
|
||||||
|
|
||||||
|
int newWidth = view.Size.Width;
|
||||||
|
int newHeight = view.Size.Height;
|
||||||
|
|
||||||
|
int oldWidth = this._thumbnailBaseSize.Width;
|
||||||
|
int oldHeight = this._thumbnailBaseSize.Height;
|
||||||
|
|
||||||
|
// TODO Use global settings object
|
||||||
|
switch ((ZoomAnchor)Properties.Settings.Default.zoom_anchor)
|
||||||
|
{
|
||||||
|
case ZoomAnchor.NW:
|
||||||
|
break;
|
||||||
|
case ZoomAnchor.N:
|
||||||
|
view.Location = new Point(locationX - newWidth / 2 + oldWidth / 2, locationY);
|
||||||
|
break;
|
||||||
|
case ZoomAnchor.NE:
|
||||||
|
view.Location = new Point(locationX - newWidth + oldWidth, locationY);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ZoomAnchor.W:
|
||||||
|
view.Location = new Point(locationX, locationY - newHeight / 2 + oldHeight / 2);
|
||||||
|
break;
|
||||||
|
case ZoomAnchor.C:
|
||||||
|
view.Location = new Point(locationX - newWidth / 2 + oldWidth / 2, locationY - newHeight / 2 + oldHeight / 2);
|
||||||
|
break;
|
||||||
|
case ZoomAnchor.E:
|
||||||
|
view.Location = new Point(locationX - newWidth + oldWidth, locationY - newHeight / 2 + oldHeight / 2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ZoomAnchor.SW:
|
||||||
|
view.Location = new Point(locationX, locationY - newHeight + this._thumbnailBaseSize.Height);
|
||||||
|
break;
|
||||||
|
case ZoomAnchor.S:
|
||||||
|
view.Location = new Point(locationX - newWidth / 2 + oldWidth / 2, locationY - newHeight + oldHeight);
|
||||||
|
break;
|
||||||
|
case ZoomAnchor.SE:
|
||||||
|
view.Location = new Point(locationX - newWidth + oldWidth, locationY - newHeight + oldHeight);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
view.Refresh();
|
||||||
|
|
||||||
|
this._ignoreViewEvents = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThumbnailZoomOut(IThumbnailView view)
|
||||||
|
{
|
||||||
|
this._ignoreViewEvents = true;
|
||||||
|
|
||||||
|
view.Size = this._thumbnailBaseSize;
|
||||||
|
view.Location = this._thumbnailBaseLocation;
|
||||||
|
|
||||||
|
view.Refresh();
|
||||||
|
|
||||||
|
this._ignoreViewEvents = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************
|
||||||
|
// ************************************************************************
|
||||||
|
// ************************************************************************
|
||||||
|
// ************************************************************************
|
||||||
|
// ************************************************************************
|
||||||
|
// ************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// TODO Reenable this method
|
||||||
|
private void UpdateClientLocation()
|
||||||
|
{
|
||||||
|
Process[] processes = Process.GetProcessesByName("ExeFile");
|
||||||
|
List<IntPtr> processHandles = new List<IntPtr>();
|
||||||
|
|
||||||
|
foreach (Process process in processes)
|
||||||
|
{
|
||||||
|
RECT rect = new RECT();
|
||||||
|
DwmApiNativeMethods.GetWindowRect(process.MainWindowHandle, out rect);
|
||||||
|
|
||||||
|
int left = Math.Abs(rect.Left);
|
||||||
|
int right = Math.Abs(rect.Right);
|
||||||
|
int client_width = Math.Abs(left - right);
|
||||||
|
|
||||||
|
int top = Math.Abs(rect.Top);
|
||||||
|
int bottom = Math.Abs(rect.Bottom);
|
||||||
|
int client_height = Math.Abs(top - bottom);
|
||||||
|
|
||||||
|
WindowProperties location = new WindowProperties();
|
||||||
|
location.X = rect.Left;
|
||||||
|
location.Y = rect.Top;
|
||||||
|
location.Width = client_width;
|
||||||
|
location.Height = client_height;
|
||||||
|
|
||||||
|
|
||||||
|
_clientLayout[process.MainWindowTitle] = location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Layouting and stuff should be renewed later
|
||||||
|
private string remove_nonconform_xml_characters(string entry)
|
||||||
|
{
|
||||||
|
foreach (var kv in _xmlBadToOkChars)
|
||||||
|
{
|
||||||
|
entry = entry.Replace(kv.Key, kv.Value);
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string restore_nonconform_xml_characters(string entry)
|
||||||
|
{
|
||||||
|
foreach (var kv in _xmlBadToOkChars)
|
||||||
|
{
|
||||||
|
entry = entry.Replace(kv.Value, kv.Key);
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
private XElement MakeXElement(string input)
|
||||||
|
{
|
||||||
|
string clean = remove_nonconform_xml_characters(input).Replace(" ", "_");
|
||||||
|
return new XElement(clean);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ParseXElement(XElement input)
|
||||||
|
{
|
||||||
|
return restore_nonconform_xml_characters(input.Name.ToString()).Replace("_", " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadLayout()
|
||||||
|
{
|
||||||
|
if (File.Exists("layout.xml"))
|
||||||
|
{
|
||||||
|
XElement rootElement = XElement.Load("layout.xml");
|
||||||
|
foreach (var el in rootElement.Elements())
|
||||||
|
{
|
||||||
|
Dictionary<string, Point> inner = new Dictionary<string, Point>();
|
||||||
|
foreach (var inner_el in el.Elements())
|
||||||
|
{
|
||||||
|
inner[ParseXElement(inner_el)] = new Point(Convert.ToInt32(inner_el.Element("x")?.Value), Convert.ToInt32(inner_el.Element("y")?.Value));
|
||||||
|
}
|
||||||
|
_uniqueLayouts[ParseXElement(el)] = inner;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists("flat_layout.xml"))
|
||||||
|
{
|
||||||
|
XElement rootElement = XElement.Load("flat_layout.xml");
|
||||||
|
foreach (var el in rootElement.Elements())
|
||||||
|
{
|
||||||
|
_flatLayout[ParseXElement(el)] = new Point(Convert.ToInt32(el.Element("x").Value), Convert.ToInt32(el.Element("y").Value));
|
||||||
|
_flatLayoutShortcuts[ParseXElement(el)] = "";
|
||||||
|
|
||||||
|
if (el.Element("shortcut") != null)
|
||||||
|
{
|
||||||
|
_flatLayoutShortcuts[ParseXElement(el)] = el.Element("shortcut").Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists("client_layout.xml"))
|
||||||
|
{
|
||||||
|
XElement rootElement = XElement.Load("client_layout.xml");
|
||||||
|
foreach (var el in rootElement.Elements())
|
||||||
|
{
|
||||||
|
WindowProperties location = new WindowProperties();
|
||||||
|
location.X = Convert.ToInt32(el.Element("x").Value);
|
||||||
|
location.Y = Convert.ToInt32(el.Element("y").Value);
|
||||||
|
location.Width = Convert.ToInt32(el.Element("width").Value);
|
||||||
|
location.Height = Convert.ToInt32(el.Element("height").Value);
|
||||||
|
|
||||||
|
_clientLayout[ParseXElement(el)] = location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveLayout()
|
||||||
|
{
|
||||||
|
XElement el = new XElement("layouts");
|
||||||
|
foreach (var client in _uniqueLayouts.Keys)
|
||||||
|
{
|
||||||
|
if (client == "")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
XElement layout = MakeXElement(client);
|
||||||
|
foreach (var thumbnail_ in _uniqueLayouts[client])
|
||||||
|
{
|
||||||
|
string thumbnail = thumbnail_.Key;
|
||||||
|
if (thumbnail == "" || thumbnail == "...")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
XElement position = MakeXElement(thumbnail);
|
||||||
|
position.Add(new XElement("x", thumbnail_.Value.X));
|
||||||
|
position.Add(new XElement("y", thumbnail_.Value.Y));
|
||||||
|
layout.Add(position);
|
||||||
|
}
|
||||||
|
el.Add(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
el.Save("layout.xml");
|
||||||
|
|
||||||
|
XElement el2 = new XElement("flat_layout");
|
||||||
|
foreach (var clientKV in _flatLayout)
|
||||||
|
{
|
||||||
|
if (clientKV.Key == "" || clientKV.Key == "...")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
XElement layout = MakeXElement(clientKV.Key);
|
||||||
|
layout.Add(new XElement("x", clientKV.Value.X));
|
||||||
|
layout.Add(new XElement("y", clientKV.Value.Y));
|
||||||
|
|
||||||
|
string shortcut;
|
||||||
|
if (_flatLayoutShortcuts.TryGetValue(clientKV.Key, out shortcut))
|
||||||
|
{
|
||||||
|
layout.Add(new XElement("shortcut", shortcut));
|
||||||
|
}
|
||||||
|
el2.Add(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
el2.Save("flat_layout.xml");
|
||||||
|
|
||||||
|
XElement el3 = new XElement("client_layout");
|
||||||
|
foreach (var clientKV in _clientLayout)
|
||||||
|
{
|
||||||
|
if (clientKV.Key == "" || clientKV.Key == "...")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
XElement layout = MakeXElement(clientKV.Key);
|
||||||
|
layout.Add(new XElement("x", clientKV.Value.X));
|
||||||
|
layout.Add(new XElement("y", clientKV.Value.Y));
|
||||||
|
layout.Add(new XElement("width", clientKV.Value.Width));
|
||||||
|
layout.Add(new XElement("height", clientKV.Value.Height));
|
||||||
|
el3.Add(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
el3.Save("client_layout.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyPerClientLayout(IThumbnailView thumbnailWindow, string last_known_active_window)
|
||||||
|
{
|
||||||
|
Dictionary<string, Point> layout;
|
||||||
|
if (_uniqueLayouts.TryGetValue(last_known_active_window, out layout))
|
||||||
|
{
|
||||||
|
Point new_loc;
|
||||||
|
if (Properties.Settings.Default.unique_layout && layout.TryGetValue(thumbnailWindow.Title, out new_loc))
|
||||||
|
{
|
||||||
|
thumbnailWindow.Location = new_loc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// create inner dict
|
||||||
|
layout[thumbnailWindow.Title] = thumbnailWindow.Location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (last_known_active_window != "")
|
||||||
|
{
|
||||||
|
// create outer dict
|
||||||
|
_uniqueLayouts[last_known_active_window] = new Dictionary<string, Point>();
|
||||||
|
_uniqueLayouts[last_known_active_window][thumbnailWindow.Title] = thumbnailWindow.Location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyFlatLayout(IThumbnailView thumbnailWindow)
|
||||||
|
{
|
||||||
|
Point layout;
|
||||||
|
if (_flatLayout.TryGetValue(thumbnailWindow.Title, out layout))
|
||||||
|
{
|
||||||
|
thumbnailWindow.Location = layout;
|
||||||
|
}
|
||||||
|
else if (thumbnailWindow.Title != "")
|
||||||
|
{
|
||||||
|
_flatLayout[thumbnailWindow.Title] = thumbnailWindow.Location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -19,12 +19,13 @@ namespace EveOPreview
|
|||||||
// UI classes
|
// UI classes
|
||||||
IApplicationController controller = new ApplicationController(container)
|
IApplicationController controller = new ApplicationController(container)
|
||||||
.RegisterView<IMainView, MainForm>()
|
.RegisterView<IMainView, MainForm>()
|
||||||
|
.RegisterView<IThumbnailView, ThumbnailView>()
|
||||||
.RegisterView<IThumbnailDescriptionView, ThumbnailDescriptionView>()
|
.RegisterView<IThumbnailDescriptionView, ThumbnailDescriptionView>()
|
||||||
.RegisterInstance(new ApplicationContext());
|
.RegisterInstance(new ApplicationContext());
|
||||||
|
|
||||||
// Application services
|
// Application services
|
||||||
controller.RegisterService<EveOPreview.Thumbnails.IThumbnailFactory, EveOPreview.Thumbnails.ThumbnailFactory>()
|
controller.RegisterService<IThumbnailManager, ThumbnailManager>()
|
||||||
.RegisterService<EveOPreview.Thumbnails.IThumbnailManager, EveOPreview.Thumbnails.ThumbnailManager>()
|
.RegisterService<IThumbnailViewFactory, ThumbnailViewFactory>()
|
||||||
.RegisterService<IThumbnailDescriptionViewFactory, ThumbnailDescriptionViewFactory>();
|
.RegisterService<IThumbnailDescriptionViewFactory, ThumbnailDescriptionViewFactory>();
|
||||||
|
|
||||||
controller.Run<EveOPreview.UI.MainPresenter>();
|
controller.Run<EveOPreview.UI.MainPresenter>();
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace EveOPreview.Thumbnails
|
|
||||||
{
|
|
||||||
public class ThumbnailFactory : IThumbnailFactory
|
|
||||||
{
|
|
||||||
public IThumbnail Create(IThumbnailManager manager, IntPtr sourceWindow, string title, Size size)
|
|
||||||
{
|
|
||||||
return new ThumbnailWindow(manager, sourceWindow, title, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,507 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.IO;
|
|
||||||
using System.Windows.Threading;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace EveOPreview.Thumbnails
|
|
||||||
{
|
|
||||||
public class ThumbnailManager : IThumbnailManager
|
|
||||||
{
|
|
||||||
private readonly Stopwatch _ignoringSizeSync;
|
|
||||||
private DispatcherTimer _dispatcherTimer;
|
|
||||||
private readonly ThumbnailFactory _thumbnailFactory;
|
|
||||||
private readonly Dictionary<IntPtr, IThumbnail> _previews;
|
|
||||||
|
|
||||||
private IntPtr _activeClientHandle;
|
|
||||||
private string _activeClientTitle;
|
|
||||||
|
|
||||||
private readonly Dictionary<string, Dictionary<string, Point>> _uniqueLayouts;
|
|
||||||
private readonly Dictionary<string, Point> _flatLayout;
|
|
||||||
private readonly Dictionary<string, string> _flatLayoutShortcuts;
|
|
||||||
private readonly Dictionary<string, ClientLocation> _clientLayout;
|
|
||||||
|
|
||||||
private readonly Dictionary<string, string> _xmlBadToOkChars;
|
|
||||||
|
|
||||||
public ThumbnailManager(IThumbnailFactory factory)
|
|
||||||
{
|
|
||||||
_ignoringSizeSync = new Stopwatch();
|
|
||||||
_ignoringSizeSync.Start();
|
|
||||||
|
|
||||||
this._activeClientHandle = (IntPtr)0;
|
|
||||||
this._activeClientTitle = "";
|
|
||||||
|
|
||||||
_xmlBadToOkChars = new Dictionary<string, string>();
|
|
||||||
_xmlBadToOkChars["<"] = "---lt---";
|
|
||||||
_xmlBadToOkChars["&"] = "---amp---";
|
|
||||||
_xmlBadToOkChars[">"] = "---gt---";
|
|
||||||
_xmlBadToOkChars["\""] = "---quot---";
|
|
||||||
_xmlBadToOkChars["\'"] = "---apos---";
|
|
||||||
_xmlBadToOkChars[","] = "---comma---";
|
|
||||||
_xmlBadToOkChars["."] = "---dot---";
|
|
||||||
|
|
||||||
_uniqueLayouts = new Dictionary<string, Dictionary<string, Point>>();
|
|
||||||
_flatLayout = new Dictionary<string, Point>();
|
|
||||||
_flatLayoutShortcuts = new Dictionary<string, string>();
|
|
||||||
_clientLayout = new Dictionary<string, ClientLocation>();
|
|
||||||
|
|
||||||
this._previews = new Dictionary<IntPtr, IThumbnail>();
|
|
||||||
|
|
||||||
// DispatcherTimer setup
|
|
||||||
_dispatcherTimer = new DispatcherTimer();
|
|
||||||
_dispatcherTimer.Tick += dispatcherTimer_Tick;
|
|
||||||
_dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
|
|
||||||
|
|
||||||
this._thumbnailFactory = new ThumbnailFactory();
|
|
||||||
}
|
|
||||||
|
|
||||||
public event Action<IList<IThumbnail>> ThumbnailsAdded;
|
|
||||||
public event Action<IList<IThumbnail>> ThumbnailsUpdated;
|
|
||||||
public event Action<IList<IThumbnail>> ThumbnailsRemoved;
|
|
||||||
public event Action<Size> ThumbnailSizeChanged;
|
|
||||||
|
|
||||||
public void Activate()
|
|
||||||
{
|
|
||||||
this.load_layout();
|
|
||||||
this._dispatcherTimer.Start();
|
|
||||||
this.RefreshThumbnails();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Deactivate()
|
|
||||||
{
|
|
||||||
this._dispatcherTimer.Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetThumbnailState(IntPtr thumbnailId, bool hideAlways)
|
|
||||||
{
|
|
||||||
IThumbnail thumbnail;
|
|
||||||
if (!this._previews.TryGetValue(thumbnailId, out thumbnail))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
thumbnail.IsPreviewEnabled = !hideAlways;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void spawn_and_kill_previews()
|
|
||||||
{
|
|
||||||
// TODO Extract this!
|
|
||||||
Process[] processes = Process.GetProcessesByName("ExeFile");
|
|
||||||
List<IntPtr> processHandles = new List<IntPtr>();
|
|
||||||
List<IThumbnail> addedList = new List<IThumbnail>();
|
|
||||||
List<IThumbnail> updatedList = new List<IThumbnail>();
|
|
||||||
List<IThumbnail> removedList = new List<IThumbnail>();
|
|
||||||
// pop new previews
|
|
||||||
|
|
||||||
foreach (Process process in processes)
|
|
||||||
{
|
|
||||||
processHandles.Add(process.MainWindowHandle);
|
|
||||||
|
|
||||||
Size sync_size = new Size();
|
|
||||||
sync_size.Width = (int)Properties.Settings.Default.sync_resize_x;
|
|
||||||
sync_size.Height = (int)Properties.Settings.Default.sync_resize_y;
|
|
||||||
|
|
||||||
if (!_previews.ContainsKey(process.MainWindowHandle) && process.MainWindowTitle != "")
|
|
||||||
{
|
|
||||||
_previews[process.MainWindowHandle] = this._thumbnailFactory.Create(this, process.MainWindowHandle, "...", sync_size);
|
|
||||||
|
|
||||||
// apply more thumbnail specific options
|
|
||||||
_previews[process.MainWindowHandle].SetTopMost(Properties.Settings.Default.always_on_top);
|
|
||||||
_previews[process.MainWindowHandle].SetWindowFrames(Properties.Settings.Default.show_thumb_frames);
|
|
||||||
|
|
||||||
// add a preview also
|
|
||||||
addedList.Add(_previews[process.MainWindowHandle]);
|
|
||||||
|
|
||||||
refresh_client_window_locations(process);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (_previews.ContainsKey(process.MainWindowHandle) && process.MainWindowTitle != _previews[process.MainWindowHandle].GetLabel()) //or update the preview titles
|
|
||||||
{
|
|
||||||
_previews[process.MainWindowHandle].SetLabel(process.MainWindowTitle);
|
|
||||||
string key = _previews[process.MainWindowHandle].GetLabel();
|
|
||||||
string value;
|
|
||||||
if (_flatLayoutShortcuts.TryGetValue(key, out value))
|
|
||||||
{
|
|
||||||
_previews[process.MainWindowHandle].RegisterShortcut(value);
|
|
||||||
}
|
|
||||||
updatedList.Add(_previews[process.MainWindowHandle]);
|
|
||||||
refresh_client_window_locations(process);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.MainWindowHandle == DwmApiNativeMethods.GetForegroundWindow())
|
|
||||||
{
|
|
||||||
_activeClientHandle = process.MainWindowHandle;
|
|
||||||
_activeClientTitle = process.MainWindowTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Check for null list
|
|
||||||
this.ThumbnailsAdded?.Invoke(addedList);
|
|
||||||
this.ThumbnailsUpdated?.Invoke(updatedList);
|
|
||||||
|
|
||||||
// clean up old previews
|
|
||||||
List<IntPtr> to_be_pruned = new List<IntPtr>();
|
|
||||||
foreach (IntPtr processHandle in _previews.Keys)
|
|
||||||
{
|
|
||||||
if (!(processHandles.Contains(processHandle)))
|
|
||||||
{
|
|
||||||
to_be_pruned.Add(processHandle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (IntPtr processHandle in to_be_pruned)
|
|
||||||
{
|
|
||||||
removedList.Add(_previews[processHandle]);
|
|
||||||
|
|
||||||
_previews[processHandle].CloseThumbnail();
|
|
||||||
_previews.Remove(processHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Check for null list
|
|
||||||
this.ThumbnailsRemoved?.Invoke(removedList);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void refresh_client_window_locations(Process process)
|
|
||||||
{
|
|
||||||
if (Properties.Settings.Default.track_client_windows && _clientLayout.ContainsKey(process.MainWindowTitle))
|
|
||||||
{
|
|
||||||
DwmApiNativeMethods.MoveWindow(process.MainWindowHandle, _clientLayout[process.MainWindowTitle].X,
|
|
||||||
_clientLayout[process.MainWindowTitle].Y, _clientLayout[process.MainWindowTitle].Width,
|
|
||||||
_clientLayout[process.MainWindowTitle].Height, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dispatcherTimer_Tick(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
spawn_and_kill_previews();
|
|
||||||
RefreshThumbnails();
|
|
||||||
if (_ignoringSizeSync.ElapsedMilliseconds > 500) { _ignoringSizeSync.Stop(); };
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyPreviewSwitch()
|
|
||||||
{
|
|
||||||
update_client_locations();
|
|
||||||
store_layout(); //todo: check if it actually changed ...
|
|
||||||
foreach (KeyValuePair<IntPtr, IThumbnail> entry in _previews)
|
|
||||||
{
|
|
||||||
entry.Value.SetTopMost(Properties.Settings.Default.always_on_top);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void SyncPreviewSize(Size size)
|
|
||||||
{
|
|
||||||
if (Properties.Settings.Default.sync_resize && _ignoringSizeSync.ElapsedMilliseconds > 500)
|
|
||||||
{
|
|
||||||
_ignoringSizeSync.Stop();
|
|
||||||
|
|
||||||
this.ThumbnailSizeChanged?.Invoke(size);
|
|
||||||
|
|
||||||
foreach (KeyValuePair<IntPtr, IThumbnail> entry in _previews)
|
|
||||||
{
|
|
||||||
if (entry.Value.IsPreviewHandle(DwmApiNativeMethods.GetForegroundWindow()))
|
|
||||||
{
|
|
||||||
entry.Value.SetSize(size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RefreshThumbnails()
|
|
||||||
{
|
|
||||||
IntPtr active_window = DwmApiNativeMethods.GetForegroundWindow();
|
|
||||||
|
|
||||||
// hide, show, resize and move
|
|
||||||
foreach (KeyValuePair<IntPtr, IThumbnail> entry in _previews)
|
|
||||||
{
|
|
||||||
if (!window_is_preview_or_client(active_window) && Properties.Settings.Default.hide_all)
|
|
||||||
{
|
|
||||||
entry.Value.HideThumbnail();
|
|
||||||
}
|
|
||||||
else if (entry.Key == _activeClientHandle && Properties.Settings.Default.hide_active)
|
|
||||||
{
|
|
||||||
entry.Value.HideThumbnail();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entry.Value.ShowThumbnail();
|
|
||||||
if (Properties.Settings.Default.unique_layout)
|
|
||||||
{
|
|
||||||
handle_unique_layout(entry.Value, _activeClientTitle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
handle_flat_layout(entry.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entry.Value.IsZoomEnabled = Properties.Settings.Default.zoom_on_hover;
|
|
||||||
entry.Value.IsOverlayEnabled = Properties.Settings.Default.show_overlay;
|
|
||||||
entry.Value.SetOpacity(Properties.Settings.Default.opacity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetupThumbnailFrames()
|
|
||||||
{
|
|
||||||
if (Properties.Settings.Default.show_thumb_frames)
|
|
||||||
{
|
|
||||||
_ignoringSizeSync.Stop();
|
|
||||||
_ignoringSizeSync.Reset();
|
|
||||||
_ignoringSizeSync.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var thumbnail in _previews)
|
|
||||||
{
|
|
||||||
thumbnail.Value.SetWindowFrames(Properties.Settings.Default.show_thumb_frames);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdatePreviewPosition(string title, Point position)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (Properties.Settings.Default.unique_layout)
|
|
||||||
{
|
|
||||||
Dictionary<string, Point> layout;
|
|
||||||
if (_uniqueLayouts.TryGetValue(_activeClientTitle, out layout))
|
|
||||||
{
|
|
||||||
layout[title] = position;
|
|
||||||
}
|
|
||||||
else if (_activeClientTitle == "")
|
|
||||||
{
|
|
||||||
_uniqueLayouts[_activeClientTitle] = new Dictionary<string, Point>();
|
|
||||||
_uniqueLayouts[_activeClientTitle][title] = position;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_flatLayout[title] = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private string remove_nonconform_xml_characters(string entry)
|
|
||||||
{
|
|
||||||
foreach (var kv in _xmlBadToOkChars)
|
|
||||||
{
|
|
||||||
entry = entry.Replace(kv.Key, kv.Value);
|
|
||||||
}
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string restore_nonconform_xml_characters(string entry)
|
|
||||||
{
|
|
||||||
foreach (var kv in _xmlBadToOkChars)
|
|
||||||
{
|
|
||||||
entry = entry.Replace(kv.Value, kv.Key);
|
|
||||||
}
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
private XElement MakeXElement(string input)
|
|
||||||
{
|
|
||||||
string clean = remove_nonconform_xml_characters(input).Replace(" ", "_");
|
|
||||||
return new XElement(clean);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string ParseXElement(XElement input)
|
|
||||||
{
|
|
||||||
return restore_nonconform_xml_characters(input.Name.ToString()).Replace("_", " ");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void load_layout()
|
|
||||||
{
|
|
||||||
if (File.Exists("layout.xml"))
|
|
||||||
{
|
|
||||||
XElement rootElement = XElement.Load("layout.xml");
|
|
||||||
foreach (var el in rootElement.Elements())
|
|
||||||
{
|
|
||||||
Dictionary<string, Point> inner = new Dictionary<string, Point>();
|
|
||||||
foreach (var inner_el in el.Elements())
|
|
||||||
{
|
|
||||||
inner[ParseXElement(inner_el)] = new Point(Convert.ToInt32(inner_el.Element("x")?.Value), Convert.ToInt32(inner_el.Element("y")?.Value));
|
|
||||||
}
|
|
||||||
_uniqueLayouts[ParseXElement(el)] = inner;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (File.Exists("flat_layout.xml"))
|
|
||||||
{
|
|
||||||
XElement rootElement = XElement.Load("flat_layout.xml");
|
|
||||||
foreach (var el in rootElement.Elements())
|
|
||||||
{
|
|
||||||
_flatLayout[ParseXElement(el)] = new Point(Convert.ToInt32(el.Element("x").Value), Convert.ToInt32(el.Element("y").Value));
|
|
||||||
_flatLayoutShortcuts[ParseXElement(el)] = "";
|
|
||||||
|
|
||||||
if (el.Element("shortcut") != null)
|
|
||||||
{
|
|
||||||
_flatLayoutShortcuts[ParseXElement(el)] = el.Element("shortcut").Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (File.Exists("client_layout.xml"))
|
|
||||||
{
|
|
||||||
XElement rootElement = XElement.Load("client_layout.xml");
|
|
||||||
foreach (var el in rootElement.Elements())
|
|
||||||
{
|
|
||||||
ClientLocation clientLocation = new ClientLocation();
|
|
||||||
clientLocation.X = Convert.ToInt32(el.Element("x").Value);
|
|
||||||
clientLocation.Y = Convert.ToInt32(el.Element("y").Value);
|
|
||||||
clientLocation.Width = Convert.ToInt32(el.Element("width").Value);
|
|
||||||
clientLocation.Height = Convert.ToInt32(el.Element("height").Value);
|
|
||||||
|
|
||||||
_clientLayout[ParseXElement(el)] = clientLocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void store_layout()
|
|
||||||
{
|
|
||||||
XElement el = new XElement("layouts");
|
|
||||||
foreach (var client in _uniqueLayouts.Keys)
|
|
||||||
{
|
|
||||||
if (client == "")
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
XElement layout = MakeXElement(client);
|
|
||||||
foreach (var thumbnail_ in _uniqueLayouts[client])
|
|
||||||
{
|
|
||||||
string thumbnail = thumbnail_.Key;
|
|
||||||
if (thumbnail == "" || thumbnail == "...")
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
XElement position = MakeXElement(thumbnail);
|
|
||||||
position.Add(new XElement("x", thumbnail_.Value.X));
|
|
||||||
position.Add(new XElement("y", thumbnail_.Value.Y));
|
|
||||||
layout.Add(position);
|
|
||||||
}
|
|
||||||
el.Add(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
el.Save("layout.xml");
|
|
||||||
|
|
||||||
XElement el2 = new XElement("flat_layout");
|
|
||||||
foreach (var clientKV in _flatLayout)
|
|
||||||
{
|
|
||||||
if (clientKV.Key == "" || clientKV.Key == "...")
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
XElement layout = MakeXElement(clientKV.Key);
|
|
||||||
layout.Add(new XElement("x", clientKV.Value.X));
|
|
||||||
layout.Add(new XElement("y", clientKV.Value.Y));
|
|
||||||
|
|
||||||
string shortcut;
|
|
||||||
if (_flatLayoutShortcuts.TryGetValue(clientKV.Key, out shortcut))
|
|
||||||
{
|
|
||||||
layout.Add(new XElement("shortcut", shortcut));
|
|
||||||
}
|
|
||||||
el2.Add(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
el2.Save("flat_layout.xml");
|
|
||||||
|
|
||||||
XElement el3 = new XElement("client_layout");
|
|
||||||
foreach (var clientKV in _clientLayout)
|
|
||||||
{
|
|
||||||
if (clientKV.Key == "" || clientKV.Key == "...")
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
XElement layout = MakeXElement(clientKV.Key);
|
|
||||||
layout.Add(new XElement("x", clientKV.Value.X));
|
|
||||||
layout.Add(new XElement("y", clientKV.Value.Y));
|
|
||||||
layout.Add(new XElement("width", clientKV.Value.Width));
|
|
||||||
layout.Add(new XElement("height", clientKV.Value.Height));
|
|
||||||
el3.Add(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
el3.Save("client_layout.xml");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handle_unique_layout(IThumbnail thumbnailWindow, string last_known_active_window)
|
|
||||||
{
|
|
||||||
Dictionary<string, Point> layout;
|
|
||||||
if (_uniqueLayouts.TryGetValue(last_known_active_window, out layout))
|
|
||||||
{
|
|
||||||
Point new_loc;
|
|
||||||
if (Properties.Settings.Default.unique_layout && layout.TryGetValue(thumbnailWindow.GetLabel(), out new_loc))
|
|
||||||
{
|
|
||||||
thumbnailWindow.SetLocation(new_loc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// create inner dict
|
|
||||||
layout[thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (last_known_active_window != "")
|
|
||||||
{
|
|
||||||
// create outer dict
|
|
||||||
_uniqueLayouts[last_known_active_window] = new Dictionary<string, Point>();
|
|
||||||
_uniqueLayouts[last_known_active_window][thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void update_client_locations()
|
|
||||||
{
|
|
||||||
Process[] processes = Process.GetProcessesByName("ExeFile");
|
|
||||||
List<IntPtr> processHandles = new List<IntPtr>();
|
|
||||||
|
|
||||||
foreach (Process process in processes)
|
|
||||||
{
|
|
||||||
RECT rect = new RECT();
|
|
||||||
DwmApiNativeMethods.GetWindowRect(process.MainWindowHandle, out rect);
|
|
||||||
|
|
||||||
int left = Math.Abs(rect.Left);
|
|
||||||
int right = Math.Abs(rect.Right);
|
|
||||||
int client_width = Math.Abs(left - right);
|
|
||||||
|
|
||||||
int top = Math.Abs(rect.Top);
|
|
||||||
int bottom = Math.Abs(rect.Bottom);
|
|
||||||
int client_height = Math.Abs(top - bottom);
|
|
||||||
|
|
||||||
ClientLocation clientLocation = new ClientLocation();
|
|
||||||
clientLocation.X = rect.Left;
|
|
||||||
clientLocation.Y = rect.Top;
|
|
||||||
clientLocation.Width = client_width;
|
|
||||||
clientLocation.Height = client_height;
|
|
||||||
|
|
||||||
|
|
||||||
_clientLayout[process.MainWindowTitle] = clientLocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handle_flat_layout(IThumbnail thumbnailWindow)
|
|
||||||
{
|
|
||||||
Point layout;
|
|
||||||
if (_flatLayout.TryGetValue(thumbnailWindow.GetLabel(), out layout))
|
|
||||||
{
|
|
||||||
thumbnailWindow.SetLocation(layout);
|
|
||||||
}
|
|
||||||
else if (thumbnailWindow.GetLabel() != "")
|
|
||||||
{
|
|
||||||
_flatLayout[thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool window_is_preview_or_client(IntPtr window)
|
|
||||||
{
|
|
||||||
bool active_window_is_right_type = false;
|
|
||||||
foreach (KeyValuePair<IntPtr, IThumbnail> entry in _previews)
|
|
||||||
{
|
|
||||||
if (entry.Key == window || entry.Value.IsPreviewHandle(window))
|
|
||||||
{
|
|
||||||
active_window_is_right_type = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return active_window_is_right_type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,444 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
using EveOPreview.Configuration;
|
|
||||||
using EveOPreview.UI;
|
|
||||||
|
|
||||||
namespace EveOPreview.Thumbnails
|
|
||||||
{
|
|
||||||
public partial class ThumbnailWindow : Form, IThumbnail
|
|
||||||
{
|
|
||||||
#region Private fields
|
|
||||||
private readonly bool _isInitializing;
|
|
||||||
private readonly IntPtr _sourceWindow;
|
|
||||||
private readonly IThumbnailManager _manager;
|
|
||||||
private readonly ThumbnailOverlay _overlay;
|
|
||||||
private Hotkey _hotkey; // This field stores the hotkey reference
|
|
||||||
|
|
||||||
private Size _baseSize;
|
|
||||||
private Point _basePosition;
|
|
||||||
|
|
||||||
private bool _isThumbnailSetUp;
|
|
||||||
private DWM_THUMBNAIL_PROPERTIES _Thumbnail;
|
|
||||||
private IntPtr _ThumbnailHandle;
|
|
||||||
|
|
||||||
private bool _ignoreMouseOverEvent;
|
|
||||||
private bool _isHoverEffectActive;
|
|
||||||
private bool _isZoomActive;
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
// This constructor should never be used directly
|
|
||||||
public ThumbnailWindow(IThumbnailManager manager, IntPtr sourceWindow, string title, Size size)
|
|
||||||
{
|
|
||||||
this._isInitializing = true;
|
|
||||||
|
|
||||||
this.IsPreviewEnabled = true;
|
|
||||||
this.IsOverlayEnabled = true;
|
|
||||||
|
|
||||||
this._sourceWindow = sourceWindow;
|
|
||||||
this._manager = manager;
|
|
||||||
|
|
||||||
this._isThumbnailSetUp = false;
|
|
||||||
this._ignoreMouseOverEvent = false;
|
|
||||||
this._isHoverEffectActive = false;
|
|
||||||
this._isZoomActive = false;
|
|
||||||
|
|
||||||
InitializeComponent();
|
|
||||||
|
|
||||||
this.Text = title;
|
|
||||||
|
|
||||||
this._overlay = new ThumbnailOverlay(this.Preview_Click);
|
|
||||||
|
|
||||||
this._isInitializing = false;
|
|
||||||
|
|
||||||
this.SetSize(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IntPtr Id
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this._sourceWindow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsZoomEnabled { get; set; }
|
|
||||||
|
|
||||||
public bool IsPreviewEnabled { get; set; }
|
|
||||||
|
|
||||||
public bool IsOverlayEnabled { get; set; }
|
|
||||||
|
|
||||||
public bool IsPreviewHandle(IntPtr handle)
|
|
||||||
{
|
|
||||||
return (this.Handle == handle) || (this._overlay.Handle == handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ShowThumbnail()
|
|
||||||
{
|
|
||||||
if (this.IsPreviewEnabled)
|
|
||||||
{
|
|
||||||
this.Show();
|
|
||||||
if (this.IsOverlayEnabled)
|
|
||||||
{
|
|
||||||
this._overlay.Show();
|
|
||||||
this.MakeOverlayTopMost();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this._overlay.Hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.HideThumbnail();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void HideThumbnail()
|
|
||||||
{
|
|
||||||
this.Hide();
|
|
||||||
this._overlay.Hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CloseThumbnail()
|
|
||||||
{
|
|
||||||
this._overlay.Close();
|
|
||||||
this.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetLabel(string label)
|
|
||||||
{
|
|
||||||
this.Text = label;
|
|
||||||
this._overlay.SetOverlayLabel(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetLabel()
|
|
||||||
{
|
|
||||||
return this.Text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetSize(Size size)
|
|
||||||
{
|
|
||||||
this.Size = size;
|
|
||||||
this._baseSize = this.Size;
|
|
||||||
this._basePosition = this.Location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetLocation(Point location)
|
|
||||||
{
|
|
||||||
if (!(this._isInitializing || this._ignoreMouseOverEvent))
|
|
||||||
{
|
|
||||||
this.Location = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.RefreshPreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Point GetLocation()
|
|
||||||
{
|
|
||||||
return this.Location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetOpacity(double opacity)
|
|
||||||
{
|
|
||||||
if (this._isHoverEffectActive)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Opacity = opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterShortcut(string shortcut)
|
|
||||||
{
|
|
||||||
if (String.IsNullOrEmpty(shortcut))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
KeysConverter converter = new KeysConverter();
|
|
||||||
object keysObject = converter.ConvertFrom(shortcut);
|
|
||||||
if (keysObject == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys key = (Keys)keysObject;
|
|
||||||
|
|
||||||
Hotkey hotkey = new Hotkey();
|
|
||||||
|
|
||||||
if ((key & Keys.Shift) == Keys.Shift)
|
|
||||||
{
|
|
||||||
hotkey.Shift = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((key & Keys.Alt) == Keys.Alt)
|
|
||||||
{
|
|
||||||
hotkey.Alt = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((key & Keys.Control) == Keys.Control)
|
|
||||||
{
|
|
||||||
hotkey.Control = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
key = key & ~Keys.Shift & ~Keys.Alt & ~Keys.Control;
|
|
||||||
hotkey.KeyCode = key;
|
|
||||||
hotkey.Pressed += Hotkey_Pressed;
|
|
||||||
hotkey.Register(this);
|
|
||||||
|
|
||||||
this._hotkey = hotkey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetTopMost(bool topmost)
|
|
||||||
{
|
|
||||||
if (!this.IsPreviewEnabled)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.TopMost = topmost;
|
|
||||||
this.MakeOverlayTopMost();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetWindowFrames(bool enable)
|
|
||||||
{
|
|
||||||
this.FormBorderStyle = enable ? FormBorderStyle.SizableToolWindow : FormBorderStyle.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override CreateParams CreateParams
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var Params = base.CreateParams;
|
|
||||||
Params.ExStyle |= (int)DwmApiNativeMethods.WS_EX_TOOLWINDOW;
|
|
||||||
return Params;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Preview_MouseHover(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (!this._ignoreMouseOverEvent)
|
|
||||||
{
|
|
||||||
this._ignoreMouseOverEvent = true;
|
|
||||||
if (this.IsZoomEnabled)
|
|
||||||
{
|
|
||||||
this.ZoomIn();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.SetTopMost(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Opacity = 1.0f;
|
|
||||||
this._isHoverEffectActive = true;
|
|
||||||
|
|
||||||
this.RefreshPreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Preview_MouseLeave(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (this._ignoreMouseOverEvent)
|
|
||||||
{
|
|
||||||
if (this.IsZoomEnabled)
|
|
||||||
{
|
|
||||||
this.ZoomOut();
|
|
||||||
}
|
|
||||||
|
|
||||||
this._ignoreMouseOverEvent = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._isHoverEffectActive = false;
|
|
||||||
this.Opacity = Properties.Settings.Default.opacity; // TODO Use local object
|
|
||||||
|
|
||||||
this.RefreshPreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Preview_Click(object sender, MouseEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.Button == MouseButtons.Left)
|
|
||||||
{
|
|
||||||
this.ActivateClient();
|
|
||||||
this._manager.NotifyPreviewSwitch();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.Button == MouseButtons.Right)
|
|
||||||
{
|
|
||||||
// do smth cool?
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.Button == MouseButtons.Middle)
|
|
||||||
{
|
|
||||||
// do smth cool?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Hotkey_Pressed(Object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
this.ActivateClient();
|
|
||||||
this._manager.NotifyPreviewSwitch();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnResize(EventArgs e)
|
|
||||||
{
|
|
||||||
this.RefreshPreview();
|
|
||||||
|
|
||||||
base.OnResize(e);
|
|
||||||
|
|
||||||
if (!(this._isInitializing || this._ignoreMouseOverEvent))
|
|
||||||
{
|
|
||||||
this._manager.SyncPreviewSize(this.Size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnMove(EventArgs e)
|
|
||||||
{
|
|
||||||
base.OnMove(e);
|
|
||||||
|
|
||||||
if (!(this._isInitializing || this._ignoreMouseOverEvent))
|
|
||||||
{
|
|
||||||
this._manager.UpdatePreviewPosition(this.Text, this.Location);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.RefreshPreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MakeOverlayTopMost()
|
|
||||||
{
|
|
||||||
this._overlay.TopMost = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RefreshPreview()
|
|
||||||
{
|
|
||||||
if (this._isInitializing)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DwmApiNativeMethods.DwmIsCompositionEnabled())
|
|
||||||
{
|
|
||||||
if (this._isThumbnailSetUp == false)
|
|
||||||
{
|
|
||||||
this.SetUpThumbnail();
|
|
||||||
}
|
|
||||||
|
|
||||||
this._Thumbnail.rcDestination = new RECT(0, 0, this.ClientRectangle.Right, this.ClientRectangle.Bottom);
|
|
||||||
DwmApiNativeMethods.DwmUpdateThumbnailProperties(this._ThumbnailHandle, this._Thumbnail);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this._isThumbnailSetUp = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Size overlaySize = this.RenderAreaPictureBox.Size;
|
|
||||||
overlaySize.Width -= 2 * 5;
|
|
||||||
overlaySize.Height -= 2 * 5;
|
|
||||||
|
|
||||||
Point overlayLocation = this.Location;
|
|
||||||
overlayLocation.X += 5 + (this.Size.Width - this.RenderAreaPictureBox.Size.Width) / 2;
|
|
||||||
overlayLocation.Y += 5 + (this.Size.Height - this.RenderAreaPictureBox.Size.Height) - (this.Size.Width - this.RenderAreaPictureBox.Size.Width) / 2;
|
|
||||||
|
|
||||||
this._overlay.Size = overlaySize;
|
|
||||||
this._overlay.Location = overlayLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetUpThumbnail()
|
|
||||||
{
|
|
||||||
if (this._isThumbnailSetUp || !DwmApiNativeMethods.DwmIsCompositionEnabled())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._ThumbnailHandle = DwmApiNativeMethods.DwmRegisterThumbnail(this.Handle, this._sourceWindow);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ZoomIn()
|
|
||||||
{
|
|
||||||
if (this._isZoomActive)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._isZoomActive = true;
|
|
||||||
|
|
||||||
// TODO Use global settings object
|
|
||||||
float zoomFactor = Properties.Settings.Default.zoom_amount;
|
|
||||||
|
|
||||||
this._baseSize = this.Size;
|
|
||||||
this._basePosition = this.Location;
|
|
||||||
|
|
||||||
this.Size = new Size((int)(zoomFactor * this.Size.Width), (int)(zoomFactor * this.Size.Height));
|
|
||||||
|
|
||||||
// TODO Use global settings object
|
|
||||||
switch ((ZoomAnchor)Properties.Settings.Default.zoom_anchor)
|
|
||||||
{
|
|
||||||
case ZoomAnchor.NW:
|
|
||||||
break;
|
|
||||||
case ZoomAnchor.N:
|
|
||||||
this.Location = new Point(this.Location.X - this.Size.Width / 2 + this._baseSize.Width / 2, this.Location.Y);
|
|
||||||
break;
|
|
||||||
case ZoomAnchor.NE:
|
|
||||||
this.Location = new Point(this.Location.X - this.Size.Width + this._baseSize.Width, this.Location.Y);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZoomAnchor.W:
|
|
||||||
this.Location = new Point(this.Location.X, this.Location.Y - this.Size.Height / 2 + this._baseSize.Height / 2);
|
|
||||||
break;
|
|
||||||
case ZoomAnchor.C:
|
|
||||||
this.Location = new Point(this.Location.X - this.Size.Width / 2 + this._baseSize.Width / 2, this.Location.Y - this.Size.Height / 2 + this._baseSize.Height / 2);
|
|
||||||
break;
|
|
||||||
case ZoomAnchor.E:
|
|
||||||
this.Location = new Point(this.Location.X - this.Size.Width + this._baseSize.Width, this.Location.Y - this.Size.Height / 2 + this._baseSize.Height / 2);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZoomAnchor.SW:
|
|
||||||
this.Location = new Point(this.Location.X, this.Location.Y - this.Size.Height + this._baseSize.Height);
|
|
||||||
break;
|
|
||||||
case ZoomAnchor.S:
|
|
||||||
this.Location = new Point(this.Location.X - this.Size.Width / 2 + this._baseSize.Width / 2, this.Location.Y - this.Size.Height + this._baseSize.Height);
|
|
||||||
break;
|
|
||||||
case ZoomAnchor.SE:
|
|
||||||
this.Location = new Point(this.Location.X - this.Size.Width + this._baseSize.Width, this.Location.Y - this.Size.Height + this._baseSize.Height);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ZoomOut()
|
|
||||||
{
|
|
||||||
if (!this._isZoomActive)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Size = this._baseSize;
|
|
||||||
this.Location = this._basePosition;
|
|
||||||
|
|
||||||
this._isZoomActive = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ActivateClient()
|
|
||||||
{
|
|
||||||
DwmApiNativeMethods.SetForegroundWindow(this._sourceWindow);
|
|
||||||
|
|
||||||
int style = DwmApiNativeMethods.GetWindowLong(this._sourceWindow, DwmApiNativeMethods.GWL_STYLE);
|
|
||||||
if ((style & DwmApiNativeMethods.WS_MAXIMIZE) == DwmApiNativeMethods.WS_MAXIMIZE)
|
|
||||||
{
|
|
||||||
// Client is already maximized, no action is required
|
|
||||||
}
|
|
||||||
else if ((style & DwmApiNativeMethods.WS_MINIMIZE) == DwmApiNativeMethods.WS_MINIMIZE)
|
|
||||||
{
|
|
||||||
DwmApiNativeMethods.ShowWindowAsync(this._sourceWindow, DwmApiNativeMethods.SW_SHOWNORMAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,34 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace EveOPreview.Thumbnails
|
|
||||||
{
|
|
||||||
public interface IThumbnail
|
|
||||||
{
|
|
||||||
IntPtr Id { get; }
|
|
||||||
|
|
||||||
bool IsZoomEnabled { get; set; }
|
|
||||||
bool IsPreviewEnabled { get; set; }
|
|
||||||
bool IsOverlayEnabled { get; set; }
|
|
||||||
|
|
||||||
bool IsPreviewHandle(IntPtr handle);
|
|
||||||
|
|
||||||
void ShowThumbnail();
|
|
||||||
void HideThumbnail();
|
|
||||||
void CloseThumbnail();
|
|
||||||
|
|
||||||
void RegisterShortcut(string shortcut);
|
|
||||||
|
|
||||||
// TODO Turn this into a property
|
|
||||||
void SetLabel(string label);
|
|
||||||
string GetLabel();
|
|
||||||
|
|
||||||
void SetLocation(Point location);
|
|
||||||
Point GetLocation();
|
|
||||||
|
|
||||||
void SetOpacity(double opacity);
|
|
||||||
void SetTopMost(bool topmost);
|
|
||||||
void SetWindowFrames(bool enable);
|
|
||||||
void SetSize(Size size);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace EveOPreview.Thumbnails
|
|
||||||
{
|
|
||||||
public interface IThumbnailFactory
|
|
||||||
{
|
|
||||||
IThumbnail Create(IThumbnailManager manager, IntPtr sourceWindow, string title, Size size);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,23 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace EveOPreview.Thumbnails
|
|
||||||
{
|
|
||||||
public interface IThumbnailManager
|
|
||||||
{
|
|
||||||
void Activate();
|
|
||||||
|
|
||||||
void NotifyPreviewSwitch();
|
|
||||||
void SetThumbnailState(IntPtr thumbnailId, bool hideAlways);
|
|
||||||
void SyncPreviewSize(Size size);
|
|
||||||
void UpdatePreviewPosition(string title, Point position);
|
|
||||||
void RefreshThumbnails();
|
|
||||||
void SetupThumbnailFrames();
|
|
||||||
|
|
||||||
event Action<IList<IThumbnail>> ThumbnailsAdded;
|
|
||||||
event Action<IList<IThumbnail>> ThumbnailsUpdated;
|
|
||||||
event Action<IList<IThumbnail>> ThumbnailsRemoved;
|
|
||||||
event Action<Size> ThumbnailSizeChanged;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -11,12 +11,13 @@ namespace EveOPreview.UI
|
|||||||
this._controller = controller;
|
this._controller = controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IThumbnailDescriptionView Create(IntPtr id, string title)
|
public IThumbnailDescriptionView Create(IntPtr id, string title, bool isDisabled)
|
||||||
{
|
{
|
||||||
IThumbnailDescriptionView view = this._controller.Create<IThumbnailDescriptionView>();
|
IThumbnailDescriptionView view = this._controller.Create<IThumbnailDescriptionView>();
|
||||||
|
|
||||||
view.Id = id;
|
view.Id = id;
|
||||||
view.Title = title;
|
view.Title = title;
|
||||||
|
view.IsDisabled = isDisabled;
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
26
Eve-O-Preview/UI/Factory/ThumbnailViewFactory.cs
Normal file
26
Eve-O-Preview/UI/Factory/ThumbnailViewFactory.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace EveOPreview.UI
|
||||||
|
{
|
||||||
|
public class ThumbnailViewFactory : IThumbnailViewFactory
|
||||||
|
{
|
||||||
|
private readonly IApplicationController _controller;
|
||||||
|
|
||||||
|
public ThumbnailViewFactory(IApplicationController controller)
|
||||||
|
{
|
||||||
|
this._controller = controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IThumbnailView Create(IntPtr id, string title, Size size)
|
||||||
|
{
|
||||||
|
IThumbnailView view = this._controller.Create<IThumbnailView>();
|
||||||
|
|
||||||
|
view.Id = id;
|
||||||
|
view.Title = title;
|
||||||
|
view.Size = size;
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -2,9 +2,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Globalization;
|
|
||||||
using EveOPreview.Configuration;
|
|
||||||
using EveOPreview.Thumbnails;
|
|
||||||
|
|
||||||
namespace EveOPreview.UI
|
namespace EveOPreview.UI
|
||||||
{
|
{
|
||||||
@@ -312,7 +309,7 @@ namespace EveOPreview.UI
|
|||||||
public event Action<ViewCloseRequest> FormCloseRequested;
|
public event Action<ViewCloseRequest> FormCloseRequested;
|
||||||
public event Action ApplicationSettingsChanged;
|
public event Action ApplicationSettingsChanged;
|
||||||
public event Action ThumbnailsSizeChanged;
|
public event Action ThumbnailsSizeChanged;
|
||||||
public event Action<IntPtr, Boolean> ThumbnailStateChanged;
|
public event Action<IntPtr> ThumbnailStateChanged;
|
||||||
public event Action ForumUrlLinkActivated;
|
public event Action ForumUrlLinkActivated;
|
||||||
|
|
||||||
#region UI events
|
#region UI events
|
||||||
@@ -343,8 +340,9 @@ namespace EveOPreview.UI
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
selectedItem.IsDisabled = (e.NewValue == CheckState.Checked);
|
||||||
|
|
||||||
this.ThumbnailStateChanged?.Invoke(selectedItem.Id, e.NewValue == CheckState.Checked);
|
this.ThumbnailStateChanged?.Invoke(selectedItem.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ForumLinkLabelClicked_Handler(object sender, LinkLabelLinkClickedEventArgs e)
|
private void ForumLinkLabelClicked_Handler(object sender, LinkLabelLinkClickedEventArgs e)
|
||||||
|
@@ -8,6 +8,8 @@ namespace EveOPreview.UI
|
|||||||
|
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
|
|
||||||
|
public bool IsDisabled { get; set; }
|
||||||
|
|
||||||
public void Show()
|
public void Show()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -1,33 +1,33 @@
|
|||||||
namespace EveOPreview.Thumbnails
|
namespace EveOPreview.UI
|
||||||
{
|
{
|
||||||
partial class ThumbnailOverlay
|
partial class ThumbnailOverlay
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Required designer variable.
|
/// Required designer variable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private System.ComponentModel.IContainer components = null;
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clean up any resources being used.
|
/// Clean up any resources being used.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing && (components != null))
|
if (disposing && (components != null))
|
||||||
{
|
{
|
||||||
components.Dispose();
|
components.Dispose();
|
||||||
}
|
}
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Windows Form Designer generated code
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Required method for Designer support - do not modify
|
/// Required method for Designer support - do not modify
|
||||||
/// the contents of this method with the code editor.
|
/// the contents of this method with the code editor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
System.Windows.Forms.PictureBox OverlayAreaPictureBox;
|
System.Windows.Forms.PictureBox OverlayAreaPictureBox;
|
||||||
this.OverlayLabel = new System.Windows.Forms.Label();
|
this.OverlayLabel = new System.Windows.Forms.Label();
|
||||||
OverlayAreaPictureBox = new System.Windows.Forms.PictureBox();
|
OverlayAreaPictureBox = new System.Windows.Forms.PictureBox();
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
this.PerformLayout();
|
this.PerformLayout();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace EveOPreview.Thumbnails
|
namespace EveOPreview.UI
|
||||||
{
|
{
|
||||||
public partial class ThumbnailOverlay : Form
|
public partial class ThumbnailOverlay : Form
|
||||||
{
|
{
|
@@ -1,6 +1,6 @@
|
|||||||
namespace EveOPreview.Thumbnails
|
namespace EveOPreview.UI
|
||||||
{
|
{
|
||||||
partial class ThumbnailWindow
|
partial class ThumbnailView
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Required designer variable.
|
/// Required designer variable.
|
||||||
@@ -31,11 +31,11 @@ namespace EveOPreview.Thumbnails
|
|||||||
this.RenderAreaPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
|
this.RenderAreaPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
|
||||||
this.RenderAreaPictureBox.TabIndex = 0;
|
this.RenderAreaPictureBox.TabIndex = 0;
|
||||||
this.RenderAreaPictureBox.TabStop = false;
|
this.RenderAreaPictureBox.TabStop = false;
|
||||||
this.RenderAreaPictureBox.MouseLeave += new System.EventHandler(this.Preview_MouseLeave);
|
this.RenderAreaPictureBox.MouseLeave += new System.EventHandler(this.LostFocus_Handler);
|
||||||
this.RenderAreaPictureBox.MouseHover += new System.EventHandler(this.Preview_MouseHover);
|
this.RenderAreaPictureBox.MouseHover += new System.EventHandler(this.Focused_Handler);
|
||||||
this.RenderAreaPictureBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Preview_Click);
|
this.RenderAreaPictureBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ThumbnailActivated_Handler);
|
||||||
//
|
//
|
||||||
// Preview
|
// ThumbnailView
|
||||||
//
|
//
|
||||||
this.AccessibleRole = System.Windows.Forms.AccessibleRole.None;
|
this.AccessibleRole = System.Windows.Forms.AccessibleRole.None;
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
@@ -47,12 +47,14 @@ namespace EveOPreview.Thumbnails
|
|||||||
this.MaximizeBox = false;
|
this.MaximizeBox = false;
|
||||||
this.MinimizeBox = false;
|
this.MinimizeBox = false;
|
||||||
this.MinimumSize = new System.Drawing.Size(64, 64);
|
this.MinimumSize = new System.Drawing.Size(64, 64);
|
||||||
this.Name = "ThumbnailWindow";
|
this.Name = "ThumbnailView";
|
||||||
this.Opacity = 0.1D;
|
this.Opacity = 0.1D;
|
||||||
this.ShowIcon = false;
|
this.ShowIcon = false;
|
||||||
this.ShowInTaskbar = false;
|
this.ShowInTaskbar = false;
|
||||||
this.Text = "Preview";
|
this.Text = "Preview";
|
||||||
this.TopMost = true;
|
this.TopMost = true;
|
||||||
|
this.Move += new System.EventHandler(this.Move_Handler);
|
||||||
|
this.Resize += new System.EventHandler(this.Resize_Handler);
|
||||||
((System.ComponentModel.ISupportInitialize)(this.RenderAreaPictureBox)).EndInit();
|
((System.ComponentModel.ISupportInitialize)(this.RenderAreaPictureBox)).EndInit();
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
this.PerformLayout();
|
this.PerformLayout();
|
282
Eve-O-Preview/UI/Implementation/ThumbnailView.cs
Normal file
282
Eve-O-Preview/UI/Implementation/ThumbnailView.cs
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace EveOPreview.UI
|
||||||
|
{
|
||||||
|
public partial class ThumbnailView : Form, IThumbnailView
|
||||||
|
{
|
||||||
|
#region Private fields
|
||||||
|
|
||||||
|
//private readonly IThumbnailManager _manager;
|
||||||
|
private readonly ThumbnailOverlay _overlay;
|
||||||
|
|
||||||
|
//private Size _baseSize;
|
||||||
|
//private Point _basePosition;
|
||||||
|
|
||||||
|
// This is pure brainless View
|
||||||
|
// Just somewhat more complex than usual
|
||||||
|
private bool _isThumbnailSetUp;
|
||||||
|
private DWM_THUMBNAIL_PROPERTIES _Thumbnail;
|
||||||
|
private IntPtr _ThumbnailHandle;
|
||||||
|
private int _currentWidth;
|
||||||
|
private int _currentHeight;
|
||||||
|
private int _currentTop;
|
||||||
|
private int _currentLeft;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public ThumbnailView()
|
||||||
|
{
|
||||||
|
this.IsEnabled = true;
|
||||||
|
this.IsActive = false;
|
||||||
|
|
||||||
|
this.IsOverlayEnabled = false;
|
||||||
|
this._isThumbnailSetUp = false;
|
||||||
|
|
||||||
|
this._currentWidth = -1;
|
||||||
|
this._currentHeight = -1;
|
||||||
|
this._currentTop = -1;
|
||||||
|
this._currentLeft = -1;
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
this._overlay = new ThumbnailOverlay(this.ThumbnailActivated_Handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntPtr Id { get; set; }
|
||||||
|
|
||||||
|
public string Title
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.Text;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.Text = value;
|
||||||
|
this._overlay.SetOverlayLabel(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEnabled { get; set; }
|
||||||
|
|
||||||
|
public bool IsActive { get; set; }
|
||||||
|
|
||||||
|
public bool IsOverlayEnabled { get; set; }
|
||||||
|
|
||||||
|
public event Action<IntPtr> ThumbnailResized;
|
||||||
|
|
||||||
|
public event Action<IntPtr> ThumbnailMoved;
|
||||||
|
|
||||||
|
public event Action<IntPtr> ThumbnailFocused;
|
||||||
|
|
||||||
|
public event Action<IntPtr> ThumbnailLostFocus;
|
||||||
|
|
||||||
|
public event Action<IntPtr> ThumbnailActivated;
|
||||||
|
|
||||||
|
public new void Show()
|
||||||
|
{
|
||||||
|
base.Show();
|
||||||
|
|
||||||
|
if (this.IsOverlayEnabled)
|
||||||
|
{
|
||||||
|
this._overlay.Show();
|
||||||
|
this._overlay.TopMost = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._overlay.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Refresh();
|
||||||
|
|
||||||
|
this.IsActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public new void Hide()
|
||||||
|
{
|
||||||
|
this.IsActive = false;
|
||||||
|
|
||||||
|
this._overlay.Hide();
|
||||||
|
base.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
public new void Close()
|
||||||
|
{
|
||||||
|
this.IsActive = false;
|
||||||
|
|
||||||
|
this._overlay.Close();
|
||||||
|
base.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is used to determine if the provided Handle is related to client or its thumbnail
|
||||||
|
public bool IsKnownHandle(IntPtr handle)
|
||||||
|
{
|
||||||
|
return (this.Id == handle) || (this.Handle == handle) || (this._overlay.Handle == handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetOpacity(double opacity)
|
||||||
|
{
|
||||||
|
this.Opacity = opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetWindowFrames(bool enable)
|
||||||
|
{
|
||||||
|
this.FormBorderStyle = enable ? FormBorderStyle.SizableToolWindow : FormBorderStyle.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetTopMost(bool enableTopmost)
|
||||||
|
{
|
||||||
|
this.TopMost = enableTopmost;
|
||||||
|
this._overlay.TopMost = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public new void Refresh()
|
||||||
|
{
|
||||||
|
if (this._isThumbnailSetUp == false)
|
||||||
|
{
|
||||||
|
this.InitializeThumbnail();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sizeChanged = (this._currentWidth != this.ClientRectangle.Right) || (this._currentHeight != this.ClientRectangle.Bottom);
|
||||||
|
bool locationChanged = (this._currentLeft != this.Location.X) || (this._currentTop != this.Location.Y);
|
||||||
|
|
||||||
|
if (sizeChanged)
|
||||||
|
{
|
||||||
|
this._currentWidth = this.ClientRectangle.Right;
|
||||||
|
this._currentHeight = this.ClientRectangle.Bottom;
|
||||||
|
|
||||||
|
this._Thumbnail.rcDestination = new RECT(0, 0, this._currentWidth, this._currentHeight);
|
||||||
|
DwmApiNativeMethods.DwmUpdateThumbnailProperties(this._ThumbnailHandle, this._Thumbnail);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(this.IsOverlayEnabled && (sizeChanged || locationChanged)))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Size overlaySize = this.RenderAreaPictureBox.Size;
|
||||||
|
overlaySize.Width -= 2 * 5;
|
||||||
|
overlaySize.Height -= 2 * 5;
|
||||||
|
|
||||||
|
Point overlayLocation = this.Location;
|
||||||
|
|
||||||
|
this._currentLeft = overlayLocation.X;
|
||||||
|
this._currentTop = overlayLocation.Y;
|
||||||
|
|
||||||
|
overlayLocation.X += 5 + (this.Size.Width - this.RenderAreaPictureBox.Size.Width) / 2;
|
||||||
|
overlayLocation.Y += 5 + (this.Size.Height - this.RenderAreaPictureBox.Size.Height) - (this.Size.Width - this.RenderAreaPictureBox.Size.Width) / 2;
|
||||||
|
|
||||||
|
this._overlay.Size = overlaySize;
|
||||||
|
this._overlay.Location = overlayLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region GUI events
|
||||||
|
protected override CreateParams CreateParams
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var Params = base.CreateParams;
|
||||||
|
Params.ExStyle |= (int)DwmApiNativeMethods.WS_EX_TOOLWINDOW;
|
||||||
|
return Params;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Move_Handler(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.ThumbnailMoved?.Invoke(this.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Resize_Handler(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.ThumbnailResized?.Invoke(this.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Focused_Handler(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.ThumbnailFocused?.Invoke(this.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LostFocus_Handler(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.ThumbnailLostFocus?.Invoke(this.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThumbnailActivated_Handler(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Button == MouseButtons.Left)
|
||||||
|
{
|
||||||
|
this.ThumbnailActivated?.Invoke(this.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (e.Button == MouseButtons.Right)
|
||||||
|
//{
|
||||||
|
// // do smth cool?
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (e.Button == MouseButtons.Middle)
|
||||||
|
//{
|
||||||
|
// // do smth cool?
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void InitializeThumbnail()
|
||||||
|
{
|
||||||
|
this._ThumbnailHandle = DwmApiNativeMethods.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//private Hotkey _hotkey; // This field stores the hotkey reference
|
||||||
|
//public void RegisterShortcut(string shortcut)
|
||||||
|
//{
|
||||||
|
//if (String.IsNullOrEmpty(shortcut))
|
||||||
|
//{
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//KeysConverter converter = new KeysConverter();
|
||||||
|
//object keysObject = converter.ConvertFrom(shortcut);
|
||||||
|
//if (keysObject == null)
|
||||||
|
//{
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//Keys key = (Keys)keysObject;
|
||||||
|
|
||||||
|
//Hotkey hotkey = new Hotkey();
|
||||||
|
|
||||||
|
//if ((key & Keys.Shift) == Keys.Shift)
|
||||||
|
//{
|
||||||
|
// hotkey.Shift = true;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if ((key & Keys.Alt) == Keys.Alt)
|
||||||
|
//{
|
||||||
|
// hotkey.Alt = true;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if ((key & Keys.Control) == Keys.Control)
|
||||||
|
//{
|
||||||
|
// hotkey.Control = true;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//key = key & ~Keys.Shift & ~Keys.Alt & ~Keys.Control;
|
||||||
|
//hotkey.KeyCode = key;
|
||||||
|
//hotkey.Pressed += Hotkey_Pressed;
|
||||||
|
//hotkey.Register(this);
|
||||||
|
|
||||||
|
//this._hotkey = hotkey;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
@@ -46,7 +46,7 @@ namespace EveOPreview.UI
|
|||||||
event Action<ViewCloseRequest> FormCloseRequested;
|
event Action<ViewCloseRequest> FormCloseRequested;
|
||||||
event Action ApplicationSettingsChanged;
|
event Action ApplicationSettingsChanged;
|
||||||
event Action ThumbnailsSizeChanged;
|
event Action ThumbnailsSizeChanged;
|
||||||
event Action<IntPtr, Boolean> ThumbnailStateChanged;
|
event Action<IntPtr> ThumbnailStateChanged;
|
||||||
event Action ForumUrlLinkActivated;
|
event Action ForumUrlLinkActivated;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -6,5 +6,6 @@ namespace EveOPreview.UI
|
|||||||
{
|
{
|
||||||
IntPtr Id { get; set; }
|
IntPtr Id { get; set; }
|
||||||
string Title { get; set; }
|
string Title { get; set; }
|
||||||
|
bool IsDisabled { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -4,6 +4,6 @@ namespace EveOPreview.UI
|
|||||||
{
|
{
|
||||||
public interface IThumbnailDescriptionViewFactory
|
public interface IThumbnailDescriptionViewFactory
|
||||||
{
|
{
|
||||||
IThumbnailDescriptionView Create(IntPtr id, string title);
|
IThumbnailDescriptionView Create(IntPtr id, string title, bool isDisabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
31
Eve-O-Preview/UI/Interface/IThumbnailView.cs
Normal file
31
Eve-O-Preview/UI/Interface/IThumbnailView.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace EveOPreview.UI
|
||||||
|
{
|
||||||
|
public interface IThumbnailView : IView
|
||||||
|
{
|
||||||
|
IntPtr Id { get; set; }
|
||||||
|
string Title { get; set; }
|
||||||
|
|
||||||
|
bool IsEnabled { get; set; }
|
||||||
|
bool IsActive { get; set; }
|
||||||
|
Point Location { get; set; }
|
||||||
|
Size Size { get; set; }
|
||||||
|
bool IsOverlayEnabled { get; set; }
|
||||||
|
|
||||||
|
bool IsKnownHandle(IntPtr handle);
|
||||||
|
|
||||||
|
void SetOpacity(double opacity);
|
||||||
|
void SetWindowFrames(bool enable);
|
||||||
|
void SetTopMost(bool enableTopmost);
|
||||||
|
|
||||||
|
void Refresh();
|
||||||
|
|
||||||
|
event Action<IntPtr> ThumbnailResized;
|
||||||
|
event Action<IntPtr> ThumbnailMoved;
|
||||||
|
event Action<IntPtr> ThumbnailFocused;
|
||||||
|
event Action<IntPtr> ThumbnailLostFocus;
|
||||||
|
event Action<IntPtr> ThumbnailActivated;
|
||||||
|
}
|
||||||
|
}
|
10
Eve-O-Preview/UI/Interface/IThumbnailViewFactory.cs
Normal file
10
Eve-O-Preview/UI/Interface/IThumbnailViewFactory.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace EveOPreview.UI
|
||||||
|
{
|
||||||
|
public interface IThumbnailViewFactory
|
||||||
|
{
|
||||||
|
IThumbnailView Create(IntPtr id, string title, Size size);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user