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() {
{ InitializeComponent();
public MainWindow() Random random = new Random();
{ this.Title += random.Next().ToString("X");
InitializeComponent(); this.grid.Background = new SolidColorBrush(
Random random = new Random(); Color.FromArgb(255, (byte)random.Next(0, 255), (byte)random.Next(0, 255), (byte)random.Next(0, 255)));
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))); }
}
}
} }

View File

@@ -3,26 +3,25 @@ using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
[assembly: AssemblyTitle("EVE Online mock executable for the EVE-O-Preview project")] [assembly:AssemblyTitle("EVE Online mock executable for the EVE-O-Preview project")]
[assembly: AssemblyDescription("")] [assembly:AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly:AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly:AssemblyCompany("")]
[assembly: AssemblyProduct("EVE-O Mock")] [assembly:AssemblyProduct("EVE-O Mock")]
[assembly: AssemblyTrademark("")] [assembly:AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly:AssemblyCulture("")]
[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 //(used if a resource is not found in the page,
//(used if a resource is not found in the page, // app, or any theme specific resource dictionaries)
// app, or any theme specific resource dictionaries) )]
)]
[assembly: AssemblyVersion("1.0.0.0")] [assembly:AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly:AssemblyFileVersion("1.0.0.0")]
[assembly: CLSCompliant(true)] [assembly:CLSCompliant(true)]

View File

@@ -10,8 +10,7 @@
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,45 +18,44 @@ 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;
} }
} }
/// <summary> /// <summary>
/// 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

@@ -9,18 +9,16 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
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,23 +8,20 @@
/// <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);
} }
#region Windows Form Designer generated code #region Windows Form Designer generated code
/// <summary> /// <summary>
/// Required method for Designer support - do not modify /// Required method for Designer support - do not modify
/// the contents of this method with the code editor. /// the contents of this method with the code editor.
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent() {
{
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();
@@ -38,12 +33,14 @@
this.tableLayoutPanel.SuspendLayout(); this.tableLayoutPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit();
this.SuspendLayout(); this.SuspendLayout();
// //
// 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,17 +52,23 @@
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;
// //
// logoPictureBox // logoPictureBox
// //
this.logoPictureBox.Dock = System.Windows.Forms.DockStyle.Fill; this.logoPictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.logoPictureBox.Image = global::PreviewToy.Properties.Resources.Eve_online; this.logoPictureBox.Image = global::PreviewToy.Properties.Resources.Eve_online;
this.logoPictureBox.Location = new System.Drawing.Point(3, 3); this.logoPictureBox.Location = new System.Drawing.Point(3, 3);
@@ -75,9 +78,9 @@
this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.logoPictureBox.TabIndex = 12; this.logoPictureBox.TabIndex = 12;
this.logoPictureBox.TabStop = false; this.logoPictureBox.TabStop = false;
// //
// labelProductName // labelProductName
// //
this.labelProductName.Dock = System.Windows.Forms.DockStyle.Fill; this.labelProductName.Dock = System.Windows.Forms.DockStyle.Fill;
this.labelProductName.Location = new System.Drawing.Point(182, 0); this.labelProductName.Location = new System.Drawing.Point(182, 0);
this.labelProductName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); this.labelProductName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
@@ -87,9 +90,9 @@
this.labelProductName.TabIndex = 19; this.labelProductName.TabIndex = 19;
this.labelProductName.Text = "Product Name"; this.labelProductName.Text = "Product Name";
this.labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; this.labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
// //
// labelVersion // labelVersion
// //
this.labelVersion.Dock = System.Windows.Forms.DockStyle.Fill; this.labelVersion.Dock = System.Windows.Forms.DockStyle.Fill;
this.labelVersion.Location = new System.Drawing.Point(182, 49); this.labelVersion.Location = new System.Drawing.Point(182, 49);
this.labelVersion.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); this.labelVersion.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
@@ -99,9 +102,9 @@
this.labelVersion.TabIndex = 0; this.labelVersion.TabIndex = 0;
this.labelVersion.Text = "Version"; this.labelVersion.Text = "Version";
this.labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; this.labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
// //
// labelCopyright // labelCopyright
// //
this.labelCopyright.Dock = System.Windows.Forms.DockStyle.Fill; this.labelCopyright.Dock = System.Windows.Forms.DockStyle.Fill;
this.labelCopyright.Location = new System.Drawing.Point(182, 98); this.labelCopyright.Location = new System.Drawing.Point(182, 98);
this.labelCopyright.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); this.labelCopyright.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
@@ -112,10 +115,11 @@
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
// //
this.labelCompanyName.Dock = System.Windows.Forms.DockStyle.Fill; this.labelCompanyName.Dock = System.Windows.Forms.DockStyle.Fill;
this.labelCompanyName.Location = new System.Drawing.Point(182, 147); this.labelCompanyName.Location = new System.Drawing.Point(182, 147);
this.labelCompanyName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); this.labelCompanyName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
@@ -126,32 +130,36 @@
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";
this.okButton.Size = new System.Drawing.Size(75, 23); this.okButton.Size = new System.Drawing.Size(75, 23);
this.okButton.TabIndex = 24; this.okButton.TabIndex = 24;
this.okButton.Text = "&OK"; this.okButton.Text = "&OK";
// //
// richTextBoxDescription // richTextBoxDescription
// //
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;
this.richTextBoxDescription.Size = new System.Drawing.Size(352, 239); this.richTextBoxDescription.Size = new System.Drawing.Size(352, 239);
this.richTextBoxDescription.TabIndex = 25; this.richTextBoxDescription.TabIndex = 25;
this.richTextBoxDescription.Text = "Description"; this.richTextBoxDescription.Text = "Description";
// //
// AboutBox // AboutBox
// //
this.AcceptButton = this.okButton; this.AcceptButton = this.okButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
@@ -169,10 +177,9 @@
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
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
private System.Windows.Forms.PictureBox logoPictureBox; private System.Windows.Forms.PictureBox logoPictureBox;

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;
@@ -20,7 +17,7 @@ namespace PreviewToy
this.labelCopyright.Text = AssemblyCopyright; this.labelCopyright.Text = AssemblyCopyright;
this.labelCompanyName.Text = AssemblyCompany; this.labelCompanyName.Text = AssemblyCompany;
this.richTextBoxDescription.Rtf = this.richTextBoxDescription.Rtf =
@"{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Arial;}{\f1\fnil\fcharset0 Calibri;}{\f2\fnil\fcharset2 Symbol;}} @"{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Arial;}{\f1\fnil\fcharset0 Calibri;}{\f2\fnil\fcharset2 Symbol;}}
{\*\generator Riched20 6.3.9600}\viewkind4\uc1 {\*\generator Riched20 6.3.9600}\viewkind4\uc1
\pard\sa200\sl276\slmult1\qc\b\fs28\lang9 EVE-O Preview\par \pard\sa200\sl276\slmult1\qc\b\fs28\lang9 EVE-O Preview\par
@@ -40,34 +37,29 @@ 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);
} }
#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,65 +67,53 @@ 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;
} }
} }
#endregion #endregion
} }
} }

View File

@@ -1,69 +1,57 @@
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>();
}
TPresenter presenter = this._container.Resolve<TPresenter>(); TPresenter presenter = this._container.Resolve<TPresenter>();
presenter.Run(); presenter.Run();
} }
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>();
}
TPresenter presenter = this._container.Resolve<TPresenter>(); TPresenter presenter = this._container.Resolve<TPresenter>();
presenter.Run(args); presenter.Run(args);
} }
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>();
}
return this._container.Resolve<TService>(); return this._container.Resolve<TService>();
} }
} }
} }

View File

@@ -3,53 +3,45 @@ 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_MESSAGE =
private const string EXCEPTION_DUMP_FILE_NAME = "EVE-O-Preview.log"; "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();
{ File.WriteAllText(ExceptionHandler.EXCEPTION_DUMP_FILE_NAME, exceptionMessage);
String exceptionMessage = exception.ToString();
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 }
}
System.Environment.Exit(1); System.Environment.Exit(1);
} }
} }
} }

View File

@@ -1,26 +1,22 @@
namespace EveOPreview namespace EveOPreview {
{ /// <summary>
/// <summary> /// Application controller
/// Application controller /// </summary>
/// </summary> public interface IApplicationController {
public interface IApplicationController IApplicationController RegisterView<TView, TPresenter>()
{ where TPresenter : class, TView
IApplicationController RegisterView<TView, TPresenter>() where TView : IView;
where TPresenter : class, TView
where TView : IView;
IApplicationController RegisterInstance<T>(T instance); IApplicationController RegisterInstance<T>(T instance);
IApplicationController RegisterService<TService, TImplementation>() IApplicationController RegisterService<TService, TImplementation>()
where TImplementation : class, TService; where TImplementation : class, TService;
void Run<TPresenter>() void Run<TPresenter>()
where TPresenter : class, IPresenter; where TPresenter : class, IPresenter;
void Run<TPresenter, TArgument>(TArgument args) void Run<TPresenter, TArgument>(TArgument args)
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>()
{ 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<TService, TImplementation>()
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>();
}
}

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,12 +1,10 @@
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 Hide();
void Show(); void Close();
void Hide(); }
void Close();
}
} }

View File

