Make region selector shower instead of whole screen )

This commit is contained in:
2025-08-29 22:19:21 +02:00
parent 554ed6098a
commit 418ae9352d
97 changed files with 6329 additions and 6327 deletions

3
.clang-format Normal file
View File

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

View File

@@ -1,8 +1,5 @@
using System.Windows; using System.Windows;
namespace EveOMock namespace EveOMock {
{ public partial class App : Application {}
public partial class App : Application
{
}
} }

View File

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

View File

@@ -2,16 +2,14 @@
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
namespace EveOMock namespace EveOMock {
{ public partial class MainWindow : Window {
public partial class MainWindow : Window public MainWindow() {
{
public MainWindow()
{
InitializeComponent(); InitializeComponent();
Random random = new Random(); Random random = new Random();
this.Title += random.Next().ToString("X"); this.Title += random.Next().ToString("X");
this.grid.Background = new SolidColorBrush(Color.FromArgb(255, (byte)random.Next(0, 255), (byte)random.Next(0, 255), (byte)random.Next(0, 255))); this.grid.Background = new SolidColorBrush(
Color.FromArgb(255, (byte)random.Next(0, 255), (byte)random.Next(0, 255), (byte)random.Next(0, 255)));
} }
} }
} }

View File

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

View File

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

View File

@@ -10,17 +10,15 @@
namespace EveOMock.Properties { namespace EveOMock.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute(
"Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance =
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default { public static Settings Default {
get { get { return defaultInstance; }
return defaultInstance;
}
} }
} }
} }

View File

