diff --git a/Eve-O-Preview/Configuration/ApplicationConfiguration.cs b/Eve-O-Preview/Configuration/AppConfig.cs similarity index 85% rename from Eve-O-Preview/Configuration/ApplicationConfiguration.cs rename to Eve-O-Preview/Configuration/AppConfig.cs index 7060fc2..8ea1e02 100644 --- a/Eve-O-Preview/Configuration/ApplicationConfiguration.cs +++ b/Eve-O-Preview/Configuration/AppConfig.cs @@ -5,15 +5,15 @@ using Newtonsoft.Json; namespace EveOPreview.Configuration { - public class ApplicationConfiguration : IApplicationConfiguration + public class AppConfig : IAppConfig { - public ApplicationConfiguration() + public AppConfig() { // Default values this.MinimizeToTray = false; this.ThumbnailRefreshPeriod = 500; - this.ThumbnailsOpacity = 0.5; + this.ThumbnailOpacity = 0.5; this.EnableClientLayoutTracking = false; this.HideActiveClientThumbnail = false; @@ -25,13 +25,16 @@ namespace EveOPreview.Configuration this.ThumbnailMinimumSize = new Size(100, 80); this.ThumbnailMaximumSize = new Size(640, 400); - this.EnableThumbnailZoom = false; + this.ThumbnailZoomEnabled = false; this.ThumbnailZoomFactor = 2; this.ThumbnailZoomAnchor = ZoomAnchor.NW; this.ShowThumbnailOverlays = true; this.ShowThumbnailFrames = true; + this.EnableActiveClientHighlight = true; + this.ActiveClientHighlightColor = Color.GreenYellow; + this.PerClientLayout = new Dictionary>(); this.FlatLayout = new Dictionary(); this.ClientLayout = new Dictionary(); @@ -41,7 +44,8 @@ namespace EveOPreview.Configuration public bool MinimizeToTray { get; set; } public int ThumbnailRefreshPeriod { get; set; } - public double ThumbnailsOpacity { get; set; } + [JsonProperty("ThumbnailsOpacity")] + public double ThumbnailOpacity { get; set; } public bool EnableClientLayoutTracking { get; set; } public bool HideActiveClientThumbnail { get; set; } @@ -53,13 +57,17 @@ namespace EveOPreview.Configuration public Size ThumbnailMaximumSize { get; set; } public Size ThumbnailMinimumSize { get; set; } - public bool EnableThumbnailZoom { get; set; } + [JsonProperty("EnableThumbnailZoom")] + public bool ThumbnailZoomEnabled { get; set; } public int ThumbnailZoomFactor { get; set; } public ZoomAnchor ThumbnailZoomAnchor { get; set; } public bool ShowThumbnailOverlays { get; set; } public bool ShowThumbnailFrames { get; set; } + public bool EnableActiveClientHighlight { get; set; } + public Color ActiveClientHighlightColor { get; set; } + [JsonProperty] private Dictionary> PerClientLayout { get; set; } [JsonProperty] diff --git a/Eve-O-Preview/Configuration/ConfigurationStorage.cs b/Eve-O-Preview/Configuration/ConfigurationStorage.cs index e60dbf6..076d967 100644 --- a/Eve-O-Preview/Configuration/ConfigurationStorage.cs +++ b/Eve-O-Preview/Configuration/ConfigurationStorage.cs @@ -7,9 +7,9 @@ namespace EveOPreview.Configuration { private const string ConfigurationFileName = "EVE-O Preview.json"; - private readonly IApplicationConfiguration _configuration; + private readonly IAppConfig _configuration; - public ConfigurationStorage(IApplicationConfiguration configuration) + public ConfigurationStorage(IAppConfig configuration) { this._configuration = configuration; } diff --git a/Eve-O-Preview/Configuration/IApplicationConfiguration.cs b/Eve-O-Preview/Configuration/IAppConfig.cs similarity index 81% rename from Eve-O-Preview/Configuration/IApplicationConfiguration.cs rename to Eve-O-Preview/Configuration/IAppConfig.cs index 47c75cc..3c75043 100644 --- a/Eve-O-Preview/Configuration/IApplicationConfiguration.cs +++ b/Eve-O-Preview/Configuration/IAppConfig.cs @@ -3,12 +3,12 @@ using System.Windows.Forms; namespace EveOPreview.Configuration { - public interface IApplicationConfiguration + public interface IAppConfig { bool MinimizeToTray { get; set; } int ThumbnailRefreshPeriod { get; set; } - double ThumbnailsOpacity { get; set; } + double ThumbnailOpacity { get; set; } bool EnableClientLayoutTracking { get; set; } bool HideActiveClientThumbnail { get; set; } @@ -20,13 +20,16 @@ namespace EveOPreview.Configuration Size ThumbnailMinimumSize { get; set; } Size ThumbnailMaximumSize { get; set; } - bool EnableThumbnailZoom { get; set; } + bool ThumbnailZoomEnabled { get; set; } int ThumbnailZoomFactor { get; set; } ZoomAnchor ThumbnailZoomAnchor { get; set; } bool ShowThumbnailOverlays { get; set; } bool ShowThumbnailFrames { get; set; } + bool EnableActiveClientHighlight { get; set; } + Color ActiveClientHighlightColor { get; set; } + Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation); void SetThumbnailLocation(string currentClient, string activeClient, Point location); diff --git a/Eve-O-Preview/Eve-O-Preview.csproj b/Eve-O-Preview/Eve-O-Preview.csproj index e0e78ce..ca46da0 100644 --- a/Eve-O-Preview/Eve-O-Preview.csproj +++ b/Eve-O-Preview/Eve-O-Preview.csproj @@ -97,7 +97,7 @@ - + @@ -118,7 +118,7 @@ - + diff --git a/Eve-O-Preview/Presentation/MainPresenter.cs b/Eve-O-Preview/Presentation/MainPresenter.cs index d9e4a9e..8e20c5f 100644 --- a/Eve-O-Preview/Presentation/MainPresenter.cs +++ b/Eve-O-Preview/Presentation/MainPresenter.cs @@ -13,7 +13,7 @@ namespace EveOPreview.UI #endregion #region Private fields - private readonly IApplicationConfiguration _configuration; + private readonly IAppConfig _configuration; private readonly IConfigurationStorage _configurationStorage; private readonly IThumbnailDescriptionViewFactory _thumbnailDescriptionViewFactory; private readonly IDictionary _thumbnailDescriptionViews; @@ -22,7 +22,7 @@ namespace EveOPreview.UI private bool _exitApplication; #endregion - public MainPresenter(IApplicationController controller, IMainView view, IApplicationConfiguration configuration, IConfigurationStorage configurationStorage, + public MainPresenter(IApplicationController controller, IMainView view, IAppConfig configuration, IConfigurationStorage configurationStorage, IThumbnailManager thumbnailManager, IThumbnailDescriptionViewFactory thumbnailDescriptionViewFactory) : base(controller, view) { @@ -98,18 +98,18 @@ namespace EveOPreview.UI this.View.MinimizeToTray = this._configuration.MinimizeToTray; - this.View.ThumbnailsOpacity = this._configuration.ThumbnailsOpacity; + this.View.ThumbnailOpacity = this._configuration.ThumbnailOpacity; this.View.EnableClientLayoutTracking = this._configuration.EnableClientLayoutTracking; this.View.HideActiveClientThumbnail = this._configuration.HideActiveClientThumbnail; this.View.ShowThumbnailsAlwaysOnTop = this._configuration.ShowThumbnailsAlwaysOnTop; this.View.HideThumbnailsOnLostFocus = this._configuration.HideThumbnailsOnLostFocus; - this.View.EnablePerClientThumbnailsLayouts = this._configuration.EnablePerClientThumbnailLayouts; + this.View.EnablePerClientThumbnailLayouts = this._configuration.EnablePerClientThumbnailLayouts; this.View.SetThumbnailSizeLimitations(this._configuration.ThumbnailMinimumSize, this._configuration.ThumbnailMaximumSize); this.View.ThumbnailSize = this._configuration.ThumbnailSize; - this.View.EnableThumbnailZoom = this._configuration.EnableThumbnailZoom; + this.View.EnableThumbnailZoom = this._configuration.ThumbnailZoomEnabled; this.View.ThumbnailZoomFactor = this._configuration.ThumbnailZoomFactor; this.View.ThumbnailZoomAnchor = ViewZoomAnchorConverter.Convert(this._configuration.ThumbnailZoomAnchor); @@ -121,17 +121,17 @@ namespace EveOPreview.UI { this._configuration.MinimizeToTray = this.View.MinimizeToTray; - this._configuration.ThumbnailsOpacity = (float)this.View.ThumbnailsOpacity; + this._configuration.ThumbnailOpacity = (float)this.View.ThumbnailOpacity; this._configuration.EnableClientLayoutTracking = this.View.EnableClientLayoutTracking; this._configuration.HideActiveClientThumbnail = this.View.HideActiveClientThumbnail; this._configuration.ShowThumbnailsAlwaysOnTop = this.View.ShowThumbnailsAlwaysOnTop; this._configuration.HideThumbnailsOnLostFocus = this.View.HideThumbnailsOnLostFocus; - this._configuration.EnablePerClientThumbnailLayouts = this.View.EnablePerClientThumbnailsLayouts; + this._configuration.EnablePerClientThumbnailLayouts = this.View.EnablePerClientThumbnailLayouts; this._configuration.ThumbnailSize = this.View.ThumbnailSize; - this._configuration.EnableThumbnailZoom = this.View.EnableThumbnailZoom; + this._configuration.ThumbnailZoomEnabled = this.View.EnableThumbnailZoom; this._configuration.ThumbnailZoomFactor = this.View.ThumbnailZoomFactor; this._configuration.ThumbnailZoomAnchor = ViewZoomAnchorConverter.Convert(this.View.ThumbnailZoomAnchor); diff --git a/Eve-O-Preview/Program.cs b/Eve-O-Preview/Program.cs index cf7d7e8..da22a50 100644 --- a/Eve-O-Preview/Program.cs +++ b/Eve-O-Preview/Program.cs @@ -29,7 +29,7 @@ namespace EveOPreview .RegisterService() .RegisterService() .RegisterService() - .RegisterInstance(new ApplicationConfiguration()); + .RegisterInstance(new AppConfig()); controller.Run(); } diff --git a/Eve-O-Preview/UI/Implementation/ThumbnailOverlay.Designer.cs b/Eve-O-Preview/UI/Implementation/ThumbnailOverlay.Designer.cs index 5336b35..47bb2f6 100644 --- a/Eve-O-Preview/UI/Implementation/ThumbnailOverlay.Designer.cs +++ b/Eve-O-Preview/UI/Implementation/ThumbnailOverlay.Designer.cs @@ -50,10 +50,9 @@ // OverlayLabel // this.OverlayLabel.AutoSize = true; - this.OverlayLabel.Dock = System.Windows.Forms.DockStyle.Top; this.OverlayLabel.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.OverlayLabel.ForeColor = System.Drawing.Color.DarkGray; - this.OverlayLabel.Location = new System.Drawing.Point(0, 0); + this.OverlayLabel.Location = new System.Drawing.Point(8, 8); this.OverlayLabel.Name = "OverlayLabel"; this.OverlayLabel.Size = new System.Drawing.Size(25, 13); this.OverlayLabel.TabIndex = 1; diff --git a/Eve-O-Preview/UI/Implementation/ThumbnailOverlay.cs b/Eve-O-Preview/UI/Implementation/ThumbnailOverlay.cs index 986dfa7..3b384da 100644 --- a/Eve-O-Preview/UI/Implementation/ThumbnailOverlay.cs +++ b/Eve-O-Preview/UI/Implementation/ThumbnailOverlay.cs @@ -1,4 +1,5 @@ using System; +using System.Drawing; using System.Windows.Forms; namespace EveOPreview.UI @@ -7,6 +8,8 @@ namespace EveOPreview.UI { #region Private fields private readonly Action _areaClickAction; + private bool _highlightEnabled; + private Color _highlightColor; #endregion public ThumbnailOverlay(Form owner, Action areaClickAction) @@ -14,6 +17,9 @@ namespace EveOPreview.UI this.Owner = owner; this._areaClickAction = areaClickAction; + this._highlightEnabled = false; + this._highlightColor = Color.Red; + InitializeComponent(); } @@ -27,6 +33,24 @@ namespace EveOPreview.UI this.OverlayLabel.Text = label; } + public void EnableOverlayLabel(bool enable) + { + this.OverlayLabel.Visible = enable; + } + + public void EnableHighlight(bool enabled, Color color) + { + if (!enabled && !this._highlightEnabled) + { + // Nothing to do here + return; + } + + this._highlightEnabled = enabled; + this._highlightColor = color; + this.Refresh(); + } + protected override CreateParams CreateParams { get @@ -36,5 +60,19 @@ namespace EveOPreview.UI return Params; } } + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + + if (this._highlightEnabled) + { + ControlPaint.DrawBorder(e.Graphics, this.ClientRectangle, + this._highlightColor, 4, ButtonBorderStyle.Solid, + this._highlightColor, 4, ButtonBorderStyle.Solid, + this._highlightColor, 4, ButtonBorderStyle.Solid, + this._highlightColor, 4, ButtonBorderStyle.Solid); + } + } } } diff --git a/Eve-O-Preview/UI/Implementation/ThumbnailView.Designer.cs b/Eve-O-Preview/UI/Implementation/ThumbnailView.Designer.cs index 9ba73e6..71e6fc9 100644 --- a/Eve-O-Preview/UI/Implementation/ThumbnailView.Designer.cs +++ b/Eve-O-Preview/UI/Implementation/ThumbnailView.Designer.cs @@ -34,8 +34,8 @@ namespace EveOPreview.UI this.Text = "Preview"; this.TopMost = true; this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MouseDown_Handler); - this.MouseLeave += new System.EventHandler(this.MouseLeave_Handler); this.MouseEnter += new System.EventHandler(this.MouseEnter_Handler); + this.MouseLeave += new System.EventHandler(this.MouseLeave_Handler); this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.MouseMove_Handler); this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.MouseUp_Handler); this.Move += new System.EventHandler(this.Move_Handler); diff --git a/Eve-O-Preview/UI/Implementation/ThumbnailView.cs b/Eve-O-Preview/UI/Implementation/ThumbnailView.cs index 59be9b1..7621fb3 100644 --- a/Eve-O-Preview/UI/Implementation/ThumbnailView.cs +++ b/Eve-O-Preview/UI/Implementation/ThumbnailView.cs @@ -113,7 +113,11 @@ namespace EveOPreview.UI { base.Show(); - // Thumbnail will be registered during the Refresh cycle + this._isPositionChanged = true; + this._isSizeChanged = true; + this._isOverlayVisible = false; + + // Thumbnail will be properly registered during the Manager's Refresh cycle this.Refresh(); this.IsActive = true; @@ -152,6 +156,12 @@ namespace EveOPreview.UI public void SetOpacity(double opacity) { this.Opacity = opacity; + + // Overlay opacity settings + // Of the thumbnail's opacity is almost full then set the overlay's one to + // full. Otherwise set it to half of the thumnail opacity + // Opacity value is stored even if the overlay is not displayed atm + this._overlay.Opacity = this.Opacity > 0.9 ? 1.0 : 1.0 - (1.0 - this.Opacity) / 2; } public void SetFrames(bool enable) @@ -187,6 +197,11 @@ namespace EveOPreview.UI this._isTopMost = enableTopmost; } + public void SetHighlight(bool enabled, Color color) + { + this._overlay.EnableHighlight(enabled, color); + } + public void ZoomIn(ViewZoomAnchor anchor, int zoomFactor) { int oldWidth = this._baseZoomSize.Width; @@ -312,40 +327,34 @@ namespace EveOPreview.UI this.UnregisterThumbnail(obsoleteThumbnailHanlde); } - if (!this.IsOverlayEnabled) - { - if (this._isOverlayVisible) - { - this._overlay.Hide(); - this._isOverlayVisible = false; - } - - return; - } + this._overlay.EnableOverlayLabel(this.IsOverlayEnabled); if (!this._isOverlayVisible) { + // One-time action to show the Overlay before it is set up + // Otherwise its position won't be set this._overlay.Show(); this._isOverlayVisible = true; } - else if (!(sizeChanged || locationChanged)) + else { - // No need to adjust in the overlay location if it is already visible and properly set - return; + if (!(sizeChanged || locationChanged)) + { + // No need to adjust in the overlay location if it is already visible and properly set + return; + } } Size overlaySize = this.ClientSize; - overlaySize.Width -= 2 * 5; - overlaySize.Height -= 2 * 5; - Point overlayLocation = this.Location; - overlayLocation.X += 5 + (this.Size.Width - this.ClientSize.Width) / 2; - overlayLocation.Y += 5 + (this.Size.Height - this.ClientSize.Height) - (this.Size.Width - this.ClientSize.Width) / 2; + overlayLocation.X += (this.Size.Width - this.ClientSize.Width) / 2; + overlayLocation.Y += (this.Size.Height - this.ClientSize.Height) - (this.Size.Width - this.ClientSize.Width) / 2; this._isPositionChanged = false; this._overlay.Size = overlaySize; this._overlay.Location = overlayLocation; + this._overlay.Invalidate(); } #region GUI events @@ -427,26 +436,7 @@ namespace EveOPreview.UI } #endregion - // This pair of methods saves/restores certain window propeties - // Methods are used to remove the 'Zoom' effect (if any) when the - // custom resize/move mode is activated - // Methods are kept on this level because moving to the presenter - // the code that responds to the mouse events like movement - // seems like a huge overkill - private void SaveWindowSizeAndLocation() - { - this._baseZoomSize = this.Size; - this._baseZoomLocation = this.Location; - this._baseZoomMaximumSize = this.MaximumSize; - } - - private void RestoreWindowSizeAndLocation() - { - this.Size = this._baseZoomSize; - this.MaximumSize = this._baseZoomMaximumSize; - this.Location = this._baseZoomLocation; - } - + #region Thumbnail management private void RegisterThumbnail() { this._thumbnailHandle = WindowManagerNativeMethods.DwmRegisterThumbnail(this.Handle, this.Id); @@ -473,6 +463,28 @@ namespace EveOPreview.UI { } } + #endregion + + #region Custom Mouse mode + // This pair of methods saves/restores certain window propeties + // Methods are used to remove the 'Zoom' effect (if any) when the + // custom resize/move mode is activated + // Methods are kept on this level because moving to the presenter + // the code that responds to the mouse events like movement + // seems like a huge overkill + private void SaveWindowSizeAndLocation() + { + this._baseZoomSize = this.Size; + this._baseZoomLocation = this.Location; + this._baseZoomMaximumSize = this.MaximumSize; + } + + private void RestoreWindowSizeAndLocation() + { + this.Size = this._baseZoomSize; + this.MaximumSize = this._baseZoomMaximumSize; + this.Location = this._baseZoomLocation; + } private void EnterCustomMouseMode() { @@ -507,5 +519,6 @@ namespace EveOPreview.UI { this._isCustomMouseModeActive = false; } + #endregion } } \ No newline at end of file diff --git a/Eve-O-Preview/UI/Interface/IMainView.cs b/Eve-O-Preview/UI/Interface/IMainView.cs index 3a2b7b1..b6193ad 100644 --- a/Eve-O-Preview/UI/Interface/IMainView.cs +++ b/Eve-O-Preview/UI/Interface/IMainView.cs @@ -12,13 +12,13 @@ namespace EveOPreview.UI { bool MinimizeToTray { get; set; } - double ThumbnailsOpacity { get; set; } + double ThumbnailOpacity { get; set; } bool EnableClientLayoutTracking { get; set; } bool HideActiveClientThumbnail { get; set; } bool ShowThumbnailsAlwaysOnTop { get; set; } bool HideThumbnailsOnLostFocus { get; set; } - bool EnablePerClientThumbnailsLayouts { get; set; } + bool EnablePerClientThumbnailLayouts { get; set; } Size ThumbnailSize { get; set; } @@ -29,6 +29,9 @@ namespace EveOPreview.UI bool ShowThumbnailOverlays { get; set; } bool ShowThumbnailFrames { get; set; } + bool EnableActiveClientHighlight { get; set; } + Color ActiveClientHighlightColor { get; set; } + void SetForumUrl(string url); void SetThumbnailSizeLimitations(Size minimumSize, Size maximumSize); diff --git a/Eve-O-Preview/UI/Interface/IThumbnailView.cs b/Eve-O-Preview/UI/Interface/IThumbnailView.cs index 1034160..21b5cfd 100644 --- a/Eve-O-Preview/UI/Interface/IThumbnailView.cs +++ b/Eve-O-Preview/UI/Interface/IThumbnailView.cs @@ -21,6 +21,7 @@ namespace EveOPreview.UI void SetOpacity(double opacity); void SetFrames(bool enable); void SetTopMost(bool enableTopmost); + void SetHighlight(bool enabled, Color color); void ZoomIn(ViewZoomAnchor anchor, int zoomFactor); void ZoomOut();