@@ -4,96 +4,76 @@ 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());
{ return;
this._container.Register(serviceType, new PerContainerLifetime()); }
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) continue;
{ }
if (!implementationType.IsClass || implementationType.IsAbstract)
{
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,22 +1,18 @@
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
{ // 'protected readonly' fields would result in non-CLS compliant code
// Properties are used instead of fields so the code remains CLS compliant protected TView View { get; private set; }
// 'protected readonly' fields would result in non-CLS compliant code protected IApplicationController Controller { get; private set; }
protected TView View { 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,19 +1,16 @@
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
{ // 'protected readonly' fields would result in non-CLS compliant code
// Properties are used instead of fields so the code remains CLS compliant protected TView View { get; private set; }
// 'protected readonly' fields would result in non-CLS compliant code protected IApplicationController Controller { get; private set; }
protected TView View { 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 abstract void Run(TArgument args); public abstract void Run(TArgument args);
} }
} }

View File

@@ -1,13 +1,10 @@
namespace EveOPreview.Configuration.Implementation namespace EveOPreview.Configuration.Implementation {
{ class AppConfig : IAppConfig {
class AppConfig : IAppConfig public AppConfig() {
{ // Default values
public AppConfig() this.ConfigFileName = null;
{ }
// Default values
this.ConfigFileName = null;
}
public string ConfigFileName { get; set; } public string ConfigFileName { get; set; }
} }
} }

View File

@@ -1,63 +1,52 @@
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);
JsonConvert.PopulateObject(rawData, this._thumbnailConfiguration, jsonSerializerSettings); JsonConvert.PopulateObject(rawData, this._thumbnailConfiguration, jsonSerializerSettings);
// Validate data after loading it // Validate data after loading it
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) {
} // Ignore error if for some reason the updated config cannot be written down
catch (IOException) }
{ }
// 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,438 +5,510 @@ 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
{ private bool _enablePerClientThumbnailLayouts;
#region Private fields private bool _enableClientLayoutTracking;
private bool _enablePerClientThumbnailLayouts; #endregion
private bool _enableClientLayoutTracking;
#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 Scout Toon 2", 2 },
{ "EVE - Example Logi Toon 1", 1 }, { "EVE - Example Tackle Toon 3", 3 } };
{ "EVE - Example Scout Toon 2", 2 },
{ "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.CycleGroup5BackwardHotkeys = new List<string> { "" };
this.CycleGroup5ForwardHotkeys = new List<string> { "" }; this.CycleGroup5ClientsOrder = new Dictionary<string, int> {
this.CycleGroup5BackwardHotkeys = new List<string> { "" }; { "EVE - cycle group 5", 1 },
this.CycleGroup5ClientsOrder = new Dictionary<string, int> };
{
{ "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 },
{"EVE - Example Toon 2", ZoomAnchor.S}
};
this.PerClientLayout = new Dictionary<string, Dictionary<string, Point>>(); this.PerClientZoomAnchor = new Dictionary<string, ZoomAnchor> { { "EVE - Example Toon 1", ZoomAnchor.N },
this.FlatLayout = new Dictionary<string, Point>(); { "EVE - Example Toon 2", ZoomAnchor.S } };
this.ClientLayout = new Dictionary<string, ClientLayout>();
this.ClientHotkey = new Dictionary<string, string>();
this.DisableThumbnail = new Dictionary<string, bool>();
this.PriorityClients = new List<string>();
this.ExecutablesToPreview = new List<string> { "exefile" }; this.PerClientLayout = new Dictionary<string, Dictionary<string, Point>>();
this.FlatLayout = new Dictionary<string, Point>();
this.ClientLayout = new Dictionary<string, ClientLayout>();
this.ClientHotkey = new Dictionary<string, string>();
this.DisableThumbnail = new Dictionary<string, bool>();
this.PriorityClients = new List<string>();
this.MinimizeToTray = false; this.ExecutablesToPreview = new List<string> { "exefile" };
this.ThumbnailRefreshPeriod = 500;
this.ThumbnailResizeTimeoutPeriod = 500; this.MinimizeToTray = false;
this.ThumbnailRefreshPeriod = 500;
this.ThumbnailResizeTimeoutPeriod = 500;
#if LINUX #if LINUX
this.EnableWineCompatibilityMode = true; this.EnableWineCompatibilityMode = true;
#else #else
this.EnableWineCompatibilityMode = false; this.EnableWineCompatibilityMode = false;
#endif #endif
this.ThumbnailOpacity = 0.5; this.ThumbnailOpacity = 0.5;
this.EnableClientLayoutTracking = false; this.EnableClientLayoutTracking = false;
this.HideActiveClientThumbnail = false; this.HideActiveClientThumbnail = false;
this.HideLoginClientThumbnail = false; this.HideLoginClientThumbnail = false;
this.MinimizeInactiveClients = false; this.MinimizeInactiveClients = false;
this.WindowsAnimationStyle = AnimationStyle.NoAnimation; this.WindowsAnimationStyle = AnimationStyle.NoAnimation;
this.ShowThumbnailsAlwaysOnTop = true; this.ShowThumbnailsAlwaysOnTop = true;
this.EnablePerClientThumbnailLayouts = false; this.EnablePerClientThumbnailLayouts = false;
this.HideThumbnailsOnLostFocus = false; this.HideThumbnailsOnLostFocus = false;
this.HideThumbnailsDelay = 2; // 2 thumbnails refresh cycles (1.0 sec) this.HideThumbnailsDelay = 2; // 2 thumbnails refresh cycles (1.0 sec)
this.ThumbnailSize = new Size(384, 216); this.ThumbnailSize = new Size(384, 216);
this.ThumbnailMinimumSize = new Size(192, 108); this.ThumbnailMinimumSize = new Size(192, 108);
this.ThumbnailMaximumSize = new Size(960, 540); this.ThumbnailMaximumSize = new Size(960, 540);
this.EnableThumbnailSnap = true; this.EnableThumbnailSnap = true;
this.ThumbnailZoomEnabled = false; this.ThumbnailZoomEnabled = false;
this.ThumbnailZoomFactor = 2; this.ThumbnailZoomFactor = 2;
this.ThumbnailZoomAnchor = ZoomAnchor.NW; this.ThumbnailZoomAnchor = ZoomAnchor.NW;
this.OverlayLabelAnchor = ZoomAnchor.NW; this.OverlayLabelAnchor = ZoomAnchor.NW;
this.ShowThumbnailOverlays = true; this.ShowThumbnailOverlays = true;
this.ShowThumbnailFrames = false; this.ShowThumbnailFrames = false;
this.LockThumbnailLocation = false; this.LockThumbnailLocation = false;
this.ThumbnailSnapToGrid = true; this.ThumbnailSnapToGrid = true;
this.ThumbnailSnapToGridSizeX = 100; this.ThumbnailSnapToGridSizeX = 100;
this.ThumbnailSnapToGridSizeY = 50; this.ThumbnailSnapToGridSizeY = 50;
this.EnableActiveClientHighlight = false; this.EnableActiveClientHighlight = false;
this.ActiveClientHighlightColor = Color.GreenYellow; this.ActiveClientHighlightColor = Color.GreenYellow;
this.ActiveClientHighlightThickness = 3; this.ActiveClientHighlightThickness = 3;
this.OverlayLabelColor = Color.Orange; this.OverlayLabelColor = Color.Orange;
this.OverlayLabelSize = 10; this.OverlayLabelSize = 10;
this.IconName = ""; this.EnableThumbnailRegionSnipping = false;
this.DefaultThumbnailRegion = new Rectangle(0, 0, 384, 216);
this.LoginThumbnailLocation = new Point(5, 5); this.CurrentProfile = "Default";
} this.AvailableProfiles = new List<string> { "Default" };
this.IconName = "";
[JsonProperty("ConfigVersion")] this.LoginThumbnailLocation = new Point(5, 5);
public int ConfigVersion { get; set; } }
[JsonProperty("CycleGroup1ForwardHotkeys")] [JsonProperty("ConfigVersion")]
public List<string> CycleGroup1ForwardHotkeys { get; set; } public int ConfigVersion { get; set; }
[JsonProperty("CycleGroup1BackwardHotkeys")] [JsonProperty("CycleGroup1ForwardHotkeys")]
public List<string> CycleGroup1BackwardHotkeys { get; set; } public List<string> CycleGroup1ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup1ClientsOrder")] [JsonProperty("CycleGroup1BackwardHotkeys")]
public Dictionary<string, int> CycleGroup1ClientsOrder { get; set; } public List<string> CycleGroup1BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup2ForwardHotkeys")] [JsonProperty("CycleGroup1ClientsOrder")]
public List<string> CycleGroup2ForwardHotkeys { get; set; } public Dictionary<string, int> CycleGroup1ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup2BackwardHotkeys")] [JsonProperty("CycleGroup2ForwardHotkeys")]
public List<string> CycleGroup2BackwardHotkeys { get; set; } public List<string> CycleGroup2ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup2ClientsOrder")] [JsonProperty("CycleGroup2BackwardHotkeys")]
public Dictionary<string, int> CycleGroup2ClientsOrder { get; set; } public List<string> CycleGroup2BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup3ForwardHotkeys")] [JsonProperty("CycleGroup2ClientsOrder")]
public List<string> CycleGroup3ForwardHotkeys { get; set; } public Dictionary<string, int> CycleGroup2ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup3BackwardHotkeys")] [JsonProperty("CycleGroup3ForwardHotkeys")]
public List<string> CycleGroup3BackwardHotkeys { get; set; } public List<string> CycleGroup3ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup3ClientsOrder")] [JsonProperty("CycleGroup3BackwardHotkeys")]
public Dictionary<string, int> CycleGroup3ClientsOrder { get; set; } public List<string> CycleGroup3BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup4ForwardHotkeys")] [JsonProperty("CycleGroup3ClientsOrder")]
public List<string> CycleGroup4ForwardHotkeys { get; set; } public Dictionary<string, int> CycleGroup3ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup4BackwardHotkeys")] [JsonProperty("CycleGroup4ForwardHotkeys")]
public List<string> CycleGroup4BackwardHotkeys { get; set; } public List<string> CycleGroup4ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup4ClientsOrder")] [JsonProperty("CycleGroup4BackwardHotkeys")]
public Dictionary<string, int> CycleGroup4ClientsOrder { get; set; } public List<string> CycleGroup4BackwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup5ForwardHotkeys")] [JsonProperty("CycleGroup4ClientsOrder")]
public List<string> CycleGroup5ForwardHotkeys { get; set; } public Dictionary<string, int> CycleGroup4ClientsOrder {
get; set;
}
[JsonProperty("CycleGroup5BackwardHotkeys")] [JsonProperty("CycleGroup5ForwardHotkeys")]
public List<string> CycleGroup5BackwardHotkeys { get; set; } public List<string> CycleGroup5ForwardHotkeys {
get; set;
}
[JsonProperty("CycleGroup5ClientsOrder")] [JsonProperty("CycleGroup5BackwardHotkeys")]
public Dictionary<string, int> CycleGroup5ClientsOrder { get; set; } public List<string> CycleGroup5BackwardHotkeys {
get; set;
}
[JsonProperty("PerClientActiveClientHighlightColor")] [JsonProperty("CycleGroup5ClientsOrder")]
public Dictionary<string, Color> PerClientActiveClientHighlightColor { get; set; } public Dictionary<string, int> CycleGroup5ClientsOrder {
get; set;
}
[JsonProperty("PerClientThumbnailSize")] [JsonProperty("PerClientActiveClientHighlightColor")]
public Dictionary<string, Size> PerClientThumbnailSize { get; set; } public Dictionary<string, Color> PerClientActiveClientHighlightColor {
get; set;
}
[JsonProperty("PerClientZoomAnchor")] [JsonProperty("PerClientThumbnailSize")]
public Dictionary<string, ZoomAnchor> PerClientZoomAnchor{ get; set; } public Dictionary<string, Size> PerClientThumbnailSize {
public bool MinimizeToTray { get; set; } get; set;
public int ThumbnailRefreshPeriod { get; set; } }
public int ThumbnailResizeTimeoutPeriod { get; set; }
[JsonProperty("WineCompatibilityMode")] [JsonProperty("PerClientThumbnailRegion")]
public bool EnableWineCompatibilityMode { get; set; } public Dictionary<string, Rectangle> PerClientThumbnailRegion {
get; set;
}
[JsonProperty("ThumbnailsOpacity")] [JsonProperty("PerClientZoomAnchor")]
public double ThumbnailOpacity { get; set; } public Dictionary<string, ZoomAnchor> PerClientZoomAnchor {
get; set;
}
public bool MinimizeToTray { get; set; }
public int ThumbnailRefreshPeriod { get; set; }
public int ThumbnailResizeTimeoutPeriod { get; set; }
public bool EnableClientLayoutTracking [JsonProperty("WineCompatibilityMode")]
{ public bool EnableWineCompatibilityMode {
get => this._enableClientLayoutTracking; get; set;
set }
{
if (!value)
{
this.ClientLayout.Clear();
}
this._enableClientLayoutTracking = value; [JsonProperty("ThumbnailsOpacity")]
} public double ThumbnailOpacity {
} get; set;
}
public bool HideActiveClientThumbnail { get; set; } public bool EnableClientLayoutTracking {
public bool HideLoginClientThumbnail { get; set; } get => this._enableClientLayoutTracking;
public bool MinimizeInactiveClients { get; set; } set {
public AnimationStyle WindowsAnimationStyle { get; set; } if (!value) {
public bool ShowThumbnailsAlwaysOnTop { get; set; } this.ClientLayout.Clear();
}
public bool EnablePerClientThumbnailLayouts this._enableClientLayoutTracking = value;
{ }
get => this._enablePerClientThumbnailLayouts; }
set
{
if (!value)
{
this.PerClientLayout.Clear();
}
this._enablePerClientThumbnailLayouts = value; public bool HideActiveClientThumbnail { get; set; }
} public bool HideLoginClientThumbnail { get; set; }
} public bool MinimizeInactiveClients { get; set; }
public AnimationStyle WindowsAnimationStyle { get; set; }
public bool ShowThumbnailsAlwaysOnTop { get; set; }
public bool HideThumbnailsOnLostFocus { get; set; } public bool EnablePerClientThumbnailLayouts {
public int HideThumbnailsDelay { get; set; } get => this._enablePerClientThumbnailLayouts;
set {
if (!value) {
this.PerClientLayout.Clear();
}
public Size ThumbnailSize { get; set; } this._enablePerClientThumbnailLayouts = value;
public Size ThumbnailMaximumSize { get; set; } }
public Size ThumbnailMinimumSize { get; set; } }
public bool EnableThumbnailSnap { get; set; } public bool HideThumbnailsOnLostFocus { get; set; }
public int HideThumbnailsDelay { get; set; }
[JsonProperty("EnableThumbnailZoom")] public Size ThumbnailSize { get; set; }
public bool ThumbnailZoomEnabled { get; set; } public Size ThumbnailMaximumSize { get; set; }
public int ThumbnailZoomFactor { get; set; } public Size ThumbnailMinimumSize { get; set; }
public ZoomAnchor ThumbnailZoomAnchor { get; set; }
public ZoomAnchor OverlayLabelAnchor { get; set; }
public bool ShowThumbnailOverlays { get; set; } public bool EnableThumbnailSnap { get; set; }
public bool ShowThumbnailFrames { get; set; }
public bool LockThumbnailLocation { get; set; }
public bool ThumbnailSnapToGrid { get; set; }
public int ThumbnailSnapToGridSizeX { get; set; }
public int ThumbnailSnapToGridSizeY { get; set; }
public bool EnableActiveClientHighlight { get; set; } [JsonProperty("EnableThumbnailZoom")]
public bool ThumbnailZoomEnabled {
get; set;
}
public int ThumbnailZoomFactor { get; set; }
public ZoomAnchor ThumbnailZoomAnchor { get; set; }
public ZoomAnchor OverlayLabelAnchor { get; set; }
public Color ActiveClientHighlightColor { get; set; } public bool ShowThumbnailOverlays { get; set; }
public Color OverlayLabelColor { get; set; } public bool ShowThumbnailFrames { get; set; }
public int OverlayLabelSize { get; set; } public bool LockThumbnailLocation { get; set; }
[JsonProperty("IconName")] public bool ThumbnailSnapToGrid { get; set; }
public string IconName { get; set; } public int ThumbnailSnapToGridSizeX { get; set; }
public int ThumbnailSnapToGridSizeY { get; set; }
public int ActiveClientHighlightThickness { get; set; } public bool EnableActiveClientHighlight { get; set; }
[JsonProperty("LoginThumbnailLocation")] public Color ActiveClientHighlightColor { get; set; }
public Point LoginThumbnailLocation { get; set; } public Color OverlayLabelColor { get; set; }
public int OverlayLabelSize { get; set; }
[JsonProperty("ToggleTrackingHotkey")] public bool EnableThumbnailRegionSnipping { get; set; }
public string ToggleTrackingHotkey { get; set; } public Rectangle DefaultThumbnailRegion { get; set; }
[JsonProperty] public string CurrentProfile { get; set; }
private Dictionary<string, Dictionary<string, Point>> PerClientLayout { get; set; } public List<string> AvailableProfiles { get; set; }
[JsonProperty] [JsonProperty("IconName")]
private Dictionary<string, Point> FlatLayout { get; set; } public string IconName {
[JsonProperty] get; set;
private Dictionary<string, ClientLayout> ClientLayout { get; set; } }
[JsonProperty]
private Dictionary<string, string> ClientHotkey { get; set; }
[JsonProperty]
private Dictionary<string, bool> DisableThumbnail { get; set; }
[JsonProperty]
private List<string> PriorityClients { get; set; }
[JsonProperty]
public List<string> ExecutablesToPreview { get; set; }
public Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation) public int ActiveClientHighlightThickness { get; set; }
{
Point location;
// What this code does: [JsonProperty("LoginThumbnailLocation")]
// If Per-Client layouts are enabled public Point LoginThumbnailLocation {
// and client name is known get; set;
// and there is a separate thumbnails layout for this client }
// and this layout contains an entry for the current client
// then return that entry
// otherwise try to get client layout from the flat all-clients layout
// If there is no layout too then use the default one
if (this.EnablePerClientThumbnailLayouts && !string.IsNullOrEmpty(activeClient))
{
Dictionary<string, Point> layoutSource;
if (this.PerClientLayout.TryGetValue(activeClient, out layoutSource) && layoutSource.TryGetValue(currentClient, out location))
{
return location;
}
}
return this.FlatLayout.TryGetValue(currentClient, out location) ? location : defaultLocation; [JsonProperty("ToggleTrackingHotkey")]
} public string ToggleTrackingHotkey {
get; set;
}
public Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize) [JsonProperty]
{ private Dictionary<string, Dictionary<string, Point>> PerClientLayout {
Size sizeOfThumbnail; get; set;
return this.PerClientThumbnailSize.TryGetValue(currentClient, out sizeOfThumbnail) ? sizeOfThumbnail : defaultSize; }
} [JsonProperty]
public ZoomAnchor GetZoomAnchor(string currentClient, ZoomAnchor defaultZoomAnchor) private Dictionary<string, Point> FlatLayout {
{ get; set;
ZoomAnchor zoomAnchor; }
return this.PerClientZoomAnchor.TryGetValue(currentClient, out zoomAnchor) ? zoomAnchor : defaultZoomAnchor; [JsonProperty]
} private Dictionary<string, ClientLayout> ClientLayout {
get; set;
}
[JsonProperty]
private Dictionary<string, string> ClientHotkey {
get; set;
}
[JsonProperty]
private Dictionary<string, bool> DisableThumbnail {
get; set;
}
[JsonProperty]
private List<string> PriorityClients {
get; set;
}
[JsonProperty]
public List<string> ExecutablesToPreview {
get; set;
}
public void SetThumbnailLocation(string currentClient, string activeClient, Point location) public Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation) {
{ Point location;
Dictionary<string, Point> layoutSource;
if (this.EnablePerClientThumbnailLayouts) // What this code does:
{ // If Per-Client layouts are enabled
if (string.IsNullOrEmpty(activeClient)) // and client name is known
{ // and there is a separate thumbnails layout for this client
return; // and this layout contains an entry for the current client
} // then return that entry
// otherwise try to get client layout from the flat all-clients layout
// If there is no layout too then use the default one
if (this.EnablePerClientThumbnailLayouts && !string.IsNullOrEmpty(activeClient)) {
Dictionary<string, Point> layoutSource;
if (this.PerClientLayout.TryGetValue(activeClient, out layoutSource) &&
layoutSource.TryGetValue(currentClient, out location)) {
return location;
}
}
if (!this.PerClientLayout.TryGetValue(activeClient, out layoutSource)) return this.FlatLayout.TryGetValue(currentClient, out location) ? location : defaultLocation;
{ }
layoutSource = new Dictionary<string, Point>();
this.PerClientLayout[activeClient] = layoutSource;
}
}
else
{
layoutSource = this.FlatLayout;
}
layoutSource[currentClient] = location; public Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize) {
} Size sizeOfThumbnail;
return this.PerClientThumbnailSize.TryGetValue(currentClient, out sizeOfThumbnail) ? sizeOfThumbnail
: defaultSize;
}
public ClientLayout GetClientLayout(string currentClient) public Rectangle GetThumbnailRegion(string currentClient, Rectangle defaultRegion) {
{ Rectangle region;
ClientLayout layout; return this.PerClientThumbnailRegion.TryGetValue(currentClient, out region) ? region : defaultRegion;
this.ClientLayout.TryGetValue(currentClient, out layout); }
return layout; public ZoomAnchor GetZoomAnchor(string currentClient, ZoomAnchor defaultZoomAnchor) {
} ZoomAnchor zoomAnchor;
return this.PerClientZoomAnchor.TryGetValue(currentClient, out zoomAnchor) ? zoomAnchor : defaultZoomAnchor;
}
public void SetClientLayout(string currentClient, ClientLayout layout) public void SetThumbnailLocation(string currentClient, string activeClient, Point location) {
{ Dictionary<string, Point> layoutSource;
this.ClientLayout[currentClient] = layout;
}
public Keys GetClientHotkey(string currentClient) if (this.EnablePerClientThumbnailLayouts) {
{ if (string.IsNullOrEmpty(activeClient)) {
string hotkey; return;
if (this.ClientHotkey.TryGetValue(currentClient, out hotkey)) }
{
// Protect from incorrect values
object rawValue = (new KeysConverter()).ConvertFromInvariantString(hotkey);
return rawValue != null ? (Keys)rawValue : Keys.None;
}
return Keys.None; if (!this.PerClientLayout.TryGetValue(activeClient, out layoutSource)) {
} layoutSource = new Dictionary<string, Point>();
this.PerClientLayout[activeClient] = layoutSource;
}
} else {
layoutSource = this.FlatLayout;
}
public void SetClientHotkey(string currentClient, Keys hotkey) layoutSource[currentClient] = location;
{ }
this.ClientHotkey[currentClient] = (new KeysConverter()).ConvertToInvariantString(hotkey);
}
public Keys StringToKey(string hotkey) public void SetThumbnailRegion(string currentClient, Rectangle region) {
{ this.PerClientThumbnailRegion[currentClient] = region;
object rawValue = (new KeysConverter()).ConvertFromInvariantString(hotkey); }
return rawValue != null ? (Keys)rawValue : Keys.None;
}
public bool IsPriorityClient(string currentClient) public void SaveProfile(string profileName) {
{ if (!this.AvailableProfiles.Contains(profileName)) {
return this.PriorityClients.Contains(currentClient); this.AvailableProfiles.Add(profileName);
} }
public bool IsExecutableToPreview(string processName) this.CurrentProfile = profileName;
{ }
return this.ExecutablesToPreview.Any(s => s.Equals(processName, StringComparison.OrdinalIgnoreCase));
}
public bool IsThumbnailDisabled(string currentClient) public void LoadProfile(string profileName) {
{ if (this.AvailableProfiles.Contains(profileName)) {
return this.DisableThumbnail.TryGetValue(currentClient, out bool isDisabled) && isDisabled; this.CurrentProfile = profileName;
} }
}
public void ToggleThumbnail(string currentClient, bool isDisabled) public void DeleteProfile(string profileName) {
{ if (profileName != "Default" && this.AvailableProfiles.Contains(profileName)) {
this.DisableThumbnail[currentClient] = isDisabled; this.AvailableProfiles.Remove(profileName);
} if (this.CurrentProfile == profileName) {
this.CurrentProfile = "Default";
}
}
}
/// <summary> public ClientLayout GetClientLayout(string currentClient) {
/// Applies restrictions to different parameters of the config ClientLayout layout;
/// </summary> this.ClientLayout.TryGetValue(currentClient, out layout);
public void ApplyRestrictions()
{ return layout;
}
public void SetClientLayout(string currentClient, ClientLayout layout) {
this.ClientLayout[currentClient] = layout;
}
public Keys GetClientHotkey(string currentClient) {
string hotkey;
if (this.ClientHotkey.TryGetValue(currentClient, out hotkey)) {
// Protect from incorrect values
object rawValue = (new KeysConverter()).ConvertFromInvariantString(hotkey);
return rawValue != null ? (Keys)rawValue : Keys.None;
}
return Keys.None;
}
public void SetClientHotkey(string currentClient, Keys hotkey) {
this.ClientHotkey[currentClient] = (new KeysConverter()).ConvertToInvariantString(hotkey);
}
public Keys StringToKey(string hotkey) {
object rawValue = (new KeysConverter()).ConvertFromInvariantString(hotkey);
return rawValue != null ? (Keys)rawValue : Keys.None;
}
public bool IsPriorityClient(string currentClient) {
return this.PriorityClients.Contains(currentClient);
}
public bool IsExecutableToPreview(string processName) {
return this.ExecutablesToPreview.Any(s => s.Equals(processName, StringComparison.OrdinalIgnoreCase));
}
public bool IsThumbnailDisabled(string currentClient) {
return this.DisableThumbnail.TryGetValue(currentClient, out bool isDisabled) && isDisabled;
}
public void ToggleThumbnail(string currentClient, bool isDisabled) {
this.DisableThumbnail[currentClient] = isDisabled;
}
/// <summary>
/// Applies restrictions to different parameters of the config
/// </summary>
public void ApplyRestrictions() {
#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.ThumbnailZoomFactor = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailZoomFactor, 2, 10); this.ThumbnailMaximumSize.Width),
this.ActiveClientHighlightThickness = ThumbnailConfiguration.ApplyRestrictions(this.ActiveClientHighlightThickness, 1, 6); ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailSize.Height, this.ThumbnailMinimumSize.Height,
} this.ThumbnailMaximumSize.Height));
this.ThumbnailOpacity =
ThumbnailConfiguration.ApplyRestrictions((int)(this.ThumbnailOpacity * 100.00), 20, 100) / 100.00;
this.ThumbnailZoomFactor = ThumbnailConfiguration.ApplyRestrictions(this.ThumbnailZoomFactor, 2, 10);
this.ActiveClientHighlightThickness =
ThumbnailConfiguration.ApplyRestrictions(this.ActiveClientHighlightThickness, 1, 6);
}
private static int ApplyRestrictions(int value, int minimum, int maximum) 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; }
}
return value; return value;
} }
} }
} }

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,28 +1,23 @@
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; this.Height = height;
this.Height = height; this.IsMaximized = maximized;
this.IsMaximized = maximized; }
}
public int X { get; set; } public int X { get; set; }
public int Y { get; set; } public int Y { get; set; }
public int Width { get; set; } public int Width { get; set; }
public int Height { get; set; } public int Height { get; set; }
public bool IsMaximized { get; set; } public bool IsMaximized { get; set; }
} }
} }

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,8 +1,6 @@
namespace EveOPreview.Configuration namespace EveOPreview.Configuration {
{ public interface IConfigurationStorage {
public interface IConfigurationStorage void Load();
{ void Save();
void Load(); }
void Save();
}
} }