@@ -1,7 +1,5 @@
namespace PreviewToy namespace PreviewToy {
{ partial class AboutBox {
partial class AboutBox
{
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
/// </summary> /// </summary>
@@ -10,10 +8,8 @@
/// <summary> /// <summary>
/// Clean up any resources being used. /// Clean up any resources being used.
/// </summary> /// </summary>
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);
@@ -25,8 +21,7 @@
/// 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() {
{
this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
this.logoPictureBox = new System.Windows.Forms.PictureBox(); this.logoPictureBox = new System.Windows.Forms.PictureBox();
this.labelProductName = new System.Windows.Forms.Label(); this.labelProductName = new System.Windows.Forms.Label();
@@ -42,8 +37,10 @@
// tableLayoutPanel // tableLayoutPanel
// //
this.tableLayoutPanel.ColumnCount = 2; this.tableLayoutPanel.ColumnCount = 2;
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F)); this.tableLayoutPanel.ColumnStyles.Add(
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 67F)); new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F));
this.tableLayoutPanel.ColumnStyles.Add(
new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 67F));
this.tableLayoutPanel.Controls.Add(this.logoPictureBox, 0, 0); this.tableLayoutPanel.Controls.Add(this.logoPictureBox, 0, 0);
this.tableLayoutPanel.Controls.Add(this.labelProductName, 1, 0); this.tableLayoutPanel.Controls.Add(this.labelProductName, 1, 0);
this.tableLayoutPanel.Controls.Add(this.labelVersion, 1, 1); this.tableLayoutPanel.Controls.Add(this.labelVersion, 1, 1);
@@ -55,12 +52,18 @@
this.tableLayoutPanel.Location = new System.Drawing.Point(9, 9); this.tableLayoutPanel.Location = new System.Drawing.Point(9, 9);
this.tableLayoutPanel.Name = "tableLayoutPanel"; this.tableLayoutPanel.Name = "tableLayoutPanel";
this.tableLayoutPanel.RowCount = 6; this.tableLayoutPanel.RowCount = 6;
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); this.tableLayoutPanel.RowStyles.Add(
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); this.tableLayoutPanel.RowStyles.Add(
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); this.tableLayoutPanel.RowStyles.Add(
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.RowStyles.Add(
new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.RowStyles.Add(
new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel.RowStyles.Add(
new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.Size = new System.Drawing.Size(534, 490); this.tableLayoutPanel.Size = new System.Drawing.Size(534, 490);
this.tableLayoutPanel.TabIndex = 0; this.tableLayoutPanel.TabIndex = 0;
// //
@@ -112,7 +115,8 @@
this.labelCopyright.TabStop = true; this.labelCopyright.TabStop = true;
this.labelCopyright.Text = "Copyright"; this.labelCopyright.Text = "Copyright";
this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.labelCopyright.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.labelCopyright_LinkClicked); this.labelCopyright.LinkClicked +=
new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.labelCopyright_LinkClicked);
// //
// labelCompanyName // labelCompanyName
// //
@@ -126,11 +130,13 @@
this.labelCompanyName.TabStop = true; this.labelCompanyName.TabStop = true;
this.labelCompanyName.Text = "Company Name"; this.labelCompanyName.Text = "Company Name";
this.labelCompanyName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; this.labelCompanyName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.labelCompanyName.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.labelCompanyName_LinkClicked); this.labelCompanyName.LinkClicked +=
new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.labelCompanyName_LinkClicked);
// //
// okButton // okButton
// //
this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)(
(System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.okButton.Location = new System.Drawing.Point(456, 464); this.okButton.Location = new System.Drawing.Point(456, 464);
this.okButton.Name = "okButton"; this.okButton.Name = "okButton";
@@ -142,7 +148,9 @@
// //
this.richTextBoxDescription.BackColor = System.Drawing.SystemColors.Control; this.richTextBoxDescription.BackColor = System.Drawing.SystemColors.Control;
this.richTextBoxDescription.Dock = System.Windows.Forms.DockStyle.Fill; this.richTextBoxDescription.Dock = System.Windows.Forms.DockStyle.Fill;
this.richTextBoxDescription.Font = new System.Drawing.Font("Microsoft Sans Serif", 6F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.richTextBoxDescription.Font =
new System.Drawing.Font("Microsoft Sans Serif", 6F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.richTextBoxDescription.Location = new System.Drawing.Point(179, 199); this.richTextBoxDescription.Location = new System.Drawing.Point(179, 199);
this.richTextBoxDescription.Name = "richTextBoxDescription"; this.richTextBoxDescription.Name = "richTextBoxDescription";
this.richTextBoxDescription.ReadOnly = true; this.richTextBoxDescription.ReadOnly = true;
@@ -169,7 +177,6 @@
this.tableLayoutPanel.ResumeLayout(false); this.tableLayoutPanel.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit();
this.ResumeLayout(false); this.ResumeLayout(false);
} }
#endregion #endregion

View File

@@ -7,12 +7,9 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Windows.Forms; using System.Windows.Forms;
namespace PreviewToy namespace PreviewToy {
{ partial class AboutBox : Form {
partial class AboutBox : Form public AboutBox() {
{
public AboutBox()
{
InitializeComponent(); InitializeComponent();
this.Text = String.Format("About {0}", AssemblyTitle); this.Text = String.Format("About {0}", AssemblyTitle);
this.labelProductName.Text = AssemblyProduct; this.labelProductName.Text = AssemblyProduct;
@@ -41,16 +38,14 @@ namespace PreviewToy
} }
// StinkRay // StinkRay
private void labelCopyright_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) private void labelCopyright_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
{
string url = "https://forums.eveonline.com/default.aspx?g=posts&t=246157"; string url = "https://forums.eveonline.com/default.aspx?g=posts&t=246157";
ProcessStartInfo sInfo = new ProcessStartInfo(new Uri(url).AbsoluteUri); ProcessStartInfo sInfo = new ProcessStartInfo(new Uri(url).AbsoluteUri);
Process.Start(sInfo); Process.Start(sInfo);
} }
// New Thread // New Thread
private void labelCompanyName_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) private void labelCompanyName_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
{
string url = "https://forums.eveonline.com/default.aspx?g=posts&m=5264866"; string url = "https://forums.eveonline.com/default.aspx?g=posts&m=5264866";
ProcessStartInfo sInfo = new ProcessStartInfo(new Uri(url).AbsoluteUri); ProcessStartInfo sInfo = new ProcessStartInfo(new Uri(url).AbsoluteUri);
Process.Start(sInfo); Process.Start(sInfo);
@@ -58,16 +53,13 @@ namespace PreviewToy
#region Assembly Attribute Accessors #region Assembly Attribute Accessors
public string AssemblyTitle public string AssemblyTitle {
{ get {
get object[] attributes =
{ Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false); if (attributes.Length > 0) {
if (attributes.Length > 0)
{
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0]; AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
if (titleAttribute.Title != "") if (titleAttribute.Title != "") {
{
return titleAttribute.Title; return titleAttribute.Title;
} }
} }
@@ -75,60 +67,48 @@ namespace PreviewToy
} }
} }
public string AssemblyVersion public string AssemblyVersion {
{ get { return Assembly.GetExecutingAssembly().GetName().Version.ToString(); }
get
{
return Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
} }
public string AssemblyDescription public string AssemblyDescription {
{ get {
get object[] attributes =
{ Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false); if (attributes.Length == 0) {
if (attributes.Length == 0)
{
return ""; return "";
} }
return ((AssemblyDescriptionAttribute)attributes[0]).Description; return ((AssemblyDescriptionAttribute)attributes[0]).Description;
} }
} }
public string AssemblyProduct public string AssemblyProduct {
{ get {
get object[] attributes =
{ Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false); if (attributes.Length == 0) {
if (attributes.Length == 0)
{
return ""; return "";
} }
return ((AssemblyProductAttribute)attributes[0]).Product; return ((AssemblyProductAttribute)attributes[0]).Product;
} }
} }
public string AssemblyCopyright public string AssemblyCopyright {
{ get {
get object[] attributes =
{ Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); if (attributes.Length == 0) {
if (attributes.Length == 0)
{
return ""; return "";
} }
return ((AssemblyCopyrightAttribute)attributes[0]).Copyright; return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
} }
} }
public string AssemblyCompany public string AssemblyCompany {
{ get {
get object[] attributes =
{ Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false); if (attributes.Length == 0) {
if (attributes.Length == 0)
{
return ""; return "";
} }
return ((AssemblyCompanyAttribute)attributes[0]).Company; return ((AssemblyCompanyAttribute)attributes[0]).Company;

View File

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

View File

@@ -3,48 +3,40 @@ using System.IO;
using System.Threading; using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
namespace EveOPreview namespace EveOPreview {
{
// A really very primitive exception handler stuff here // A really very primitive exception handler stuff here
// No IoC, no fancy DI containers - just a plain exception stacktrace dump // No IoC, no fancy DI containers - just a plain exception stacktrace dump
// If this code is called then something was gone really bad // If this code is called then something was gone really bad
// so even the DI infrastructure might be dead already. // so even the DI infrastructure might be dead already.
// So this dumb and non elegant approach is used // So this dumb and non elegant approach is used
sealed class ExceptionHandler sealed class ExceptionHandler {
{
private const string EXCEPTION_DUMP_FILE_NAME = "EVE-O-Preview.log"; private const string EXCEPTION_DUMP_FILE_NAME = "EVE-O-Preview.log";
private const string EXCEPTION_MESSAGE = "EVE-O-Preview has encountered a problem and needs to close. Additional information has been saved in the crash log file."; private const string EXCEPTION_MESSAGE =
"EVE-O-Preview has encountered a problem and needs to close. Additional information has been saved in the crash log file.";
public void SetupExceptionHandlers() public void SetupExceptionHandlers() {
{ if (System.Diagnostics.Debugger.IsAttached) {
if (System.Diagnostics.Debugger.IsAttached)
{
return; return;
} }
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += delegate (Object sender, ThreadExceptionEventArgs e) Application.ThreadException += delegate(Object sender, ThreadExceptionEventArgs e) {
{
this.ExceptionEventHandler(e.Exception); this.ExceptionEventHandler(e.Exception);
}; };
AppDomain.CurrentDomain.UnhandledException += delegate (Object sender, UnhandledExceptionEventArgs e) AppDomain.CurrentDomain.UnhandledException += delegate(Object sender, UnhandledExceptionEventArgs e) {
{
this.ExceptionEventHandler(e.ExceptionObject as Exception); this.ExceptionEventHandler(e.ExceptionObject as Exception);
}; };
} }
private void ExceptionEventHandler(Exception exception) private void ExceptionEventHandler(Exception exception) {
{ try {
try
{
String exceptionMessage = exception.ToString(); String exceptionMessage = exception.ToString();
File.WriteAllText(ExceptionHandler.EXCEPTION_DUMP_FILE_NAME, exceptionMessage); File.WriteAllText(ExceptionHandler.EXCEPTION_DUMP_FILE_NAME, exceptionMessage);
MessageBox.Show(ExceptionHandler.EXCEPTION_MESSAGE, @"EVE-O-Preview", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(ExceptionHandler.EXCEPTION_MESSAGE, @"EVE-O-Preview", MessageBoxButtons.OK,
} MessageBoxIcon.Error);
catch } catch {
{
// We are in unstable state now so even this operation might fail // We are in unstable state now so even this operation might fail
// Still we actually don't care anymore - anyway the application has been cashed // Still we actually don't care anymore - anyway the application has been cashed
} }

View File

@@ -1,10 +1,8 @@
namespace EveOPreview namespace EveOPreview {
{
/// <summary> /// <summary>
/// Application controller /// Application controller
/// </summary> /// </summary>
public interface IApplicationController public interface IApplicationController {
{
IApplicationController RegisterView<TView, TPresenter>() IApplicationController RegisterView<TView, TPresenter>()
where TPresenter : class, TView where TPresenter : class, TView
where TView : IView; where TView : IView;
@@ -21,6 +19,4 @@
where TPresenter : class, IPresenter<TArgument>; where TPresenter : class, IPresenter<TArgument>;
TService Create<TService>() TService Create<TService>()
where TService : class; where TService : class; } }
}
}

View File

@@ -3,24 +3,10 @@ using System.Collections.Generic;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
namespace EveOPreview namespace EveOPreview {
{
/// <summary> /// <summary>
/// Generic interface for an Inversion Of Control container /// Generic interface for an Inversion Of Control container
/// </summary> /// </summary>
public interface IIocContainer public interface IIocContainer {
{
void Register<TService, TImplementation>() void Register<TService, TImplementation>()
where TImplementation : TService; where TImplementation : TService; void Register(Type serviceType, Assembly container); void Register<TService>(); void Register<TService>(Expression<Func<TService>> factory); void Register<TService, TArgument>(Expression<Func<TArgument, TService>> factory); void RegisterInstance<TService>(TService instance); TService Resolve<TService>(); IEnumerable<TService> ResolveAll<TService>(); object Resolve(Type serviceType); IEnumerable<object> ResolveAll(Type serviceType); bool IsRegistered<TService>(); } }
void Register(Type serviceType, Assembly container);
void Register<TService>();
void Register<TService>(Expression<Func<TService>> factory);
void Register<TService, TArgument>(Expression<Func<TArgument, TService>> factory);
void RegisterInstance<TService>(TService instance);
TService Resolve<TService>();
IEnumerable<TService> ResolveAll<TService>();
object Resolve(Type serviceType);
IEnumerable<object> ResolveAll(Type serviceType);
bool IsRegistered<TService>();
}
}

View File

@@ -1,7 +1,5 @@
namespace EveOPreview namespace EveOPreview {
{ public interface IPresenter {
public interface IPresenter
{
void Run(); void Run();
} }
} }

View File

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

View File

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

View File

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

View File

@@ -1,21 +1,17 @@
namespace EveOPreview namespace EveOPreview {
{
public abstract class Presenter<TView> : IPresenter public abstract class Presenter<TView> : IPresenter
where TView : IView where TView : IView {
{
// Properties are used instead of fields so the code remains CLS compliant // Properties are used instead of fields so the code remains CLS compliant
// 'protected readonly' fields would result in non-CLS compliant code // 'protected readonly' fields would result in non-CLS compliant code
protected TView View { get; private set; } protected TView View { get; private set; }
protected IApplicationController Controller { get; private set; } protected IApplicationController Controller { get; private set; }
protected Presenter(IApplicationController controller, TView view) protected Presenter(IApplicationController controller, TView view) {
{
this.Controller = controller; this.Controller = controller;
this.View = view; this.View = view;
} }
public void Run() public void Run() {
{
this.View.Show(); this.View.Show();
} }
} }

View File

@@ -1,15 +1,12 @@
namespace EveOPreview namespace EveOPreview {
{
public abstract class Presenter<TView, TArgument> : IPresenter<TArgument> public abstract class Presenter<TView, TArgument> : IPresenter<TArgument>
where TView : IView where TView : IView {
{
// Properties are used instead of fields so the code remains CLS compliant // Properties are used instead of fields so the code remains CLS compliant
// 'protected readonly' fields would result in non-CLS compliant code // 'protected readonly' fields would result in non-CLS compliant code
protected TView View { get; private set; } protected TView View { get; private set; }
protected IApplicationController Controller { get; private set; } protected IApplicationController Controller { get; private set; }
protected Presenter(IApplicationController controller, TView view) protected Presenter(IApplicationController controller, TView view) {
{
this.Controller = controller; this.Controller = controller;
this.View = view; this.View = view;
} }

View File

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

View File

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

View File

@@ -5,73 +5,56 @@ using System.Linq;
using System.Windows.Forms; using System.Windows.Forms;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace EveOPreview.Configuration.Implementation namespace EveOPreview.Configuration.Implementation {
{ sealed class ThumbnailConfiguration : IThumbnailConfiguration {
sealed class ThumbnailConfiguration : IThumbnailConfiguration
{
#region Private fields #region Private fields
private bool _enablePerClientThumbnailLayouts; private bool _enablePerClientThumbnailLayouts;
private bool _enableClientLayoutTracking; private bool _enableClientLayoutTracking;
#endregion #endregion
public ThumbnailConfiguration() public ThumbnailConfiguration() {
{
this.ConfigVersion = 1; this.ConfigVersion = 1;
this.CycleGroup1ForwardHotkeys = new List<string> { "F14", "Control+F14" }; this.CycleGroup1ForwardHotkeys = new List<string> { "F14", "Control+F14" };
this.CycleGroup1BackwardHotkeys = new List<string> { "F13", "Control+F13" }; this.CycleGroup1BackwardHotkeys = new List<string> { "F13", "Control+F13" };
this.CycleGroup1ClientsOrder = new Dictionary<string, int> this.CycleGroup1ClientsOrder = new Dictionary<string, int> {
{ { "EVE - Example DPS Toon 1", 1 }, { "EVE - Example DPS Toon 2", 2 }, { "EVE - Example DPS Toon 3", 3 }
{ "EVE - Example DPS Toon 1", 1 },
{ "EVE - Example DPS Toon 2", 2 },
{ "EVE - Example DPS Toon 3", 3 }
}; };
this.CycleGroup2ForwardHotkeys = new List<string> { "F16", "Control+F16" }; this.CycleGroup2ForwardHotkeys = new List<string> { "F16", "Control+F16" };
this.CycleGroup2BackwardHotkeys = new List<string> { "F15", "Control+F15" }; this.CycleGroup2BackwardHotkeys = new List<string> { "F15", "Control+F15" };
this.CycleGroup2ClientsOrder = new Dictionary<string, int> this.CycleGroup2ClientsOrder = new Dictionary<string, int> { { "EVE - Example Logi Toon 1", 1 },
{
{ "EVE - Example Logi Toon 1", 1 },
{ "EVE - Example Scout Toon 2", 2 }, { "EVE - Example Scout Toon 2", 2 },
{ "EVE - Example Tackle Toon 3", 3 } { "EVE - Example Tackle Toon 3", 3 } };
};
this.CycleGroup3ForwardHotkeys = new List<string> { "" }; this.CycleGroup3ForwardHotkeys = new List<string> { "" };
this.CycleGroup3BackwardHotkeys = new List<string> { "" }; this.CycleGroup3BackwardHotkeys = new List<string> { "" };
this.CycleGroup3ClientsOrder = new Dictionary<string, int> this.CycleGroup3ClientsOrder = new Dictionary<string, int> {
{
{ "EVE - cycle group 3", 1 }, { "EVE - cycle group 3", 1 },
}; };
this.CycleGroup4ForwardHotkeys = new List<string> { "" }; this.CycleGroup4ForwardHotkeys = new List<string> { "" };
this.CycleGroup4BackwardHotkeys = new List<string> { "" }; this.CycleGroup4BackwardHotkeys = new List<string> { "" };
this.CycleGroup4ClientsOrder = new Dictionary<string, int> this.CycleGroup4ClientsOrder = new Dictionary<string, int> {
{
{ "EVE - cycle group 4", 1 }, { "EVE - cycle group 4", 1 },
}; };
this.CycleGroup5ForwardHotkeys = new List<string> { "" }; this.CycleGroup5ForwardHotkeys = new List<string> { "" };
this.CycleGroup5BackwardHotkeys = new List<string> { "" }; this.CycleGroup5BackwardHotkeys = new List<string> { "" };
this.CycleGroup5ClientsOrder = new Dictionary<string, int> this.CycleGroup5ClientsOrder = new Dictionary<string, int> {
{
{ "EVE - cycle group 5", 1 }, { "EVE - cycle group 5", 1 },
}; };
this.PerClientActiveClientHighlightColor = new Dictionary<string, Color> this.PerClientActiveClientHighlightColor =
{ new Dictionary<string, Color> { { "EVE - Example Toon 1", Color.Red },
{"EVE - Example Toon 1", Color.Red}, { "EVE - Example Toon 2", Color.Green } };
{"EVE - Example Toon 2", Color.Green}
};
this.PerClientThumbnailSize = new Dictionary<string, Size> this.PerClientThumbnailSize =
{ new Dictionary<string, Size> { { "EVE - Example Toon 1", new Size(200, 200) },
{"EVE - Example Toon 1", new Size(200, 200)}, { "EVE - Example Toon 2", new Size(200, 200) } };
{"EVE - Example Toon 2", new Size(200, 200)}
};
this.PerClientZoomAnchor = new Dictionary<string, ZoomAnchor> this.PerClientThumbnailRegion = new Dictionary<string, Rectangle>();
{
{"EVE - Example Toon 1", ZoomAnchor.N }, this.PerClientZoomAnchor = new Dictionary<string, ZoomAnchor> { { "EVE - Example Toon 1", ZoomAnchor.N },
{"EVE - Example Toon 2", ZoomAnchor.S} { "EVE - Example Toon 2", ZoomAnchor.S } };
};
this.PerClientLayout = new Dictionary<string, Dictionary<string, Point>>(); this.PerClientLayout = new Dictionary<string, Dictionary<string, Point>>();
this.FlatLayout = new Dictionary<string, Point>(); this.FlatLayout = new Dictionary<string, Point>();
@@ -131,85 +114,132 @@ namespace EveOPreview.Configuration.Implementation
this.OverlayLabelColor = Color.Orange; this.OverlayLabelColor = Color.Orange;
this.OverlayLabelSize = 10; this.OverlayLabelSize = 10;
this.EnableThumbnailRegionSnipping = false;
this.DefaultThumbnailRegion = new Rectangle(0, 0, 384, 216);
this.CurrentProfile = "Default";
this.AvailableProfiles = new List<string> { "Default" };
this.IconName = ""; this.IconName = "";
this.LoginThumbnailLocation = new Point(5, 5); this.LoginThumbnailLocation = new Point(5, 5);
} }
[JsonProperty("ConfigVersion")] [JsonProperty("ConfigVersion")]
public int ConfigVersion { get; set; } public int ConfigVersion { get; set; }
[JsonProperty("CycleGroup1ForwardHotkeys")] [JsonProperty("CycleGroup1ForwardHotkeys")]
public List<string> CycleGroup1ForwardHotkeys { get; set; } public List<string> CycleGroup1ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup1BackwardHotkeys")] [JsonProperty("CycleGroup1BackwardHotkeys")]
public List<string> CycleGroup1BackwardHotkeys { get; set; } public List<string> CycleGroup1BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup1ClientsOrder")] [JsonProperty("CycleGroup1ClientsOrder")]
public Dictionary<string, int> CycleGroup1ClientsOrder { get; set; } public Dictionary<string, int> CycleGroup1ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup2ForwardHotkeys")] [JsonProperty("CycleGroup2ForwardHotkeys")]
public List<string> CycleGroup2ForwardHotkeys { get; set; } public List<string> CycleGroup2ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup2BackwardHotkeys")] [JsonProperty("CycleGroup2BackwardHotkeys")]
public List<string> CycleGroup2BackwardHotkeys { get; set; } public List<string> CycleGroup2BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup2ClientsOrder")] [JsonProperty("CycleGroup2ClientsOrder")]
public Dictionary<string, int> CycleGroup2ClientsOrder { get; set; } public Dictionary<string, int> CycleGroup2ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup3ForwardHotkeys")] [JsonProperty("CycleGroup3ForwardHotkeys")]
public List<string> CycleGroup3ForwardHotkeys { get; set; } public List<string> CycleGroup3ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup3BackwardHotkeys")] [JsonProperty("CycleGroup3BackwardHotkeys")]
public List<string> CycleGroup3BackwardHotkeys { get; set; } public List<string> CycleGroup3BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup3ClientsOrder")] [JsonProperty("CycleGroup3ClientsOrder")]
public Dictionary<string, int> CycleGroup3ClientsOrder { get; set; } public Dictionary<string, int> CycleGroup3ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup4ForwardHotkeys")] [JsonProperty("CycleGroup4ForwardHotkeys")]
public List<string> CycleGroup4ForwardHotkeys { get; set; } public List<string> CycleGroup4ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup4BackwardHotkeys")] [JsonProperty("CycleGroup4BackwardHotkeys")]
public List<string> CycleGroup4BackwardHotkeys { get; set; } public List<string> CycleGroup4BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup4ClientsOrder")] [JsonProperty("CycleGroup4ClientsOrder")]
public Dictionary<string, int> CycleGroup4ClientsOrder { get; set; } public Dictionary<string, int> CycleGroup4ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup5ForwardHotkeys")] [JsonProperty("CycleGroup5ForwardHotkeys")]
public List<string> CycleGroup5ForwardHotkeys { get; set; } public List<string> CycleGroup5ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup5BackwardHotkeys")] [JsonProperty("CycleGroup5BackwardHotkeys")]
public List<string> CycleGroup5BackwardHotkeys { get; set; } public List<string> CycleGroup5BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup5ClientsOrder")] [JsonProperty("CycleGroup5ClientsOrder")]
public Dictionary<string, int> CycleGroup5ClientsOrder { get; set; } public Dictionary<string, int> CycleGroup5ClientsOrder {
get; set;
}
[JsonProperty("PerClientActiveClientHighlightColor")] [JsonProperty("PerClientActiveClientHighlightColor")]
public Dictionary<string, Color> PerClientActiveClientHighlightColor { get; set; } public Dictionary<string, Color> PerClientActiveClientHighlightColor {
get; set;
}
[JsonProperty("PerClientThumbnailSize")] [JsonProperty("PerClientThumbnailSize")]
public Dictionary<string, Size> PerClientThumbnailSize { get; set; } public Dictionary<string, Size> PerClientThumbnailSize {
get; set;
}
[JsonProperty("PerClientThumbnailRegion")]
public Dictionary<string, Rectangle> PerClientThumbnailRegion {
get; set;
}
[JsonProperty("PerClientZoomAnchor")] [JsonProperty("PerClientZoomAnchor")]
public Dictionary<string, ZoomAnchor> PerClientZoomAnchor{ get; set; } public Dictionary<string, ZoomAnchor> PerClientZoomAnchor {
get; set;
}
public bool MinimizeToTray { get; set; } public bool MinimizeToTray { get; set; }
public int ThumbnailRefreshPeriod { get; set; } public int ThumbnailRefreshPeriod { get; set; }
public int ThumbnailResizeTimeoutPeriod { get; set; } public int ThumbnailResizeTimeoutPeriod { get; set; }
[JsonProperty("WineCompatibilityMode")] [JsonProperty("WineCompatibilityMode")]
public bool EnableWineCompatibilityMode { get; set; } public bool EnableWineCompatibilityMode {
get; set;
}
[JsonProperty("ThumbnailsOpacity")] [JsonProperty("ThumbnailsOpacity")]
public double ThumbnailOpacity { get; set; } public double ThumbnailOpacity {
get; set;
}
public bool EnableClientLayoutTracking public bool EnableClientLayoutTracking {
{
get => this._enableClientLayoutTracking; get => this._enableClientLayoutTracking;
set set {
{ if (!value) {
if (!value)
{
this.ClientLayout.Clear(); this.ClientLayout.Clear();
} }
@@ -223,13 +253,10 @@ namespace EveOPreview.Configuration.Implementation
public AnimationStyle WindowsAnimationStyle { get; set; } public AnimationStyle WindowsAnimationStyle { get; set; }
public bool ShowThumbnailsAlwaysOnTop { get; set; } public bool ShowThumbnailsAlwaysOnTop { get; set; }
public bool EnablePerClientThumbnailLayouts public bool EnablePerClientThumbnailLayouts {
{
get => this._enablePerClientThumbnailLayouts; get => this._enablePerClientThumbnailLayouts;
set set {
{ if (!value) {
if (!value)
{
this.PerClientLayout.Clear(); this.PerClientLayout.Clear();
} }
@@ -247,7 +274,9 @@ namespace EveOPreview.Configuration.Implementation
public bool EnableThumbnailSnap { get; set; } public bool EnableThumbnailSnap { get; set; }
[JsonProperty("EnableThumbnailZoom")] [JsonProperty("EnableThumbnailZoom")]
public bool ThumbnailZoomEnabled { get; set; } public bool ThumbnailZoomEnabled {
get; set;
}
public int ThumbnailZoomFactor { get; set; } public int ThumbnailZoomFactor { get; set; }
public ZoomAnchor ThumbnailZoomAnchor { get; set; } public ZoomAnchor ThumbnailZoomAnchor { get; set; }
public ZoomAnchor OverlayLabelAnchor { get; set; } public ZoomAnchor OverlayLabelAnchor { get; set; }
@@ -264,34 +293,59 @@ namespace EveOPreview.Configuration.Implementation
public Color ActiveClientHighlightColor { get; set; } public Color ActiveClientHighlightColor { get; set; }
public Color OverlayLabelColor { get; set; } public Color OverlayLabelColor { get; set; }
public int OverlayLabelSize { get; set; } public int OverlayLabelSize { get; set; }
public bool EnableThumbnailRegionSnipping { get; set; }
public Rectangle DefaultThumbnailRegion { get; set; }
public string CurrentProfile { get; set; }
public List<string> AvailableProfiles { get; set; }
[JsonProperty("IconName")] [JsonProperty("IconName")]
public string IconName { get; set; } public string IconName {
get; set;
}
public int ActiveClientHighlightThickness { get; set; } public int ActiveClientHighlightThickness { get; set; }
[JsonProperty("LoginThumbnailLocation")] [JsonProperty("LoginThumbnailLocation")]
public Point LoginThumbnailLocation { get; set; } public Point LoginThumbnailLocation {
get; set;
}
[JsonProperty("ToggleTrackingHotkey")] [JsonProperty("ToggleTrackingHotkey")]
public string ToggleTrackingHotkey { get; set; } public string ToggleTrackingHotkey {
get; set;
}
[JsonProperty] [JsonProperty]
private Dictionary<string, Dictionary<string, Point>> PerClientLayout { get; set; } private Dictionary<string, Dictionary<string, Point>> PerClientLayout {
get; set;
}
[JsonProperty] [JsonProperty]
private Dictionary<string, Point> FlatLayout { get; set; } private Dictionary<string, Point> FlatLayout {
get; set;
}
[JsonProperty] [JsonProperty]
private Dictionary<string, ClientLayout> ClientLayout { get; set; } private Dictionary<string, ClientLayout> ClientLayout {
get; set;
}
[JsonProperty] [JsonProperty]
private Dictionary<string, string> ClientHotkey { get; set; } private Dictionary<string, string> ClientHotkey {
get; set;
}
[JsonProperty] [JsonProperty]
private Dictionary<string, bool> DisableThumbnail { get; set; } private Dictionary<string, bool> DisableThumbnail {
get; set;
}
[JsonProperty] [JsonProperty]
private List<string> PriorityClients { get; set; } private List<string> PriorityClients {
get; set;
}
[JsonProperty] [JsonProperty]
public List<string> ExecutablesToPreview { get; set; } public List<string> ExecutablesToPreview {
get; set;
}
public Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation) public Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation) {
{
Point location; Point location;
// What this code does: // What this code does:
@@ -302,11 +356,10 @@ namespace EveOPreview.Configuration.Implementation
// then return that entry // then return that entry
// otherwise try to get client layout from the flat all-clients layout // otherwise try to get client layout from the flat all-clients layout
// If there is no layout too then use the default one // If there is no layout too then use the default one
if (this.EnablePerClientThumbnailLayouts && !string.IsNullOrEmpty(activeClient)) if (this.EnablePerClientThumbnailLayouts && !string.IsNullOrEmpty(activeClient)) {
{
Dictionary<string, Point> layoutSource; Dictionary<string, Point> layoutSource;
if (this.PerClientLayout.TryGetValue(activeClient, out layoutSource) && layoutSource.TryGetValue(currentClient, out location)) if (this.PerClientLayout.TryGetValue(activeClient, out layoutSource) &&
{ layoutSource.TryGetValue(currentClient, out location)) {
return location; return location;
} }
} }
@@ -314,60 +367,81 @@ namespace EveOPreview.Configuration.Implementation
return this.FlatLayout.TryGetValue(currentClient, out location) ? location : defaultLocation; return this.FlatLayout.TryGetValue(currentClient, out location) ? location : defaultLocation;
} }
public Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize) public Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize) {
{
Size sizeOfThumbnail; Size sizeOfThumbnail;
return this.PerClientThumbnailSize.TryGetValue(currentClient, out sizeOfThumbnail) ? sizeOfThumbnail : defaultSize; return this.PerClientThumbnailSize.TryGetValue(currentClient, out sizeOfThumbnail) ? sizeOfThumbnail
: defaultSize;
} }
public ZoomAnchor GetZoomAnchor(string currentClient, ZoomAnchor defaultZoomAnchor)
{ public Rectangle GetThumbnailRegion(string currentClient, Rectangle defaultRegion) {
Rectangle region;
return this.PerClientThumbnailRegion.TryGetValue(currentClient, out region) ? region : defaultRegion;
}
public ZoomAnchor GetZoomAnchor(string currentClient, ZoomAnchor defaultZoomAnchor) {
ZoomAnchor zoomAnchor; ZoomAnchor zoomAnchor;
return this.PerClientZoomAnchor.TryGetValue(currentClient, out zoomAnchor) ? zoomAnchor : defaultZoomAnchor; return this.PerClientZoomAnchor.TryGetValue(currentClient, out zoomAnchor) ? zoomAnchor : defaultZoomAnchor;
} }
public void SetThumbnailLocation(string currentClient, string activeClient, Point location) public void SetThumbnailLocation(string currentClient, string activeClient, Point location) {
{
Dictionary<string, Point> layoutSource; Dictionary<string, Point> layoutSource;
if (this.EnablePerClientThumbnailLayouts) if (this.EnablePerClientThumbnailLayouts) {
{ if (string.IsNullOrEmpty(activeClient)) {
if (string.IsNullOrEmpty(activeClient))
{
return; return;
} }
if (!this.PerClientLayout.TryGetValue(activeClient, out layoutSource)) if (!this.PerClientLayout.TryGetValue(activeClient, out layoutSource)) {
{
layoutSource = new Dictionary<string, Point>(); layoutSource = new Dictionary<string, Point>();
this.PerClientLayout[activeClient] = layoutSource; this.PerClientLayout[activeClient] = layoutSource;
} }
} } else {
else
{
layoutSource = this.FlatLayout; layoutSource = this.FlatLayout;
} }
layoutSource[currentClient] = location; layoutSource[currentClient] = location;
} }
public ClientLayout GetClientLayout(string currentClient) public void SetThumbnailRegion(string currentClient, Rectangle region) {
{ this.PerClientThumbnailRegion[currentClient] = region;
}
public void SaveProfile(string profileName) {
if (!this.AvailableProfiles.Contains(profileName)) {
this.AvailableProfiles.Add(profileName);
}
this.CurrentProfile = profileName;
}
public void LoadProfile(string profileName) {
if (this.AvailableProfiles.Contains(profileName)) {
this.CurrentProfile = profileName;
}
}
public void DeleteProfile(string profileName) {
if (profileName != "Default" && this.AvailableProfiles.Contains(profileName)) {
this.AvailableProfiles.Remove(profileName);
if (this.CurrentProfile == profileName) {
this.CurrentProfile = "Default";
}
}
}
public ClientLayout GetClientLayout(string currentClient) {
ClientLayout layout; ClientLayout layout;
this.ClientLayout.TryGetValue(currentClient, out layout); this.ClientLayout.TryGetValue(currentClient, out layout);
return layout; return layout;
} }
public void SetClientLayout(string currentClient, ClientLayout layout) public void SetClientLayout(string currentClient, ClientLayout layout) {
{
this.ClientLayout[currentClient] = layout; this.ClientLayout[currentClient] = layout;
} }
public Keys GetClientHotkey(string currentClient) public Keys GetClientHotkey(string currentClient) {
{
string hotkey; string hotkey;
if (this.ClientHotkey.TryGetValue(currentClient, out hotkey)) if (this.ClientHotkey.TryGetValue(currentClient, out hotkey)) {
{
// Protect from incorrect values // Protect from incorrect values
object rawValue = (new KeysConverter()).ConvertFromInvariantString(hotkey); object rawValue = (new KeysConverter()).ConvertFromInvariantString(hotkey);
return rawValue != null ? (Keys)rawValue : Keys.None; return rawValue != null ? (Keys)rawValue : Keys.None;
@@ -376,63 +450,61 @@ namespace EveOPreview.Configuration.Implementation
return Keys.None; return Keys.None;
} }
public void SetClientHotkey(string currentClient, Keys hotkey) public void SetClientHotkey(string currentClient, Keys hotkey) {
{
this.ClientHotkey[currentClient] = (new KeysConverter()).ConvertToInvariantString(hotkey); this.ClientHotkey[currentClient] = (new KeysConverter()).ConvertToInvariantString(hotkey);
} }
public Keys StringToKey(string hotkey) public Keys StringToKey(string hotkey) {
{
object rawValue = (new KeysConverter()).ConvertFromInvariantString(hotkey); object rawValue = (new KeysConverter()).ConvertFromInvariantString(hotkey);
return rawValue != null ? (Keys)rawValue : Keys.None; return rawValue != null ? (Keys)rawValue : Keys.None;
} }
public bool IsPriorityClient(string currentClient) public bool IsPriorityClient(string currentClient) {
{
return this.PriorityClients.Contains(currentClient); return this.PriorityClients.Contains(currentClient);
} }
public bool IsExecutableToPreview(string processName) public bool IsExecutableToPreview(string processName) {
{
return this.ExecutablesToPreview.Any(s => s.Equals(processName, StringComparison.OrdinalIgnoreCase)); return this.ExecutablesToPreview.Any(s => s.Equals(processName, StringComparison.OrdinalIgnoreCase));
} }
public bool IsThumbnailDisabled(string currentClient) public bool IsThumbnailDisabled(string currentClient) {
{
return this.DisableThumbnail.TryGetValue(currentClient, out bool isDisabled) && isDisabled; return this.DisableThumbnail.TryGetValue(currentClient, out bool isDisabled) && isDisabled;
} }
public void ToggleThumbnail(string currentClient, bool isDisabled) public void ToggleThumbnail(string currentClient, bool isDisabled) {
{
this.DisableThumbnail[currentClient] = isDisabled; this.DisableThumbnail[currentClient] = isDisabled;
} }
/// <summary> /// <summary>
/// Applies restrictions to different parameters of the config /// Applies restrictions to different parameters of the config
/// </summary> /// </summary>
public void ApplyRestrictions() public void ApplyRestrictions() {
{
#if LINUX #if LINUX
this.ThumbnailRefreshPeriod = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailRefreshPeriod, 10, 1000); this.ThumbnailRefreshPeriod =
ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailRefreshPeriod, 10, 1000);
#else #else
this.ThumbnailRefreshPeriod = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailRefreshPeriod, 300, 1000); this.ThumbnailRefreshPeriod =
ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailRefreshPeriod, 300, 1000);
#endif #endif
this.ThumbnailResizeTimeoutPeriod = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailResizeTimeoutPeriod, 200, 5000); this.ThumbnailResizeTimeoutPeriod =
this.ThumbnailSize = new Size(ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailSize.Width, this.ThumbnailMinimumSize.Width, this.ThumbnailMaximumSize.Width), ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailResizeTimeoutPeriod, 200, 5000);
ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailSize.Height, this.ThumbnailMinimumSize.Height, this.ThumbnailMaximumSize.Height)); this.ThumbnailSize = new Size(
this.ThumbnailOpacity = ThumbnailConfiguration.ApplyRestrictions((int)(this.ThumbnailOpacity * 100.00), 20, 100) / 100.00; ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailSize.Width, this.ThumbnailMinimumSize.Width,
this.ThumbnailMaximumSize.Width),
ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailSize.Height, this.ThumbnailMinimumSize.Height,
this.ThumbnailMaximumSize.Height));
this.ThumbnailOpacity =
ThumbnailConfiguration.ApplyRestrictions((int)(this.ThumbnailOpacity * 100.00), 20, 100) / 100.00;
this.ThumbnailZoomFactor = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailZoomFactor, 2, 10); this.ThumbnailZoomFactor = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailZoomFactor, 2, 10);
this.ActiveClientHighlightThickness = ThumbnailConfiguration.ApplyRestrictions(this.ActiveClientHighlightThickness, 1, 6); this.ActiveClientHighlightThickness =
ThumbnailConfiguration.ApplyRestrictions(this.ActiveClientHighlightThickness, 1, 6);
} }
private static int ApplyRestrictions(int value, int minimum, int maximum) private static int ApplyRestrictions(int value, int minimum, int maximum) {
{ if (value <= minimum) {
if (value <= minimum)
{
return minimum; return minimum;
} }
if (value >= maximum) if (value >= maximum) {
{
return maximum; return maximum;
} }

View File

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

View File

@@ -1,13 +1,8 @@
namespace EveOPreview.Configuration namespace EveOPreview.Configuration {
{ public class ClientLayout {
public class ClientLayout public ClientLayout() {}
{
public ClientLayout()
{
}
public ClientLayout(int x, int y, int width, int height, bool maximized) public ClientLayout(int x, int y, int width, int height, bool maximized) {
{
this.X = x; this.X = x;
this.Y = y; this.Y = y;
this.Width = width; this.Width = width;

View File

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

View File

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

View File

@@ -2,10 +2,8 @@
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
namespace EveOPreview.Configuration namespace EveOPreview.Configuration {
{ public interface IThumbnailConfiguration {
public interface IThumbnailConfiguration
{
List<string> CycleGroup1ForwardHotkeys { get; set; } List<string> CycleGroup1ForwardHotkeys { get; set; }
List<string> CycleGroup1BackwardHotkeys { get; set; } List<string> CycleGroup1BackwardHotkeys { get; set; }
Dictionary<string, int> CycleGroup1ClientsOrder { get; set; } Dictionary<string, int> CycleGroup1ClientsOrder { get; set; }
@@ -30,6 +28,7 @@ namespace EveOPreview.Configuration
Dictionary<string, Color> PerClientActiveClientHighlightColor { get; set; } Dictionary<string, Color> PerClientActiveClientHighlightColor { get; set; }
Dictionary<string, Size> PerClientThumbnailSize { get; set; } Dictionary<string, Size> PerClientThumbnailSize { get; set; }
Dictionary<string, Rectangle> PerClientThumbnailRegion { get; set; }
bool MinimizeToTray { get; set; } bool MinimizeToTray { get; set; }
int ThumbnailRefreshPeriod { get; set; } int ThumbnailRefreshPeriod { get; set; }
@@ -73,6 +72,12 @@ namespace EveOPreview.Configuration
Color OverlayLabelColor { get; set; } Color OverlayLabelColor { get; set; }
int OverlayLabelSize { get; set; } int OverlayLabelSize { get; set; }
bool EnableThumbnailRegionSnipping { get; set; }
Rectangle DefaultThumbnailRegion { get; set; }
string CurrentProfile { get; set; }
List<string> AvailableProfiles { get; set; }
string IconName { get; set; } string IconName { get; set; }
Point LoginThumbnailLocation { get; set; } Point LoginThumbnailLocation { get; set; }
@@ -80,7 +85,13 @@ namespace EveOPreview.Configuration
Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation); Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation);
Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize); Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize);
ZoomAnchor GetZoomAnchor(string currentClient, ZoomAnchor defaultZoomAnchor); ZoomAnchor GetZoomAnchor(string currentClient, ZoomAnchor defaultZoomAnchor);
Rectangle GetThumbnailRegion(string currentClient, Rectangle defaultRegion);
void SetThumbnailLocation(string currentClient, string activeClient, Point location); void SetThumbnailLocation(string currentClient, string activeClient, Point location);
void SetThumbnailRegion(string currentClient, Rectangle region);
void SaveProfile(string profileName);
void LoadProfile(string profileName);
void DeleteProfile(string profileName);
ClientLayout GetClientLayout(string currentClient); ClientLayout GetClientLayout(string currentClient);
void SetClientLayout(string currentClient, ClientLayout layout); void SetClientLayout(string currentClient, ClientLayout layout);

View File

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

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<DefineConstants Condition="'$(EVEOTarget)'=='Linux'">LINUX</DefineConstants> <DefineConstants Condition="'$(EVEOTarget)'=='Linux'">LINUX</DefineConstants>
<TargetFramework>net8.0-windows8.0</TargetFramework> <TargetFramework>net6.0-windows</TargetFramework>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<PublishSingleFile>true</PublishSingleFile> <PublishSingleFile>true</PublishSingleFile>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract> <IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>

View File

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

View File

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

View File

@@ -4,19 +4,15 @@ using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages; using EveOPreview.Mediator.Messages;
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Handlers.Configuration namespace EveOPreview.Mediator.Handlers.Configuration {
{ sealed class SaveConfigurationHandler : IRequestHandler<SaveConfiguration> {
sealed class SaveConfigurationHandler : IRequestHandler<SaveConfiguration>
{
private readonly IConfigurationStorage _storage; private readonly IConfigurationStorage _storage;
public SaveConfigurationHandler(IConfigurationStorage storage) public SaveConfigurationHandler(IConfigurationStorage storage) {
{
this._storage = storage; this._storage = storage;
} }
public Task<Unit> Handle(SaveConfiguration message, CancellationToken cancellationToken) public Task<Unit> Handle(SaveConfiguration message, CancellationToken cancellationToken) {
{
this._storage.Save(); this._storage.Save();
return Unit.Task; return Unit.Task;

View File

@@ -4,26 +4,21 @@ using EveOPreview.Mediator.Messages;
using EveOPreview.Services; using EveOPreview.Services;
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Handlers.Services namespace EveOPreview.Mediator.Handlers.Services {
{ sealed class StartStopServiceHandler : IRequestHandler<StartService>, IRequestHandler<StopService> {
sealed class StartStopServiceHandler : IRequestHandler<StartService>, IRequestHandler<StopService>
{
private readonly IThumbnailManager _manager; private readonly IThumbnailManager _manager;
public StartStopServiceHandler(IThumbnailManager manager) public StartStopServiceHandler(IThumbnailManager manager) {
{
this._manager = manager; this._manager = manager;
} }
public Task<Unit> Handle(StartService message, CancellationToken cancellationToken) public Task<Unit> Handle(StartService message, CancellationToken cancellationToken) {
{
this._manager.Start(); this._manager.Start();
return Unit.Task; return Unit.Task;
} }
public Task<Unit> Handle(StopService message, CancellationToken cancellationToken) public Task<Unit> Handle(StopService message, CancellationToken cancellationToken) {
{
this._manager.Stop(); this._manager.Stop();
return Unit.Task; return Unit.Task;

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,22 +4,19 @@ using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages; using EveOPreview.Mediator.Messages;
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Handlers.Thumbnails namespace EveOPreview.Mediator.Handlers.Thumbnails {
{ sealed class ThumbnailLocationUpdatedHandler : INotificationHandler<ThumbnailLocationUpdated> {
sealed class ThumbnailLocationUpdatedHandler : INotificationHandler<ThumbnailLocationUpdated>
{
private readonly IMediator _mediator; private readonly IMediator _mediator;
private readonly IThumbnailConfiguration _configuration; private readonly IThumbnailConfiguration _configuration;
public ThumbnailLocationUpdatedHandler(IMediator mediator, IThumbnailConfiguration configuration) public ThumbnailLocationUpdatedHandler(IMediator mediator, IThumbnailConfiguration configuration) {
{
this._mediator = mediator; this._mediator = mediator;
this._configuration = configuration; this._configuration = configuration;
} }
public Task Handle(ThumbnailLocationUpdated notification, CancellationToken cancellationToken) public Task Handle(ThumbnailLocationUpdated notification, CancellationToken cancellationToken) {
{ this._configuration.SetThumbnailLocation(notification.ThumbnailName, notification.ActiveClientName,
this._configuration.SetThumbnailLocation(notification.ThumbnailName, notification.ActiveClientName, notification.Location); notification.Location);
return this._mediator.Send(new SaveConfiguration(), cancellationToken); return this._mediator.Send(new SaveConfiguration(), cancellationToken);
} }

View File

@@ -0,0 +1,20 @@
using System.Threading;
using System.Threading.Tasks;
using EveOPreview.Mediator.Messages;
using EveOPreview.Services;
using MediatR;
namespace EveOPreview.Mediator.Handlers.Thumbnails {
public class ThumbnailRegionSettingsUpdatedHandler : INotificationHandler<ThumbnailRegionSettingsUpdated> {
private readonly IThumbnailManager _thumbnailManager;
public ThumbnailRegionSettingsUpdatedHandler(IThumbnailManager thumbnailManager) {
this._thumbnailManager = thumbnailManager;
}
public Task Handle(ThumbnailRegionSettingsUpdated notification, CancellationToken cancellationToken) {
this._thumbnailManager.UpdateThumbnailRegionSettings();
return Task.CompletedTask;
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,13 +4,12 @@ using System.Diagnostics;
using System.Drawing; using System.Drawing;
using EveOPreview.Configuration; using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages; using EveOPreview.Mediator.Messages;
using EveOPreview.View; using EveOPreview.View;
using MediatR; using MediatR;
namespace EveOPreview.Presenters namespace EveOPreview.Presenters {
{ public class MainFormPresenter : Presenter<IMainFormView>, IMainFormPresenter {
public class MainFormPresenter : Presenter<IMainFormView>, IMainFormPresenter
{
#region Private constants #region Private constants
private const string FORUM_URL = @"https://forum.eveonline.com/t/4202"; private const string FORUM_URL = @"https://forum.eveonline.com/t/4202";
#endregion #endregion
@@ -25,9 +24,9 @@ namespace EveOPreview.Presenters
private bool _exitApplication; private bool _exitApplication;
#endregion #endregion
public MainFormPresenter(IApplicationController controller, IMainFormView view, IMediator mediator, IThumbnailConfiguration configuration, IConfigurationStorage configurationStorage) public MainFormPresenter(IApplicationController controller, IMainFormView view, IMediator mediator,
: base(controller, view) IThumbnailConfiguration configuration, IConfigurationStorage configurationStorage)
{ : base(controller, view) {
this._mediator = mediator; this._mediator = mediator;
this._configuration = configuration; this._configuration = configuration;
this._configurationStorage = configurationStorage; this._configurationStorage = configurationStorage;
@@ -49,14 +48,12 @@ namespace EveOPreview.Presenters
this.View.IconName = this._configuration.IconName; this.View.IconName = this._configuration.IconName;
} }
private void Activate() private void Activate() {
{
this._suppressSizeNotifications = true; this._suppressSizeNotifications = true;
this.LoadApplicationSettings(); this.LoadApplicationSettings();
this.View.SetDocumentationUrl(MainFormPresenter.FORUM_URL); this.View.SetDocumentationUrl(MainFormPresenter.FORUM_URL);
this.View.SetVersionInfo(this.GetApplicationVersion()); this.View.SetVersionInfo(this.GetApplicationVersion());
if (this._configuration.MinimizeToTray) if (this._configuration.MinimizeToTray) {
{
this.View.Minimize(); this.View.Minimize();
} }
@@ -64,20 +61,16 @@ namespace EveOPreview.Presenters
this._suppressSizeNotifications = false; this._suppressSizeNotifications = false;
} }
private void Minimize() private void Minimize() {
{ if (!this._configuration.MinimizeToTray) {
if (!this._configuration.MinimizeToTray)
{
return; return;
} }
this.View.Hide(); this.View.Hide();
} }
private void Close(ViewCloseRequest request) private void Close(ViewCloseRequest request) {
{ if (this._exitApplication || !this.View.MinimizeToTray) {
if (this._exitApplication || !this.View.MinimizeToTray)
{
this._mediator.Send(new StopService()).Wait(); this._mediator.Send(new StopService()).Wait();
this._configurationStorage.Save(); this._configurationStorage.Save();
@@ -89,17 +82,14 @@ namespace EveOPreview.Presenters
this.View.Minimize(); this.View.Minimize();
} }
private async void UpdateThumbnailsSize() private async void UpdateThumbnailsSize() {
{ if (!this._suppressSizeNotifications) {
if (!this._suppressSizeNotifications)
{
this.SaveApplicationSettings(); this.SaveApplicationSettings();
await this._mediator.Publish(new ThumbnailConfiguredSizeUpdated()); await this._mediator.Publish(new ThumbnailConfiguredSizeUpdated());
} }
} }
private void LoadApplicationSettings() private void LoadApplicationSettings() {
{
this._configurationStorage.Load(); this._configurationStorage.Load();
this.View.MinimizeToTray = this._configuration.MinimizeToTray; this.View.MinimizeToTray = this._configuration.MinimizeToTray;
@@ -109,12 +99,14 @@ namespace EveOPreview.Presenters
this.View.EnableClientLayoutTracking = this._configuration.EnableClientLayoutTracking; this.View.EnableClientLayoutTracking = this._configuration.EnableClientLayoutTracking;
this.View.HideActiveClientThumbnail = this._configuration.HideActiveClientThumbnail; this.View.HideActiveClientThumbnail = this._configuration.HideActiveClientThumbnail;
this.View.MinimizeInactiveClients = this._configuration.MinimizeInactiveClients; this.View.MinimizeInactiveClients = this._configuration.MinimizeInactiveClients;
this.View.WindowsAnimationStyle = ViewAnimationStyleConverter.Convert(this._configuration.WindowsAnimationStyle); this.View.WindowsAnimationStyle =
ViewAnimationStyleConverter.Convert(this._configuration.WindowsAnimationStyle);
this.View.ShowThumbnailsAlwaysOnTop = this._configuration.ShowThumbnailsAlwaysOnTop; this.View.ShowThumbnailsAlwaysOnTop = this._configuration.ShowThumbnailsAlwaysOnTop;
this.View.HideThumbnailsOnLostFocus = this._configuration.HideThumbnailsOnLostFocus; this.View.HideThumbnailsOnLostFocus = this._configuration.HideThumbnailsOnLostFocus;
this.View.EnablePerClientThumbnailLayouts = this._configuration.EnablePerClientThumbnailLayouts; this.View.EnablePerClientThumbnailLayouts = this._configuration.EnablePerClientThumbnailLayouts;
this.View.SetThumbnailSizeLimitations(this._configuration.ThumbnailMinimumSize, this._configuration.ThumbnailMaximumSize); this.View.SetThumbnailSizeLimitations(this._configuration.ThumbnailMinimumSize,
this._configuration.ThumbnailMaximumSize);
this.View.ThumbnailSize = this._configuration.ThumbnailSize; this.View.ThumbnailSize = this._configuration.ThumbnailSize;
this.View.EnableThumbnailZoom = this._configuration.ThumbnailZoomEnabled; this.View.EnableThumbnailZoom = this._configuration.ThumbnailZoomEnabled;
@@ -134,11 +126,16 @@ namespace EveOPreview.Presenters
this.View.OverlayLabelColor = this._configuration.OverlayLabelColor; this.View.OverlayLabelColor = this._configuration.OverlayLabelColor;
this.View.OverlayLabelSize = this._configuration.OverlayLabelSize; this.View.OverlayLabelSize = this._configuration.OverlayLabelSize;
this.View.EnableThumbnailRegionSnipping = this._configuration.EnableThumbnailRegionSnipping;
this.View.DefaultThumbnailRegion = this._configuration.DefaultThumbnailRegion;
this.View.AvailableProfiles = this._configuration.AvailableProfiles;
this.View.CurrentProfile = this._configuration.CurrentProfile;
this.View.IconName = this._configuration.IconName; this.View.IconName = this._configuration.IconName;
} }
private async void SaveApplicationSettings() private async void SaveApplicationSettings() {
{
this._configuration.MinimizeToTray = this.View.MinimizeToTray; this._configuration.MinimizeToTray = this.View.MinimizeToTray;
this._configuration.ThumbnailOpacity = (float)this.View.ThumbnailOpacity; this._configuration.ThumbnailOpacity = (float)this.View.ThumbnailOpacity;
@@ -146,7 +143,8 @@ namespace EveOPreview.Presenters
this._configuration.EnableClientLayoutTracking = this.View.EnableClientLayoutTracking; this._configuration.EnableClientLayoutTracking = this.View.EnableClientLayoutTracking;
this._configuration.HideActiveClientThumbnail = this.View.HideActiveClientThumbnail; this._configuration.HideActiveClientThumbnail = this.View.HideActiveClientThumbnail;
this._configuration.MinimizeInactiveClients = this.View.MinimizeInactiveClients; this._configuration.MinimizeInactiveClients = this.View.MinimizeInactiveClients;
this._configuration.WindowsAnimationStyle = ViewAnimationStyleConverter.Convert(this.View.WindowsAnimationStyle); this._configuration.WindowsAnimationStyle =
ViewAnimationStyleConverter.Convert(this.View.WindowsAnimationStyle);
this._configuration.ShowThumbnailsAlwaysOnTop = this.View.ShowThumbnailsAlwaysOnTop; this._configuration.ShowThumbnailsAlwaysOnTop = this.View.ShowThumbnailsAlwaysOnTop;
this._configuration.HideThumbnailsOnLostFocus = this.View.HideThumbnailsOnLostFocus; this._configuration.HideThumbnailsOnLostFocus = this.View.HideThumbnailsOnLostFocus;
this._configuration.EnablePerClientThumbnailLayouts = this.View.EnablePerClientThumbnailLayouts; this._configuration.EnablePerClientThumbnailLayouts = this.View.EnablePerClientThumbnailLayouts;
@@ -159,8 +157,7 @@ namespace EveOPreview.Presenters
this._configuration.OverlayLabelAnchor = ViewZoomAnchorConverter.Convert(this.View.OverlayLabelAnchor); this._configuration.OverlayLabelAnchor = ViewZoomAnchorConverter.Convert(this.View.OverlayLabelAnchor);
this._configuration.ShowThumbnailOverlays = this.View.ShowThumbnailOverlays; this._configuration.ShowThumbnailOverlays = this.View.ShowThumbnailOverlays;
if (this._configuration.ShowThumbnailFrames != this.View.ShowThumbnailFrames) if (this._configuration.ShowThumbnailFrames != this.View.ShowThumbnailFrames) {
{
this._configuration.ShowThumbnailFrames = this.View.ShowThumbnailFrames; this._configuration.ShowThumbnailFrames = this.View.ShowThumbnailFrames;
await this._mediator.Publish(new ThumbnailFrameSettingsUpdated()); await this._mediator.Publish(new ThumbnailFrameSettingsUpdated());
} }
@@ -176,6 +173,18 @@ namespace EveOPreview.Presenters
this._configuration.OverlayLabelColor = this.View.OverlayLabelColor; this._configuration.OverlayLabelColor = this.View.OverlayLabelColor;
this._configuration.OverlayLabelSize = this.View.OverlayLabelSize; this._configuration.OverlayLabelSize = this.View.OverlayLabelSize;
this._configuration.EnableThumbnailRegionSnipping = this.View.EnableThumbnailRegionSnipping;
this._configuration.DefaultThumbnailRegion = this.View.DefaultThumbnailRegion;
this._configuration.AvailableProfiles = this.View.AvailableProfiles;
this._configuration.CurrentProfile = this.View.CurrentProfile;
// Publish region settings update if they changed
if (this._configuration.EnableThumbnailRegionSnipping != this.View.EnableThumbnailRegionSnipping ||
this._configuration.DefaultThumbnailRegion != this.View.DefaultThumbnailRegion) {
await this._mediator.Publish(new ThumbnailRegionSettingsUpdated());
}
this._configuration.IconName = this.View.IconName; this._configuration.IconName = this.View.IconName;
this._configurationStorage.Save(); this._configurationStorage.Save();
@@ -185,15 +194,11 @@ namespace EveOPreview.Presenters
await this._mediator.Send(new SaveConfiguration()); await this._mediator.Send(new SaveConfiguration());
} }
public void AddThumbnails(IList<string> thumbnailTitles) {
public void AddThumbnails(IList<string> thumbnailTitles)
{
IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count); IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count);
lock (this._descriptionsCache) lock (this._descriptionsCache) {
{ foreach (string title in thumbnailTitles) {
foreach (string title in thumbnailTitles)
{
IThumbnailDescription description = this.CreateThumbnailDescription(title); IThumbnailDescription description = this.CreateThumbnailDescription(title);
this._descriptionsCache[title] = description; this._descriptionsCache[title] = description;
@@ -204,16 +209,12 @@ namespace EveOPreview.Presenters
this.View.AddThumbnails(descriptions); this.View.AddThumbnails(descriptions);
} }
public void RemoveThumbnails(IList<string> thumbnailTitles) public void RemoveThumbnails(IList<string> thumbnailTitles) {
{
IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count); IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count);
lock (this._descriptionsCache) lock (this._descriptionsCache) {
{ foreach (string title in thumbnailTitles) {
foreach (string title in thumbnailTitles) if (!this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description)) {
{
if (!this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description))
{
continue; continue;
} }
@@ -225,31 +226,26 @@ namespace EveOPreview.Presenters
this.View.RemoveThumbnails(descriptions); this.View.RemoveThumbnails(descriptions);
} }
private IThumbnailDescription CreateThumbnailDescription(string title) private IThumbnailDescription CreateThumbnailDescription(string title) {
{
bool isDisabled = this._configuration.IsThumbnailDisabled(title); bool isDisabled = this._configuration.IsThumbnailDisabled(title);
return new ThumbnailDescription(title, isDisabled); return new ThumbnailDescription(title, isDisabled);
} }
private async void UpdateThumbnailState(String title) private async void UpdateThumbnailState(String title) {
{ if (this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description)) {
if (this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description))
{
this._configuration.ToggleThumbnail(title, description.IsDisabled); this._configuration.ToggleThumbnail(title, description.IsDisabled);
} }
await this._mediator.Send(new SaveConfiguration()); await this._mediator.Send(new SaveConfiguration());
} }
public void UpdateThumbnailSize(Size size) public void UpdateThumbnailSize(Size size) {
{
this._suppressSizeNotifications = true; this._suppressSizeNotifications = true;
this.View.ThumbnailSize = size; this.View.ThumbnailSize = size;
this._suppressSizeNotifications = false; this._suppressSizeNotifications = false;
} }
private void OpenDocumentationLink() private void OpenDocumentationLink() {
{
// funtimes // funtimes
// https://brockallen.com/2016/09/24/process-start-for-urls-on-net-core/ // https://brockallen.com/2016/09/24/process-start-for-urls-on-net-core/
// https://github.com/dotnet/runtime/issues/17938 // https://github.com/dotnet/runtime/issues/17938
@@ -264,8 +260,7 @@ namespace EveOPreview.Presenters
#endif #endif
} }
private string GetApplicationVersion() private string GetApplicationVersion() {
{
Version version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version; Version version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version;
string target = "Windows"; string target = "Windows";
#if LINUX #if LINUX
@@ -274,8 +269,7 @@ namespace EveOPreview.Presenters
return $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision} {target}"; return $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision} {target}";
} }
private void ExitApplication() private void ExitApplication() {
{
this._exitApplication = true; this._exitApplication = true;
this.View.Close(); this.View.Close();
} }

View File

@@ -1,17 +1,13 @@
using EveOPreview.Configuration; using EveOPreview.Configuration;
namespace EveOPreview.View namespace EveOPreview.View {
{ static class ViewAnimationStyleConverter {
static class ViewAnimationStyleConverter public static AnimationStyle Convert(ViewAnimationStyle value) {
{
public static AnimationStyle Convert(ViewAnimationStyle value)
{
// Cheat based on fact that the order and byte values of both enums are the same // Cheat based on fact that the order and byte values of both enums are the same
return (AnimationStyle)((int)value); return (AnimationStyle)((int)value);
} }
public static ViewAnimationStyle Convert(AnimationStyle value) public static ViewAnimationStyle Convert(AnimationStyle value) {
{
// Cheat based on fact that the order and byte values of both enums are the same // Cheat based on fact that the order and byte values of both enums are the same
return (ViewAnimationStyle)((int)value); return (ViewAnimationStyle)((int)value);
} }

View File

@@ -1,17 +1,13 @@
using EveOPreview.Configuration; using EveOPreview.Configuration;
namespace EveOPreview.View namespace EveOPreview.View {
{ static class ViewZoomAnchorConverter {
static class ViewZoomAnchorConverter public static ZoomAnchor Convert(ViewZoomAnchor value) {
{
public static ZoomAnchor Convert(ViewZoomAnchor value)
{
// Cheat based on fact that the order and byte values of both enums are the same // Cheat based on fact that the order and byte values of both enums are the same
return (ZoomAnchor)((int)value); return (ZoomAnchor)((int)value);
} }
public static ViewZoomAnchor Convert(ZoomAnchor value) public static ViewZoomAnchor Convert(ZoomAnchor value) {
{
// Cheat based on fact that the order and byte values of both enums are the same // Cheat based on fact that the order and byte values of both enums are the same
return (ViewZoomAnchor)((int)value); return (ViewZoomAnchor)((int)value);
} }

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,100 +2,84 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using EveOPreview.Services.Interop; using EveOPreview.Services.Interop;
namespace EveOPreview.Services.Implementation namespace EveOPreview.Services.Implementation {
{ class DwmThumbnail : IDwmThumbnail {
class DwmThumbnail : IDwmThumbnail
{
#region Private fields #region Private fields
private readonly IWindowManager _windowManager; private readonly IWindowManager _windowManager;
private IntPtr _handle; private IntPtr _handle;
private DWM_THUMBNAIL_PROPERTIES _properties; private DWM_THUMBNAIL_PROPERTIES _properties;
#endregion #endregion
public DwmThumbnail(IWindowManager windowManager) public DwmThumbnail(IWindowManager windowManager) {
{
this._windowManager = windowManager; this._windowManager = windowManager;
this._handle = IntPtr.Zero; this._handle = IntPtr.Zero;
} }
public void Register(IntPtr destination, IntPtr source) public void Register(IntPtr destination, IntPtr source) {
{
this._properties = new DWM_THUMBNAIL_PROPERTIES(); this._properties = new DWM_THUMBNAIL_PROPERTIES();
this._properties.dwFlags = DWM_TNP_CONSTANTS.DWM_TNP_VISIBLE this._properties.dwFlags = DWM_TNP_CONSTANTS.DWM_TNP_VISIBLE + DWM_TNP_CONSTANTS.DWM_TNP_OPACITY +
+ DWM_TNP_CONSTANTS.DWM_TNP_OPACITY DWM_TNP_CONSTANTS.DWM_TNP_RECTDESTINATION +
+ DWM_TNP_CONSTANTS.DWM_TNP_RECTDESTINATION DWM_TNP_CONSTANTS.DWM_TNP_SOURCECLIENTAREAONLY;
+ DWM_TNP_CONSTANTS.DWM_TNP_SOURCECLIENTAREAONLY;
this._properties.opacity = 255; this._properties.opacity = 255;
this._properties.fVisible = true; this._properties.fVisible = true;
this._properties.fSourceClientAreaOnly = true; this._properties.fSourceClientAreaOnly = true;
this._properties.rcSource = new RECT(0, 0, 0, 0); // Initialize with empty source rect
if (!this._windowManager.IsCompositionEnabled) if (!this._windowManager.IsCompositionEnabled) {
{
return; return;
} }
try try {
{
this._handle = DwmNativeMethods.DwmRegisterThumbnail(destination, source); this._handle = DwmNativeMethods.DwmRegisterThumbnail(destination, source);
} } catch (ArgumentException) {
catch (ArgumentException)
{
// This exception is raised if the source client is already closed // This exception is raised if the source client is already closed
// Can happen on a really slow CPU's that the window is still being // Can happen on a really slow CPU's that the window is still being
// listed in the process list yet it already cannot be used as // listed in the process list yet it already cannot be used as
// a thumbnail source // a thumbnail source
this._handle = IntPtr.Zero; this._handle = IntPtr.Zero;
} } catch (COMException) {
catch (COMException)
{
// This exception is raised if DWM is suddenly not available // This exception is raised if DWM is suddenly not available
// (f.e. when switching between Windows user accounts) // (f.e. when switching between Windows user accounts)
this._handle = IntPtr.Zero; this._handle = IntPtr.Zero;
} }
} }
public void Unregister() public void Unregister() {
{ if ((!this._windowManager.IsCompositionEnabled) || (this._handle == IntPtr.Zero)) {
if ((!this._windowManager.IsCompositionEnabled) || (this._handle == IntPtr.Zero))
{
return; return;
} }
try try {
{
DwmNativeMethods.DwmUnregisterThumbnail(this._handle); DwmNativeMethods.DwmUnregisterThumbnail(this._handle);
} } catch (ArgumentException) {
catch (ArgumentException) } catch (COMException) {
{
}
catch (COMException)
{
// This exception is raised when DWM is not available for some reason // This exception is raised when DWM is not available for some reason
} }
} }
public void Move(int left, int top, int right, int bottom) public void Move(int left, int top, int right, int bottom) {
{
this._properties.rcDestination = new RECT(left, top, right, bottom); this._properties.rcDestination = new RECT(left, top, right, bottom);
} }
public void Update() public void SetSourceRegion(int left, int top, int right, int bottom) {
{ this._properties.rcSource = new RECT(left, top, right, bottom);
if ((!this._windowManager.IsCompositionEnabled) || (this._handle == IntPtr.Zero)) this._properties.dwFlags |= DWM_TNP_CONSTANTS.DWM_TNP_RECTSOURCE;
{ }
public void ClearSourceRegion() {
this._properties.dwFlags &= ~DWM_TNP_CONSTANTS.DWM_TNP_RECTSOURCE;
}
public void Update() {
if ((!this._windowManager.IsCompositionEnabled) || (this._handle == IntPtr.Zero)) {
return; return;
} }
try try {
{
DwmNativeMethods.DwmUpdateThumbnailProperties(this._handle, this._properties); DwmNativeMethods.DwmUpdateThumbnailProperties(this._handle, this._properties);
} } catch (ArgumentException) {
catch (ArgumentException)
{
// This exception will be thrown if the EVE client disappears while this method is running // This exception will be thrown if the EVE client disappears while this method is running
} } catch (COMException) {
catch (COMException)
{
// This exception is raised when DWM is not available for some reason // This exception is raised when DWM is not available for some reason
} }
} }

View File

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

View File

@@ -4,10 +4,8 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
namespace EveOPreview.Services.Implementation namespace EveOPreview.Services.Implementation {
{ sealed class ProcessMonitor : IProcessMonitor {
sealed class ProcessMonitor : IProcessMonitor
{
#region Private constants #region Private constants
private const string DEFAULT_PROCESS_NAME = "Uwow-64"; private const string DEFAULT_PROCESS_NAME = "Uwow-64";
private const string CURRENT_PROCESS_NAME = "EVE-O Preview"; private const string CURRENT_PROCESS_NAME = "EVE-O Preview";
@@ -20,8 +18,7 @@ namespace EveOPreview.Services.Implementation
private readonly HashSet<int> _trackedPids; // Change to HashSet for multiple PIDs private readonly HashSet<int> _trackedPids; // Change to HashSet for multiple PIDs
#endregion #endregion
public ProcessMonitor(IThumbnailConfiguration configuration) public ProcessMonitor(IThumbnailConfiguration configuration) {
{
this._processCache = new Dictionary<IntPtr, string>(512); this._processCache = new Dictionary<IntPtr, string>(512);
this._configuration = configuration; this._configuration = configuration;
this._trackedPids = new HashSet<int>(); // Initialize empty set this._trackedPids = new HashSet<int>(); // Initialize empty set
@@ -31,11 +28,9 @@ namespace EveOPreview.Services.Implementation
this._currentProcessInfo = new ProcessInfo(IntPtr.Zero, ""); this._currentProcessInfo = new ProcessInfo(IntPtr.Zero, "");
} }
private bool IsMonitoredProcess(string processName, int processId) private bool IsMonitoredProcess(string processName, int processId) {
{
// If we're tracking this specific PID, include it // If we're tracking this specific PID, include it
if (_trackedPids.Contains(processId)) if (_trackedPids.Contains(processId)) {
{
return true; return true;
} }
@@ -43,21 +38,17 @@ namespace EveOPreview.Services.Implementation
return _configuration.IsExecutableToPreview(processName); return _configuration.IsExecutableToPreview(processName);
} }
private IProcessInfo GetCurrentProcessInfo() private IProcessInfo GetCurrentProcessInfo() {
{
var currentProcess = Process.GetCurrentProcess(); var currentProcess = Process.GetCurrentProcess();
return new ProcessInfo(currentProcess.MainWindowHandle, currentProcess.MainWindowTitle); return new ProcessInfo(currentProcess.MainWindowHandle, currentProcess.MainWindowTitle);
} }
public IProcessInfo GetMainProcess() public IProcessInfo GetMainProcess() {
{ if (this._currentProcessInfo.Handle == IntPtr.Zero) {
if (this._currentProcessInfo.Handle == IntPtr.Zero)
{
var processInfo = this.GetCurrentProcessInfo(); var processInfo = this.GetCurrentProcessInfo();
// Are we initialized yet? // Are we initialized yet?
if (processInfo.Title != "") if (processInfo.Title != "") {
{
this._currentProcessInfo = processInfo; this._currentProcessInfo = processInfo;
} }
} }
@@ -65,39 +56,35 @@ namespace EveOPreview.Services.Implementation
return this._currentProcessInfo; return this._currentProcessInfo;
} }
public ICollection<IProcessInfo> GetAllProcesses() public ICollection<IProcessInfo> GetAllProcesses() {
{
ICollection<IProcessInfo> result = new List<IProcessInfo>(this._processCache.Count); ICollection<IProcessInfo> result = new List<IProcessInfo>(this._processCache.Count);
// TODO Lock list here just in case // TODO Lock list here just in case
foreach (KeyValuePair<IntPtr, string> entry in this._processCache) foreach (KeyValuePair<IntPtr, string> entry in this._processCache) {
{
result.Add(new ProcessInfo(entry.Key, entry.Value)); result.Add(new ProcessInfo(entry.Key, entry.Value));
} }
return result; return result;
} }
public void GetUpdatedProcesses(out ICollection<IProcessInfo> addedProcesses, out ICollection<IProcessInfo> updatedProcesses, out ICollection<IProcessInfo> removedProcesses) public void GetUpdatedProcesses(out ICollection<IProcessInfo> addedProcesses,
{ out ICollection<IProcessInfo> updatedProcesses,
out ICollection<IProcessInfo> removedProcesses) {
addedProcesses = new List<IProcessInfo>(16); addedProcesses = new List<IProcessInfo>(16);
updatedProcesses = new List<IProcessInfo>(16); updatedProcesses = new List<IProcessInfo>(16);
removedProcesses = new List<IProcessInfo>(16); removedProcesses = new List<IProcessInfo>(16);
IList<IntPtr> knownProcesses = new List<IntPtr>(this._processCache.Keys); IList<IntPtr> knownProcesses = new List<IntPtr>(this._processCache.Keys);
foreach (Process process in Process.GetProcesses()) foreach (Process process in Process.GetProcesses()) {
{
string processName = process.ProcessName; string processName = process.ProcessName;
int processId = process.Id; int processId = process.Id;
if (!this.IsMonitoredProcess(processName, processId)) if (!this.IsMonitoredProcess(processName, processId)) {
{
continue; continue;
} }
IntPtr mainWindowHandle = process.MainWindowHandle; IntPtr mainWindowHandle = process.MainWindowHandle;
if (mainWindowHandle == IntPtr.Zero) if (mainWindowHandle == IntPtr.Zero) {
{
continue; // No need to monitor non-visual processes continue; // No need to monitor non-visual processes
} }
@@ -113,17 +100,13 @@ namespace EveOPreview.Services.Implementation
this._processCache.TryGetValue(mainWindowHandle, out string cachedTitle); this._processCache.TryGetValue(mainWindowHandle, out string cachedTitle);
if (cachedTitle == null) if (cachedTitle == null) {
{
// This is a new process in the list // This is a new process in the list
this._processCache.Add(mainWindowHandle, mainWindowTitle); this._processCache.Add(mainWindowHandle, mainWindowTitle);
addedProcesses.Add(new ProcessInfo(mainWindowHandle, mainWindowTitle)); addedProcesses.Add(new ProcessInfo(mainWindowHandle, mainWindowTitle));
} } else {
else
{
// This is an already known process // This is an already known process
if (cachedTitle != mainWindowTitle) if (cachedTitle != mainWindowTitle) {
{
this._processCache[mainWindowHandle] = mainWindowTitle; this._processCache[mainWindowHandle] = mainWindowTitle;
updatedProcesses.Add(new ProcessInfo(mainWindowHandle, mainWindowTitle)); updatedProcesses.Add(new ProcessInfo(mainWindowHandle, mainWindowTitle));
} }
@@ -132,8 +115,7 @@ namespace EveOPreview.Services.Implementation
knownProcesses.Remove(mainWindowHandle); knownProcesses.Remove(mainWindowHandle);
} }
foreach (IntPtr index in knownProcesses) foreach (IntPtr index in knownProcesses) {
{
string title = this._processCache[index]; string title = this._processCache[index];
removedProcesses.Add(new ProcessInfo(index, title)); removedProcesses.Add(new ProcessInfo(index, title));
this._processCache.Remove(index); this._processCache.Remove(index);
@@ -141,34 +123,28 @@ namespace EveOPreview.Services.Implementation
} }
// Update to handle multiple PIDs // Update to handle multiple PIDs
public void SetTrackedPid(int pid) public void SetTrackedPid(int pid) {
{
if (pid == 0) // Special case: 0 means stop tracking all if (pid == 0) // Special case: 0 means stop tracking all
{ {
this._trackedPids.Clear(); this._trackedPids.Clear();
return; return;
} }
if (this._trackedPids.Contains(pid)) if (this._trackedPids.Contains(pid)) {
{
this._trackedPids.Remove(pid); // Toggle off if already tracking this._trackedPids.Remove(pid); // Toggle off if already tracking
} } else {
else
{
this._trackedPids.Add(pid); // Toggle on if not tracking this._trackedPids.Add(pid); // Toggle on if not tracking
} }
} }
// Update to return currently tracked PID (for compatibility) // Update to return currently tracked PID (for compatibility)
public int GetTrackedPid() public int GetTrackedPid() {
{
// Return the first tracked PID, or 0 if none // Return the first tracked PID, or 0 if none
return this._trackedPids.FirstOrDefault(); return this._trackedPids.FirstOrDefault();
} }
// Add method to get all tracked PIDs if needed // Add method to get all tracked PIDs if needed
public IReadOnlyCollection<int> GetTrackedPids() public IReadOnlyCollection<int> GetTrackedPids() {
{
return this._trackedPids; return this._trackedPids;
} }
} }

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,10 +1,8 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{ static class Gdi32NativeMethods {
static class Gdi32NativeMethods
{
public const int SRCCOPY = 13369376; public const int SRCCOPY = 13369376;
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
@@ -23,6 +21,7 @@ namespace EveOPreview.Services.Interop
public static extern bool DeleteObject(IntPtr hObject); public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjectSource, int nXSrc, int nYSrc, int dwRop); public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight,
IntPtr hObjectSource, int nXSrc, int nYSrc, int dwRop);
} }
} }

View File

@@ -1,17 +1,14 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
class MARGINS class MARGINS {
{
public int cxLeftWidth; public int cxLeftWidth;
public int cxRightWidth; public int cxRightWidth;
public int cyTopHeight; public int cyTopHeight;
public int cyBottomHeight; public int cyBottomHeight;
public MARGINS(int left, int top, int right, int bottom) public MARGINS(int left, int top, int right, int bottom) {
{
cxLeftWidth = left; cxLeftWidth = left;
cyTopHeight = top; cyTopHeight = top;
cxRightWidth = right; cxRightWidth = right;

View File

@@ -1,17 +1,14 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
struct RECT struct RECT {
{
public int Left; public int Left;
public int Top; public int Top;
public int Right; public int Right;
public int Bottom; public int Bottom;
public RECT(int left, int top, int right, int bottom) public RECT(int left, int top, int right, int bottom) {
{
this.Left = left; this.Left = left;
this.Top = top; this.Top = top;
this.Right = right; this.Right = right;

View File

@@ -1,10 +1,8 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{ static class User32NativeMethods {
static class User32NativeMethods
{
public const uint SPI_SETANIMATION = 0x0049; public const uint SPI_SETANIMATION = 0x0049;
public const uint SPI_GETANIMATION = 0x0048; public const uint SPI_GETANIMATION = 0x0048;
@@ -65,6 +63,7 @@ namespace EveOPreview.Services.Interop
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hdc); public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hdc);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern long SystemParametersInfo(long uAction, int lpvParam, ref ANIMATIONINFO uParam, int fuWinIni); public static extern long SystemParametersInfo(long uAction, int lpvParam, ref ANIMATIONINFO uParam,
int fuWinIni);
} }
} }

View File

@@ -1,11 +1,9 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace EveOPreview.Services.Interop namespace EveOPreview.Services.Interop {
{
// Definition for Window Placement Structure // Definition for Window Placement Structure
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
struct WINDOWPLACEMENT struct WINDOWPLACEMENT {
{
public int length; public int length;
public int flags; public int flags;
public int showCmd; public int showCmd;

View File

@@ -0,0 +1,71 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace EveOPreview.View.Implementation {
public partial class InputDialog : Form {
private TextBox _inputTextBox;
private Button _okButton;
private Button _cancelButton;
private Label _promptLabel;
public string InputText => _inputTextBox.Text;
public InputDialog(string title, string prompt) {
InitializeComponent();
this.Text = title;
_promptLabel.Text = prompt;
}
private void InitializeComponent() {
this._promptLabel = new Label();
this._inputTextBox = new TextBox();
this._okButton = new Button();
this._cancelButton = new Button();
this.SuspendLayout();
// Form
this.AcceptButton = this._okButton;
this.CancelButton = this._cancelButton;
this.ClientSize = new Size(300, 120);
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.StartPosition = FormStartPosition.CenterParent;
// Prompt Label
this._promptLabel.AutoSize = true;
this._promptLabel.Location = new Point(12, 15);
this._promptLabel.Size = new Size(35, 15);
this._promptLabel.Text = "Prompt:";
// Input TextBox
this._inputTextBox.Location = new Point(12, 35);
this._inputTextBox.Size = new Size(270, 23);
this._inputTextBox.TabIndex = 0;
// OK Button
this._okButton.DialogResult = DialogResult.OK;
this._okButton.Location = new Point(120, 70);
this._okButton.Size = new Size(75, 23);
this._okButton.TabIndex = 1;
this._okButton.Text = "OK";
// Cancel Button
this._cancelButton.DialogResult = DialogResult.Cancel;
this._cancelButton.Location = new Point(210, 70);
this._cancelButton.Size = new Size(75, 23);
this._cancelButton.TabIndex = 2;
this._cancelButton.Text = "Cancel";
// Controls
this.Controls.Add(this._promptLabel);
this.Controls.Add(this._inputTextBox);
this.Controls.Add(this._okButton);
this.Controls.Add(this._cancelButton);
this.ResumeLayout(false);
this.PerformLayout();
}
}
}

View File

@@ -3,10 +3,8 @@ using System.Drawing;
using EveOPreview.Configuration; using EveOPreview.Configuration;
using EveOPreview.Services; using EveOPreview.Services;
namespace EveOPreview.View namespace EveOPreview.View {
{ sealed class LiveThumbnailView : ThumbnailView {
sealed class LiveThumbnailView : ThumbnailView
{
#region Private fields #region Private fields
private IDwmThumbnail _thumbnail; private IDwmThumbnail _thumbnail;
private Point _startLocation; private Point _startLocation;
@@ -14,36 +12,53 @@ namespace EveOPreview.View
private IThumbnailConfiguration _config; private IThumbnailConfiguration _config;
#endregion #endregion
public LiveThumbnailView(IWindowManager windowManager, IThumbnailConfiguration config, IThumbnailManager thumbnailManager) public LiveThumbnailView(IWindowManager windowManager, IThumbnailConfiguration config,
: base(windowManager, config, thumbnailManager) IThumbnailManager thumbnailManager)
{ : base(windowManager, config, thumbnailManager) {
this._startLocation = new Point(0, 0); this._startLocation = new Point(0, 0);
this._endLocation = new Point(this.ClientSize); this._endLocation = new Point(this.ClientSize);
this._config = config; this._config = config;
} }
protected override void RefreshThumbnail(bool forceRefresh) protected override void RefreshThumbnail(bool forceRefresh) {
{
// To prevent flickering the old broken thumbnail is removed AFTER the new shiny one is created // To prevent flickering the old broken thumbnail is removed AFTER the new shiny one is created
IDwmThumbnail obsoleteThumbnail = forceRefresh ? this._thumbnail : null; IDwmThumbnail obsoleteThumbnail = forceRefresh ? this._thumbnail : null;
if ((this._thumbnail == null) || forceRefresh) if ((this._thumbnail == null) || forceRefresh) {
{
this.RegisterThumbnail(); this.RegisterThumbnail();
} }
obsoleteThumbnail?.Unregister(); obsoleteThumbnail?.Unregister();
} }
protected override void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop, int highlightWidthRight, int highlightWidthBottom, int highlightWidthLeft) protected override void ApplyRegionSettings() {
{ if (this._thumbnail == null)
return;
if (this._config.EnableThumbnailRegionSnipping) {
var region = this._config.GetThumbnailRegion(this.Title, this._config.DefaultThumbnailRegion);
if (region.Width > 0 && region.Height > 0) {
this._thumbnail.SetSourceRegion(region.Left, region.Top, region.Right, region.Bottom);
} else {
this._thumbnail.ClearSourceRegion();
}
} else {
this._thumbnail.ClearSourceRegion();
}
this._thumbnail.Update();
}
protected override void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop,
int highlightWidthRight, int highlightWidthBottom,
int highlightWidthLeft) {
var left = 0 + highlightWidthLeft; var left = 0 + highlightWidthLeft;
var top = 0 + highlightWidthTop; var top = 0 + highlightWidthTop;
var right = baseWidth - highlightWidthRight; var right = baseWidth - highlightWidthRight;
var bottom = baseHeight - highlightWidthBottom; var bottom = baseHeight - highlightWidthBottom;
if ((this._startLocation.X == left) && (this._startLocation.Y == top) && (this._endLocation.X == right) && (this._endLocation.Y == bottom)) if ((this._startLocation.X == left) && (this._startLocation.Y == top) && (this._endLocation.X == right) &&
{ (this._endLocation.Y == bottom)) {
return; // No update required return; // No update required
} }
this._startLocation = new Point(left, top); this._startLocation = new Point(left, top);
@@ -53,10 +68,10 @@ namespace EveOPreview.View
this._thumbnail.Update(); this._thumbnail.Update();
} }
private void RegisterThumbnail() private void RegisterThumbnail() {
{
this._thumbnail = this.WindowManager.GetLiveThumbnail(this.Handle, this.Id); this._thumbnail = this.WindowManager.GetLiveThumbnail(this.Handle, this.Id);
this._thumbnail.Move(this._startLocation.X, this._startLocation.Y, this._endLocation.X, this._endLocation.Y); this._thumbnail.Move(this._startLocation.X, this._startLocation.Y, this._endLocation.X,
this._endLocation.Y);
this._thumbnail.Update(); this._thumbnail.Update();
} }
} }

View File

@@ -1,10 +1,8 @@
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
namespace EveOPreview.View namespace EveOPreview.View {
{ partial class MainForm {
partial class MainForm
{
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
/// </summary> /// </summary>
@@ -14,10 +12,8 @@ namespace EveOPreview.View
/// 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);
@@ -29,8 +25,7 @@ namespace EveOPreview.View
/// 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() {
{
components = new System.ComponentModel.Container(); components = new System.ComponentModel.Container();
ToolStripMenuItem RestoreWindowMenuItem; ToolStripMenuItem RestoreWindowMenuItem;
ToolStripMenuItem ExitMenuItem; ToolStripMenuItem ExitMenuItem;
@@ -58,7 +53,8 @@ namespace EveOPreview.View
Label CreditMaintLabel; Label CreditMaintLabel;
Label DocumentationLinkLabel; Label DocumentationLinkLabel;
Label DescriptionLabel; Label DescriptionLabel;
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); System.ComponentModel.ComponentResourceManager resources =
new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
Label NameLabel; Label NameLabel;
AnimationStyleCombo = new ComboBox(); AnimationStyleCombo = new ComboBox();
MinimizeInactiveClientsCheckBox = new CheckBox(); MinimizeInactiveClientsCheckBox = new CheckBox();
@@ -110,6 +106,20 @@ namespace EveOPreview.View
EnableActiveClientHighlightCheckBox = new CheckBox(); EnableActiveClientHighlightCheckBox = new CheckBox();
ShowThumbnailOverlaysCheckBox = new CheckBox(); ShowThumbnailOverlaysCheckBox = new CheckBox();
ShowThumbnailFramesCheckBox = new CheckBox(); ShowThumbnailFramesCheckBox = new CheckBox();
EnableThumbnailRegionSnippingCheckBox = new CheckBox();
RegionLeftNumericEdit = new NumericUpDown();
RegionTopNumericEdit = new NumericUpDown();
RegionWidthNumericEdit = new NumericUpDown();
RegionHeightNumericEdit = new NumericUpDown();
RegionLeftLabel = new Label();
RegionTopLabel = new Label();
RegionWidthLabel = new Label();
RegionHeightLabel = new Label();
PickRegionButton = new Button();
ProfileComboBox = new ComboBox();
SaveProfileButton = new Button();
DeleteProfileButton = new Button();
ProfileLabel = new Label();
ThumbnailsList = new CheckedListBox(); ThumbnailsList = new CheckedListBox();
VersionLabel = new Label(); VersionLabel = new Label();
DocumentationLink = new LinkLabel(); DocumentationLink = new LinkLabel();
@@ -376,6 +386,20 @@ namespace EveOPreview.View
// ThumbnailSettingsPanel // ThumbnailSettingsPanel
// //
ThumbnailSettingsPanel.BorderStyle = BorderStyle.FixedSingle; ThumbnailSettingsPanel.BorderStyle = BorderStyle.FixedSingle;
ThumbnailSettingsPanel.Controls.Add(EnableThumbnailRegionSnippingCheckBox);
ThumbnailSettingsPanel.Controls.Add(RegionLeftLabel);
ThumbnailSettingsPanel.Controls.Add(RegionLeftNumericEdit);
ThumbnailSettingsPanel.Controls.Add(RegionTopLabel);
ThumbnailSettingsPanel.Controls.Add(RegionTopNumericEdit);
ThumbnailSettingsPanel.Controls.Add(RegionWidthLabel);
ThumbnailSettingsPanel.Controls.Add(RegionWidthNumericEdit);
ThumbnailSettingsPanel.Controls.Add(RegionHeightLabel);
ThumbnailSettingsPanel.Controls.Add(RegionHeightNumericEdit);
ThumbnailSettingsPanel.Controls.Add(PickRegionButton);
ThumbnailSettingsPanel.Controls.Add(ProfileLabel);
ThumbnailSettingsPanel.Controls.Add(ProfileComboBox);
ThumbnailSettingsPanel.Controls.Add(SaveProfileButton);
ThumbnailSettingsPanel.Controls.Add(DeleteProfileButton);
ThumbnailSettingsPanel.Controls.Add(ThumbnailSnapToGridCheckBox); ThumbnailSettingsPanel.Controls.Add(ThumbnailSnapToGridCheckBox);
ThumbnailSettingsPanel.Controls.Add(ThumbnailSnapToGridSizeYNumericEdit); ThumbnailSettingsPanel.Controls.Add(ThumbnailSnapToGridSizeYNumericEdit);
ThumbnailSettingsPanel.Controls.Add(SnapYLabel); ThumbnailSettingsPanel.Controls.Add(SnapYLabel);
@@ -395,10 +419,171 @@ namespace EveOPreview.View
ThumbnailSettingsPanel.Size = new Size(512, 399); ThumbnailSettingsPanel.Size = new Size(512, 399);
ThumbnailSettingsPanel.TabIndex = 19; ThumbnailSettingsPanel.TabIndex = 19;
// //
// EnableThumbnailRegionSnippingCheckBox
//
EnableThumbnailRegionSnippingCheckBox.AutoSize = true;
EnableThumbnailRegionSnippingCheckBox.Location = new Point(18, 270);
EnableThumbnailRegionSnippingCheckBox.Margin = new Padding(5, 6, 5, 6);
EnableThumbnailRegionSnippingCheckBox.Name = "EnableThumbnailRegionSnippingCheckBox";
EnableThumbnailRegionSnippingCheckBox.Size = new Size(280, 29);
EnableThumbnailRegionSnippingCheckBox.TabIndex = 40;
EnableThumbnailRegionSnippingCheckBox.Text = "Enable Region Snipping";
EnableThumbnailRegionSnippingCheckBox.UseVisualStyleBackColor = true;
EnableThumbnailRegionSnippingCheckBox.CheckedChanged += OptionChanged_Handler;
//
// RegionLeftLabel
//
RegionLeftLabel.AutoSize = true;
RegionLeftLabel.Location = new Point(13, 310);
RegionLeftLabel.Margin = new Padding(5, 0, 5, 0);
RegionLeftLabel.Name = "RegionLeftLabel";
RegionLeftLabel.Size = new Size(45, 25);
RegionLeftLabel.TabIndex = 41;
RegionLeftLabel.Text = "Left";
//
// RegionLeftNumericEdit
//
RegionLeftNumericEdit.BackColor = SystemColors.Window;
RegionLeftNumericEdit.BorderStyle = BorderStyle.FixedSingle;
RegionLeftNumericEdit.CausesValidation = false;
RegionLeftNumericEdit.Increment = new decimal(new int[] { 10, 0, 0, 0 });
RegionLeftNumericEdit.Location = new Point(93, 305);
RegionLeftNumericEdit.Margin = new Padding(5, 6, 5, 6);
RegionLeftNumericEdit.Maximum = new decimal(new int[] { 999999, 0, 0, 0 });
RegionLeftNumericEdit.Name = "RegionLeftNumericEdit";
RegionLeftNumericEdit.Size = new Size(80, 31);
RegionLeftNumericEdit.TabIndex = 42;
RegionLeftNumericEdit.ValueChanged += OptionChanged_Handler;
//
// RegionTopLabel
//
RegionTopLabel.AutoSize = true;
RegionTopLabel.Location = new Point(183, 308);
RegionTopLabel.Margin = new Padding(5, 0, 5, 0);
RegionTopLabel.Name = "RegionTopLabel";
RegionTopLabel.Size = new Size(42, 25);
RegionTopLabel.TabIndex = 43;
RegionTopLabel.Text = "Top";
//
// RegionTopNumericEdit
//
RegionTopNumericEdit.BackColor = SystemColors.Window;
RegionTopNumericEdit.BorderStyle = BorderStyle.FixedSingle;
RegionTopNumericEdit.CausesValidation = false;
RegionTopNumericEdit.Increment = new decimal(new int[] { 10, 0, 0, 0 });
RegionTopNumericEdit.Location = new Point(230, 305);
RegionTopNumericEdit.Margin = new Padding(5, 6, 5, 6);
RegionTopNumericEdit.Maximum = new decimal(new int[] { 999999, 0, 0, 0 });
RegionTopNumericEdit.Name = "RegionTopNumericEdit";
RegionTopNumericEdit.Size = new Size(80, 31);
RegionTopNumericEdit.TabIndex = 44;
RegionTopNumericEdit.ValueChanged += OptionChanged_Handler;
//
// RegionWidthLabel
//
RegionWidthLabel.AutoSize = true;
RegionWidthLabel.Location = new Point(13, 350);
RegionWidthLabel.Margin = new Padding(5, 0, 5, 0);
RegionWidthLabel.Name = "RegionWidthLabel";
RegionWidthLabel.Size = new Size(65, 25);
RegionWidthLabel.TabIndex = 45;
RegionWidthLabel.Text = "Width";
//
// RegionWidthNumericEdit
//
RegionWidthNumericEdit.BackColor = SystemColors.Window;
RegionWidthNumericEdit.BorderStyle = BorderStyle.FixedSingle;
RegionWidthNumericEdit.CausesValidation = false;
RegionWidthNumericEdit.Increment = new decimal(new int[] { 10, 0, 0, 0 });
RegionWidthNumericEdit.Location = new Point(93, 345);
RegionWidthNumericEdit.Margin = new Padding(5, 6, 5, 6);
RegionWidthNumericEdit.Maximum = new decimal(new int[] { 999999, 0, 0, 0 });
RegionWidthNumericEdit.Name = "RegionWidthNumericEdit";
RegionWidthNumericEdit.Size = new Size(80, 31);
RegionWidthNumericEdit.TabIndex = 46;
RegionWidthNumericEdit.ValueChanged += OptionChanged_Handler;
//
// RegionHeightLabel
//
RegionHeightLabel.AutoSize = true;
RegionHeightLabel.Location = new Point(183, 348);
RegionHeightLabel.Margin = new Padding(5, 0, 5, 0);
RegionHeightLabel.Name = "RegionHeightLabel";
RegionHeightLabel.Size = new Size(70, 25);
RegionHeightLabel.TabIndex = 47;
RegionHeightLabel.Text = "Height";
//
// RegionHeightNumericEdit
//
RegionHeightNumericEdit.BackColor = SystemColors.Window;
RegionHeightNumericEdit.BorderStyle = BorderStyle.FixedSingle;
RegionHeightNumericEdit.CausesValidation = false;
RegionHeightNumericEdit.Increment = new decimal(new int[] { 10, 0, 0, 0 });
RegionHeightNumericEdit.Location = new Point(230, 345);
RegionHeightNumericEdit.Margin = new Padding(5, 6, 5, 6);
RegionHeightNumericEdit.Maximum = new decimal(new int[] { 999999, 0, 0, 0 });
RegionHeightNumericEdit.Name = "RegionHeightNumericEdit";
RegionHeightNumericEdit.Size = new Size(80, 31);
RegionHeightNumericEdit.TabIndex = 48;
RegionHeightNumericEdit.ValueChanged += OptionChanged_Handler;
//
// PickRegionButton
//
PickRegionButton.Location = new Point(330, 305);
PickRegionButton.Margin = new Padding(5, 6, 5, 6);
PickRegionButton.Name = "PickRegionButton";
PickRegionButton.Size = new Size(120, 35);
PickRegionButton.TabIndex = 49;
PickRegionButton.Text = "Pick Region";
PickRegionButton.UseVisualStyleBackColor = true;
PickRegionButton.Click += PickRegionButton_Click;
//
// ProfileLabel
//
ProfileLabel.AutoSize = true;
ProfileLabel.Location = new Point(13, 270);
ProfileLabel.Margin = new Padding(5, 0, 5, 0);
ProfileLabel.Name = "ProfileLabel";
ProfileLabel.Size = new Size(55, 25);
ProfileLabel.TabIndex = 50;
ProfileLabel.Text = "Profile";
//
// ProfileComboBox
//
ProfileComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
ProfileComboBox.Location = new Point(93, 265);
ProfileComboBox.Margin = new Padding(5, 6, 5, 6);
ProfileComboBox.Name = "ProfileComboBox";
ProfileComboBox.Size = new Size(150, 33);
ProfileComboBox.TabIndex = 51;
ProfileComboBox.SelectedIndexChanged += ProfileComboBox_SelectedIndexChanged;
//
// SaveProfileButton
//
SaveProfileButton.Location = new Point(260, 265);
SaveProfileButton.Margin = new Padding(5, 6, 5, 6);
SaveProfileButton.Name = "SaveProfileButton";
SaveProfileButton.Size = new Size(80, 35);
SaveProfileButton.TabIndex = 52;
SaveProfileButton.Text = "Save";
SaveProfileButton.UseVisualStyleBackColor = true;
SaveProfileButton.Click += SaveProfileButton_Click;
//
// DeleteProfileButton
//
DeleteProfileButton.Location = new Point(360, 265);
DeleteProfileButton.Margin = new Padding(5, 6, 5, 6);
DeleteProfileButton.Name = "DeleteProfileButton";
DeleteProfileButton.Size = new Size(80, 35);
DeleteProfileButton.TabIndex = 53;
DeleteProfileButton.Text = "Delete";
DeleteProfileButton.UseVisualStyleBackColor = true;
DeleteProfileButton.Click += DeleteProfileButton_Click;
//
// ThumbnailSnapToGridCheckBox // ThumbnailSnapToGridCheckBox
// //
ThumbnailSnapToGridCheckBox.AutoSize = true; ThumbnailSnapToGridCheckBox.AutoSize = true;
ThumbnailSnapToGridCheckBox.Location = new Point(18, 200); ThumbnailSnapToGridCheckBox.Location = new Point(18, 320);
ThumbnailSnapToGridCheckBox.Margin = new Padding(5, 6, 5, 6); ThumbnailSnapToGridCheckBox.Margin = new Padding(5, 6, 5, 6);
ThumbnailSnapToGridCheckBox.Name = "ThumbnailSnapToGridCheckBox"; ThumbnailSnapToGridCheckBox.Name = "ThumbnailSnapToGridCheckBox";
ThumbnailSnapToGridCheckBox.Size = new Size(226, 29); ThumbnailSnapToGridCheckBox.Size = new Size(226, 29);
@@ -413,7 +598,7 @@ namespace EveOPreview.View
ThumbnailSnapToGridSizeYNumericEdit.BorderStyle = BorderStyle.FixedSingle; ThumbnailSnapToGridSizeYNumericEdit.BorderStyle = BorderStyle.FixedSingle;
ThumbnailSnapToGridSizeYNumericEdit.CausesValidation = false; ThumbnailSnapToGridSizeYNumericEdit.CausesValidation = false;
ThumbnailSnapToGridSizeYNumericEdit.Increment = new decimal(new int[] { 10, 0, 0, 0 }); ThumbnailSnapToGridSizeYNumericEdit.Increment = new decimal(new int[] { 10, 0, 0, 0 });
ThumbnailSnapToGridSizeYNumericEdit.Location = new Point(217, 235); ThumbnailSnapToGridSizeYNumericEdit.Location = new Point(217, 355);
ThumbnailSnapToGridSizeYNumericEdit.Margin = new Padding(5, 6, 5, 6); ThumbnailSnapToGridSizeYNumericEdit.Margin = new Padding(5, 6, 5, 6);
ThumbnailSnapToGridSizeYNumericEdit.Maximum = new decimal(new int[] { 999999, 0, 0, 0 }); ThumbnailSnapToGridSizeYNumericEdit.Maximum = new decimal(new int[] { 999999, 0, 0, 0 });
ThumbnailSnapToGridSizeYNumericEdit.Name = "ThumbnailSnapToGridSizeYNumericEdit"; ThumbnailSnapToGridSizeYNumericEdit.Name = "ThumbnailSnapToGridSizeYNumericEdit";
@@ -425,7 +610,7 @@ namespace EveOPreview.View
// SnapYLabel // SnapYLabel
// //
SnapYLabel.AutoSize = true; SnapYLabel.AutoSize = true;
SnapYLabel.Location = new Point(183, 238); SnapYLabel.Location = new Point(183, 358);
SnapYLabel.Margin = new Padding(5, 0, 5, 0); SnapYLabel.Margin = new Padding(5, 0, 5, 0);
SnapYLabel.Name = "SnapYLabel"; SnapYLabel.Name = "SnapYLabel";
SnapYLabel.Size = new Size(22, 25); SnapYLabel.Size = new Size(22, 25);
@@ -438,7 +623,7 @@ namespace EveOPreview.View
ThumbnailSnapToGridSizeXNumericEdit.BorderStyle = BorderStyle.FixedSingle; ThumbnailSnapToGridSizeXNumericEdit.BorderStyle = BorderStyle.FixedSingle;
ThumbnailSnapToGridSizeXNumericEdit.CausesValidation = false; ThumbnailSnapToGridSizeXNumericEdit.CausesValidation = false;
ThumbnailSnapToGridSizeXNumericEdit.Increment = new decimal(new int[] { 10, 0, 0, 0 }); ThumbnailSnapToGridSizeXNumericEdit.Increment = new decimal(new int[] { 10, 0, 0, 0 });
ThumbnailSnapToGridSizeXNumericEdit.Location = new Point(93, 235); ThumbnailSnapToGridSizeXNumericEdit.Location = new Point(93, 355);
ThumbnailSnapToGridSizeXNumericEdit.Margin = new Padding(5, 6, 5, 6); ThumbnailSnapToGridSizeXNumericEdit.Margin = new Padding(5, 6, 5, 6);
ThumbnailSnapToGridSizeXNumericEdit.Maximum = new decimal(new int[] { 999999, 0, 0, 0 }); ThumbnailSnapToGridSizeXNumericEdit.Maximum = new decimal(new int[] { 999999, 0, 0, 0 });
ThumbnailSnapToGridSizeXNumericEdit.Name = "ThumbnailSnapToGridSizeXNumericEdit"; ThumbnailSnapToGridSizeXNumericEdit.Name = "ThumbnailSnapToGridSizeXNumericEdit";
@@ -450,7 +635,7 @@ namespace EveOPreview.View
// SnapXLabel // SnapXLabel
// //
SnapXLabel.AutoSize = true; SnapXLabel.AutoSize = true;
SnapXLabel.Location = new Point(13, 238); SnapXLabel.Location = new Point(13, 358);
SnapXLabel.Margin = new Padding(5, 0, 5, 0); SnapXLabel.Margin = new Padding(5, 0, 5, 0);
SnapXLabel.Name = "SnapXLabel"; SnapXLabel.Name = "SnapXLabel";
SnapXLabel.Size = new Size(68, 25); SnapXLabel.Size = new Size(68, 25);
@@ -1163,7 +1348,8 @@ namespace EveOPreview.View
DocumentationLink.Size = new Size(437, 63); DocumentationLink.Size = new Size(437, 63);
DocumentationLink.TabIndex = 2; DocumentationLink.TabIndex = 2;
DocumentationLink.TabStop = true; DocumentationLink.TabStop = true;
DocumentationLink.Text = "to be set from prresenter to be set from prresenter to be set from prresenter to be set from prresenter"; DocumentationLink.Text =
"to be set from prresenter to be set from prresenter to be set from prresenter to be set from prresenter";
DocumentationLink.LinkClicked += DocumentationLinkClicked_Handler; DocumentationLink.LinkClicked += DocumentationLinkClicked_Handler;
// //
// NotifyIcon // NotifyIcon
@@ -1177,7 +1363,8 @@ namespace EveOPreview.View
// TrayMenu // TrayMenu
// //
TrayMenu.ImageScalingSize = new Size(24, 24); TrayMenu.ImageScalingSize = new Size(24, 24);
TrayMenu.Items.AddRange(new ToolStripItem[] { TitleMenuItem, RestoreWindowMenuItem, SeparatorMenuItem, ExitMenuItem }); TrayMenu.Items.AddRange(
new ToolStripItem[] { TitleMenuItem, RestoreWindowMenuItem, SeparatorMenuItem, ExitMenuItem });
TrayMenu.Name = "contextMenuStrip1"; TrayMenu.Name = "contextMenuStrip1";
TrayMenu.Size = new Size(202, 106); TrayMenu.Size = new Size(202, 106);
// //
@@ -1230,7 +1417,6 @@ namespace EveOPreview.View
AboutPanel.PerformLayout(); AboutPanel.PerformLayout();
TrayMenu.ResumeLayout(false); TrayMenu.ResumeLayout(false);
ResumeLayout(false); ResumeLayout(false);
} }
#endregion #endregion
@@ -1273,6 +1459,20 @@ namespace EveOPreview.View
private NumericUpDown ThumbnailSnapToGridSizeXNumericEdit; private NumericUpDown ThumbnailSnapToGridSizeXNumericEdit;
private Label SnapXLabel; private Label SnapXLabel;
private CheckBox ThumbnailSnapToGridCheckBox; private CheckBox ThumbnailSnapToGridCheckBox;
private CheckBox EnableThumbnailRegionSnippingCheckBox;
private NumericUpDown RegionLeftNumericEdit;
private NumericUpDown RegionTopNumericEdit;
private NumericUpDown RegionWidthNumericEdit;
private NumericUpDown RegionHeightNumericEdit;
private Label RegionLeftLabel;
private Label RegionTopLabel;
private Label RegionWidthLabel;
private Label RegionHeightLabel;
private Button PickRegionButton;
private ComboBox ProfileComboBox;
private Button SaveProfileButton;
private Button DeleteProfileButton;
private Label ProfileLabel;
private Label label3; private Label label3;
private Label label2; private Label label2;
private Panel OverlayLabelColorButton; private Panel OverlayLabelColorButton;

View File

@@ -7,11 +7,10 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Windows.Forms; using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement; using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using EveOPreview.View.Implementation;
namespace EveOPreview.View namespace EveOPreview.View {
{ public partial class MainForm : Form, IMainFormView {
public partial class MainForm : Form, IMainFormView
{
#region Private fields #region Private fields
private readonly ApplicationContext _context; private readonly ApplicationContext _context;
private readonly Dictionary<ViewZoomAnchor, RadioButton> _zoomAnchorMap; private readonly Dictionary<ViewZoomAnchor, RadioButton> _zoomAnchorMap;
@@ -24,8 +23,7 @@ namespace EveOPreview.View
private string _iconName; private string _iconName;
#endregion #endregion
public MainForm(ApplicationContext context) public MainForm(ApplicationContext context) {
{
this._context = context; this._context = context;
this._zoomAnchorMap = new Dictionary<ViewZoomAnchor, RadioButton>(); this._zoomAnchorMap = new Dictionary<ViewZoomAnchor, RadioButton>();
this._overlayLabelMap = new Dictionary<ViewZoomAnchor, RadioButton>(); this._overlayLabelMap = new Dictionary<ViewZoomAnchor, RadioButton>();
@@ -45,61 +43,47 @@ namespace EveOPreview.View
this.AnimationStyleCombo.DataSource = Enum.GetValues(typeof(AnimationStyle)); this.AnimationStyleCombo.DataSource = Enum.GetValues(typeof(AnimationStyle));
} }
public bool MinimizeToTray public bool MinimizeToTray {
{
get => this.MinimizeToTrayCheckBox.Checked; get => this.MinimizeToTrayCheckBox.Checked;
set => this.MinimizeToTrayCheckBox.Checked = value; set => this.MinimizeToTrayCheckBox.Checked = value;
} }
public string IconName public string IconName {
{
get => this._iconName; get => this._iconName;
set { set {
this._iconName = value; this._iconName = value;
// Set Icon // Set Icon
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); System.ComponentModel.ComponentResourceManager resources =
if (this._iconName == null || ((resources.GetObject(this._iconName))) == null) new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
{ if (this._iconName == null || ((resources.GetObject(this._iconName))) == null) {
this._iconName = "IconOriginal"; this._iconName = "IconOriginal";
} }
// pull icon from resources // pull icon from resources
try try {
{
var iconBytes = (byte[])resources.GetObject(this._iconName); var iconBytes = (byte[])resources.GetObject(this._iconName);
using (MemoryStream ms = new MemoryStream(iconBytes)) using (MemoryStream ms = new MemoryStream(iconBytes)) {
{
this.Icon = new Icon(ms); this.Icon = new Icon(ms);
this.NotifyIcon.Icon = this.Icon; this.NotifyIcon.Icon = this.Icon;
} }
} } catch (Exception) {
catch (Exception ex)
{
// Log ? // Log ?
} }
if (value != "") if (value != "") {
{
this.ApplicationSettingsChanged?.Invoke(); this.ApplicationSettingsChanged?.Invoke();
} }
} }
} }
public double ThumbnailOpacity public double ThumbnailOpacity {
{
get => Math.Min(this.ThumbnailOpacityTrackBar.Value / 100.00, 1.00); get => Math.Min(this.ThumbnailOpacityTrackBar.Value / 100.00, 1.00);
set set {
{
int barValue = (int)(100.0 * value); int barValue = (int)(100.0 * value);
if (barValue > 100) if (barValue > 100) {
{
barValue = 100; barValue = 100;
} } else if (barValue < 10) {
else if (barValue < 10)
{
barValue = 10; barValue = 10;
} }
@@ -107,86 +91,69 @@ namespace EveOPreview.View
} }
} }
public bool EnableClientLayoutTracking public bool EnableClientLayoutTracking {
{
get => this.EnableClientLayoutTrackingCheckBox.Checked; get => this.EnableClientLayoutTrackingCheckBox.Checked;
set => this.EnableClientLayoutTrackingCheckBox.Checked = value; set => this.EnableClientLayoutTrackingCheckBox.Checked = value;
} }
public bool HideActiveClientThumbnail public bool HideActiveClientThumbnail {
{
get => this.HideActiveClientThumbnailCheckBox.Checked; get => this.HideActiveClientThumbnailCheckBox.Checked;
set => this.HideActiveClientThumbnailCheckBox.Checked = value; set => this.HideActiveClientThumbnailCheckBox.Checked = value;
} }
public bool MinimizeInactiveClients public bool MinimizeInactiveClients {
{
get => this.MinimizeInactiveClientsCheckBox.Checked; get => this.MinimizeInactiveClientsCheckBox.Checked;
set => this.MinimizeInactiveClientsCheckBox.Checked = value; set => this.MinimizeInactiveClientsCheckBox.Checked = value;
} }
public ViewAnimationStyle WindowsAnimationStyle public ViewAnimationStyle WindowsAnimationStyle {
{
get => (ViewAnimationStyle)this.AnimationStyleCombo.SelectedItem; get => (ViewAnimationStyle)this.AnimationStyleCombo.SelectedItem;
set => this.AnimationStyleCombo.SelectedIndex = (int)value; set => this.AnimationStyleCombo.SelectedIndex = (int)value;
} }
public bool ShowThumbnailsAlwaysOnTop public bool ShowThumbnailsAlwaysOnTop {
{
get => this.ShowThumbnailsAlwaysOnTopCheckBox.Checked; get => this.ShowThumbnailsAlwaysOnTopCheckBox.Checked;
set => this.ShowThumbnailsAlwaysOnTopCheckBox.Checked = value; set => this.ShowThumbnailsAlwaysOnTopCheckBox.Checked = value;
} }
public bool HideThumbnailsOnLostFocus public bool HideThumbnailsOnLostFocus {
{
get => this.HideThumbnailsOnLostFocusCheckBox.Checked; get => this.HideThumbnailsOnLostFocusCheckBox.Checked;
set => this.HideThumbnailsOnLostFocusCheckBox.Checked = value; set => this.HideThumbnailsOnLostFocusCheckBox.Checked = value;
} }
public bool EnablePerClientThumbnailLayouts public bool EnablePerClientThumbnailLayouts {
{
get => this.EnablePerClientThumbnailsLayoutsCheckBox.Checked; get => this.EnablePerClientThumbnailsLayoutsCheckBox.Checked;
set => this.EnablePerClientThumbnailsLayoutsCheckBox.Checked = value; set => this.EnablePerClientThumbnailsLayoutsCheckBox.Checked = value;
} }
public Size ThumbnailSize public Size ThumbnailSize {
{
get => new Size((int)this.ThumbnailsWidthNumericEdit.Value, (int)this.ThumbnailsHeightNumericEdit.Value); get => new Size((int)this.ThumbnailsWidthNumericEdit.Value, (int)this.ThumbnailsHeightNumericEdit.Value);
set set {
{
this.ThumbnailsWidthNumericEdit.Value = value.Width; this.ThumbnailsWidthNumericEdit.Value = value.Width;
this.ThumbnailsHeightNumericEdit.Value = value.Height; this.ThumbnailsHeightNumericEdit.Value = value.Height;
} }
} }
public bool EnableThumbnailZoom public bool EnableThumbnailZoom {
{
get => this.EnableThumbnailZoomCheckBox.Checked; get => this.EnableThumbnailZoomCheckBox.Checked;
set set {
{
this.EnableThumbnailZoomCheckBox.Checked = value; this.EnableThumbnailZoomCheckBox.Checked = value;
this.RefreshZoomSettings(); this.RefreshZoomSettings();
} }
} }
public int ThumbnailZoomFactor public int ThumbnailZoomFactor {
{
get => (int)this.ThumbnailZoomFactorNumericEdit.Value; get => (int)this.ThumbnailZoomFactorNumericEdit.Value;
set => this.ThumbnailZoomFactorNumericEdit.Value = value; set => this.ThumbnailZoomFactorNumericEdit.Value = value;
} }
public ViewZoomAnchor ThumbnailZoomAnchor public ViewZoomAnchor ThumbnailZoomAnchor {
{ get {
get if (this._zoomAnchorMap[this._cachedThumbnailZoomAnchor].Checked) {
{
if (this._zoomAnchorMap[this._cachedThumbnailZoomAnchor].Checked)
{
return this._cachedThumbnailZoomAnchor; return this._cachedThumbnailZoomAnchor;
} }
foreach (KeyValuePair<ViewZoomAnchor, RadioButton> valuePair in this._zoomAnchorMap) foreach (KeyValuePair<ViewZoomAnchor, RadioButton> valuePair in this._zoomAnchorMap) {
{ if (!valuePair.Value.Checked) {
if (!valuePair.Value.Checked)
{
continue; continue;
} }
@@ -197,26 +164,20 @@ namespace EveOPreview.View
// Default value // Default value
return ViewZoomAnchor.NW; return ViewZoomAnchor.NW;
} }
set set {
{
this._cachedThumbnailZoomAnchor = value; this._cachedThumbnailZoomAnchor = value;
this._zoomAnchorMap[this._cachedThumbnailZoomAnchor].Checked = true; this._zoomAnchorMap[this._cachedThumbnailZoomAnchor].Checked = true;
} }
} }
public ViewZoomAnchor OverlayLabelAnchor public ViewZoomAnchor OverlayLabelAnchor {
{ get {
get if (this._overlayLabelMap[this._cachedOverlayLabelAnchor].Checked) {
{
if (this._overlayLabelMap[this._cachedOverlayLabelAnchor].Checked)
{
return this._cachedOverlayLabelAnchor; return this._cachedOverlayLabelAnchor;
} }
foreach (KeyValuePair<ViewZoomAnchor, RadioButton> valuePair in this._overlayLabelMap) foreach (KeyValuePair<ViewZoomAnchor, RadioButton> valuePair in this._overlayLabelMap) {
{ if (!valuePair.Value.Checked) {
if (!valuePair.Value.Checked)
{
continue; continue;
} }
@@ -227,84 +188,141 @@ namespace EveOPreview.View
// Default Value // Default Value
return ViewZoomAnchor.NW; return ViewZoomAnchor.NW;
} }
set set {
{
this._cachedOverlayLabelAnchor = value; this._cachedOverlayLabelAnchor = value;
this._overlayLabelMap[this._cachedOverlayLabelAnchor].Checked = true; this._overlayLabelMap[this._cachedOverlayLabelAnchor].Checked = true;
} }
} }
public bool ShowThumbnailOverlays public bool ShowThumbnailOverlays {
{
get => this.ShowThumbnailOverlaysCheckBox.Checked; get => this.ShowThumbnailOverlaysCheckBox.Checked;
set => this.ShowThumbnailOverlaysCheckBox.Checked = value; set => this.ShowThumbnailOverlaysCheckBox.Checked = value;
} }
public bool ShowThumbnailFrames public bool ShowThumbnailFrames {
{
get => this.ShowThumbnailFramesCheckBox.Checked; get => this.ShowThumbnailFramesCheckBox.Checked;
set => this.ShowThumbnailFramesCheckBox.Checked = value; set => this.ShowThumbnailFramesCheckBox.Checked = value;
} }
public bool LockThumbnailLocation public bool LockThumbnailLocation {
{
get => this.LockThumbnailLocationCheckbox.Checked; get => this.LockThumbnailLocationCheckbox.Checked;
set => this.LockThumbnailLocationCheckbox.Checked = value; set => this.LockThumbnailLocationCheckbox.Checked = value;
} }
public bool ThumbnailSnapToGrid public bool ThumbnailSnapToGrid {
{
get => this.ThumbnailSnapToGridCheckBox.Checked; get => this.ThumbnailSnapToGridCheckBox.Checked;
set => this.ThumbnailSnapToGridCheckBox.Checked = value; set => this.ThumbnailSnapToGridCheckBox.Checked = value;
} }
public int ThumbnailSnapToGridSizeX public int ThumbnailSnapToGridSizeX {
{
get => (int)ThumbnailSnapToGridSizeXNumericEdit.Value; get => (int)ThumbnailSnapToGridSizeXNumericEdit.Value;
set => ThumbnailSnapToGridSizeXNumericEdit.Value = value; set => ThumbnailSnapToGridSizeXNumericEdit.Value = value;
} }
public int ThumbnailSnapToGridSizeY public int ThumbnailSnapToGridSizeY {
{
get => (int)ThumbnailSnapToGridSizeYNumericEdit.Value; get => (int)ThumbnailSnapToGridSizeYNumericEdit.Value;
set => ThumbnailSnapToGridSizeYNumericEdit.Value = value; set => ThumbnailSnapToGridSizeYNumericEdit.Value = value;
} }
public bool EnableActiveClientHighlight public bool EnableActiveClientHighlight {
{
get => this.EnableActiveClientHighlightCheckBox.Checked; get => this.EnableActiveClientHighlightCheckBox.Checked;
set => this.EnableActiveClientHighlightCheckBox.Checked = value; set => this.EnableActiveClientHighlightCheckBox.Checked = value;
} }
public Color ActiveClientHighlightColor public Color ActiveClientHighlightColor {
{
get => this._activeClientHighlightColor; get => this._activeClientHighlightColor;
set set {
{
this._activeClientHighlightColor = value; this._activeClientHighlightColor = value;
this.ActiveClientHighlightColorButton.BackColor = value; this.ActiveClientHighlightColorButton.BackColor = value;
} }
} }
private Color _activeClientHighlightColor; private Color _activeClientHighlightColor;
public Color OverlayLabelColor public Color OverlayLabelColor {
{
get => this._OverlayLabelColor; get => this._OverlayLabelColor;
set set {
{
this._OverlayLabelColor = value; this._OverlayLabelColor = value;
this.OverlayLabelColorButton.BackColor = value; this.OverlayLabelColorButton.BackColor = value;
} }
} }
private Color _OverlayLabelColor; private Color _OverlayLabelColor;
public int OverlayLabelSize public int OverlayLabelSize {
{
get => (int)this.OverlayLabelSizeNumericEdit.Value; get => (int)this.OverlayLabelSizeNumericEdit.Value;
set set => this.OverlayLabelSizeNumericEdit.Value = value;
{ }
this.OverlayLabelSizeNumericEdit.Value = value;
public bool EnableThumbnailRegionSnipping {
get => this.EnableThumbnailRegionSnippingCheckBox.Checked;
set => this.EnableThumbnailRegionSnippingCheckBox.Checked = value;
}
public Rectangle DefaultThumbnailRegion {
get => new Rectangle((int)this.RegionLeftNumericEdit.Value, (int)this.RegionTopNumericEdit.Value,
(int)this.RegionWidthNumericEdit.Value, (int)this.RegionHeightNumericEdit.Value);
set {
this.RegionLeftNumericEdit.Value = value.Left;
this.RegionTopNumericEdit.Value = value.Top;
this.RegionWidthNumericEdit.Value = value.Width;
this.RegionHeightNumericEdit.Value = value.Height;
} }
} }
public new void Show()
{ private void PickRegionButton_Click(object sender, EventArgs e) {
// Registers the current instance as the application's Main Form using (var picker = new RegionPickerDialog()) {
if (picker.ShowDialog() == DialogResult.OK) {
var region = picker.SelectedRegion;
this.DefaultThumbnailRegion = region;
this.ApplicationSettingsChanged?.Invoke();
}
}
}
public string CurrentProfile {
get => this.ProfileComboBox.Text;
set {
if (this.ProfileComboBox.Items.Contains(value)) {
this.ProfileComboBox.SelectedItem = value;
}
}
}
public List<string> AvailableProfiles {
get => this.ProfileComboBox.Items.Cast<string>().ToList();
set {
this.ProfileComboBox.Items.Clear();
foreach (var profile in value) {
this.ProfileComboBox.Items.Add(profile);
}
}
}
private void ProfileComboBox_SelectedIndexChanged(object sender, EventArgs e) {
if (!this._suppressEvents) {
this.ApplicationSettingsChanged?.Invoke();
}
}
private void SaveProfileButton_Click(object sender, EventArgs e) {
using (var inputDialog = new InputDialog("Save Profile", "Enter profile name:")) {
if (inputDialog.ShowDialog() == DialogResult.OK) {
string profileName = inputDialog.InputText;
if (!string.IsNullOrWhiteSpace(profileName)) {
this.ProfileComboBox.Items.Add(profileName);
this.ProfileComboBox.SelectedItem = profileName;
this.ApplicationSettingsChanged?.Invoke();
}
}
}
}
private void DeleteProfileButton_Click(object sender, EventArgs e) {
if (this.ProfileComboBox.SelectedItem != null) {
string selectedProfile = this.ProfileComboBox.SelectedItem.ToString();
if (selectedProfile != "Default") {
this.ProfileComboBox.Items.Remove(selectedProfile);
this.ApplicationSettingsChanged?.Invoke();
}
}
}
public new void Show() {// Registers the current instance as the application's Main Form
this._context.MainForm = this; this._context.MainForm = this;
this._suppressEvents = true; this._suppressEvents = true;
@@ -314,53 +332,44 @@ namespace EveOPreview.View
Application.Run(this._context); Application.Run(this._context);
} }
public void SetThumbnailSizeLimitations(Size minimumSize, Size maximumSize) public void SetThumbnailSizeLimitations(Size minimumSize, Size maximumSize) {
{
this._minimumSize = minimumSize; this._minimumSize = minimumSize;
this._maximumSize = maximumSize; this._maximumSize = maximumSize;
} }
public void Minimize() public void Minimize() {
{
this.WindowState = FormWindowState.Minimized; this.WindowState = FormWindowState.Minimized;
} }
public void SetVersionInfo(string version) public void SetVersionInfo(string version) {
{
this.VersionLabel.Text = version; this.VersionLabel.Text = version;
} }
public void SetDocumentationUrl(string url) public void SetDocumentationUrl(string url) {
{
this.DocumentationLink.Text = url; this.DocumentationLink.Text = url;
} }
public void AddThumbnails(IList<IThumbnailDescription> thumbnails) public void AddThumbnails(IList<IThumbnailDescription> thumbnails) {
{
this.ThumbnailsList.BeginUpdate(); this.ThumbnailsList.BeginUpdate();
foreach (IThumbnailDescription view in thumbnails) foreach (IThumbnailDescription view in thumbnails) {
{
this.ThumbnailsList.SetItemChecked(this.ThumbnailsList.Items.Add(view), view.IsDisabled); this.ThumbnailsList.SetItemChecked(this.ThumbnailsList.Items.Add(view), view.IsDisabled);
} }
this.ThumbnailsList.EndUpdate(); this.ThumbnailsList.EndUpdate();
} }
public void RemoveThumbnails(IList<IThumbnailDescription> thumbnails) public void RemoveThumbnails(IList<IThumbnailDescription> thumbnails) {
{
this.ThumbnailsList.BeginUpdate(); this.ThumbnailsList.BeginUpdate();
foreach (IThumbnailDescription view in thumbnails) foreach (IThumbnailDescription view in thumbnails) {
{
this.ThumbnailsList.Items.Remove(view); this.ThumbnailsList.Items.Remove(view);
} }
this.ThumbnailsList.EndUpdate(); this.ThumbnailsList.EndUpdate();
} }
public void RefreshZoomSettings() public void RefreshZoomSettings() {
{
bool enableControls = this.EnableThumbnailZoom; bool enableControls = this.EnableThumbnailZoom;
this.ThumbnailZoomFactorNumericEdit.Enabled = enableControls; this.ThumbnailZoomFactorNumericEdit.Enabled = enableControls;
this.ZoomAnchorPanel.Enabled = enableControls; this.ZoomAnchorPanel.Enabled = enableControls;
@@ -383,8 +392,7 @@ namespace EveOPreview.View
public Action DocumentationLinkActivated { get; set; } public Action DocumentationLinkActivated { get; set; }
#region UI events #region UI events
private void ContentTabControl_DrawItem(object sender, DrawItemEventArgs e) private void ContentTabControl_DrawItem(object sender, DrawItemEventArgs e) {
{
TabControl control = (TabControl)sender; TabControl control = (TabControl)sender;
TabPage page = control.TabPages[e.Index]; TabPage page = control.TabPages[e.Index];
Rectangle bounds = control.GetTabRect(e.Index); Rectangle bounds = control.GetTabRect(e.Index);
@@ -392,8 +400,7 @@ namespace EveOPreview.View
Graphics graphics = e.Graphics; Graphics graphics = e.Graphics;
Brush textBrush = new SolidBrush(SystemColors.ActiveCaptionText); Brush textBrush = new SolidBrush(SystemColors.ActiveCaptionText);
Brush backgroundBrush = (e.State == DrawItemState.Selected) Brush backgroundBrush = (e.State == DrawItemState.Selected) ? new SolidBrush(SystemColors.Control)
? new SolidBrush(SystemColors.Control)
: new SolidBrush(SystemColors.ControlDark); : new SolidBrush(SystemColors.ControlDark);
graphics.FillRectangle(backgroundBrush, e.Bounds); graphics.FillRectangle(backgroundBrush, e.Bounds);
@@ -408,20 +415,16 @@ namespace EveOPreview.View
graphics.DrawString(page.Text, font, textBrush, bounds, stringFlags); graphics.DrawString(page.Text, font, textBrush, bounds, stringFlags);
} }
private void OptionChanged_Handler(object sender, EventArgs e) private void OptionChanged_Handler(object sender, EventArgs e) {
{ if (this._suppressEvents) {
if (this._suppressEvents)
{
return; return;
} }
this.ApplicationSettingsChanged?.Invoke(); this.ApplicationSettingsChanged?.Invoke();
} }
private void ThumbnailSizeChanged_Handler(object sender, EventArgs e) private void ThumbnailSizeChanged_Handler(object sender, EventArgs e) {
{ if (this._suppressEvents) {
if (this._suppressEvents)
{
return; return;
} }
@@ -429,21 +432,19 @@ namespace EveOPreview.View
this._suppressEvents = true; this._suppressEvents = true;
Size thumbnailSize = this.ThumbnailSize; Size thumbnailSize = this.ThumbnailSize;
thumbnailSize.Width = Math.Min(Math.Max(thumbnailSize.Width, this._minimumSize.Width), this._maximumSize.Width); thumbnailSize.Width = Math.Min(Math.Max(thumbnailSize.Width, this._minimumSize.Width), this._maximumSize.Width);
thumbnailSize.Height = Math.Min(Math.Max(thumbnailSize.Height, this._minimumSize.Height), this._maximumSize.Height); thumbnailSize.Height =
Math.Min(Math.Max(thumbnailSize.Height, this._minimumSize.Height), this._maximumSize.Height);
this.ThumbnailSize = thumbnailSize; this.ThumbnailSize = thumbnailSize;
this._suppressEvents = false; this._suppressEvents = false;
this.ThumbnailsSizeChanged?.Invoke(); this.ThumbnailsSizeChanged?.Invoke();
} }
private void ActiveClientHighlightColorButton_Click(object sender, EventArgs e) private void ActiveClientHighlightColorButton_Click(object sender, EventArgs e) {
{ using (ColorDialog dialog = new ColorDialog()) {
using (ColorDialog dialog = new ColorDialog())
{
dialog.Color = this.ActiveClientHighlightColor; dialog.Color = this.ActiveClientHighlightColor;
if (dialog.ShowDialog() != DialogResult.OK) if (dialog.ShowDialog() != DialogResult.OK) {
{
return; return;
} }
@@ -453,14 +454,11 @@ namespace EveOPreview.View
this.OptionChanged_Handler(sender, e); this.OptionChanged_Handler(sender, e);
} }
private void OverlayLabelColorButton_Click(object sender, EventArgs e) private void OverlayLabelColorButton_Click(object sender, EventArgs e) {
{ using (ColorDialog dialog = new ColorDialog()) {
using (ColorDialog dialog = new ColorDialog())
{
dialog.Color = this.OverlayLabelColor; dialog.Color = this.OverlayLabelColor;
if (dialog.ShowDialog() != DialogResult.OK) if (dialog.ShowDialog() != DialogResult.OK) {
{
return; return;
} }
this.OverlayLabelColor = dialog.Color; this.OverlayLabelColor = dialog.Color;
@@ -469,10 +467,8 @@ namespace EveOPreview.View
this.OptionChanged_Handler(sender, e); this.OptionChanged_Handler(sender, e);
} }
private void ThumbnailsList_ItemCheck_Handler(object sender, ItemCheckEventArgs e) private void ThumbnailsList_ItemCheck_Handler(object sender, ItemCheckEventArgs e) {
{ if (!(this.ThumbnailsList.Items[e.Index] is IThumbnailDescription selectedItem)) {
if (!(this.ThumbnailsList.Items[e.Index] is IThumbnailDescription selectedItem))
{
return; return;
} }
@@ -481,23 +477,19 @@ namespace EveOPreview.View
this.ThumbnailStateChanged?.Invoke(selectedItem.Title); this.ThumbnailStateChanged?.Invoke(selectedItem.Title);
} }
private void DocumentationLinkClicked_Handler(object sender, LinkLabelLinkClickedEventArgs e) private void DocumentationLinkClicked_Handler(object sender, LinkLabelLinkClickedEventArgs e) {
{
this.DocumentationLinkActivated?.Invoke(); this.DocumentationLinkActivated?.Invoke();
} }
private void MainFormResize_Handler(object sender, EventArgs e) private void MainFormResize_Handler(object sender, EventArgs e) {
{ if (this.WindowState != FormWindowState.Minimized) {
if (this.WindowState != FormWindowState.Minimized)
{
return; return;
} }
this.FormMinimized?.Invoke(); this.FormMinimized?.Invoke();
} }
private void MainFormClosing_Handler(object sender, FormClosingEventArgs e) private void MainFormClosing_Handler(object sender, FormClosingEventArgs e) {
{
ViewCloseRequest request = new ViewCloseRequest(); ViewCloseRequest request = new ViewCloseRequest();
this.FormCloseRequested?.Invoke(request); this.FormCloseRequested?.Invoke(request);
@@ -505,22 +497,19 @@ namespace EveOPreview.View
e.Cancel = !request.Allow; e.Cancel = !request.Allow;
} }
private void RestoreMainForm_Handler(object sender, EventArgs e) private void RestoreMainForm_Handler(object sender, EventArgs e) {
{
// This is form's GUI lifecycle event that is invariant to the Form data // This is form's GUI lifecycle event that is invariant to the Form data
base.Show(); base.Show();
this.WindowState = FormWindowState.Normal; this.WindowState = FormWindowState.Normal;
this.BringToFront(); this.BringToFront();
} }
private void ExitMenuItemClick_Handler(object sender, EventArgs e) private void ExitMenuItemClick_Handler(object sender, EventArgs e) {
{
this.ApplicationExitRequested?.Invoke(); this.ApplicationExitRequested?.Invoke();
} }
#endregion #endregion
private void InitZoomAnchorMap() private void InitZoomAnchorMap() {
{
this._zoomAnchorMap[ViewZoomAnchor.NW] = this.ZoomAanchorNWRadioButton; this._zoomAnchorMap[ViewZoomAnchor.NW] = this.ZoomAanchorNWRadioButton;
this._zoomAnchorMap[ViewZoomAnchor.N] = this.ZoomAanchorNRadioButton; this._zoomAnchorMap[ViewZoomAnchor.N] = this.ZoomAanchorNRadioButton;
this._zoomAnchorMap[ViewZoomAnchor.NE] = this.ZoomAanchorNERadioButton; this._zoomAnchorMap[ViewZoomAnchor.NE] = this.ZoomAanchorNERadioButton;
@@ -531,8 +520,7 @@ namespace EveOPreview.View
this._zoomAnchorMap[ViewZoomAnchor.S] = this.ZoomAanchorSRadioButton; this._zoomAnchorMap[ViewZoomAnchor.S] = this.ZoomAanchorSRadioButton;
this._zoomAnchorMap[ViewZoomAnchor.SE] = this.ZoomAanchorSERadioButton; this._zoomAnchorMap[ViewZoomAnchor.SE] = this.ZoomAanchorSERadioButton;
} }
private void InitOverlayLabelMap() private void InitOverlayLabelMap() {
{
this._overlayLabelMap[ViewZoomAnchor.NW] = this.OverlayLabelNWRadioButton; this._overlayLabelMap[ViewZoomAnchor.NW] = this.OverlayLabelNWRadioButton;
this._overlayLabelMap[ViewZoomAnchor.N] = this.OverlayLabelNRadioButton; this._overlayLabelMap[ViewZoomAnchor.N] = this.OverlayLabelNRadioButton;
this._overlayLabelMap[ViewZoomAnchor.NE] = this.OverlayLabelNERadioButton; this._overlayLabelMap[ViewZoomAnchor.NE] = this.OverlayLabelNERadioButton;
@@ -543,30 +531,22 @@ namespace EveOPreview.View
this._overlayLabelMap[ViewZoomAnchor.S] = this.OverlayLabelSRadioButton; this._overlayLabelMap[ViewZoomAnchor.S] = this.OverlayLabelSRadioButton;
this._overlayLabelMap[ViewZoomAnchor.SE] = this.OverlayLabelSERadioButton; this._overlayLabelMap[ViewZoomAnchor.SE] = this.OverlayLabelSERadioButton;
} }
private void InitFormSize() private void InitFormSize() {
{
const int BUFFER_PIXEL_AMOUNT = 8; const int BUFFER_PIXEL_AMOUNT = 8;
// resize form height based on tabbed control item height // resize form height based on tabbed control item height
var tabControl = (System.Windows.Forms.TabControl)this.Controls.Find("ContentTabControl", false).First(); var tabControl = (System.Windows.Forms.TabControl)this.Controls.Find("ContentTabControl", false).First();
if (tabControl != null) if (tabControl != null) {
{
var furnitureSize = this.Height - tabControl.Height; var furnitureSize = this.Height - tabControl.Height;
var calculatedHeight = (tabControl.ItemSize.Width * tabControl.Controls.Count) + furnitureSize + BUFFER_PIXEL_AMOUNT; var calculatedHeight =
if (this.Height < calculatedHeight) (tabControl.ItemSize.Width * tabControl.Controls.Count) + furnitureSize + BUFFER_PIXEL_AMOUNT;
{ if (this.Height < calculatedHeight) {
this.Height = calculatedHeight; this.Height = calculatedHeight;
} }
} }
} }
private void AnimationStyleCombo_SelectedIndexChanged(object sender, EventArgs e) private void AnimationStyleCombo_SelectedIndexChanged(object sender, EventArgs e) {}
{
}
private void GeneralSettingsPanel_Paint(object sender, PaintEventArgs e)
{
} private void GeneralSettingsPanel_Paint(object sender, PaintEventArgs e) {}
} }
} }

View File

@@ -0,0 +1,40 @@
namespace EveOPreview.View.Implementation {
partial class RegionPickerDialog {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
this.SuspendLayout();
//
// RegionPickerDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Name = "RegionPickerDialog";
this.Text = "Region Picker";
this.ResumeLayout(false);
}
#endregion
}
}

View File

@@ -0,0 +1,136 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace EveOPreview.View.Implementation {
public partial class RegionPickerDialog : Form {
private Point _startPoint;
private Point _endPoint;
private bool _isDrawing;
private Rectangle _selectedRegion;
public Rectangle SelectedRegion => _selectedRegion;
public RegionPickerDialog() {
InitializeComponent();
InitializeDialog();
}
private void InitializeDialog() {
// Make the form cover all screens
Rectangle totalBounds = GetTotalScreenBounds();
this.Bounds = totalBounds;
this.StartPosition = FormStartPosition.Manual;
this.FormBorderStyle = FormBorderStyle.None;
this.WindowState = FormWindowState.Maximized;
this.TopMost = true;
this.ShowInTaskbar = false;
this.Cursor = Cursors.Cross;
// Make the form semi-transparent but not fully transparent
this.BackColor = Color.Black;
this.Opacity = 0.3;
// Add event handlers
this.MouseDown += RegionPickerDialog_MouseDown;
this.MouseMove += RegionPickerDialog_MouseMove;
this.MouseUp += RegionPickerDialog_MouseUp;
this.KeyDown += RegionPickerDialog_KeyDown;
this.Paint += RegionPickerDialog_Paint;
// Add instructions label
var instructionsLabel = new Label { Text = "Click and drag to select a region. Press ESC to cancel.",
ForeColor = Color.White,
BackColor = Color.Black,
Font = new Font("Arial", 12, FontStyle.Bold),
AutoSize = true,
Location = new Point(10, 10) };
this.Controls.Add(instructionsLabel);
}
private Rectangle GetTotalScreenBounds() {
Rectangle bounds = Screen.PrimaryScreen.Bounds;
foreach (Screen screen in Screen.AllScreens) {
bounds = Rectangle.Union(bounds, screen.Bounds);
}
return bounds;
}
private void RegionPickerDialog_MouseDown(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
_startPoint = e.Location;
_isDrawing = true;
this.Capture = true;
this.Invalidate();
}
}
private void RegionPickerDialog_MouseMove(object sender, MouseEventArgs e) {
if (_isDrawing) {
_endPoint = e.Location;
this.Invalidate();
}
}
private void RegionPickerDialog_MouseUp(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left && _isDrawing) {
_isDrawing = false;
_endPoint = e.Location;
this.Capture = false;
// Calculate the selected region
int x = Math.Min(_startPoint.X, _endPoint.X);
int y = Math.Min(_startPoint.Y, _endPoint.Y);
int width = Math.Abs(_endPoint.X - _startPoint.X);
int height = Math.Abs(_endPoint.Y - _startPoint.Y);
if (width > 10 && height > 10) // Minimum size
{
_selectedRegion = new Rectangle(x, y, width, height);
this.DialogResult = DialogResult.OK;
this.Close();
} else {
// Reset if region is too small
_startPoint = Point.Empty;
_endPoint = Point.Empty;
this.Invalidate();
}
}
}
private void RegionPickerDialog_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.Escape) {
this.DialogResult = DialogResult.Cancel;
this.Close();
}
}
private void RegionPickerDialog_Paint(object sender, PaintEventArgs e) {
if (_isDrawing) {
// Draw selection rectangle
using (Pen pen = new Pen(Color.Red, 2)) {
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
int x = Math.Min(_startPoint.X, _endPoint.X);
int y = Math.Min(_startPoint.Y, _endPoint.Y);
int width = Math.Abs(_endPoint.X - _startPoint.X);
int height = Math.Abs(_endPoint.Y - _startPoint.Y);
e.Graphics.DrawRectangle(pen, x, y, width, height);
}
// Draw size information
if (_startPoint != Point.Empty && _endPoint != Point.Empty) {
int width = Math.Abs(_endPoint.X - _startPoint.X);
int height = Math.Abs(_endPoint.Y - _startPoint.Y);
string sizeText = $"{width} x {height}";
using (Font font = new Font("Arial", 10, FontStyle.Bold)) using (Brush brush =
new SolidBrush(Color.White)) {
e.Graphics.DrawString(sizeText, font, brush, _endPoint.X + 5, _endPoint.Y + 5);
}
}
}
}
}
}

View File

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

View File

@@ -4,69 +4,92 @@ using System.Windows.Forms;
using EveOPreview.Configuration; using EveOPreview.Configuration;
using EveOPreview.Services; using EveOPreview.Services;
namespace EveOPreview.View namespace EveOPreview.View {
{ sealed class StaticThumbnailView : ThumbnailView {
sealed class StaticThumbnailView : ThumbnailView
{
#region Private fields #region Private fields
private readonly PictureBox _thumbnail; private readonly PictureBox _thumbnail;
private IThumbnailConfiguration _config; private IThumbnailConfiguration _config;
#endregion #endregion
public StaticThumbnailView(IWindowManager windowManager, IThumbnailConfiguration config, IThumbnailManager thumbnailManager) public StaticThumbnailView(IWindowManager windowManager, IThumbnailConfiguration config,
: base(windowManager, config, thumbnailManager) IThumbnailManager thumbnailManager)
{ : base(windowManager, config, thumbnailManager) {
this._thumbnail = new StaticThumbnailImage this._thumbnail =
{ new StaticThumbnailImage { TabStop = false, SizeMode = PictureBoxSizeMode.StretchImage,
TabStop = false,
SizeMode = PictureBoxSizeMode.StretchImage,
Location = new Point(0, 0), Location = new Point(0, 0),
Size = new Size(this.ClientSize.Width, this.ClientSize.Height) Size = new Size(this.ClientSize.Width, this.ClientSize.Height) };
};
this.Controls.Add(this._thumbnail); this.Controls.Add(this._thumbnail);
this._config = config; this._config = config;
} }
protected override void RefreshThumbnail(bool forceRefresh) protected override void RefreshThumbnail(bool forceRefresh) {
{ if (!forceRefresh) {
if (!forceRefresh)
{
return; return;
} }
var thumbnail = this.WindowManager.GetStaticThumbnail(this.Id); var thumbnail = this.WindowManager.GetStaticThumbnail(this.Id);
if (thumbnail != null) if (thumbnail != null) {
{
var oldImage = this._thumbnail.Image; var oldImage = this._thumbnail.Image;
this._thumbnail.Image = thumbnail; this._thumbnail.Image = thumbnail;
oldImage?.Dispose(); oldImage?.Dispose();
} }
} }
protected override void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop, int highlightWidthRight, int highlightWidthBottom, int highlightWidthLeft) protected override void ApplyRegionSettings() {
{ if (this._thumbnail.Image == null)
return;
if (this._config.EnableThumbnailRegionSnipping) {
var region = this._config.GetThumbnailRegion(this.Title, this._config.DefaultThumbnailRegion);
if (region.Width > 0 && region.Height > 0) {
// Crop the image to the specified region
var croppedImage = CropImage((Image)this._thumbnail.Image, region);
var oldImage = this._thumbnail.Image;
this._thumbnail.Image = croppedImage;
oldImage?.Dispose();
}
}
}
private Image CropImage(Image sourceImage, Rectangle region) {
// Ensure the region is within the image bounds
var imageRect = new Rectangle(0, 0, sourceImage.Width, sourceImage.Height);
var cropRect = Rectangle.Intersect(region, imageRect);
if (cropRect.Width <= 0 || cropRect.Height <= 0) {
return sourceImage; // Return original if region is invalid
}
var croppedImage = new Bitmap(cropRect.Width, cropRect.Height);
using (var graphics = Graphics.FromImage(croppedImage)) {
graphics.DrawImage(sourceImage, new Rectangle(0, 0, cropRect.Width, cropRect.Height), cropRect,
GraphicsUnit.Pixel);
}
return croppedImage;
}
protected override void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop,
int highlightWidthRight, int highlightWidthBottom,
int highlightWidthLeft) {
var left = 0 + highlightWidthLeft; var left = 0 + highlightWidthLeft;
var top = 0 + highlightWidthTop; var top = 0 + highlightWidthTop;
if (this.IsLocationUpdateRequired(this._thumbnail.Location, left, top)) if (this.IsLocationUpdateRequired(this._thumbnail.Location, left, top)) {
{
this._thumbnail.Location = new Point(left, top); this._thumbnail.Location = new Point(left, top);
} }
var width = baseWidth - highlightWidthLeft - highlightWidthRight; var width = baseWidth - highlightWidthLeft - highlightWidthRight;
var height = baseHeight - highlightWidthTop - highlightWidthBottom; var height = baseHeight - highlightWidthTop - highlightWidthBottom;
if (this.IsSizeUpdateRequired(this._thumbnail.Size, width, height)) if (this.IsSizeUpdateRequired(this._thumbnail.Size, width, height)) {
{
this._thumbnail.Size = new Size(width, height); this._thumbnail.Size = new Size(width, height);
} }
} }
private bool IsLocationUpdateRequired(Point currentLocation, int left, int top) private bool IsLocationUpdateRequired(Point currentLocation, int left, int top) {
{
return (currentLocation.X != left) || (currentLocation.Y != top); return (currentLocation.X != left) || (currentLocation.Y != top);
} }
private bool IsSizeUpdateRequired(Size currentSize, int width, int height) private bool IsSizeUpdateRequired(Size currentSize, int width, int height) {
{
return (currentSize.Width != width) || (currentSize.Height != height); return (currentSize.Width != width) || (currentSize.Height != height);
} }
} }

View File

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

View File

@@ -1,7 +1,5 @@
namespace EveOPreview.View namespace EveOPreview.View {
{ partial class ThumbnailOverlay {
partial class ThumbnailOverlay
{
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
/// </summary> /// </summary>
@@ -11,10 +9,8 @@
/// 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);
@@ -26,8 +22,7 @@
/// 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();
@@ -50,7 +45,8 @@
// OverlayLabel // OverlayLabel
// //
this.OverlayLabel.AutoSize = true; this.OverlayLabel.AutoSize = true;
this.OverlayLabel.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.OverlayLabel.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.OverlayLabel.ForeColor = System.Drawing.Color.DarkGray; this.OverlayLabel.ForeColor = System.Drawing.Color.DarkGray;
this.OverlayLabel.Location = new System.Drawing.Point(8, 8); this.OverlayLabel.Location = new System.Drawing.Point(8, 8);
this.OverlayLabel.Name = "OverlayLabel"; this.OverlayLabel.Name = "OverlayLabel";
@@ -80,7 +76,6 @@
((System.ComponentModel.ISupportInitialize)(OverlayAreaPictureBox)).EndInit(); ((System.ComponentModel.ISupportInitialize)(OverlayAreaPictureBox)).EndInit();
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();
} }
#endregion #endregion

View File

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

View File

@@ -1,7 +1,5 @@
namespace EveOPreview.View namespace EveOPreview.View {
{ partial class ThumbnailView {
partial class ThumbnailView
{
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
/// </summary> /// </summary>
@@ -12,8 +10,7 @@ namespace EveOPreview.View
/// 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() {
{
this.SuspendLayout(); this.SuspendLayout();
// //
// ThumbnailView // ThumbnailView
@@ -43,11 +40,8 @@ namespace EveOPreview.View
this.Move += new System.EventHandler(this.Move_Handler); this.Move += new System.EventHandler(this.Move_Handler);
this.Resize += new System.EventHandler(this.Resize_Handler); this.Resize += new System.EventHandler(this.Resize_Handler);
this.ResumeLayout(false); this.ResumeLayout(false);
} }
#endregion #endregion
} }
} }

View File

@@ -7,10 +7,8 @@ using EveOPreview.Configuration;
using EveOPreview.Services; using EveOPreview.Services;
using EveOPreview.UI.Hotkeys; using EveOPreview.UI.Hotkeys;
namespace EveOPreview.View namespace EveOPreview.View {
{ public abstract partial class ThumbnailView : Form, IThumbnailView {
public abstract partial class ThumbnailView : Form, IThumbnailView
{
#region Private constants #region Private constants
private const double OPACITY_THRESHOLD = 0.9; private const double OPACITY_THRESHOLD = 0.9;
private const double OPACITY_EPSILON = 0.1; private const double OPACITY_EPSILON = 0.1;
@@ -47,8 +45,8 @@ namespace EveOPreview.View
private IThumbnailManager _thumbnailManager; private IThumbnailManager _thumbnailManager;
#endregion #endregion
protected ThumbnailView(IWindowManager windowManager, IThumbnailConfiguration config, IThumbnailManager thumbnailManager) protected ThumbnailView(IWindowManager windowManager, IThumbnailConfiguration config,
{ IThumbnailManager thumbnailManager) {
this._config = config; this._config = config;
this.SuppressResizeEvent(); this.SuppressResizeEvent();
@@ -81,14 +79,13 @@ namespace EveOPreview.View
public IntPtr Id { get; set; } public IntPtr Id { get; set; }
public string Title public string Title {
{
get => this.Text; get => this.Text;
set set {
{
this.Text = value; this.Text = value;
this._overlay.SetOverlayLabel(value.Replace("EVE - ", "").Replace("EVE Frontier - ", "*")); this._overlay.SetOverlayLabel(value.Replace("EVE - ", "").Replace("EVE Frontier - ", "*"));
this._overlay.SetPropertiesOverlayLabel(_config.OverlayLabelSize, _config.OverlayLabelColor, _config.OverlayLabelAnchor); this._overlay.SetPropertiesOverlayLabel(_config.OverlayLabelSize, _config.OverlayLabelColor,
_config.OverlayLabelAnchor);
SetDefaultBorderColor(); SetDefaultBorderColor();
} }
} }
@@ -98,18 +95,15 @@ namespace EveOPreview.View
public bool IsOverlayEnabled { get; set; } public bool IsOverlayEnabled { get; set; }
public ZoomAnchor ClientZoomAnchor { get; set; } public ZoomAnchor ClientZoomAnchor { get; set; }
public Point ThumbnailLocation public Point ThumbnailLocation {
{
get => this.Location; get => this.Location;
set set {
{
this.StartPosition = FormStartPosition.Manual; this.StartPosition = FormStartPosition.Manual;
this.Location = value; this.Location = value;
} }
} }
public Size ThumbnailSize public Size ThumbnailSize {
{
get => this.ClientSize; get => this.ClientSize;
set => this.ClientSize = value; set => this.ClientSize = value;
} }
@@ -128,24 +122,17 @@ namespace EveOPreview.View
private bool WindowMoved = false; private bool WindowMoved = false;
public void SetDefaultBorderColor() public void SetDefaultBorderColor() {
{ this._myBorderColor = new Lazy<Color>(() => {
this._myBorderColor = new Lazy<Color>(() => if (this._config.PerClientActiveClientHighlightColor.Any(x => x.Key == this.Title)) {
{
if (this._config.PerClientActiveClientHighlightColor.Any(x => x.Key == this.Title))
{
return this._config.PerClientActiveClientHighlightColor[Title]; return this._config.PerClientActiveClientHighlightColor[Title];
} } else {
else
{
return _config.ActiveClientHighlightColor; return _config.ActiveClientHighlightColor;
} }
}); });
} }
public new void Show() public new void Show() { this.SuppressResizeEvent();
{
this.SuppressResizeEvent();
base.Show(); base.Show();
@@ -158,9 +145,7 @@ namespace EveOPreview.View
this.IsActive = true; this.IsActive = true;
} }
public new void Hide() public new void Hide() { this.SuppressResizeEvent();
{
this.SuppressResizeEvent();
this.IsActive = false; this.IsActive = false;
@@ -168,9 +153,7 @@ namespace EveOPreview.View
base.Hide(); base.Hide();
} }
public new virtual void Close() public new virtual void Close() { this.SuppressResizeEvent();
{
this.SuppressResizeEvent();
this.IsActive = false; this.IsActive = false;
this._overlay.Close(); this._overlay.Close();
@@ -178,31 +161,25 @@ namespace EveOPreview.View
} }
// This method is used to determine if the provided Handle is related to client or its thumbnail // This method is used to determine if the provided Handle is related to client or its thumbnail
public bool IsKnownHandle(IntPtr handle) public bool IsKnownHandle(IntPtr handle) {
{
return (this.Id == handle) || (this.Handle == handle) || (this._overlay.Handle == handle); return (this.Id == handle) || (this.Handle == handle) || (this._overlay.Handle == handle);
} }
public void SetSizeLimitations(Size minimumSize, Size maximumSize) public void SetSizeLimitations(Size minimumSize, Size maximumSize) {
{
this.MinimumSize = minimumSize; this.MinimumSize = minimumSize;
this.MaximumSize = maximumSize; this.MaximumSize = maximumSize;
} }
public void SetOpacity(double opacity) public void SetOpacity(double opacity) {
{ if (opacity >= OPACITY_THRESHOLD) {
if (opacity >= OPACITY_THRESHOLD)
{
opacity = 1.0; opacity = 1.0;
} }
if (Math.Abs(opacity - this._opacity) < OPACITY_EPSILON) if (Math.Abs(opacity - this._opacity) < OPACITY_EPSILON) {
{
return; return;
} }
try try {
{
this.Opacity = opacity; this.Opacity = opacity;
// Overlay opacity settings // Overlay opacity settings
@@ -212,21 +189,17 @@ namespace EveOPreview.View
this._overlay.Opacity = opacity > 0.8 ? 1.0 : 1.0 - (1.0 - opacity) / 2; this._overlay.Opacity = opacity > 0.8 ? 1.0 : 1.0 - (1.0 - opacity) / 2;
this._opacity = opacity; this._opacity = opacity;
} } catch (Win32Exception) {
catch (Win32Exception)
{
// Something went wrong in WinForms internals // Something went wrong in WinForms internals
// Opacity will be updated in the next cycle // Opacity will be updated in the next cycle
} }
} }
public void SetFrames(bool enable) public void SetFrames(bool enable) {
{
FormBorderStyle style = enable ? FormBorderStyle.SizableToolWindow : FormBorderStyle.None; FormBorderStyle style = enable ? FormBorderStyle.SizableToolWindow : FormBorderStyle.None;
// No need to change the borders style if it is ALREADY correct // No need to change the borders style if it is ALREADY correct
if (this.FormBorderStyle == style) if (this.FormBorderStyle == style) {
{
return; return;
} }
@@ -234,14 +207,10 @@ namespace EveOPreview.View
this.FormBorderStyle = style; this.FormBorderStyle = style;
} }
public void SetOverlayLabel() public void SetOverlayLabel() {}
{
}
public void SetTopMost(bool enableTopmost) public void SetTopMost(bool enableTopmost) {
{ if (this._isTopMost == enableTopmost) {
if (this._isTopMost == enableTopmost)
{
return; return;
} }
@@ -251,26 +220,20 @@ namespace EveOPreview.View
this._isTopMost = enableTopmost; this._isTopMost = enableTopmost;
} }
public void SetHighlight() public void SetHighlight() {
{
SetHighlight(_config.EnableActiveClientHighlight, _config.ActiveClientHighlightThickness); SetHighlight(_config.EnableActiveClientHighlight, _config.ActiveClientHighlightThickness);
} }
public void SetHighlight(bool enabled, int width) public void SetHighlight(bool enabled, int width) {
{ if (this._isHighlightRequested == enabled) {
if (this._isHighlightRequested == enabled)
{
return; return;
} }
if (enabled) if (enabled) {
{
this._isHighlightRequested = true; this._isHighlightRequested = true;
this._highlightWidth = width; this._highlightWidth = width;
this.BackColor = _myBorderColor.Value; this.BackColor = _myBorderColor.Value;
} } else {
else
{
this._isHighlightRequested = false; this._isHighlightRequested = false;
this.BackColor = SystemColors.Control; this.BackColor = SystemColors.Control;
} }
@@ -278,14 +241,12 @@ namespace EveOPreview.View
this._isSizeChanged = true; this._isSizeChanged = true;
} }
public void ClearBorder() public void ClearBorder() {
{
this.SetHighlight(false, 0); this.SetHighlight(false, 0);
this.Refresh(true); this.Refresh(true);
} }
public void ZoomIn(ViewZoomAnchor anchor, int zoomFactor) public void ZoomIn(ViewZoomAnchor anchor, int zoomFactor) {
{
int oldWidth = this._baseZoomSize.Width; int oldWidth = this._baseZoomSize.Width;
int oldHeight = this._baseZoomSize.Height; int oldHeight = this._baseZoomSize.Height;
@@ -299,12 +260,12 @@ namespace EveOPreview.View
// First change size, THEN move the window // First change size, THEN move the window
// Otherwise there is a chance to fail in a loop // Otherwise there is a chance to fail in a loop
// Zoom required -> Moved the windows 1st -> Focus is lost -> Window is moved back -> Focus is back on -> Zoom required -> ... // Zoom required -> Moved the windows 1st -> Focus is lost -> Window is moved back -> Focus is back on -> Zoom
// required -> ...
this.MaximumSize = new Size(0, 0); this.MaximumSize = new Size(0, 0);
this.Size = new Size(newWidth, newHeight); this.Size = new Size(newWidth, newHeight);
switch (anchor) switch (anchor) {
{
case ViewZoomAnchor.NW: case ViewZoomAnchor.NW:
break; break;
case ViewZoomAnchor.N: case ViewZoomAnchor.N:
@@ -318,7 +279,8 @@ namespace EveOPreview.View
this.Location = new Point(locationX, locationY - newHeight / 2 + oldHeight / 2); this.Location = new Point(locationX, locationY - newHeight / 2 + oldHeight / 2);
break; break;
case ViewZoomAnchor.C: case ViewZoomAnchor.C:
this.Location = new Point(locationX - newWidth / 2 + oldWidth / 2, locationY - newHeight / 2 + oldHeight / 2); this.Location =
new Point(locationX - newWidth / 2 + oldWidth / 2, locationY - newHeight / 2 + oldHeight / 2);
break; break;
case ViewZoomAnchor.E: case ViewZoomAnchor.E:
this.Location = new Point(locationX - newWidth + oldWidth, locationY - newHeight / 2 + oldHeight / 2); this.Location = new Point(locationX - newWidth + oldWidth, locationY - newHeight / 2 + oldHeight / 2);
@@ -336,20 +298,16 @@ namespace EveOPreview.View
} }
} }
public void ZoomOut() public void ZoomOut() {
{
this.RestoreWindowSizeAndLocation(); this.RestoreWindowSizeAndLocation();
} }
public void RegisterHotkey(Keys hotkey) public void RegisterHotkey(Keys hotkey) {
{ if (this._hotkeyHandler != null) {
if (this._hotkeyHandler != null)
{
this.UnregisterHotkey(); this.UnregisterHotkey();
} }
if (hotkey == Keys.None) if (hotkey == Keys.None) {
{
return; return;
} }
@@ -358,10 +316,8 @@ namespace EveOPreview.View
this._hotkeyHandler.Register(); this._hotkeyHandler.Register();
} }
public void UnregisterHotkey() public void UnregisterHotkey() {
{ if (this._hotkeyHandler == null) {
if (this._hotkeyHandler == null)
{
return; return;
} }
@@ -371,9 +327,9 @@ namespace EveOPreview.View
this._hotkeyHandler = null; this._hotkeyHandler = null;
} }
public void Refresh(bool forceRefresh) public void Refresh(bool forceRefresh) {
{
this.RefreshThumbnail(forceRefresh); this.RefreshThumbnail(forceRefresh);
this.ApplyRegionSettings();
this.HighlightThumbnail(forceRefresh || this._isSizeChanged); this.HighlightThumbnail(forceRefresh || this._isSizeChanged);
this.RefreshOverlay(forceRefresh || this._isSizeChanged || this._isLocationChanged); this.RefreshOverlay(forceRefresh || this._isSizeChanged || this._isLocationChanged);
@@ -382,12 +338,15 @@ namespace EveOPreview.View
protected abstract void RefreshThumbnail(bool forceRefresh); protected abstract void RefreshThumbnail(bool forceRefresh);
protected abstract void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop, int highlightWidthRight, int highlightWidthBottom, int highlightWidthLeft); protected abstract void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop, int highlightWidthRight,
int highlightWidthBottom, int highlightWidthLeft);
private void HighlightThumbnail(bool forceRefresh) protected virtual void ApplyRegionSettings() {
{ // Default implementation does nothing
if (!forceRefresh && (this._isHighlightRequested == this._isHighlightEnabled)) }
{
private void HighlightThumbnail(bool forceRefresh) {
if (!forceRefresh && (this._isHighlightRequested == this._isHighlightEnabled)) {
// Nothing to do here // Nothing to do here
return; return;
} }
@@ -397,8 +356,7 @@ namespace EveOPreview.View
int baseWidth = this.ClientSize.Width; int baseWidth = this.ClientSize.Width;
int baseHeight = this.ClientSize.Height; int baseHeight = this.ClientSize.Height;
if (!this._isHighlightRequested) if (!this._isHighlightRequested) {
{
// No highlighting enabled, so no math required // No highlighting enabled, so no math required
this.ResizeThumbnail(baseWidth, baseHeight, 0, 0, 0, 0); this.ResizeThumbnail(baseWidth, baseHeight, 0, 0, 0, 0);
return; return;
@@ -412,13 +370,12 @@ namespace EveOPreview.View
int highlightWidthLeft = (baseWidth - actualWidth) / 2; int highlightWidthLeft = (baseWidth - actualWidth) / 2;
int highlightWidthRight = baseWidth - actualWidth - highlightWidthLeft; int highlightWidthRight = baseWidth - actualWidth - highlightWidthLeft;
this.ResizeThumbnail(this.ClientSize.Width, this.ClientSize.Height, this._highlightWidth, highlightWidthRight, this._highlightWidth, highlightWidthLeft); this.ResizeThumbnail(this.ClientSize.Width, this.ClientSize.Height, this._highlightWidth, highlightWidthRight,
this._highlightWidth, highlightWidthLeft);
} }
private void RefreshOverlay(bool forceRefresh) private void RefreshOverlay(bool forceRefresh) {
{ if (this._isOverlayVisible && !forceRefresh) {
if (this._isOverlayVisible && !forceRefresh)
{
// No need to update anything. Everything is already set up // No need to update anything. Everything is already set up
return; return;
} }
@@ -426,8 +383,7 @@ namespace EveOPreview.View
// Only show overlay if enabled AND thumbnail is active/visible. // Only show overlay if enabled AND thumbnail is active/visible.
this._overlay.EnableOverlayLabel(this.IsOverlayEnabled && this.Visible); this._overlay.EnableOverlayLabel(this.IsOverlayEnabled && this.Visible);
if (!this._isOverlayVisible) if (!this._isOverlayVisible) {
{
// One-time action to show the Overlay before it is set up // One-time action to show the Overlay before it is set up
// Otherwise its position won't be set // Otherwise its position won't be set
this._overlay.Show(); this._overlay.Show();
@@ -444,40 +400,35 @@ namespace EveOPreview.View
this._isLocationChanged = false; this._isLocationChanged = false;
this._overlay.Size = overlaySize; this._overlay.Size = overlaySize;
this._overlay.SetPropertiesOverlayLabel(_config.OverlayLabelSize, _config.OverlayLabelColor, _config.OverlayLabelAnchor); this._overlay.SetPropertiesOverlayLabel(_config.OverlayLabelSize, _config.OverlayLabelColor,
_config.OverlayLabelAnchor);
this._overlay.Location = overlayLocation; this._overlay.Location = overlayLocation;
this._overlay.Refresh(); this._overlay.Refresh();
} }
private void SuppressResizeEvent() private void SuppressResizeEvent() {
{
// Workaround for WinForms issue with the Resize event being fired with inconsistent ClientSize value // Workaround for WinForms issue with the Resize event being fired with inconsistent ClientSize value
// Any Resize events fired before this timestamp will be ignored // Any Resize events fired before this timestamp will be ignored
this._suppressResizeEventsTimestamp = DateTime.UtcNow.AddMilliseconds(_config.ThumbnailResizeTimeoutPeriod); this._suppressResizeEventsTimestamp = DateTime.UtcNow.AddMilliseconds(_config.ThumbnailResizeTimeoutPeriod);
} }
#region GUI events #region GUI events
protected override CreateParams CreateParams protected override CreateParams CreateParams {
{ get {
get
{
var Params = base.CreateParams; var Params = base.CreateParams;
Params.ExStyle |= (int)InteropConstants.WS_EX_TOOLWINDOW; Params.ExStyle |= (int)InteropConstants.WS_EX_TOOLWINDOW;
return Params; return Params;
} }
} }
private void Move_Handler(object sender, EventArgs e) private void Move_Handler(object sender, EventArgs e) {
{
this._isLocationChanged = true; this._isLocationChanged = true;
this.ThumbnailMoved?.Invoke(this.Id); this.ThumbnailMoved?.Invoke(this.Id);
} }
private void Resize_Handler(object sender, EventArgs e) private void Resize_Handler(object sender, EventArgs e) {
{ if (DateTime.UtcNow < this._suppressResizeEventsTimestamp) {
if (DateTime.UtcNow < this._suppressResizeEventsTimestamp)
{
return; return;
} }
@@ -486,54 +437,46 @@ namespace EveOPreview.View
this.ThumbnailResized?.Invoke(this.Id); this.ThumbnailResized?.Invoke(this.Id);
} }
private void MouseEnter_Handler(object sender, EventArgs e) private void MouseEnter_Handler(object sender, EventArgs e) {
{
this.ExitCustomMouseMode(); this.ExitCustomMouseMode();
this.SaveWindowSizeAndLocation(); this.SaveWindowSizeAndLocation();
this.ThumbnailFocused?.Invoke(this.Id); this.ThumbnailFocused?.Invoke(this.Id);
} }
private void MouseLeave_Handler(object sender, EventArgs e) private void MouseLeave_Handler(object sender, EventArgs e) {
{
this.ThumbnailLostFocus?.Invoke(this.Id); this.ThumbnailLostFocus?.Invoke(this.Id);
} }
private void MouseDown_Handler(object sender, MouseEventArgs e) private void MouseDown_Handler(object sender, MouseEventArgs e) {
{
this.MouseDownEventHandler(e.Button, Control.ModifierKeys); this.MouseDownEventHandler(e.Button, Control.ModifierKeys);
} }
private void MouseMove_Handler(object sender, MouseEventArgs e) private void MouseMove_Handler(object sender, MouseEventArgs e) {
{ if (this._isCustomMouseModeActive) {
if (this._isCustomMouseModeActive)
{
this.ProcessCustomMouseMode(e.Button.HasFlag(MouseButtons.Left), e.Button.HasFlag(MouseButtons.Right)); this.ProcessCustomMouseMode(e.Button.HasFlag(MouseButtons.Left), e.Button.HasFlag(MouseButtons.Right));
} }
} }
private void MouseUp_Handler(object sender, MouseEventArgs e) private void MouseUp_Handler(object sender, MouseEventArgs e) {
{ if (e.Button == MouseButtons.Right) {
if (e.Button == MouseButtons.Right)
{
this.ExitCustomMouseMode(); this.ExitCustomMouseMode();
// Snap to Grid on release of mouse (if moved) // Snap to Grid on release of mouse (if moved)
if (_config.ThumbnailSnapToGrid && this.WindowMoved) if (_config.ThumbnailSnapToGrid && this.WindowMoved) {
{ var x = (int)Math.Round((double)this.Location.X / (double)_config.ThumbnailSnapToGridSizeX) *
var x = (int)Math.Round((double)this.Location.X / (double)_config.ThumbnailSnapToGridSizeX) * _config.ThumbnailSnapToGridSizeX; _config.ThumbnailSnapToGridSizeX;
var y = (int)Math.Round((double)this.Location.Y / (double)_config.ThumbnailSnapToGridSizeY) * _config.ThumbnailSnapToGridSizeY; var y = (int)Math.Round((double)this.Location.Y / (double)_config.ThumbnailSnapToGridSizeY) *
_config.ThumbnailSnapToGridSizeY;
this.Location = new Point(x, y); this.Location = new Point(x, y);
this._baseZoomLocation = this.Location; this._baseZoomLocation = this.Location;
this.WindowMoved = false; this.WindowMoved = false;
} }
} }
} }
private void HotkeyPressed_Handler(object sender, HandledEventArgs e) private void HotkeyPressed_Handler(object sender, HandledEventArgs e) {
{
this.SetHighlight(); this.SetHighlight();
this.ThumbnailActivated?.Invoke(this.Id); this.ThumbnailActivated?.Invoke(this.Id);
@@ -548,46 +491,38 @@ namespace EveOPreview.View
// Methods are kept on this level because moving to the presenter // Methods are kept on this level because moving to the presenter
// the code that responds to the mouse events like movement // the code that responds to the mouse events like movement
// seems like a huge overkill // seems like a huge overkill
private void SaveWindowSizeAndLocation() private void SaveWindowSizeAndLocation() {
{
this._baseZoomSize = this.Size; this._baseZoomSize = this.Size;
this._baseZoomLocation = this.Location; this._baseZoomLocation = this.Location;
this._baseZoomMaximumSize = this.MaximumSize; this._baseZoomMaximumSize = this.MaximumSize;
} }
private void RestoreWindowSizeAndLocation() private void RestoreWindowSizeAndLocation() {
{
this.Size = this._baseZoomSize; this.Size = this._baseZoomSize;
this.MaximumSize = this._baseZoomMaximumSize; this.MaximumSize = this._baseZoomMaximumSize;
this.Location = this._baseZoomLocation; this.Location = this._baseZoomLocation;
} }
private void EnterCustomMouseMode() private void EnterCustomMouseMode() {
{
this.RestoreWindowSizeAndLocation(); this.RestoreWindowSizeAndLocation();
this._isCustomMouseModeActive = true; this._isCustomMouseModeActive = true;
this._baseMousePosition = Control.MousePosition; this._baseMousePosition = Control.MousePosition;
} }
private void ProcessCustomMouseMode(bool leftButton, bool rightButton) private void ProcessCustomMouseMode(bool leftButton, bool rightButton) {
{
Point mousePosition = Control.MousePosition; Point mousePosition = Control.MousePosition;
int offsetX = mousePosition.X - this._baseMousePosition.X; int offsetX = mousePosition.X - this._baseMousePosition.X;
int offsetY = mousePosition.Y - this._baseMousePosition.Y; int offsetY = mousePosition.Y - this._baseMousePosition.Y;
this._baseMousePosition = mousePosition; this._baseMousePosition = mousePosition;
if (!_config.LockThumbnailLocation) if (!_config.LockThumbnailLocation) {
{
// Left + Right buttons trigger thumbnail resize // Left + Right buttons trigger thumbnail resize
// Right button only trigger thumbnail movement // Right button only trigger thumbnail movement
if (leftButton && rightButton) if (leftButton && rightButton) {
{
this.Size = new Size(this.Size.Width + offsetX, this.Size.Height + offsetY); this.Size = new Size(this.Size.Width + offsetX, this.Size.Height + offsetY);
this._baseZoomSize = this.Size; this._baseZoomSize = this.Size;
} } else {
else
{
this.Location = new Point(this.Location.X + offsetX, this.Location.Y + offsetY); this.Location = new Point(this.Location.X + offsetX, this.Location.Y + offsetY);
this._baseZoomLocation = this.Location; this._baseZoomLocation = this.Location;
this.WindowMoved = true; this.WindowMoved = true;
@@ -595,17 +530,14 @@ namespace EveOPreview.View
} }
} }
private void ExitCustomMouseMode() private void ExitCustomMouseMode() {
{
this._isCustomMouseModeActive = false; this._isCustomMouseModeActive = false;
} }
#endregion #endregion
#region Custom GUI events #region Custom GUI events
protected virtual void MouseDownEventHandler(MouseButtons mouseButtons, Keys modifierKeys) protected virtual void MouseDownEventHandler(MouseButtons mouseButtons, Keys modifierKeys) {
{ switch (mouseButtons) {
switch (mouseButtons)
{
case MouseButtons.Left when modifierKeys == Keys.Control: case MouseButtons.Left when modifierKeys == Keys.Control:
this.ThumbnailDeactivated?.Invoke(this.Id, false); this.ThumbnailDeactivated?.Invoke(this.Id, false);
break; break;

View File

@@ -2,21 +2,17 @@
using System.Drawing; using System.Drawing;
using EveOPreview.Configuration; using EveOPreview.Configuration;
namespace EveOPreview.View namespace EveOPreview.View {
{ sealed class ThumbnailViewFactory : IThumbnailViewFactory {
sealed class ThumbnailViewFactory : IThumbnailViewFactory
{
private readonly IApplicationController _controller; private readonly IApplicationController _controller;
private readonly bool _enableWineCompatibilityMode; private readonly bool _enableWineCompatibilityMode;
public ThumbnailViewFactory(IApplicationController controller, IThumbnailConfiguration configuration) public ThumbnailViewFactory(IApplicationController controller, IThumbnailConfiguration configuration) {
{
this._controller = controller; this._controller = controller;
this._enableWineCompatibilityMode = configuration.EnableWineCompatibilityMode; this._enableWineCompatibilityMode = configuration.EnableWineCompatibilityMode;
} }
public IThumbnailView Create(IntPtr id, string title, Size size) public IThumbnailView Create(IntPtr id, string title, Size size) {
{
IThumbnailView view = this._enableWineCompatibilityMode IThumbnailView view = this._enableWineCompatibilityMode
? (IThumbnailView)this._controller.Create<StaticThumbnailView>() ? (IThumbnailView)this._controller.Create<StaticThumbnailView>()
: (IThumbnailView)this._controller.Create<LiveThumbnailView>(); : (IThumbnailView)this._controller.Create<LiveThumbnailView>();

View File

@@ -2,14 +2,12 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
namespace EveOPreview.View namespace EveOPreview.View {
{
/// <summary> /// <summary>
/// Main view interface /// Main view interface
/// Presenter uses it to access GUI properties /// Presenter uses it to access GUI properties
/// </summary> /// </summary>
public interface IMainFormView : IView public interface IMainFormView : IView {
{
bool MinimizeToTray { get; set; } bool MinimizeToTray { get; set; }
double ThumbnailOpacity { get; set; } double ThumbnailOpacity { get; set; }
@@ -42,6 +40,12 @@ namespace EveOPreview.View
Color OverlayLabelColor { get; set; } Color OverlayLabelColor { get; set; }
int OverlayLabelSize { get; set; } int OverlayLabelSize { get; set; }
bool EnableThumbnailRegionSnipping { get; set; }
Rectangle DefaultThumbnailRegion { get; set; }
string CurrentProfile { get; set; }
List<string> AvailableProfiles { get; set; }
string IconName { get; set; } string IconName { get; set; }
void SetDocumentationUrl(string url); void SetDocumentationUrl(string url);

View File

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

View File

@@ -4,10 +4,8 @@ using System.Windows.Forms;
using EveOPreview.Configuration; using EveOPreview.Configuration;
using EveOPreview.Services; using EveOPreview.Services;
namespace EveOPreview.View namespace EveOPreview.View {
{ public interface IThumbnailView : IView {
public interface IThumbnailView : IView
{
IntPtr Id { get; set; } IntPtr Id { get; set; }
string Title { get; set; } string Title { get; set; }

View File

@@ -1,10 +1,8 @@
using System; using System;
using System.Drawing; using System.Drawing;
namespace EveOPreview.View namespace EveOPreview.View {
{ public interface IThumbnailViewFactory {
public interface IThumbnailViewFactory
{
IThumbnailView Create(IntPtr id, string title, Size size); IThumbnailView Create(IntPtr id, string title, Size size);
} }
} }

View File

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

View File

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