View File

@@ -2,100 +2,111 @@
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> CycleGroup1BackwardHotkeys { get; set; }
List<string> CycleGroup1ForwardHotkeys { get; set; } Dictionary<string, int> CycleGroup1ClientsOrder { get; set; }
List<string> CycleGroup1BackwardHotkeys { get; set; }
Dictionary<string, int> CycleGroup1ClientsOrder { get; set; }
List<string> CycleGroup2ForwardHotkeys { get; set; } List<string> CycleGroup2ForwardHotkeys { get; set; }
List<string> CycleGroup2BackwardHotkeys { get; set; } List<string> CycleGroup2BackwardHotkeys { get; set; }
Dictionary<string, int> CycleGroup2ClientsOrder { get; set; } Dictionary<string, int> CycleGroup2ClientsOrder { get; set; }
List<string> CycleGroup3ForwardHotkeys { get; set; } List<string> CycleGroup3ForwardHotkeys { get; set; }
List<string> CycleGroup3BackwardHotkeys { get; set; } List<string> CycleGroup3BackwardHotkeys { get; set; }
Dictionary<string, int> CycleGroup3ClientsOrder { get; set; } Dictionary<string, int> CycleGroup3ClientsOrder { get; set; }
List<string> CycleGroup4ForwardHotkeys { get; set; } List<string> CycleGroup4ForwardHotkeys { get; set; }
List<string> CycleGroup4BackwardHotkeys { get; set; } List<string> CycleGroup4BackwardHotkeys { get; set; }
Dictionary<string, int> CycleGroup4ClientsOrder { get; set; } Dictionary<string, int> CycleGroup4ClientsOrder { get; set; }
List<string> CycleGroup5ForwardHotkeys { get; set; } List<string> CycleGroup5ForwardHotkeys { get; set; }
List<string> CycleGroup5BackwardHotkeys { get; set; } List<string> CycleGroup5BackwardHotkeys { get; set; }
Dictionary<string, int> CycleGroup5ClientsOrder { get; set; } Dictionary<string, int> CycleGroup5ClientsOrder { get; set; }
string ToggleTrackingHotkey { get; set; } string ToggleTrackingHotkey { get; set; }
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; }
int ThumbnailResizeTimeoutPeriod { get; set; } int ThumbnailResizeTimeoutPeriod { get; set; }
bool EnableWineCompatibilityMode { get; set; } bool EnableWineCompatibilityMode { get; set; }
double ThumbnailOpacity { get; set; } double ThumbnailOpacity { get; set; }
bool EnableClientLayoutTracking { get; set; } bool EnableClientLayoutTracking { get; set; }
bool HideActiveClientThumbnail { get; set; } bool HideActiveClientThumbnail { get; set; }
bool HideLoginClientThumbnail { get; set; } bool HideLoginClientThumbnail { get; set; }
bool MinimizeInactiveClients { get; set; } bool MinimizeInactiveClients { get; set; }
AnimationStyle WindowsAnimationStyle { get; set; } AnimationStyle WindowsAnimationStyle { get; set; }
bool ShowThumbnailsAlwaysOnTop { get; set; } bool ShowThumbnailsAlwaysOnTop { get; set; }
bool EnablePerClientThumbnailLayouts { get; set; } bool EnablePerClientThumbnailLayouts { get; set; }
bool HideThumbnailsOnLostFocus { get; set; } bool HideThumbnailsOnLostFocus { get; set; }
int HideThumbnailsDelay { get; set; } int HideThumbnailsDelay { get; set; }
Size ThumbnailSize { get; set; } Size ThumbnailSize { get; set; }
Size ThumbnailMinimumSize { get; set; } Size ThumbnailMinimumSize { get; set; }
Size ThumbnailMaximumSize { get; set; } Size ThumbnailMaximumSize { get; set; }
bool EnableThumbnailSnap { get; set; } bool EnableThumbnailSnap { get; set; }
bool ThumbnailZoomEnabled { get; set; } bool ThumbnailZoomEnabled { get; set; }
int ThumbnailZoomFactor { get; set; } int ThumbnailZoomFactor { get; set; }
ZoomAnchor ThumbnailZoomAnchor { get; set; } ZoomAnchor ThumbnailZoomAnchor { get; set; }
ZoomAnchor OverlayLabelAnchor { get; set; } ZoomAnchor OverlayLabelAnchor { get; set; }
bool ShowThumbnailOverlays { get; set; } bool ShowThumbnailOverlays { get; set; }
bool ShowThumbnailFrames { get; set; } bool ShowThumbnailFrames { get; set; }
bool LockThumbnailLocation { get; set; } bool LockThumbnailLocation { get; set; }
bool ThumbnailSnapToGrid { get; set; } bool ThumbnailSnapToGrid { get; set; }
int ThumbnailSnapToGridSizeX { get; set; } int ThumbnailSnapToGridSizeX { get; set; }
int ThumbnailSnapToGridSizeY { get; set; } int ThumbnailSnapToGridSizeY { get; set; }
bool EnableActiveClientHighlight { get; set; } bool EnableActiveClientHighlight { get; set; }
Color ActiveClientHighlightColor { get; set; } Color ActiveClientHighlightColor { get; set; }
int ActiveClientHighlightThickness { get; set; } int ActiveClientHighlightThickness { get; set; }
Color OverlayLabelColor { get; set; } Color OverlayLabelColor { get; set; }
int OverlayLabelSize { get; set; } int OverlayLabelSize { get; set; }
string IconName { get; set; } bool EnableThumbnailRegionSnipping { get; set; }
Rectangle DefaultThumbnailRegion { get; set; }
Point LoginThumbnailLocation { get; set; } string CurrentProfile { get; set; }
List<string> AvailableProfiles { get; set; }
Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation); string IconName { get; set; }
Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize);
ZoomAnchor GetZoomAnchor(string currentClient, ZoomAnchor defaultZoomAnchor);
void SetThumbnailLocation(string currentClient, string activeClient, Point location);
ClientLayout GetClientLayout(string currentClient); Point LoginThumbnailLocation { get; set; }
void SetClientLayout(string currentClient, ClientLayout layout);
Keys GetClientHotkey(string currentClient); Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation);
void SetClientHotkey(string currentClient, Keys hotkey); Size GetThumbnailSize(string currentClient, string activeClient, Size defaultSize);
Keys StringToKey(string hotkey); ZoomAnchor GetZoomAnchor(string currentClient, ZoomAnchor defaultZoomAnchor);
Rectangle GetThumbnailRegion(string currentClient, Rectangle defaultRegion);
void SetThumbnailLocation(string currentClient, string activeClient, Point location);
void SetThumbnailRegion(string currentClient, Rectangle region);
bool IsPriorityClient(string currentClient); void SaveProfile(string profileName);
bool IsExecutableToPreview(string processName); void LoadProfile(string profileName);
List<string> ExecutablesToPreview { get; set; } void DeleteProfile(string profileName);
bool IsThumbnailDisabled(string currentClient); ClientLayout GetClientLayout(string currentClient);
void ToggleThumbnail(string currentClient, bool isDisabled); void SetClientLayout(string currentClient, ClientLayout layout);
void ApplyRestrictions(); Keys GetClientHotkey(string currentClient);
} void SetClientHotkey(string currentClient, Keys hotkey);
Keys StringToKey(string hotkey);
bool IsPriorityClient(string currentClient);
bool IsExecutableToPreview(string processName);
List<string> ExecutablesToPreview { get; set; }
bool IsThumbnailDisabled(string currentClient);
void ToggleThumbnail(string currentClient, bool isDisabled);
void ApplyRestrictions();
}
} }

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,131 +2,114 @@ 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 const int MAX_ID = 0xBFFF;
private static int _currentId;
private const int MAX_ID = 0xBFFF;
#region Private fields #region Private fields
private readonly int _hotkeyId; private readonly int _hotkeyId;
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;
this._hotkeyTarget = target; this._hotkeyTarget = target;
// Assign properties // Assign properties
this.IsRegistered = false; this.IsRegistered = false;
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(); }
}
public bool IsRegistered { get; private set; } public bool IsRegistered { get; private set; }
public Keys KeyCode { get; private set; } public Keys KeyCode { get; private set; }
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
{ this.Unregister();
// Unregister and say we managed it return true;
this.Unregister(); }
return true;
}
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; }
}
// Remove all modifiers from the 'main' hotkey // Remove all modifiers from the 'main' hotkey
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; }
}
Application.AddMessageFilter(this); Application.AddMessageFilter(this);
this.IsRegistered = true; this.IsRegistered = true;
// We successfully registered // We successfully registered
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;
}
this.IsRegistered = false; this.IsRegistered = false;
Application.RemoveMessageFilter(this); Application.RemoveMessageFilter(this);
// Clean up after ourselves // Clean up after ourselves
HotkeyHandlerNativeMethods.UnregisterHotKey(this._hotkeyTarget, this._hotkeyId); HotkeyHandlerNativeMethods.UnregisterHotKey(this._hotkeyTarget, this._hotkeyId);
} }
#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) #endregion
&& this.OnPressed();
}
#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);
// Return whether we handled the event or not // Return whether we handled the event or not
return handledEventArgs.Handled; return handledEventArgs.Handled;
} }
} }
} }

View File

@@ -1,23 +1,21 @@
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")]
{ public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id); public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
public const uint WM_HOTKEY = 0x0312; public const uint WM_HOTKEY = 0x0312;
public const uint MOD_ALT = 0x1; public const uint MOD_ALT = 0x1;
public const uint MOD_CONTROL = 0x2; public const uint MOD_CONTROL = 0x2;
public const uint MOD_SHIFT = 0x4; public const uint MOD_SHIFT = 0x4;
public const uint MOD_WIN = 0x8; public const uint MOD_WIN = 0x8;
public const uint ERROR_HOTKEY_ALREADY_REGISTERED = 1409; public const uint ERROR_HOTKEY_ALREADY_REGISTERED = 1409;
} }
} }

View File

@@ -4,22 +4,18 @@ 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,29 +4,24 @@ 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,22 +4,18 @@ 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,22 +4,18 @@ 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,22 +4,18 @@ 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,32 +4,26 @@ 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
{ private readonly IMainFormPresenter _presenter;
#region Private fields #endregion
private readonly IMainFormPresenter _presenter;
#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); }
}
return Task.CompletedTask;
return Task.CompletedTask; }
} }
}
} }

View File

@@ -4,24 +4,21 @@ 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 IThumbnailConfiguration _configuration;
private readonly IMediator _mediator;
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,14 +1,11 @@
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) {
{ this.Value = value;
protected NotificationBase(TValue value) }
{
this.Value = value;
}
public TValue Value { get; } public TValue Value { get; }
} }
} }

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,17 +1,14 @@
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) {
{ this.Added = addedThumbnails;
public ThumbnailListUpdated(IList<string> addedThumbnails, IList<string> removedThumbnails) this.Removed = removedThumbnails;
{ }
this.Added = addedThumbnails;
this.Removed = removedThumbnails;
}
public IList<string> Added { get; } public IList<string> Added { get; }
public IList<string> Removed { get; } public IList<string> Removed { get; }
} }
} }

View File

@@ -1,21 +1,18 @@
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) {
{ this.ThumbnailName = thumbnailName;
public ThumbnailLocationUpdated(string thumbnailName, string activeClientName, Point location) this.ActiveClientName = activeClientName;
{ this.Location = location;
this.ThumbnailName = thumbnailName; }
this.ActiveClientName = activeClientName;
this.Location = location;
}
public string ThumbnailName { get; } public string ThumbnailName { get; }
public string ActiveClientName { get; } public string ActiveClientName { get; }
public Point Location { get; } public Point Location { get; }
} }
} }

View File

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

View File

@@ -4,280 +4,274 @@ 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
{ private const string FORUM_URL = @"https://forum.eveonline.com/t/4202";
#region Private constants #endregion
private const string FORUM_URL = @"https://forum.eveonline.com/t/4202";
#endregion
#region Private fields #region Private fields
private readonly IMediator _mediator; private readonly IMediator _mediator;
private readonly IThumbnailConfiguration _configuration; private readonly IThumbnailConfiguration _configuration;
private readonly IConfigurationStorage _configurationStorage; private readonly IConfigurationStorage _configurationStorage;
private readonly IDictionary<string, IThumbnailDescription> _descriptionsCache; private readonly IDictionary<string, IThumbnailDescription> _descriptionsCache;
private bool _suppressSizeNotifications; private bool _suppressSizeNotifications;
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;
this._descriptionsCache = new Dictionary<string, IThumbnailDescription>(); this._descriptionsCache = new Dictionary<string, IThumbnailDescription>();
this._suppressSizeNotifications = false; this._suppressSizeNotifications = false;
this._exitApplication = false; this._exitApplication = false;
this.View.FormActivated = this.Activate; this.View.FormActivated = this.Activate;
this.View.FormMinimized = this.Minimize; this.View.FormMinimized = this.Minimize;
this.View.FormCloseRequested = this.Close; this.View.FormCloseRequested = this.Close;
this.View.ApplicationSettingsChanged = this.SaveApplicationSettings; this.View.ApplicationSettingsChanged = this.SaveApplicationSettings;
this.View.ThumbnailsSizeChanged = this.UpdateThumbnailsSize; this.View.ThumbnailsSizeChanged = this.UpdateThumbnailsSize;
this.View.ThumbnailStateChanged = this.UpdateThumbnailState; this.View.ThumbnailStateChanged = this.UpdateThumbnailState;
this.View.DocumentationLinkActivated = this.OpenDocumentationLink; this.View.DocumentationLinkActivated = this.OpenDocumentationLink;
this.View.ApplicationExitRequested = this.ExitApplication; this.View.ApplicationExitRequested = this.ExitApplication;
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();
}
this._mediator.Send(new StartService()); this._mediator.Send(new StartService());
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();
request.Allow = true; request.Allow = true;
return; return;
} }
request.Allow = false; request.Allow = false;
this.View.Minimize(); this.View.Minimize();
} }
private async void UpdateThumbnailsSize() private async void UpdateThumbnailsSize() {
{ if (!this._suppressSizeNotifications) {
if (!this._suppressSizeNotifications) this.SaveApplicationSettings();
{ await this._mediator.Publish(new ThumbnailConfiguredSizeUpdated());
this.SaveApplicationSettings(); }
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;
this.View.ThumbnailOpacity = this._configuration.ThumbnailOpacity; this.View.ThumbnailOpacity = this._configuration.ThumbnailOpacity;
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 =
this.View.ShowThumbnailsAlwaysOnTop = this._configuration.ShowThumbnailsAlwaysOnTop; ViewAnimationStyleConverter.Convert(this._configuration.WindowsAnimationStyle);
this.View.HideThumbnailsOnLostFocus = this._configuration.HideThumbnailsOnLostFocus; this.View.ShowThumbnailsAlwaysOnTop = this._configuration.ShowThumbnailsAlwaysOnTop;
this.View.EnablePerClientThumbnailLayouts = this._configuration.EnablePerClientThumbnailLayouts; this.View.HideThumbnailsOnLostFocus = this._configuration.HideThumbnailsOnLostFocus;
this.View.EnablePerClientThumbnailLayouts = this._configuration.EnablePerClientThumbnailLayouts;
this.View.SetThumbnailSizeLimitations(this._configuration.ThumbnailMinimumSize, this._configuration.ThumbnailMaximumSize); this.View.SetThumbnailSizeLimitations(this._configuration.ThumbnailMinimumSize,
this.View.ThumbnailSize = this._configuration.ThumbnailSize; this._configuration.ThumbnailMaximumSize);
this.View.ThumbnailSize = this._configuration.ThumbnailSize;
this.View.EnableThumbnailZoom = this._configuration.ThumbnailZoomEnabled; this.View.EnableThumbnailZoom = this._configuration.ThumbnailZoomEnabled;
this.View.ThumbnailZoomFactor = this._configuration.ThumbnailZoomFactor; this.View.ThumbnailZoomFactor = this._configuration.ThumbnailZoomFactor;
this.View.ThumbnailZoomAnchor = ViewZoomAnchorConverter.Convert(this._configuration.ThumbnailZoomAnchor); this.View.ThumbnailZoomAnchor = ViewZoomAnchorConverter.Convert(this._configuration.ThumbnailZoomAnchor);
this.View.OverlayLabelAnchor = ViewZoomAnchorConverter.Convert(this._configuration.OverlayLabelAnchor); this.View.OverlayLabelAnchor = ViewZoomAnchorConverter.Convert(this._configuration.OverlayLabelAnchor);
this.View.ShowThumbnailOverlays = this._configuration.ShowThumbnailOverlays; this.View.ShowThumbnailOverlays = this._configuration.ShowThumbnailOverlays;
this.View.ShowThumbnailFrames = this._configuration.ShowThumbnailFrames; this.View.ShowThumbnailFrames = this._configuration.ShowThumbnailFrames;
this.View.LockThumbnailLocation = this._configuration.LockThumbnailLocation; this.View.LockThumbnailLocation = this._configuration.LockThumbnailLocation;
this.View.ThumbnailSnapToGrid = this._configuration.ThumbnailSnapToGrid; this.View.ThumbnailSnapToGrid = this._configuration.ThumbnailSnapToGrid;
this.View.ThumbnailSnapToGridSizeX = this._configuration.ThumbnailSnapToGridSizeX; this.View.ThumbnailSnapToGridSizeX = this._configuration.ThumbnailSnapToGridSizeX;
this.View.ThumbnailSnapToGridSizeY = this._configuration.ThumbnailSnapToGridSizeY; this.View.ThumbnailSnapToGridSizeY = this._configuration.ThumbnailSnapToGridSizeY;
this.View.EnableActiveClientHighlight = this._configuration.EnableActiveClientHighlight; this.View.EnableActiveClientHighlight = this._configuration.EnableActiveClientHighlight;
this.View.ActiveClientHighlightColor = this._configuration.ActiveClientHighlightColor; this.View.ActiveClientHighlightColor = this._configuration.ActiveClientHighlightColor;
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.IconName = this._configuration.IconName; this.View.EnableThumbnailRegionSnipping = this._configuration.EnableThumbnailRegionSnipping;
} this.View.DefaultThumbnailRegion = this._configuration.DefaultThumbnailRegion;
private async void SaveApplicationSettings() this.View.AvailableProfiles = this._configuration.AvailableProfiles;
{ this.View.CurrentProfile = this._configuration.CurrentProfile;
this._configuration.MinimizeToTray = this.View.MinimizeToTray;
this._configuration.ThumbnailOpacity = (float)this.View.ThumbnailOpacity; this.View.IconName = this._configuration.IconName;
}
this._configuration.EnableClientLayoutTracking = this.View.EnableClientLayoutTracking; private async void SaveApplicationSettings() {
this._configuration.HideActiveClientThumbnail = this.View.HideActiveClientThumbnail; this._configuration.MinimizeToTray = this.View.MinimizeToTray;
this._configuration.MinimizeInactiveClients = this.View.MinimizeInactiveClients;
this._configuration.WindowsAnimationStyle = ViewAnimationStyleConverter.Convert(this.View.WindowsAnimationStyle); this._configuration.ThumbnailOpacity = (float)this.View.ThumbnailOpacity;
this._configuration.EnableClientLayoutTracking = this.View.EnableClientLayoutTracking;
this._configuration.HideActiveClientThumbnail = this.View.HideActiveClientThumbnail;
this._configuration.MinimizeInactiveClients = this.View.MinimizeInactiveClients;
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;
this._configuration.ThumbnailSize = this.View.ThumbnailSize; this._configuration.ThumbnailSize = this.View.ThumbnailSize;
this._configuration.ThumbnailZoomEnabled = this.View.EnableThumbnailZoom; this._configuration.ThumbnailZoomEnabled = this.View.EnableThumbnailZoom;
this._configuration.ThumbnailZoomFactor = this.View.ThumbnailZoomFactor; this._configuration.ThumbnailZoomFactor = this.View.ThumbnailZoomFactor;
this._configuration.ThumbnailZoomAnchor = ViewZoomAnchorConverter.Convert(this.View.ThumbnailZoomAnchor); this._configuration.ThumbnailZoomAnchor = ViewZoomAnchorConverter.Convert(this.View.ThumbnailZoomAnchor);
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()); }
}
this._configuration.LockThumbnailLocation = this.View.LockThumbnailLocation; this._configuration.LockThumbnailLocation = this.View.LockThumbnailLocation;
this._configuration.ThumbnailSnapToGrid = this.View.ThumbnailSnapToGrid; this._configuration.ThumbnailSnapToGrid = this.View.ThumbnailSnapToGrid;
this._configuration.ThumbnailSnapToGridSizeX = this.View.ThumbnailSnapToGridSizeX; this._configuration.ThumbnailSnapToGridSizeX = this.View.ThumbnailSnapToGridSizeX;
this._configuration.ThumbnailSnapToGridSizeY = this.View.ThumbnailSnapToGridSizeY; this._configuration.ThumbnailSnapToGridSizeY = this.View.ThumbnailSnapToGridSizeY;
this._configuration.EnableActiveClientHighlight = this.View.EnableActiveClientHighlight; this._configuration.EnableActiveClientHighlight = this.View.EnableActiveClientHighlight;
this._configuration.ActiveClientHighlightColor = this.View.ActiveClientHighlightColor; this._configuration.ActiveClientHighlightColor = this.View.ActiveClientHighlightColor;
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.IconName = this.View.IconName; this._configuration.EnableThumbnailRegionSnipping = this.View.EnableThumbnailRegionSnipping;
this._configuration.DefaultThumbnailRegion = this.View.DefaultThumbnailRegion;
this._configurationStorage.Save(); this._configuration.AvailableProfiles = this.View.AvailableProfiles;
this._configuration.CurrentProfile = this.View.CurrentProfile;
this.View.RefreshZoomSettings(); // 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());
}
await this._mediator.Send(new SaveConfiguration()); this._configuration.IconName = this.View.IconName;
}
this._configurationStorage.Save();
public void AddThumbnails(IList<string> thumbnailTitles) this.View.RefreshZoomSettings();
{
IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count);
lock (this._descriptionsCache) await this._mediator.Send(new SaveConfiguration());
{ }
foreach (string title in thumbnailTitles)
{
IThumbnailDescription description = this.CreateThumbnailDescription(title);
this._descriptionsCache[title] = description;
descriptions.Add(description); public void AddThumbnails(IList<string> thumbnailTitles) {
} IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count);
}
this.View.AddThumbnails(descriptions); lock (this._descriptionsCache) {
} foreach (string title in thumbnailTitles) {
IThumbnailDescription description = this.CreateThumbnailDescription(title);
this._descriptionsCache[title] = description;
public void RemoveThumbnails(IList<string> thumbnailTitles) descriptions.Add(description);
{ }
IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count); }
lock (this._descriptionsCache) this.View.AddThumbnails(descriptions);
{ }
foreach (string title in thumbnailTitles)
{
if (!this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description))
{
continue;
}
this._descriptionsCache.Remove(title); public void RemoveThumbnails(IList<string> thumbnailTitles) {
descriptions.Add(description); IList<IThumbnailDescription> descriptions = new List<IThumbnailDescription>(thumbnailTitles.Count);
}
}
this.View.RemoveThumbnails(descriptions); lock (this._descriptionsCache) {
} foreach (string title in thumbnailTitles) {
if (!this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description)) {
continue;
}
private IThumbnailDescription CreateThumbnailDescription(string title) this._descriptionsCache.Remove(title);
{ descriptions.Add(description);
bool isDisabled = this._configuration.IsThumbnailDisabled(title); }
return new ThumbnailDescription(title, isDisabled); }
}
private async void UpdateThumbnailState(String title) this.View.RemoveThumbnails(descriptions);
{ }
if (this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description))
{
this._configuration.ToggleThumbnail(title, description.IsDisabled);
}
await this._mediator.Send(new SaveConfiguration()); private IThumbnailDescription CreateThumbnailDescription(string title) {
} bool isDisabled = this._configuration.IsThumbnailDisabled(title);
return new ThumbnailDescription(title, isDisabled);
}
public void UpdateThumbnailSize(Size size) private async void UpdateThumbnailState(String title) {
{ if (this._descriptionsCache.TryGetValue(title, out IThumbnailDescription description)) {
this._suppressSizeNotifications = true; this._configuration.ToggleThumbnail(title, description.IsDisabled);
this.View.ThumbnailSize = size; }
this._suppressSizeNotifications = false;
}
private void OpenDocumentationLink() await this._mediator.Send(new SaveConfiguration());
{ }
// funtimes
// https://brockallen.com/2016/09/24/process-start-for-urls-on-net-core/
// https://github.com/dotnet/runtime/issues/17938
// TODO Move out to a separate service / presenter / message handler public void UpdateThumbnailSize(Size size) {
this._suppressSizeNotifications = true;
this.View.ThumbnailSize = size;
this._suppressSizeNotifications = false;
}
private void OpenDocumentationLink() {
// funtimes
// https://brockallen.com/2016/09/24/process-start-for-urls-on-net-core/
// https://github.com/dotnet/runtime/issues/17938
// TODO Move out to a separate service / presenter / message handler
#if LINUX #if LINUX
Process.Start("xdg-open", new Uri(MainFormPresenter.FORUM_URL).AbsoluteUri); Process.Start("xdg-open", new Uri(MainFormPresenter.FORUM_URL).AbsoluteUri);
#else #else
ProcessStartInfo processStartInfo = new ProcessStartInfo(new Uri(MainFormPresenter.FORUM_URL).AbsoluteUri); ProcessStartInfo processStartInfo = new ProcessStartInfo(new Uri(MainFormPresenter.FORUM_URL).AbsoluteUri);
processStartInfo.UseShellExecute = true; processStartInfo.UseShellExecute = true;
Process.Start(processStartInfo); Process.Start(processStartInfo);
#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
target = "Linux"; target = "Linux";
#endif #endif
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,19 +1,15 @@
using EveOPreview.Configuration; using EveOPreview.Configuration;
namespace EveOPreview.View namespace EveOPreview.View {
{ static class ViewAnimationStyleConverter {
static class ViewAnimationStyleConverter public static AnimationStyle Convert(ViewAnimationStyle value) {
{ // Cheat based on fact that the order and byte values of both enums are the same
public static AnimationStyle Convert(ViewAnimationStyle value) return (AnimationStyle)((int)value);
{ }
// Cheat based on fact that the order and byte values of both enums are the same
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,19 +1,15 @@
using EveOPreview.Configuration; using EveOPreview.Configuration;
namespace EveOPreview.View namespace EveOPreview.View {
{ static class ViewZoomAnchorConverter {
static class ViewZoomAnchorConverter public static ZoomAnchor Convert(ViewZoomAnchor value) {
{ // Cheat based on fact that the order and byte values of both enums are the same
public static ZoomAnchor Convert(ViewZoomAnchor value) return (ZoomAnchor)((int)value);
{ }
// Cheat based on fact that the order and byte values of both enums are the same
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,13 +1,11 @@
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 RemoveThumbnails(IList<string> thumbnailTitles);
void AddThumbnails(IList<string> thumbnailTitles);
void RemoveThumbnails(IList<string> thumbnailTitles);
void UpdateThumbnailSize(Size size); void UpdateThumbnailSize(Size size);
} }
} }

View File

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

View File

@@ -7,108 +7,96 @@ 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 Program._singleInstanceMutex = Program.GetInstanceToken();
Program._singleInstanceMutex = Program.GetInstanceToken();
// If it was not possible to acquire the app token then another app instance is already running // If it was not possible to acquire the app token then another app instance is already running
// Nothing to do here // Nothing to do here
if (Program._singleInstanceMutex == null) if (Program._singleInstanceMutex == null) {
{ return;
return; }
}
ExceptionHandler handler = new ExceptionHandler(); ExceptionHandler handler = new ExceptionHandler();
handler.SetupExceptionHandlers(); handler.SetupExceptionHandlers();
IApplicationController controller = Program.InitializeApplicationController(); IApplicationController controller = Program.InitializeApplicationController();
Program.InitializeWinForms(); Program.InitializeWinForms();
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);
{ // if that didn't fail then another instance is already running
Mutex.OpenExisting(Program.MUTEX_NAME); return null;
// if that didn't fail then another instance is already running } catch (UnauthorizedAccessException) {
return null; return null;
} } catch (Exception) {
catch (UnauthorizedAccessException) Mutex token = new Mutex(true, Program.MUTEX_NAME, out var result);
{ return result ? token : null;
return null; }
} }
catch (Exception)
{
Mutex token = new Mutex(true, Program.MUTEX_NAME, out var result);
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
Application.SetHighDpiMode(HighDpiMode.PerMonitorV2); Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);
#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
// Low-level services // Low-level services
container.Register<IWindowManager>(); container.Register<IWindowManager>();
container.Register<IProcessMonitor>(); container.Register<IProcessMonitor>();
// MediatR // MediatR
container.Register<IMediator, MediatR.Mediator>(); container.Register<IMediator, MediatR.Mediator>();
container.RegisterInstance<ServiceFactory>(t => container.Resolve(t)); container.RegisterInstance<ServiceFactory>(t => container.Resolve(t));
container.Register(typeof(INotificationHandler<>), typeof(Program).Assembly); container.Register(typeof(INotificationHandler<>), typeof(Program).Assembly);
container.Register(typeof(IRequestHandler<>), typeof(Program).Assembly); container.Register(typeof(IRequestHandler<>), typeof(Program).Assembly);
container.Register(typeof(IRequestHandler<,>), typeof(Program).Assembly); container.Register(typeof(IRequestHandler<, >), typeof(Program).Assembly);
// Configuration services // Configuration services
container.Register<IConfigurationStorage>(); container.Register<IConfigurationStorage>();
container.Register<IAppConfig>(); container.Register<IAppConfig>();
container.Register<IThumbnailConfiguration>(); container.Register<IThumbnailConfiguration>();
// Application services // Application services
container.Register<IThumbnailManager>(); container.Register<IThumbnailManager>();
container.Register<IThumbnailViewFactory>(); container.Register<IThumbnailViewFactory>();
container.Register<IThumbnailDescription>(); container.Register<IThumbnailDescription>();
IApplicationController controller = new ApplicationController(container); IApplicationController controller = new ApplicationController(container);
// UI classes // UI classes
controller.RegisterView<StaticThumbnailView, StaticThumbnailView>(); controller.RegisterView<StaticThumbnailView, StaticThumbnailView>();
controller.RegisterView<LiveThumbnailView, LiveThumbnailView>(); controller.RegisterView<LiveThumbnailView, LiveThumbnailView>();
controller.RegisterView<IMainFormView, MainForm>(); controller.RegisterView<IMainFormView, MainForm>();
controller.RegisterInstance(new ApplicationContext()); controller.RegisterInstance(new ApplicationContext());
return controller; return controller;
} }
} }
} }

View File

@@ -10,8 +10,7 @@
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,45 +18,44 @@ 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;
} }
} }
/// <summary> /// <summary>
/// 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,102 +2,86 @@
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
{ private readonly IWindowManager _windowManager;
#region Private fields private IntPtr _handle;
private readonly IWindowManager _windowManager; private DWM_THUMBNAIL_PROPERTIES _properties;
private IntPtr _handle; #endregion
private DWM_THUMBNAIL_PROPERTIES _properties;
#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 + DWM_TNP_CONSTANTS.DWM_TNP_OPACITY +
this._properties.dwFlags = DWM_TNP_CONSTANTS.DWM_TNP_VISIBLE DWM_TNP_CONSTANTS.DWM_TNP_RECTDESTINATION +
+ DWM_TNP_CONSTANTS.DWM_TNP_OPACITY DWM_TNP_CONSTANTS.DWM_TNP_SOURCECLIENTAREAONLY;
+ DWM_TNP_CONSTANTS.DWM_TNP_RECTDESTINATION this._properties.opacity = 255;
+ DWM_TNP_CONSTANTS.DWM_TNP_SOURCECLIENTAREAONLY; this._properties.fVisible = true;
this._properties.opacity = 255; this._properties.fSourceClientAreaOnly = true;
this._properties.fVisible = true; this._properties.rcSource = new RECT(0, 0, 0, 0); // Initialize with empty source rect
this._properties.fSourceClientAreaOnly = true;
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) {
} // This exception is raised if the source client is already closed
catch (ArgumentException) // 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
// This exception is raised if the source client is already closed // a thumbnail source
// Can happen on a really slow CPU's that the window is still being this._handle = IntPtr.Zero;
// listed in the process list yet it already cannot be used as } catch (COMException) {
// a thumbnail source // This exception is raised if DWM is suddenly not available
this._handle = IntPtr.Zero; // (f.e. when switching between Windows user accounts)
} this._handle = IntPtr.Zero;
catch (COMException) }
{ }
// This exception is raised if DWM is suddenly not available
// (f.e. when switching between Windows user accounts)
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 (COMException) {
catch (ArgumentException) // This exception is raised when DWM is not available for some reason
{ }
} }
catch (COMException)
{
// 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;
{ }
return;
}
try public void ClearSourceRegion() {
{ this._properties.dwFlags &= ~DWM_TNP_CONSTANTS.DWM_TNP_RECTSOURCE;
DwmNativeMethods.DwmUpdateThumbnailProperties(this._handle, this._properties); }
}
catch (ArgumentException) public void Update() {
{ if ((!this._windowManager.IsCompositionEnabled) || (this._handle == IntPtr.Zero)) {
// This exception will be thrown if the EVE client disappears while this method is running return;
} }
catch (COMException)
{ try {
// This exception is raised when DWM is not available for some reason DwmNativeMethods.DwmUpdateThumbnailProperties(this._handle, this._properties);
} } catch (ArgumentException) {
} // This exception will be thrown if the EVE client disappears while this method is running
} } catch (COMException) {
// This exception is raised when DWM is not available for some reason
}
}
}
} }

View File

@@ -1,16 +1,13 @@
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) {
{ this.Handle = handle;
public ProcessInfo(IntPtr handle, string title) this.Title = title;
{ }
this.Handle = handle;
this.Title = title;
}
public IntPtr Handle { get; } public IntPtr Handle { get; }
public string Title { get; } public string Title { get; }
} }
} }

View File

@@ -4,172 +4,148 @@ 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
{ private const string DEFAULT_PROCESS_NAME = "Uwow-64";
#region Private constants private const string CURRENT_PROCESS_NAME = "EVE-O Preview";
private const string DEFAULT_PROCESS_NAME = "Uwow-64"; #endregion
private const string CURRENT_PROCESS_NAME = "EVE-O Preview";
#endregion
#region Private fields #region Private fields
private readonly IDictionary<IntPtr, string> _processCache; private readonly IDictionary<IntPtr, string> _processCache;
private IProcessInfo _currentProcessInfo; private IProcessInfo _currentProcessInfo;
private readonly IThumbnailConfiguration _configuration; private readonly IThumbnailConfiguration _configuration;
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
// This field cannot be initialized properly in constructor // This field cannot be initialized properly in constructor
// At the moment this code is executed the main application window is not yet initialized // At the moment this code is executed the main application window is not yet initialized
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;
}
// Also include any processes that match executable tracking // Also include any processes that match executable tracking
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; }
} }
}
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,
addedProcesses = new List<IProcessInfo>(16); out ICollection<IProcessInfo> removedProcesses) {
updatedProcesses = new List<IProcessInfo>(16); addedProcesses = new List<IProcessInfo>(16);
removedProcesses = new List<IProcessInfo>(16); updatedProcesses = 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 }
}
// Get all processes with same name and sort by PID // Get all processes with same name and sort by PID
var sameNameProcesses = Process.GetProcessesByName(processName) var sameNameProcesses = Process.GetProcessesByName(processName)
.Where(p => p.MainWindowHandle != IntPtr.Zero) .Where(p => p.MainWindowHandle != IntPtr.Zero)
.OrderBy(p => p.Id) .OrderBy(p => p.Id)
.ToList(); .ToList();
// Find index of current process in sorted list // Find index of current process in sorted list
int index = sameNameProcesses.FindIndex(p => p.Id == process.Id); int index = sameNameProcesses.FindIndex(p => p.Id == process.Id);
string mainWindowTitle = $"{process.MainWindowTitle} ({index + 1})"; string mainWindowTitle = $"{process.MainWindowTitle} ({index + 1})";
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 {
} // This is an already known process
else if (cachedTitle != mainWindowTitle) {
{ this._processCache[mainWindowHandle] = mainWindowTitle;
// This is an already known process updatedProcesses.Add(new ProcessInfo(mainWindowHandle, mainWindowTitle));
if (cachedTitle != mainWindowTitle) }
{ }
this._processCache[mainWindowHandle] = mainWindowTitle;
updatedProcesses.Add(new ProcessInfo(mainWindowHandle, mainWindowTitle));
}
}
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); }
} }
}
// 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 {
} this._trackedPids.Add(pid); // Toggle on if not tracking
else }
{ }
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,321 +5,278 @@ 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
{ private const int WINDOW_SIZE_THRESHOLD = 300;
#region Private constants private const int NO_ANIMATION = 0;
private const int WINDOW_SIZE_THRESHOLD = 300; #endregion
private const int NO_ANIMATION = 0;
#endregion
#region Private fields #region Private fields
private readonly bool _enableWineCompatabilityMode; private readonly bool _enableWineCompatabilityMode;
private string _bashLocation; private string _bashLocation;
private string _wmctrlLocation; private string _wmctrlLocation;
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");
this._wmctrlLocation = FindLinuxBinLocation("wmctrl"); this._wmctrlLocation = FindLinuxBinLocation("wmctrl");
#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.Major >= 10) // Win 10 (Environment.OSVersion.Version.Minor >= 2)) // Win 8 and Win 8.1
|| DwmNativeMethods.DwmIsCompositionEnabled(); // In case of Win 7 an API call is requiredWin 7 || (Environment.OSVersion.Version.Major >= 10) // Win 10
_animationParam.cbSize = (System.UInt32)Marshal.SizeOf(typeof(ANIMATIONINFO)); || DwmNativeMethods.DwmIsCompositionEnabled(); // In case of Win 7 an API call is requiredWin 7
} _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}";
{ if (System.IO.File.Exists(locationToCheck)) {
string locationToCheck = $"{path}/{command}"; string binLocation = System.IO.Path.GetDirectoryName(locationToCheck);
if (System.IO.File.Exists(locationToCheck)) string binLocationUnixStyle = binLocation.Replace("\\", "/");
{
string binLocation = System.IO.Path.GetDirectoryName(locationToCheck);
string binLocationUnixStyle = binLocation.Replace("\\", "/");
return binLocationUnixStyle; return binLocationUnixStyle;
} }
} }
WriteToLog($"[{DateTime.Now}] Error: {command} not found in expected locations."); WriteToLog($"[{DateTime.Now}] Error: {command} not found in expected locations.");
return null; return null;
} }
#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);
{ } catch (Exception ex) {
System.IO.File.AppendAllText(EXCEPTION_DUMP_FILE_NAME, message + Environment.NewLine); Console.WriteLine($"Failed to write to log file: {ex.Message}");
} }
catch (Exception ex) }
{
Console.WriteLine($"Failed to write to log file: {ex.Message}");
}
}
private int? _currentAnimationSetting = null; private int? _currentAnimationSetting = null;
private ANIMATIONINFO _animationParam = new ANIMATIONINFO(); private ANIMATIONINFO _animationParam = new ANIMATIONINFO();
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(
var animationOffReturn = User32NativeMethods.SystemParametersInfo(User32NativeMethods.SPI_SETANIMATION, (System.Int32)Marshal.SizeOf(typeof(ANIMATIONINFO)), ref _animationParam, 0); 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)),
// Restore current Animation Settings ref _animationParam, 0);
if (_animationParam.iMinAnimate != (int)_currentAnimationSetting) // Restore current Animation Settings
{ 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) {
} WriteToLog($"[{DateTime.Now}] executing wmctrl - Exception: {ex.Message}");
catch (Exception ex)
{
WriteToLog($"[{DateTime.Now}] executing wmctrl - Exception: {ex.Message}");
}
}
public void ActivateWindow(IntPtr handle, string windowName)
{
if (this._enableWineCompatabilityMode)
{
this.WineActivateWindow(windowName);
} }
else }
{
public void ActivateWindow(IntPtr handle, string windowName) {
if (this._enableWineCompatabilityMode) {
this.WineActivateWindow(windowName);
} 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 {
} WINDOWPLACEMENT param = new WINDOWPLACEMENT();
else param.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
{ User32NativeMethods.GetWindowPlacement(handle, ref param);
WINDOWPLACEMENT param = new WINDOWPLACEMENT(); param.showCmd = WINDOWPLACEMENT.SW_MINIMIZE;
param.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT)); User32NativeMethods.SetWindowPlacement(handle, ref param);
User32NativeMethods.GetWindowPlacement(handle, ref param); }
param.showCmd = WINDOWPLACEMENT.SW_MINIMIZE; }
User32NativeMethods.SetWindowPlacement(handle, ref param);
}
}
#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:
{ User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_RESTORE);
case AnimationStyle.OriginalAnimation: break;
User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_RESTORE); case AnimationStyle.NoAnimation:
break; TurnOffAnimation();
case AnimationStyle.NoAnimation: User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_RESTORE);
TurnOffAnimation(); RestoreAnimation();
User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_RESTORE); break;
RestoreAnimation(); }
break; }
}
}
}
public void MinimizeWindow(IntPtr handle, AnimationStyle animation, bool enableAnimation)
{
if (enableAnimation)
{
switch (animation)
{
case AnimationStyle.OriginalAnimation:
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND, InteropConstants.SC_MINIMIZE, 0);
break;
case AnimationStyle.NoAnimation:
TurnOffAnimation();
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND, InteropConstants.SC_MINIMIZE, 0);
RestoreAnimation();
break;
}
}
else
{
switch (animation)
{
case AnimationStyle.OriginalAnimation:
WINDOWPLACEMENT param = new WINDOWPLACEMENT();
param.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
User32NativeMethods.GetWindowPlacement(handle, ref param);
param.showCmd = WINDOWPLACEMENT.SW_MINIMIZE;
User32NativeMethods.SetWindowPlacement(handle, ref param);
break;
case AnimationStyle.NoAnimation:
TurnOffAnimation();
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND, InteropConstants.SC_MINIMIZE, 0);
RestoreAnimation();
break;
}
}
}
#endif
public void MoveWindow(IntPtr handle, int left, int top, int width, int height)
{
User32NativeMethods.MoveWindow(handle, left, top, width, height, true);
}
public void MaximizeWindow(IntPtr handle)
{
User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_SHOWMAXIMIZED);
} }
public (int Left, int Top, int Right, int Bottom) GetWindowPosition(IntPtr handle) public void MinimizeWindow(IntPtr handle, AnimationStyle animation, bool enableAnimation) {
{ if (enableAnimation) {
User32NativeMethods.GetWindowRect(handle, out RECT windowRectangle); switch (animation) {
case AnimationStyle.OriginalAnimation:
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND,
InteropConstants.SC_MINIMIZE, 0);
break;
case AnimationStyle.NoAnimation:
TurnOffAnimation();
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND,
InteropConstants.SC_MINIMIZE, 0);
RestoreAnimation();
break;
}
} else {
switch (animation) {
case AnimationStyle.OriginalAnimation:
WINDOWPLACEMENT param = new WINDOWPLACEMENT();
param.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
User32NativeMethods.GetWindowPlacement(handle, ref param);
param.showCmd = WINDOWPLACEMENT.SW_MINIMIZE;
User32NativeMethods.SetWindowPlacement(handle, ref param);
break;
case AnimationStyle.NoAnimation:
TurnOffAnimation();
User32NativeMethods.SendMessage(handle, InteropConstants.WM_SYSCOMMAND,
InteropConstants.SC_MINIMIZE, 0);
RestoreAnimation();
break;
}
}
}
#endif
return (windowRectangle.Left, windowRectangle.Top, windowRectangle.Right, windowRectangle.Bottom); public void MoveWindow(IntPtr handle, int left, int top, int width, int height) {
} User32NativeMethods.MoveWindow(handle, left, top, width, height, true);
}
public bool IsWindowMaximized(IntPtr handle) public void MaximizeWindow(IntPtr handle) {
{ User32NativeMethods.ShowWindowAsync(handle, InteropConstants.SW_SHOWMAXIMIZED);
return User32NativeMethods.IsZoomed(handle); }
}
public bool IsWindowMinimized(IntPtr handle) public (int Left, int Top, int Right, int Bottom) GetWindowPosition(IntPtr handle) {
{ User32NativeMethods.GetWindowRect(handle, out RECT windowRectangle);
return User32NativeMethods.IsIconic(handle);
}
public IDwmThumbnail GetLiveThumbnail(IntPtr destination, IntPtr source) return (windowRectangle.Left, windowRectangle.Top, windowRectangle.Right, windowRectangle.Bottom);
{ }
IDwmThumbnail thumbnail = new DwmThumbnail(this);
thumbnail.Register(destination, source);
return thumbnail; public bool IsWindowMaximized(IntPtr handle) {
} return User32NativeMethods.IsZoomed(handle);
}
public Image GetStaticThumbnail(IntPtr source) public bool IsWindowMinimized(IntPtr handle) {
{ return User32NativeMethods.IsIconic(handle);
var sourceContext = User32NativeMethods.GetDC(source); }
User32NativeMethods.GetClientRect(source, out RECT windowRect); public IDwmThumbnail GetLiveThumbnail(IntPtr destination, IntPtr source) {
IDwmThumbnail thumbnail = new DwmThumbnail(this);
thumbnail.Register(destination, source);
var width = windowRect.Right - windowRect.Left; return thumbnail;
var height = windowRect.Bottom - windowRect.Top; }
// Check if there is anything to make thumbnail of public Image GetStaticThumbnail(IntPtr source) {
if ((width < WINDOW_SIZE_THRESHOLD) || (height < WINDOW_SIZE_THRESHOLD)) var sourceContext = User32NativeMethods.GetDC(source);
{
return null;
}
var destContext = Gdi32NativeMethods.CreateCompatibleDC(sourceContext); User32NativeMethods.GetClientRect(source, out RECT windowRect);
var bitmap = Gdi32NativeMethods.CreateCompatibleBitmap(sourceContext, width, height);
var oldBitmap = Gdi32NativeMethods.SelectObject(destContext, bitmap); var width = windowRect.Right - windowRect.Left;
Gdi32NativeMethods.BitBlt(destContext, 0, 0, width, height, sourceContext, 0, 0, Gdi32NativeMethods.SRCCOPY); var height = windowRect.Bottom - windowRect.Top;
Gdi32NativeMethods.SelectObject(destContext, oldBitmap);
Gdi32NativeMethods.DeleteDC(destContext);
User32NativeMethods.ReleaseDC(source, sourceContext);
Image image = Image.FromHbitmap(bitmap); // Check if there is anything to make thumbnail of
Gdi32NativeMethods.DeleteObject(bitmap); if ((width < WINDOW_SIZE_THRESHOLD) || (height < WINDOW_SIZE_THRESHOLD)) {
return null;
}
return image; var destContext = Gdi32NativeMethods.CreateCompatibleDC(sourceContext);
} var bitmap = Gdi32NativeMethods.CreateCompatibleBitmap(sourceContext, width, height);
}
var oldBitmap = Gdi32NativeMethods.SelectObject(destContext, bitmap);
Gdi32NativeMethods.BitBlt(destContext, 0, 0, width, height, sourceContext, 0, 0,
Gdi32NativeMethods.SRCCOPY);
Gdi32NativeMethods.SelectObject(destContext, oldBitmap);
Gdi32NativeMethods.DeleteDC(destContext);
User32NativeMethods.ReleaseDC(source, sourceContext);
Image image = Image.FromHbitmap(bitmap);
Gdi32NativeMethods.DeleteObject(bitmap);
return image;
}
}
} }

View File

@@ -1,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 Unregister();
void Register(IntPtr destination, IntPtr source);
void Unregister();
void Move(int left, int top, int right, int bottom); void Move(int left, int top, int right, int bottom);
void Update(); void SetSourceRegion(int left, int top, int right, int bottom);
} void ClearSourceRegion();
void Update();
}
} }

View File

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

View File

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

View File

@@ -1,17 +1,16 @@
using EveOPreview.View; using EveOPreview.View;
namespace EveOPreview.Services namespace EveOPreview.Services {
{ public interface IThumbnailManager {
public interface IThumbnailManager void Start();
{ void Stop();
void Start();
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);
IThumbnailView GetActiveClient(); IThumbnailView GetActiveClient();
} }
} }

View File

@@ -2,25 +2,23 @@
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();
#if LINUX #if LINUX
void ActivateWindow(IntPtr handle, string windowName); void ActivateWindow(IntPtr handle, string windowName);
#else #else
void ActivateWindow(IntPtr handle, AnimationStyle animation); void ActivateWindow(IntPtr handle, AnimationStyle animation);
#endif #endif
void MinimizeWindow(IntPtr handle, AnimationStyle animation, bool enableAnimation); void MinimizeWindow(IntPtr handle, AnimationStyle animation, bool enableAnimation);
void MoveWindow(IntPtr handle, int left, int top, int width, int height); void MoveWindow(IntPtr handle, int left, int top, int width, int height);
void MaximizeWindow(IntPtr handle); void MaximizeWindow(IntPtr handle);
(int Left, int Top, int Right, int Bottom) GetWindowPosition(IntPtr handle); (int Left, int Top, int Right, int Bottom) GetWindowPosition(IntPtr handle);
bool IsWindowMaximized(IntPtr handle); bool IsWindowMaximized(IntPtr handle);
bool IsWindowMinimized(IntPtr handle); bool IsWindowMinimized(IntPtr handle);
IDwmThumbnail GetLiveThumbnail(IntPtr destination, IntPtr source); IDwmThumbnail GetLiveThumbnail(IntPtr destination, IntPtr source);
Image GetStaticThumbnail(IntPtr source); Image GetStaticThumbnail(IntPtr source);
} }
} }

View File

@@ -1,83 +1,81 @@
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_STYLE = (-16);
public const int GWL_ID = (-12); public const int GWL_EXSTYLE = (-20);
public const int GWL_STYLE = (-16);
public const int GWL_EXSTYLE = (-20);
// Window Styles // Window Styles
public const UInt32 WS_OVERLAPPED = 0; public const UInt32 WS_OVERLAPPED = 0;
public const UInt32 WS_POPUP = 0x80000000; public const UInt32 WS_POPUP = 0x80000000;
public const UInt32 WS_CHILD = 0x40000000; public const UInt32 WS_CHILD = 0x40000000;
public const UInt32 WS_MINIMIZE = 0x20000000; public const UInt32 WS_MINIMIZE = 0x20000000;
public const UInt32 WS_VISIBLE = 0x10000000; public const UInt32 WS_VISIBLE = 0x10000000;
public const UInt32 WS_DISABLED = 0x8000000; public const UInt32 WS_DISABLED = 0x8000000;
public const UInt32 WS_CLIPSIBLINGS = 0x4000000; public const UInt32 WS_CLIPSIBLINGS = 0x4000000;
public const UInt32 WS_CLIPCHILDREN = 0x2000000; public const UInt32 WS_CLIPCHILDREN = 0x2000000;
public const UInt32 WS_MAXIMIZE = 0x1000000; public const UInt32 WS_MAXIMIZE = 0x1000000;
public const UInt32 WS_CAPTION = 0xC00000; // WS_BORDER or WS_DLGFRAME public const UInt32 WS_CAPTION = 0xC00000; // WS_BORDER or WS_DLGFRAME
public const UInt32 WS_BORDER = 0x800000; public const UInt32 WS_BORDER = 0x800000;
public const UInt32 WS_DLGFRAME = 0x400000; public const UInt32 WS_DLGFRAME = 0x400000;
public const UInt32 WS_VSCROLL = 0x200000; public const UInt32 WS_VSCROLL = 0x200000;
public const UInt32 WS_HSCROLL = 0x100000; public const UInt32 WS_HSCROLL = 0x100000;
public const UInt32 WS_SYSMENU = 0x80000; public const UInt32 WS_SYSMENU = 0x80000;
public const UInt32 WS_THICKFRAME = 0x40000; public const UInt32 WS_THICKFRAME = 0x40000;
public const UInt32 WS_GROUP = 0x20000; public const UInt32 WS_GROUP = 0x20000;
public const UInt32 WS_TABSTOP = 0x10000; public const UInt32 WS_TABSTOP = 0x10000;
public const UInt32 WS_MINIMIZEBOX = 0x20000; public const UInt32 WS_MINIMIZEBOX = 0x20000;
public const UInt32 WS_MAXIMIZEBOX = 0x10000; public const UInt32 WS_MAXIMIZEBOX = 0x10000;
public const UInt32 WS_TILED = WS_OVERLAPPED; public const UInt32 WS_TILED = WS_OVERLAPPED;
public const UInt32 WS_ICONIC = WS_MINIMIZE; public const UInt32 WS_ICONIC = WS_MINIMIZE;
public const UInt32 WS_SIZEBOX = WS_THICKFRAME; public const UInt32 WS_SIZEBOX = WS_THICKFRAME;
// Extended Window Styles // Extended Window Styles
public const UInt32 WS_EX_DLGMODALFRAME = 0x0001; public const UInt32 WS_EX_DLGMODALFRAME = 0x0001;
public const UInt32 WS_EX_NOPARENTNOTIFY = 0x0004; public const UInt32 WS_EX_NOPARENTNOTIFY = 0x0004;
public const UInt32 WS_EX_TOPMOST = 0x0008; public const UInt32 WS_EX_TOPMOST = 0x0008;
public const UInt32 WS_EX_ACCEPTFILES = 0x0010; public const UInt32 WS_EX_ACCEPTFILES = 0x0010;
public const UInt32 WS_EX_TRANSPARENT = 0x0020; public const UInt32 WS_EX_TRANSPARENT = 0x0020;
public const UInt32 WS_EX_MDICHILD = 0x0040; public const UInt32 WS_EX_MDICHILD = 0x0040;
public const UInt32 WS_EX_TOOLWINDOW = 0x0080; public const UInt32 WS_EX_TOOLWINDOW = 0x0080;
public const UInt32 WS_EX_WINDOWEDGE = 0x0100; public const UInt32 WS_EX_WINDOWEDGE = 0x0100;
public const UInt32 WS_EX_CLIENTEDGE = 0x0200; public const UInt32 WS_EX_CLIENTEDGE = 0x0200;
public const UInt32 WS_EX_CONTEXTHELP = 0x0400; public const UInt32 WS_EX_CONTEXTHELP = 0x0400;
public const UInt32 WS_EX_RIGHT = 0x1000; public const UInt32 WS_EX_RIGHT = 0x1000;
public const UInt32 WS_EX_LEFT = 0x0000; public const UInt32 WS_EX_LEFT = 0x0000;
public const UInt32 WS_EX_RTLREADING = 0x2000; public const UInt32 WS_EX_RTLREADING = 0x2000;
public const UInt32 WS_EX_LTRREADING = 0x0000; public const UInt32 WS_EX_LTRREADING = 0x0000;
public const UInt32 WS_EX_LEFTSCROLLBAR = 0x4000; public const UInt32 WS_EX_LEFTSCROLLBAR = 0x4000;
public const UInt32 WS_EX_RIGHTSCROLLBAR = 0x0000; public const UInt32 WS_EX_RIGHTSCROLLBAR = 0x0000;
public const UInt32 WS_EX_CONTROLPARENT = 0x10000; public const UInt32 WS_EX_CONTROLPARENT = 0x10000;
public const UInt32 WS_EX_STATICEDGE = 0x20000; public const UInt32 WS_EX_STATICEDGE = 0x20000;
public const UInt32 WS_EX_APPWINDOW = 0x40000; public const UInt32 WS_EX_APPWINDOW = 0x40000;
public const UInt32 WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE); public const UInt32 WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE);
public const UInt32 WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST); public const UInt32 WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST);
public const UInt32 WS_EX_LAYERED = 0x00080000; public const UInt32 WS_EX_LAYERED = 0x00080000;
public const UInt32 WS_EX_NOINHERITLAYOUT = 0x00100000; // Disable inheritance of mirroring by children public const UInt32 WS_EX_NOINHERITLAYOUT = 0x00100000; // Disable inheritance of mirroring by children
public const UInt32 WS_EX_LAYOUTRTL = 0x00400000; // Right to left mirroring public const UInt32 WS_EX_LAYOUTRTL = 0x00400000; // Right to left mirroring
public const UInt32 WS_EX_COMPOSITED = 0x02000000; public const UInt32 WS_EX_COMPOSITED = 0x02000000;
public const UInt32 WS_EX_NOACTIVATE = 0x08000000; public const UInt32 WS_EX_NOACTIVATE = 0x08000000;
public const int WM_SIZE = 5; public const int WM_SIZE = 5;
public const int WM_SYSCOMMAND = 0x0112; public const int WM_SYSCOMMAND = 0x0112;
public const int SC_MINIMIZE = 0xf020; public const int SC_MINIMIZE = 0xf020;
public const int SIZE_RESTORED = 0; public const int SIZE_RESTORED = 0;
public const int SIZE_MINIMIZED = 1; public const int SIZE_MINIMIZED = 1;
public const int SIZE_MAXIMIZED = 2; public const int SIZE_MAXIMIZED = 2;
public const int SIZE_MAXSHOW = 3; public const int SIZE_MAXSHOW = 3;
public const int SIZE_MAXHIDE = 4; public const int SIZE_MAXHIDE = 4;
public const int WM_NCLBUTTONDOWN = 0xA1; public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HTCAPTION = 0x2; public const int HTCAPTION = 0x2;
public const int SW_SHOWNORMAL = 1; public const int SW_SHOWNORMAL = 1;
public const int SW_SHOWMINIMIZED = 2; public const int SW_SHOWMINIMIZED = 2;
public const int SW_SHOWMAXIMIZED = 3; public const int SW_SHOWMAXIMIZED = 3;
public const int SW_RESTORE = 9; public const int SW_RESTORE = 9;
} }
} }

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,20 +1,18 @@
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;
{ [MarshalAs(UnmanagedType.Bool)]
public uint dwFlags; public bool fEnable;
[MarshalAs(UnmanagedType.Bool)] public IntPtr hRegionBlur;
public bool fEnable; [MarshalAs(UnmanagedType.Bool)]
public IntPtr hRegionBlur; public bool fTransitionOnMaximized;
[MarshalAs(UnmanagedType.Bool)]
public bool fTransitionOnMaximized;
public const uint DWM_BB_ENABLE = 0x00000001; public const uint DWM_BB_ENABLE = 0x00000001;
public const uint DWM_BB_BLURREGION = 0x00000002; public const uint DWM_BB_BLURREGION = 0x00000002;
public const uint DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004; public const uint DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004;
} }
} }

View File

@@ -1,17 +1,15 @@
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 RECT rcDestination;
public uint dwFlags; public RECT rcSource;
public RECT rcDestination; public byte opacity;
public RECT rcSource; [MarshalAs(UnmanagedType.Bool)]
public byte opacity; public bool fVisible;
[MarshalAs(UnmanagedType.Bool)] [MarshalAs(UnmanagedType.Bool)]
public bool fVisible; public bool fSourceClientAreaOnly;
[MarshalAs(UnmanagedType.Bool)] }
public bool fSourceClientAreaOnly;
}
} }

View File

@@ -1,11 +1,9 @@
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_RECTSOURCE = 0x00000002;
public const uint DWM_TNP_RECTDESTINATION = 0x00000001; public const uint DWM_TNP_OPACITY = 0x00000004;
public const uint DWM_TNP_RECTSOURCE = 0x00000002; public const uint DWM_TNP_VISIBLE = 0x00000008;
public const uint DWM_TNP_OPACITY = 0x00000004; public const uint DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010;
public const uint DWM_TNP_VISIBLE = 0x00000008; }
public const uint DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010;
}
} }

View File

@@ -2,37 +2,34 @@ 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)]
{ public static extern void DwmEnableBlurBehindWindow(IntPtr hWnd, DWM_BLURBEHIND pBlurBehind);
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmEnableBlurBehindWindow(IntPtr hWnd, DWM_BLURBEHIND pBlurBehind);
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, MARGINS pMargins); public static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, MARGINS pMargins);
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
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)]
public static extern void DwmEnableComposition(bool bEnable); public static extern void DwmEnableComposition(bool bEnable);
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
public static extern IntPtr DwmRegisterThumbnail(IntPtr dest, IntPtr source); public static extern IntPtr DwmRegisterThumbnail(IntPtr dest, IntPtr source);
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmUnregisterThumbnail(IntPtr hThumbnail); public static extern void DwmUnregisterThumbnail(IntPtr hThumbnail);
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmUpdateThumbnailProperties(IntPtr hThumbnail, DWM_THUMBNAIL_PROPERTIES props); public static extern void DwmUpdateThumbnailProperties(IntPtr hThumbnail, DWM_THUMBNAIL_PROPERTIES props);
[DllImport("dwmapi.dll", PreserveSig = false)] [DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmQueryThumbnailSourceSize(IntPtr hThumbnail, out Size size); public static extern void DwmQueryThumbnailSourceSize(IntPtr hThumbnail, out Size size);
} }
} }

View File

@@ -1,28 +1,27 @@
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")]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc); public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
public static extern bool DeleteDC(IntPtr hdc); public static extern bool DeleteDC(IntPtr hdc);
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int width, int height); public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int width, int height);
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject); public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject);
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
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,21 +1,18 @@
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 cxRightWidth;
public int cxLeftWidth; public int cyTopHeight;
public int cxRightWidth; public int cyBottomHeight;
public int cyTopHeight;
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; cyBottomHeight = bottom;
cyBottomHeight = bottom; }
} }
}
} }

View File

@@ -1,21 +1,18 @@
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 Top;
public int Left; public int Right;
public int Top; public int Bottom;
public int Right;
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; this.Bottom = bottom;
this.Bottom = bottom; }
} }
}
} }

View File

@@ -1,70 +1,69 @@
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_GETANIMATION = 0x0048;
public const uint SPI_SETANIMATION = 0x0049;
public const uint SPI_GETANIMATION = 0x0048;
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow(); public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr window); public static extern bool SetForegroundWindow(IntPtr window);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern void SetFocus(IntPtr window); public static extern void SetFocus(IntPtr window);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern void EnableWindow(IntPtr window, bool isEnabled); public static extern void EnableWindow(IntPtr window, bool isEnabled);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("User32.dll")] [DllImport("User32.dll")]
public static extern bool ReleaseCapture(); public static extern bool ReleaseCapture();
[DllImport("User32.dll")] [DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImport("user32.dll", SetLastError = true)] [DllImport("user32.dll", SetLastError = true)]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex); public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern int GetWindowRect(IntPtr hWnd, out RECT rect); public static extern int GetWindowRect(IntPtr hWnd, out RECT rect);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool GetClientRect(IntPtr hWnd, out RECT rect); public static extern bool GetClientRect(IntPtr hWnd, out RECT rect);
[DllImport("user32.dll", SetLastError = true)] [DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)] [return:MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl); public static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
[DllImport("user32.dll")] [DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)] [return:MarshalAs(UnmanagedType.Bool)]
public static extern bool IsIconic(IntPtr hWnd); public static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool IsZoomed(IntPtr hWnd); public static extern bool IsZoomed(IntPtr hWnd);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd); public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr hWnd); public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll")] [DllImport("user32.dll")]
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,30 +1,28 @@
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 flags;
public int length; public int showCmd;
public int flags; public System.Drawing.Point ptMinPosition;
public int showCmd; public System.Drawing.Point ptMaxPosition;
public System.Drawing.Point ptMinPosition; public System.Drawing.Rectangle rcNormalPosition;
public System.Drawing.Point ptMaxPosition;
public System.Drawing.Rectangle rcNormalPosition;
//Definitions For Different Window Placement Constants // Definitions For Different Window Placement Constants
public const int SW_HIDE = 0; public const int SW_HIDE = 0;
public const int SW_SHOWNORMAL = 1; public const int SW_SHOWNORMAL = 1;
public const int SW_NORMAL = 1; public const int SW_NORMAL = 1;
public const int SW_SHOWMINIMIZED = 2; public const int SW_SHOWMINIMIZED = 2;
public const int SW_SHOWMAXIMIZED = 3; public const int SW_SHOWMAXIMIZED = 3;
public const int SW_MAXIMIZE = 3; public const int SW_MAXIMIZE = 3;
public const int SW_SHOWNOACTIVATE = 4; public const int SW_SHOWNOACTIVATE = 4;
public const int SW_SHOW = 5; public const int SW_SHOW = 5;
public const int SW_MINIMIZE = 6; public const int SW_MINIMIZE = 6;
public const int SW_SHOWMINNOACTIVE = 7; public const int SW_SHOWMINNOACTIVE = 7;
public const int SW_SHOWNA = 8; public const int SW_SHOWNA = 8;
public const int SW_RESTORE = 9; public const int SW_RESTORE = 9;
} }
} }

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,61 +3,76 @@ 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
{ private IDwmThumbnail _thumbnail;
#region Private fields private Point _startLocation;
private IDwmThumbnail _thumbnail; private Point _endLocation;
private Point _startLocation; private IThumbnailConfiguration _config;
private Point _endLocation; #endregion
private IThumbnailConfiguration _config;
#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)
var left = 0 + highlightWidthLeft; return;
var top = 0 + highlightWidthTop;
var right = baseWidth - highlightWidthRight;
var bottom = baseHeight - highlightWidthBottom;
if ((this._startLocation.X == left) && (this._startLocation.Y == top) && (this._endLocation.X == right) && (this._endLocation.Y == bottom)) if (this._config.EnableThumbnailRegionSnipping) {
{ var region = this._config.GetThumbnailRegion(this.Title, this._config.DefaultThumbnailRegion);
return; // No update required if (region.Width > 0 && region.Height > 0) {
} this._thumbnail.SetSourceRegion(region.Left, region.Top, region.Right, region.Bottom);
this._startLocation = new Point(left, top); } else {
this._endLocation = new Point(right, bottom); this._thumbnail.ClearSourceRegion();
}
} else {
this._thumbnail.ClearSourceRegion();
}
this._thumbnail.Move(left, top, right, bottom); this._thumbnail.Update();
this._thumbnail.Update(); }
}
private void RegisterThumbnail() protected override void ResizeThumbnail(int baseWidth, int baseHeight, int highlightWidthTop,
{ int highlightWidthRight, int highlightWidthBottom,
this._thumbnail = this.WindowManager.GetLiveThumbnail(this.Handle, this.Id); int highlightWidthLeft) {
this._thumbnail.Move(this._startLocation.X, this._startLocation.Y, this._endLocation.X, this._endLocation.Y); var left = 0 + highlightWidthLeft;
this._thumbnail.Update(); var top = 0 + highlightWidthTop;
} var right = baseWidth - highlightWidthRight;
} var bottom = baseHeight - highlightWidthBottom;
if ((this._startLocation.X == left) && (this._startLocation.Y == top) && (this._endLocation.X == right) &&
(this._endLocation.Y == bottom)) {
return; // No update required
}
this._startLocation = new Point(left, top);
this._endLocation = new Point(right, bottom);
this._thumbnail.Move(left, top, right, bottom);
this._thumbnail.Update();
}
private void RegisterThumbnail() {
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.Update();
}
}
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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,23 +1,17 @@
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) {
{ const int WM_NCHITTEST = 0x0084;
protected override void WndProc(ref Message m) const int HTTRANSPARENT = (-1);
{
const int WM_NCHITTEST = 0x0084;
const int HTTRANSPARENT = (-1);
if (m.Msg == WM_NCHITTEST) if (m.Msg == WM_NCHITTEST) {
{ m.Result = (IntPtr)HTTRANSPARENT;
m.Result = (IntPtr)HTTRANSPARENT; } else {
} base.WndProc(ref m);
else }
{ }
base.WndProc(ref m); }
}
}
}
} }

View File

@@ -4,70 +4,93 @@ 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
{ private readonly PictureBox _thumbnail;
#region Private fields private IThumbnailConfiguration _config;
private readonly PictureBox _thumbnail; #endregion
private IThumbnailConfiguration _config;
#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, Location = new Point(0, 0),
SizeMode = PictureBoxSizeMode.StretchImage, Size = new Size(this.ClientSize.Width, this.ClientSize.Height) };
Location = new Point(0, 0), this.Controls.Add(this._thumbnail);
Size = new Size(this.ClientSize.Width, this.ClientSize.Height) this._config = config;
}; }
this.Controls.Add(this._thumbnail);
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)
var left = 0 + highlightWidthLeft; return;
var top = 0 + highlightWidthTop;
if (this.IsLocationUpdateRequired(this._thumbnail.Location, left, top))
{
this._thumbnail.Location = new Point(left, top);
}
var width = baseWidth - highlightWidthLeft - highlightWidthRight; if (this._config.EnableThumbnailRegionSnipping) {
var height = baseHeight - highlightWidthTop - highlightWidthBottom; var region = this._config.GetThumbnailRegion(this.Title, this._config.DefaultThumbnailRegion);
if (this.IsSizeUpdateRequired(this._thumbnail.Size, width, height)) if (region.Width > 0 && region.Height > 0) {
{ // Crop the image to the specified region
this._thumbnail.Size = new Size(width, height); var croppedImage = CropImage((Image)this._thumbnail.Image, region);
} var oldImage = this._thumbnail.Image;
} this._thumbnail.Image = croppedImage;
oldImage?.Dispose();
}
}
}
private bool IsLocationUpdateRequired(Point currentLocation, int left, int top) private Image CropImage(Image sourceImage, Rectangle region) {
{ // Ensure the region is within the image bounds
return (currentLocation.X != left) || (currentLocation.Y != top); var imageRect = new Rectangle(0, 0, sourceImage.Width, sourceImage.Height);
} var cropRect = Rectangle.Intersect(region, imageRect);
private bool IsSizeUpdateRequired(Size currentSize, int width, int height) if (cropRect.Width <= 0 || cropRect.Height <= 0) {
{ return sourceImage; // Return original if region is invalid
return (currentSize.Width != width) || (currentSize.Height != height); }
}
} 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 top = 0 + highlightWidthTop;
if (this.IsLocationUpdateRequired(this._thumbnail.Location, left, top)) {
this._thumbnail.Location = new Point(left, top);
}
var width = baseWidth - highlightWidthLeft - highlightWidthRight;
var height = baseHeight - highlightWidthTop - highlightWidthBottom;
if (this.IsSizeUpdateRequired(this._thumbnail.Size, width, height)) {
this._thumbnail.Size = new Size(width, height);
}
}
private bool IsLocationUpdateRequired(Point currentLocation, int left, int top) {
return (currentLocation.X != left) || (currentLocation.Y != top);
}
private bool IsSizeUpdateRequired(Size currentSize, int width, int height) {
return (currentSize.Width != width) || (currentSize.Height != height);
}
}
} }

View File

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

View File

@@ -1,90 +1,85 @@
namespace EveOPreview.View namespace EveOPreview.View {
{ partial class ThumbnailOverlay {
partial class ThumbnailOverlay /// <summary>
{ /// Required designer variable.
/// <summary> /// </summary>
/// Required designer variable. private System.ComponentModel.IContainer components = null;
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary> /// <summary>
/// Clean up any resources being used. /// Clean up any resources being used.
/// </summary> /// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing) {
{ if (disposing && (components != null)) {
if (disposing && (components != null)) components.Dispose();
{ }
components.Dispose(); base.Dispose(disposing);
} }
base.Dispose(disposing);
}
#region Windows Form Designer generated code #region Windows Form Designer generated code
/// <summary> /// <summary>
/// Required method for Designer support - do not modify /// Required method for Designer support - do not modify
/// the contents of this method with the code editor. /// the contents of this method with the code editor.
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent() {
{ System.Windows.Forms.PictureBox OverlayAreaPictureBox;
System.Windows.Forms.PictureBox OverlayAreaPictureBox; this.OverlayLabel = new System.Windows.Forms.Label();
this.OverlayLabel = new System.Windows.Forms.Label(); OverlayAreaPictureBox = new System.Windows.Forms.PictureBox();
OverlayAreaPictureBox = new System.Windows.Forms.PictureBox(); ((System.ComponentModel.ISupportInitialize)(OverlayAreaPictureBox)).BeginInit();
((System.ComponentModel.ISupportInitialize)(OverlayAreaPictureBox)).BeginInit(); this.SuspendLayout();
this.SuspendLayout(); //
// // OverlayAreaPictureBox
// OverlayAreaPictureBox //
// OverlayAreaPictureBox.BackColor = System.Drawing.Color.Transparent;
OverlayAreaPictureBox.BackColor = System.Drawing.Color.Transparent; OverlayAreaPictureBox.Cursor = System.Windows.Forms.Cursors.Hand;
OverlayAreaPictureBox.Cursor = System.Windows.Forms.Cursors.Hand; OverlayAreaPictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
OverlayAreaPictureBox.Dock = System.Windows.Forms.DockStyle.Fill; OverlayAreaPictureBox.Location = new System.Drawing.Point(0, 0);
OverlayAreaPictureBox.Location = new System.Drawing.Point(0, 0); OverlayAreaPictureBox.Name = "OverlayAreaPictureBox";
OverlayAreaPictureBox.Name = "OverlayAreaPictureBox"; OverlayAreaPictureBox.Size = new System.Drawing.Size(284, 262);
OverlayAreaPictureBox.Size = new System.Drawing.Size(284, 262); OverlayAreaPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
OverlayAreaPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; OverlayAreaPictureBox.TabIndex = 0;
OverlayAreaPictureBox.TabIndex = 0; OverlayAreaPictureBox.TabStop = false;
OverlayAreaPictureBox.TabStop = false; OverlayAreaPictureBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OverlayArea_Click);
OverlayAreaPictureBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OverlayArea_Click); //
// // OverlayLabel
// OverlayLabel //
// this.OverlayLabel.AutoSize = true;
this.OverlayLabel.AutoSize = true; this.OverlayLabel.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular,
this.OverlayLabel.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 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";
this.OverlayLabel.Size = new System.Drawing.Size(25, 13); this.OverlayLabel.Size = new System.Drawing.Size(25, 13);
this.OverlayLabel.TabIndex = 1; this.OverlayLabel.TabIndex = 1;
this.OverlayLabel.Text = "..."; this.OverlayLabel.Text = "...";
this.OverlayLabel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OverlayArea_Click); this.OverlayLabel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OverlayArea_Click);
// //
// ThumbnailOverlay // ThumbnailOverlay
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackColor = System.Drawing.Color.Black; this.BackColor = System.Drawing.Color.Black;
this.ClientSize = new System.Drawing.Size(284, 262); this.ClientSize = new System.Drawing.Size(284, 262);
this.ControlBox = false; this.ControlBox = false;
this.Controls.Add(this.OverlayLabel); this.Controls.Add(this.OverlayLabel);
this.Controls.Add(OverlayAreaPictureBox); this.Controls.Add(OverlayAreaPictureBox);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.MaximizeBox = false; this.MaximizeBox = false;
this.MinimizeBox = false; this.MinimizeBox = false;
this.Name = "ThumbnailOverlay"; this.Name = "ThumbnailOverlay";
this.ShowIcon = false; this.ShowIcon = false;
this.ShowInTaskbar = false; this.ShowInTaskbar = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.Text = "PreviewOverlay"; this.Text = "PreviewOverlay";
this.TransparencyKey = System.Drawing.Color.Black; this.TransparencyKey = System.Drawing.Color.Black;
((System.ComponentModel.ISupportInitialize)(OverlayAreaPictureBox)).EndInit(); ((System.ComponentModel.ISupportInitialize)(OverlayAreaPictureBox)).EndInit();
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();
}
} #endregion
#endregion private System.Windows.Forms.Label OverlayLabel;
}
private System.Windows.Forms.Label OverlayLabel;
}
} }

View File

@@ -3,49 +3,41 @@ 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
{ private readonly Action<object, MouseEventArgs> _areaClickAction;
#region Private fields #endregion
private readonly Action<object, MouseEventArgs> _areaClickAction;
#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; this.OverlayLabel.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.OverlayLabel.TextAlign = System.Drawing.ContentAlignment.TopLeft; break;
break;
case ZoomAnchor.N: case ZoomAnchor.N:
this.OverlayLabel.Left = (this.Width / 2) - (this.OverlayLabel.Width / 2); this.OverlayLabel.Left = (this.Width / 2) - (this.OverlayLabel.Width / 2);
this.OverlayLabel.Top = margin; this.OverlayLabel.Top = margin;
@@ -87,21 +79,18 @@ namespace EveOPreview.View
this.OverlayLabel.TextAlign = System.Drawing.ContentAlignment.BottomRight; this.OverlayLabel.TextAlign = System.Drawing.ContentAlignment.BottomRight;
break; break;
} }
} }
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;
{ Params.ExStyle |= (int)InteropConstants.WS_EX_TOOLWINDOW;
var Params = base.CreateParams; return Params;
Params.ExStyle |= (int)InteropConstants.WS_EX_TOOLWINDOW; }
return Params; }
} }
}
}
} }

View File

@@ -1,53 +1,47 @@
namespace EveOPreview.View namespace EveOPreview.View {
{ partial class ThumbnailView {
partial class ThumbnailView
{
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
/// </summary> /// </summary>
#region Windows Form Designer generated code #region Windows Form Designer generated code
/// <summary> /// <summary>
/// Required method for Designer support - do not modify /// Required method for Designer support - do not modify
/// the contents of this method with the code editor. /// the contents of this method with the code editor.
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent() {
{ this.SuspendLayout();
this.SuspendLayout(); //
// // ThumbnailView
// ThumbnailView //
// this.AccessibleRole = System.Windows.Forms.AccessibleRole.None;
this.AccessibleRole = System.Windows.Forms.AccessibleRole.None; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; this.BackColor = System.Drawing.Color.Black;
this.BackColor = System.Drawing.Color.Black; this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; this.ClientSize = new System.Drawing.Size(153, 89);
this.ClientSize = new System.Drawing.Size(153, 89); this.ControlBox = false;
this.ControlBox = false; this.DoubleBuffered = true;
this.DoubleBuffered = true; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; this.MaximizeBox = false;
this.MaximizeBox = false; this.MinimizeBox = false;
this.MinimizeBox = false; this.MinimumSize = new System.Drawing.Size(20, 20);
this.MinimumSize = new System.Drawing.Size(20, 20); this.Name = "ThumbnailView";
this.Name = "ThumbnailView"; this.Opacity = 0.1D;
this.Opacity = 0.1D; this.ShowIcon = false;
this.ShowIcon = false; this.ShowInTaskbar = false;
this.ShowInTaskbar = false; this.Text = "Preview";
this.Text = "Preview"; this.TopMost = true;
this.TopMost = true; this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MouseDown_Handler);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MouseDown_Handler); this.MouseEnter += new System.EventHandler(this.MouseEnter_Handler);
this.MouseEnter += new System.EventHandler(this.MouseEnter_Handler); this.MouseLeave += new System.EventHandler(this.MouseLeave_Handler);
this.MouseLeave += new System.EventHandler(this.MouseLeave_Handler); this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.MouseMove_Handler);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.MouseMove_Handler); this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.MouseUp_Handler);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.MouseUp_Handler); 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
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -2,30 +2,26 @@
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 bool _enableWineCompatibilityMode;
private readonly IApplicationController _controller;
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.Id = id; view.Id = id;
view.Title = title; view.Title = title;
view.ThumbnailSize = size; view.ThumbnailSize = size;
return view; return view;
} }
} }
} }

View File

@@ -2,65 +2,69 @@
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; }
bool EnableClientLayoutTracking { get; set; } bool EnableClientLayoutTracking { get; set; }
bool HideActiveClientThumbnail { get; set; } bool HideActiveClientThumbnail { get; set; }
bool MinimizeInactiveClients { get; set; } bool MinimizeInactiveClients { get; set; }
ViewAnimationStyle WindowsAnimationStyle { get; set; } ViewAnimationStyle WindowsAnimationStyle { get; set; }
bool ShowThumbnailsAlwaysOnTop { get; set; } bool ShowThumbnailsAlwaysOnTop { get; set; }
bool HideThumbnailsOnLostFocus { get; set; } bool HideThumbnailsOnLostFocus { get; set; }
bool EnablePerClientThumbnailLayouts { get; set; } bool EnablePerClientThumbnailLayouts { get; set; }
Size ThumbnailSize { get; set; } Size ThumbnailSize { get; set; }
bool EnableThumbnailZoom { get; set; } bool EnableThumbnailZoom { get; set; }
int ThumbnailZoomFactor { get; set; } int ThumbnailZoomFactor { get; set; }
ViewZoomAnchor ThumbnailZoomAnchor { get; set; } ViewZoomAnchor ThumbnailZoomAnchor { get; set; }
ViewZoomAnchor OverlayLabelAnchor { get; set; } ViewZoomAnchor OverlayLabelAnchor { get; set; }
bool ShowThumbnailOverlays { get; set; } bool ShowThumbnailOverlays { get; set; }
bool ShowThumbnailFrames { get; set; } bool ShowThumbnailFrames { get; set; }
bool LockThumbnailLocation { get; set; } bool LockThumbnailLocation { get; set; }
bool ThumbnailSnapToGrid { get; set; } bool ThumbnailSnapToGrid { get; set; }
int ThumbnailSnapToGridSizeX { get; set; } int ThumbnailSnapToGridSizeX { get; set; }
int ThumbnailSnapToGridSizeY { get; set; } int ThumbnailSnapToGridSizeY { get; set; }
bool EnableActiveClientHighlight { get; set; } bool EnableActiveClientHighlight { get; set; }
Color ActiveClientHighlightColor { get; set; } Color ActiveClientHighlightColor { get; set; }
Color OverlayLabelColor { get; set; } Color OverlayLabelColor { get; set; }
int OverlayLabelSize { get; set; } int OverlayLabelSize { get; set; }
string IconName { get; set; } bool EnableThumbnailRegionSnipping { get; set; }
Rectangle DefaultThumbnailRegion { get; set; }
void SetDocumentationUrl(string url); string CurrentProfile { get; set; }
void SetVersionInfo(string version); List<string> AvailableProfiles { get; set; }
void SetThumbnailSizeLimitations(Size minimumSize, Size maximumSize);
void Minimize(); string IconName { get; set; }
void AddThumbnails(IList<IThumbnailDescription> thumbnails); void SetDocumentationUrl(string url);
void RemoveThumbnails(IList<IThumbnailDescription> thumbnails); void SetVersionInfo(string version);
void RefreshZoomSettings(); void SetThumbnailSizeLimitations(Size minimumSize, Size maximumSize);
Action ApplicationExitRequested { get; set; } void Minimize();
Action FormActivated { get; set; }
Action FormMinimized { get; set; } void AddThumbnails(IList<IThumbnailDescription> thumbnails);
Action<ViewCloseRequest> FormCloseRequested { get; set; } void RemoveThumbnails(IList<IThumbnailDescription> thumbnails);
Action ApplicationSettingsChanged { get; set; } void RefreshZoomSettings();
Action ThumbnailsSizeChanged { get; set; }
Action<string> ThumbnailStateChanged { get; set; } Action ApplicationExitRequested { get; set; }
Action DocumentationLinkActivated { get; set; } Action FormActivated { get; set; }
} Action FormMinimized { get; set; }
Action<ViewCloseRequest> FormCloseRequested { get; set; }
Action ApplicationSettingsChanged { get; set; }
Action ThumbnailsSizeChanged { get; set; }
Action<string> ThumbnailStateChanged { get; set; }
Action DocumentationLinkActivated { get; set; }
}
} }

View File

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

View File

@@ -4,46 +4,44 @@ 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; }
{ string Title { get; set; }
IntPtr Id { get; set; }
string Title { get; set; }
bool IsActive { get; set; } bool IsActive { get; set; }
Point ThumbnailLocation { get; set; } Point ThumbnailLocation { get; set; }
Size ThumbnailSize { get; set; } Size ThumbnailSize { get; set; }
bool IsOverlayEnabled { get; set; } bool IsOverlayEnabled { get; set; }
ZoomAnchor ClientZoomAnchor { get; set; } ZoomAnchor ClientZoomAnchor { get; set; }
bool IsKnownHandle(IntPtr handle); bool IsKnownHandle(IntPtr handle);
void SetSizeLimitations(Size minimumSize, Size maximumSize); void SetSizeLimitations(Size minimumSize, Size maximumSize);
void SetOpacity(double opacity); void SetOpacity(double opacity);
void SetFrames(bool enable); void SetFrames(bool enable);
void SetOverlayLabel(); void SetOverlayLabel();
void SetTopMost(bool enableTopmost); void SetTopMost(bool enableTopmost);
void SetHighlight(); void SetHighlight();
void SetHighlight(bool enabled, int width); void SetHighlight(bool enabled, int width);
void ZoomIn(ViewZoomAnchor anchor, int zoomFactor); void ZoomIn(ViewZoomAnchor anchor, int zoomFactor);
void ZoomOut(); void ZoomOut();
void RegisterHotkey(Keys hotkey); void RegisterHotkey(Keys hotkey);
void UnregisterHotkey(); void UnregisterHotkey();
void Refresh(bool forceRefresh); void Refresh(bool forceRefresh);
Action<IntPtr> ThumbnailResized { get; set; } Action<IntPtr> ThumbnailResized { get; set; }
Action<IntPtr> ThumbnailMoved { get; set; } Action<IntPtr> ThumbnailMoved { get; set; }
Action<IntPtr> ThumbnailFocused { get; set; } Action<IntPtr> ThumbnailFocused { get; set; }
Action<IntPtr> ThumbnailLostFocus { get; set; } Action<IntPtr> ThumbnailLostFocus { get; set; }
Action<IntPtr> ThumbnailActivated { get; set; } Action<IntPtr> ThumbnailActivated { get; set; }
Action<IntPtr, bool> ThumbnailDeactivated { get; set; } Action<IntPtr, bool> ThumbnailDeactivated { get; set; }
IWindowManager WindowManager { get; } IWindowManager WindowManager { get; }
void SetDefaultBorderColor(); void SetDefaultBorderColor();
void ClearBorder(); void ClearBorder();
} }
} }

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
}
} }