diff --git a/Eve-O-Preview/Configuration/Configuration.cs b/Eve-O-Preview/Configuration/Configuration.cs
new file mode 100644
index 0000000..62d40ec
--- /dev/null
+++ b/Eve-O-Preview/Configuration/Configuration.cs
@@ -0,0 +1,7 @@
+namespace EveOPreview
+{
+ public class Configuration
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Eve-O-Preview/Configuration/ConfigurationStorage.cs b/Eve-O-Preview/Configuration/ConfigurationStorage.cs
new file mode 100644
index 0000000..974930e
--- /dev/null
+++ b/Eve-O-Preview/Configuration/ConfigurationStorage.cs
@@ -0,0 +1,7 @@
+namespace EveOPreview.Managers
+{
+ public class ConfigurationStorage
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Eve-O-Preview/Eve-O-Preview.csproj b/Eve-O-Preview/Eve-O-Preview.csproj
index 9e8f21c..99848fb 100644
--- a/Eve-O-Preview/Eve-O-Preview.csproj
+++ b/Eve-O-Preview/Eve-O-Preview.csproj
@@ -110,6 +110,7 @@
+
@@ -118,8 +119,10 @@
MainForm.cs
+
+
Form
diff --git a/Eve-O-Preview/GUI/MainForm.cs b/Eve-O-Preview/GUI/MainForm.cs
index 52f7249..902c16a 100644
--- a/Eve-O-Preview/GUI/MainForm.cs
+++ b/Eve-O-Preview/GUI/MainForm.cs
@@ -12,29 +12,13 @@ namespace EveOPreview
{
public partial class MainForm : Form
{
- private readonly ThumbnailFactory _thumbnailFactory;
-
public event EventHandler Minimized;
public event EventHandler Maximized;
public event EventHandler Restored;
-
- private readonly Dictionary _previews;
- private DispatcherTimer _dispatcherTimer;
-
- private IntPtr _activeClientHandle;
- private string _activeClientTitle;
-
- private readonly Dictionary> _uniqueLayouts;
- private readonly Dictionary _flatLayout;
- private readonly Dictionary _flatLayoutShortcuts;
- private readonly Dictionary _clientLayout;
-
private readonly bool _isInitialized;
+ private readonly ThumbnailManager _manager;
- private readonly Stopwatch _ignoringSizeSync;
-
- private readonly Dictionary _xmlBadToOkChars;
private Dictionary _zoomAnchorButtonMap;
@@ -42,49 +26,63 @@ namespace EveOPreview
{
_isInitialized = false;
- this._activeClientHandle = (IntPtr)0;
- this._activeClientTitle = "";
-
- this._previews = new Dictionary();
-
- _xmlBadToOkChars = new Dictionary();
- _xmlBadToOkChars["<"] = "---lt---";
- _xmlBadToOkChars["&"] = "---amp---";
- _xmlBadToOkChars[">"] = "---gt---";
- _xmlBadToOkChars["\""] = "---quot---";
- _xmlBadToOkChars["\'"] = "---apos---";
- _xmlBadToOkChars[","] = "---comma---";
- _xmlBadToOkChars["."] = "---dot---";
-
- _uniqueLayouts = new Dictionary>();
- _flatLayout = new Dictionary();
- _flatLayoutShortcuts = new Dictionary();
- _clientLayout = new Dictionary();
-
- _ignoringSizeSync = new Stopwatch();
- _ignoringSizeSync.Start();
-
InitializeComponent();
init_options();
- // DispatcherTimer setup
- _dispatcherTimer = new DispatcherTimer();
- _dispatcherTimer.Tick += dispatcherTimer_Tick;
- _dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
- _dispatcherTimer.Start();
+ // TODO Fix this
+ previews_check_listbox.DisplayMember = "Text";
- this._thumbnailFactory = new ThumbnailFactory();
+ this._manager = new ThumbnailManager(add_thumbnail,remove_thumbnail, set_aero_status, set_size);
_isInitialized = true;
- previews_check_listbox.DisplayMember = "Text";
-
+ this._manager.Activate();
}
+ private void add_thumbnail(IList thumbnails)
+ {
+ this.previews_check_listbox.BeginUpdate();
+ foreach (string th in thumbnails)
+ {
+ previews_check_listbox.Items.Add(th);
+ }
+ this.previews_check_listbox.EndUpdate();
+ }
+
+ private void remove_thumbnail(IList thumbnails)
+ {
+ this.previews_check_listbox.BeginUpdate();
+ foreach (string th in thumbnails)
+ {
+ previews_check_listbox.Items.Remove(th);
+ }
+ this.previews_check_listbox.EndUpdate();
+ }
+
+ private void set_aero_status(bool value)
+ {
+
+ if (value)
+ {
+ aero_status_label.Text = "AERO is ON";
+ aero_status_label.ForeColor = Color.Black;
+ }
+ else
+ {
+ aero_status_label.Text = "AERO is OFF";
+ aero_status_label.ForeColor = Color.Red;
+ }
+ }
+
+ private void set_size(int x, int y)
+ {
+ option_sync_size_x.Text = x.ToString();
+ option_sync_size_y.Text = y.ToString();
+ }
private void GlassForm_Load(object sender, EventArgs e)
{
- refresh_thumbnails();
+ this._manager.refresh_thumbnails();
}
private void init_options()
@@ -131,470 +129,60 @@ namespace EveOPreview
}
opacity_bar.Value = Math.Min(100, (int)(100.0 * Properties.Settings.Default.opacity));
-
- load_layout();
}
- private void spawn_and_kill_previews()
- {
- if (!_isInitialized) { return; }
-
- Process[] processes = Process.GetProcessesByName("ExeFile");
- List processHandles = new List();
-
- // pop new previews
-
- foreach (Process process in processes)
- {
- processHandles.Add(process.MainWindowHandle);
-
- Size sync_size = new Size();
- sync_size.Width = (int)Properties.Settings.Default.sync_resize_x;
- sync_size.Height = (int)Properties.Settings.Default.sync_resize_y;
-
- if (!_previews.ContainsKey(process.MainWindowHandle) && process.MainWindowTitle != "")
- {
- _previews[process.MainWindowHandle] = this._thumbnailFactory.Create(this, process.MainWindowHandle, "...", sync_size);
-
- // apply more thumbnail specific options
- _previews[process.MainWindowHandle].SetTopMost(Properties.Settings.Default.always_on_top);
- _previews[process.MainWindowHandle].SetWindowFrames(Properties.Settings.Default.show_thumb_frames);
-
- // add a preview also
- previews_check_listbox.BeginUpdate();
- previews_check_listbox.Items.Add(_previews[process.MainWindowHandle]);
- previews_check_listbox.EndUpdate();
-
- refresh_client_window_locations(process);
- }
-
- else if (_previews.ContainsKey(process.MainWindowHandle) && process.MainWindowTitle != _previews[process.MainWindowHandle].GetLabel()) //or update the preview titles
- {
- _previews[process.MainWindowHandle].SetLabel(process.MainWindowTitle);
- string key = _previews[process.MainWindowHandle].GetLabel();
- string value;
- if (_flatLayoutShortcuts.TryGetValue(key, out value))
- {
- _previews[process.MainWindowHandle].RegisterShortcut(value);
- }
- refresh_client_window_locations(process);
- }
-
- if (process.MainWindowHandle == DwmApiNativeMethods.GetForegroundWindow())
- {
- _activeClientHandle = process.MainWindowHandle;
- _activeClientTitle = process.MainWindowTitle;
- }
-
- }
-
- // clean up old previews
- List to_be_pruned = new List();
- foreach (IntPtr processHandle in _previews.Keys)
- {
- if (!(processHandles.Contains(processHandle)))
- {
- to_be_pruned.Add(processHandle);
- }
- }
-
- foreach (IntPtr processHandle in to_be_pruned)
- {
- previews_check_listbox.BeginUpdate();
- previews_check_listbox.Items.Remove(_previews[processHandle]);
- previews_check_listbox.EndUpdate();
-
- _previews[processHandle].CloseThumbnail();
- _previews.Remove(processHandle);
- }
-
- previews_check_listbox.Update();
-
- }
-
- private void refresh_client_window_locations(Process process)
- {
- if (Properties.Settings.Default.track_client_windows && _clientLayout.ContainsKey(process.MainWindowTitle))
- {
- DwmApiNativeMethods.MoveWindow(process.MainWindowHandle, _clientLayout[process.MainWindowTitle].X,
- _clientLayout[process.MainWindowTitle].Y, _clientLayout[process.MainWindowTitle].Width,
- _clientLayout[process.MainWindowTitle].Height, true);
- }
- }
-
-
- private string remove_nonconform_xml_characters(string entry)
- {
- foreach (var kv in _xmlBadToOkChars)
- {
- entry = entry.Replace(kv.Key, kv.Value);
- }
- return entry;
- }
-
- private string restore_nonconform_xml_characters(string entry)
- {
- foreach (var kv in _xmlBadToOkChars)
- {
- entry = entry.Replace(kv.Value, kv.Key);
- }
- return entry;
- }
-
- private XElement MakeXElement(string input)
- {
- string clean = remove_nonconform_xml_characters(input).Replace(" ", "_");
- return new XElement(clean);
- }
-
- private string ParseXElement(XElement input)
- {
- return restore_nonconform_xml_characters(input.Name.ToString()).Replace("_", " ");
- }
-
- private void load_layout()
- {
- if (File.Exists("layout.xml"))
- {
- XElement rootElement = XElement.Load("layout.xml");
- foreach (var el in rootElement.Elements())
- {
- Dictionary inner = new Dictionary();
- foreach (var inner_el in el.Elements())
- {
- inner[ParseXElement(inner_el)] = new Point(Convert.ToInt32(inner_el.Element("x")?.Value), Convert.ToInt32(inner_el.Element("y")?.Value));
- }
- _uniqueLayouts[ParseXElement(el)] = inner;
- }
- }
-
- if (File.Exists("flat_layout.xml"))
- {
- XElement rootElement = XElement.Load("flat_layout.xml");
- foreach (var el in rootElement.Elements())
- {
- _flatLayout[ParseXElement(el)] = new Point(Convert.ToInt32(el.Element("x").Value), Convert.ToInt32(el.Element("y").Value));
- _flatLayoutShortcuts[ParseXElement(el)] = "";
-
- if (el.Element("shortcut") != null)
- {
- _flatLayoutShortcuts[ParseXElement(el)] = el.Element("shortcut").Value;
- }
- }
- }
-
- if (File.Exists("client_layout.xml"))
- {
- XElement rootElement = XElement.Load("client_layout.xml");
- foreach (var el in rootElement.Elements())
- {
- ClientLocation clientLocation = new ClientLocation();
- clientLocation.X = Convert.ToInt32(el.Element("x").Value);
- clientLocation.Y = Convert.ToInt32(el.Element("y").Value);
- clientLocation.Width = Convert.ToInt32(el.Element("width").Value);
- clientLocation.Height = Convert.ToInt32(el.Element("height").Value);
-
- _clientLayout[ParseXElement(el)] = clientLocation;
- }
- }
- }
-
- private void store_layout()
- {
- XElement el = new XElement("layouts");
- foreach (var client in _uniqueLayouts.Keys)
- {
- if (client == "")
- {
- continue;
- }
- XElement layout = MakeXElement(client);
- foreach (var thumbnail_ in _uniqueLayouts[client])
- {
- string thumbnail = thumbnail_.Key;
- if (thumbnail == "" || thumbnail == "...")
- {
- continue;
- }
- XElement position = MakeXElement(thumbnail);
- position.Add(new XElement("x", thumbnail_.Value.X));
- position.Add(new XElement("y", thumbnail_.Value.Y));
- layout.Add(position);
- }
- el.Add(layout);
- }
-
- el.Save("layout.xml");
-
- XElement el2 = new XElement("flat_layout");
- foreach (var clientKV in _flatLayout)
- {
- if (clientKV.Key == "" || clientKV.Key == "...")
- {
- continue;
- }
- XElement layout = MakeXElement(clientKV.Key);
- layout.Add(new XElement("x", clientKV.Value.X));
- layout.Add(new XElement("y", clientKV.Value.Y));
-
- string shortcut;
- if (_flatLayoutShortcuts.TryGetValue(clientKV.Key, out shortcut))
- {
- layout.Add(new XElement("shortcut", shortcut));
- }
- el2.Add(layout);
- }
-
- el2.Save("flat_layout.xml");
-
- XElement el3 = new XElement("client_layout");
- foreach (var clientKV in _clientLayout)
- {
- if (clientKV.Key == "" || clientKV.Key == "...")
- {
- continue;
- }
- XElement layout = MakeXElement(clientKV.Key);
- layout.Add(new XElement("x", clientKV.Value.X));
- layout.Add(new XElement("y", clientKV.Value.Y));
- layout.Add(new XElement("width", clientKV.Value.Width));
- layout.Add(new XElement("height", clientKV.Value.Height));
- el3.Add(layout);
- }
-
- el3.Save("client_layout.xml");
- }
-
- private void handle_unique_layout(IThumbnail thumbnailWindow, string last_known_active_window)
- {
- Dictionary layout;
- if (_uniqueLayouts.TryGetValue(last_known_active_window, out layout))
- {
- Point new_loc;
- if (Properties.Settings.Default.unique_layout && layout.TryGetValue(thumbnailWindow.GetLabel(), out new_loc))
- {
- thumbnailWindow.SetLocation(new_loc);
- }
- else
- {
- // create inner dict
- layout[thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
- }
- }
- else if (last_known_active_window != "")
- {
- // create outer dict
- _uniqueLayouts[last_known_active_window] = new Dictionary();
- _uniqueLayouts[last_known_active_window][thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
- }
- }
-
-
- private void update_client_locations()
- {
- Process[] processes = Process.GetProcessesByName("ExeFile");
- List processHandles = new List();
-
- foreach (Process process in processes)
- {
- RECT rect = new RECT();
- DwmApiNativeMethods.GetWindowRect(process.MainWindowHandle, out rect);
-
- int left = Math.Abs(rect.Left);
- int right = Math.Abs(rect.Right);
- int client_width = Math.Abs(left - right);
-
- int top = Math.Abs(rect.Top);
- int bottom = Math.Abs(rect.Bottom);
- int client_height = Math.Abs(top - bottom);
-
- ClientLocation clientLocation = new ClientLocation();
- clientLocation.X = rect.Left;
- clientLocation.Y = rect.Top;
- clientLocation.Width = client_width;
- clientLocation.Height = client_height;
-
-
- _clientLayout[process.MainWindowTitle] = clientLocation;
- }
- }
-
-
- public void NotifyPreviewSwitch()
- {
- update_client_locations();
- store_layout(); //todo: check if it actually changed ...
- foreach (KeyValuePair entry in _previews)
- {
- entry.Value.SetTopMost(Properties.Settings.Default.always_on_top);
- }
- }
-
-
- private void handle_flat_layout(IThumbnail thumbnailWindow)
- {
- Point layout;
- if (_flatLayout.TryGetValue(thumbnailWindow.GetLabel(), out layout))
- {
- thumbnailWindow.SetLocation(layout);
- }
- else if (thumbnailWindow.GetLabel() != "")
- {
- _flatLayout[thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
- }
- }
-
- private bool window_is_preview_or_client(IntPtr window)
- {
- bool active_window_is_right_type = false;
- foreach (KeyValuePair entry in _previews)
- {
- if (entry.Key == window || entry.Value.IsPreviewHandle(window))
- {
- active_window_is_right_type = true;
- }
- }
- return active_window_is_right_type;
- }
-
-
- private void refresh_thumbnails()
- {
-
- IntPtr active_window = DwmApiNativeMethods.GetForegroundWindow();
-
- // hide, show, resize and move
- foreach (KeyValuePair entry in _previews)
- {
- if (!window_is_preview_or_client(active_window) && Properties.Settings.Default.hide_all)
- {
- entry.Value.HideThumbnail();
- }
- else if (entry.Key == _activeClientHandle && Properties.Settings.Default.hide_active)
- {
- entry.Value.HideThumbnail();
- }
- else
- {
- entry.Value.ShowThumbnail();
- if (Properties.Settings.Default.unique_layout)
- {
- handle_unique_layout(entry.Value, _activeClientTitle);
- }
- else
- {
- handle_flat_layout(entry.Value);
- }
- }
- entry.Value.IsZoomEnabled = Properties.Settings.Default.zoom_on_hover;
- entry.Value.IsOverlayEnabled = Properties.Settings.Default.show_overlay;
- entry.Value.SetOpacity(Properties.Settings.Default.opacity);
- }
-
- DwmApiNativeMethods.DwmIsCompositionEnabled();
- }
-
-
- public void SyncPreviewSize(Size sync_size)
- {
- if (!_isInitialized) { return; }
-
- if (Properties.Settings.Default.sync_resize &&
- Properties.Settings.Default.show_thumb_frames &&
- _ignoringSizeSync.ElapsedMilliseconds > 500)
- {
- _ignoringSizeSync.Stop();
-
- option_sync_size_x.Text = sync_size.Width.ToString();
- option_sync_size_y.Text = sync_size.Height.ToString();
-
- foreach (KeyValuePair entry in _previews)
- {
- if (entry.Value.IsPreviewHandle(DwmApiNativeMethods.GetForegroundWindow()))
- {
- entry.Value.SetSize(sync_size);
- }
- }
-
- }
-
- }
-
-
- public void UpdatePreviewPosition(string preview_title, Point position)
- {
-
- if (Properties.Settings.Default.unique_layout)
- {
- Dictionary layout;
- if (_uniqueLayouts.TryGetValue(_activeClientTitle, out layout))
- {
- layout[preview_title] = position;
- }
- else if (_activeClientTitle == "")
- {
- _uniqueLayouts[_activeClientTitle] = new Dictionary();
- _uniqueLayouts[_activeClientTitle][preview_title] = position;
- }
- }
- else
- {
- _flatLayout[preview_title] = position;
- }
-
- }
-
-
- private void dispatcherTimer_Tick(object sender, EventArgs e)
- {
- spawn_and_kill_previews();
- refresh_thumbnails();
- if (_ignoringSizeSync.ElapsedMilliseconds > 500) { _ignoringSizeSync.Stop(); };
-
- if (DwmApiNativeMethods.DwmIsCompositionEnabled())
- {
- aero_status_label.Text = "AERO is ON";
- aero_status_label.ForeColor = Color.Black;
- }
- else
- {
- aero_status_label.Text = "AERO is OFF";
- aero_status_label.ForeColor = Color.Red;
- }
-
- }
private void option_hide_all_if_noneve_CheckedChanged(object sender, EventArgs e)
{
+ if (!_isInitialized)
+ {
+ return;
+ }
+
Properties.Settings.Default.hide_all = option_hide_all_if_not_right_type.Checked;
Properties.Settings.Default.Save();
- refresh_thumbnails();
+ this._manager.refresh_thumbnails();
}
private void option_unique_layout_CheckedChanged(object sender, EventArgs e)
{
+ if (!_isInitialized)
+ {
+ return;
+ }
+
Properties.Settings.Default.unique_layout = option_unique_layout.Checked;
Properties.Settings.Default.Save();
- refresh_thumbnails();
+ this._manager.refresh_thumbnails();
}
private void option_hide_active_CheckedChanged(object sender, EventArgs e)
{
+ if (!_isInitialized)
+ {
+ return;
+ }
+
Properties.Settings.Default.hide_active = option_hide_active.Checked;
Properties.Settings.Default.Save();
- refresh_thumbnails();
+ this._manager.refresh_thumbnails();
}
private void option_sync_size_CheckedChanged(object sender, EventArgs e)
{
+ if (!_isInitialized)
+ {
+ return;
+ }
+
Properties.Settings.Default.sync_resize = option_sync_size.Checked;
Properties.Settings.Default.Save();
- refresh_thumbnails();
+ this._manager.refresh_thumbnails();
}
@@ -622,51 +210,59 @@ namespace EveOPreview
Properties.Settings.Default.Save();
// resize
- SyncPreviewSize(new Size((int)Properties.Settings.Default.sync_resize_x,
+ this._manager.SyncPreviewSize(new Size((int)Properties.Settings.Default.sync_resize_x,
(int)Properties.Settings.Default.sync_resize_y));
}
private void option_sync_size_x_TextChanged(object sender, EventArgs e)
{
+ if (!_isInitialized)
+ {
+ return;
+ }
+
parse_size_entry();
}
private void option_sync_size_y_TextChanged(object sender, EventArgs e)
{
+ if (!_isInitialized)
+ {
+ return;
+ }
+
parse_size_entry();
}
private void option_always_on_top_CheckedChanged(object sender, EventArgs e)
{
+ if (!_isInitialized)
+ {
+ return;
+ }
+
Properties.Settings.Default.always_on_top = option_always_on_top.Checked;
Properties.Settings.Default.Save();
- refresh_thumbnails();
+ this._manager.refresh_thumbnails();
}
private void option_show_thumbnail_frames_CheckedChanged(object sender, EventArgs e)
{
+ if (!_isInitialized)
+ {
+ return;
+ }
+
Properties.Settings.Default.show_thumb_frames = option_show_thumbnail_frames.Checked;
Properties.Settings.Default.Save();
- if (Properties.Settings.Default.show_thumb_frames)
- {
- _ignoringSizeSync.Stop();
- _ignoringSizeSync.Reset();
- _ignoringSizeSync.Start();
- }
-
- foreach (var thumbnail in _previews)
- {
- thumbnail.Value.SetWindowFrames(Properties.Settings.Default.show_thumb_frames);
- }
-
+ this._manager.set_frames();
}
-
private void list_running_clients_SelectedIndexChanged(object sender, EventArgs e) { }
@@ -685,24 +281,25 @@ namespace EveOPreview
private void option_zoom_on_hover_CheckedChanged(object sender, EventArgs e)
{
+ if (!_isInitialized) return;
+
Properties.Settings.Default.zoom_on_hover = option_zoom_on_hover.Checked;
Properties.Settings.Default.Save();
- refresh_thumbnails();
+ this._manager.refresh_thumbnails();
option_zoom_factor.Enabled = Properties.Settings.Default.zoom_on_hover;
- if (_isInitialized)
- {
+
foreach (var kv in _zoomAnchorButtonMap)
{
kv.Value.Enabled = Properties.Settings.Default.zoom_on_hover;
}
- }
+
}
private void option_show_overlay_CheckedChanged(object sender, EventArgs e)
{
Properties.Settings.Default.show_overlay = option_show_overlay.Checked;
Properties.Settings.Default.Save();
- refresh_thumbnails();
+ this._manager.refresh_thumbnails();
}
@@ -746,14 +343,14 @@ namespace EveOPreview
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
- refresh_thumbnails();
+ this._manager.refresh_thumbnails();
}
private void checkedListBox1_SelectedIndexChanged2(object sender, EventArgs e)
{
System.Windows.Forms.ItemCheckEventArgs arg = (System.Windows.Forms.ItemCheckEventArgs)e;
((ThumbnailWindow)this.previews_check_listbox.Items[arg.Index]).IsPreviewEnabled = (arg.NewValue != System.Windows.Forms.CheckState.Checked);
- refresh_thumbnails();
+ this._manager.refresh_thumbnails();
}
private void flowLayoutPanel1_Paint(object sender, PaintEventArgs e)
@@ -763,18 +360,26 @@ namespace EveOPreview
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
+ if (!_isInitialized)
+ {
+ return;
+ }
Properties.Settings.Default.track_client_windows = option_track_client_windows.Checked;
Properties.Settings.Default.Save();
- refresh_thumbnails();
+ this._manager.refresh_thumbnails();
}
private void opacity_bar_Scroll(object sender, ScrollEventArgs e)
{
+ if (!_isInitialized)
+ {
+ return;
+ }
// fire off opacity change
Properties.Settings.Default.opacity = Math.Min((float)e.NewValue / 100.0f, 1.0f);
Properties.Settings.Default.Save();
- refresh_thumbnails();
+ this._manager.refresh_thumbnails();
}
diff --git a/Eve-O-Preview/Thumbnail/ThumbnailFactory.cs b/Eve-O-Preview/Thumbnail/ThumbnailFactory.cs
index a603043..f56fbf5 100644
--- a/Eve-O-Preview/Thumbnail/ThumbnailFactory.cs
+++ b/Eve-O-Preview/Thumbnail/ThumbnailFactory.cs
@@ -5,9 +5,9 @@ namespace EveOPreview
{
public class ThumbnailFactory
{
- public IThumbnail Create(MainForm parent, IntPtr sourceWindow, string title, Size size)
+ public IThumbnail Create(ThumbnailManager manager, IntPtr sourceWindow, string title, Size size)
{
- return new ThumbnailWindow(parent, sourceWindow, title, size);
+ return new ThumbnailWindow(manager, sourceWindow, title, size);
}
}
}
\ No newline at end of file
diff --git a/Eve-O-Preview/Thumbnail/ThumbnailManager.cs b/Eve-O-Preview/Thumbnail/ThumbnailManager.cs
new file mode 100644
index 0000000..3a52deb
--- /dev/null
+++ b/Eve-O-Preview/Thumbnail/ThumbnailManager.cs
@@ -0,0 +1,507 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Windows.Threading;
+using System.Xml.Linq;
+
+namespace EveOPreview
+{
+ public class ThumbnailManager
+ {
+ private readonly Stopwatch _ignoringSizeSync;
+ private DispatcherTimer _dispatcherTimer;
+ private readonly ThumbnailFactory _thumbnailFactory;
+ private readonly Dictionary _previews;
+
+ private IntPtr _activeClientHandle;
+ private string _activeClientTitle;
+
+ private readonly Dictionary> _uniqueLayouts;
+ private readonly Dictionary _flatLayout;
+ private readonly Dictionary _flatLayoutShortcuts;
+ private readonly Dictionary _clientLayout;
+
+ private readonly Dictionary _xmlBadToOkChars;
+
+ private readonly Action> _addThumbnail;
+ private readonly Action> _removeThumbnail;
+ private readonly Action _setAeroStatus;
+ private readonly Action _sizeChange;
+
+ public ThumbnailManager(Action> addThumbnail, Action> removeThumbnail, Action setAeroStatus, Action sizeChange)
+ {
+ _addThumbnail = addThumbnail;
+ _removeThumbnail = removeThumbnail;
+ _setAeroStatus = setAeroStatus;
+ _sizeChange = sizeChange;
+
+ _ignoringSizeSync = new Stopwatch();
+ _ignoringSizeSync.Start();
+
+ this._activeClientHandle = (IntPtr)0;
+ this._activeClientTitle = "";
+
+ _xmlBadToOkChars = new Dictionary();
+ _xmlBadToOkChars["<"] = "---lt---";
+ _xmlBadToOkChars["&"] = "---amp---";
+ _xmlBadToOkChars[">"] = "---gt---";
+ _xmlBadToOkChars["\""] = "---quot---";
+ _xmlBadToOkChars["\'"] = "---apos---";
+ _xmlBadToOkChars[","] = "---comma---";
+ _xmlBadToOkChars["."] = "---dot---";
+
+ _uniqueLayouts = new Dictionary>();
+ _flatLayout = new Dictionary();
+ _flatLayoutShortcuts = new Dictionary();
+ _clientLayout = new Dictionary();
+
+ this._previews = new Dictionary();
+
+ // DispatcherTimer setup
+ _dispatcherTimer = new DispatcherTimer();
+ _dispatcherTimer.Tick += dispatcherTimer_Tick;
+ _dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
+
+ this._thumbnailFactory = new ThumbnailFactory();
+ }
+
+ public void Activate()
+ {
+ this.load_layout();
+ this._dispatcherTimer.Start();
+ }
+
+ public void Deactivate()
+ {
+ this._dispatcherTimer.Stop();
+ }
+
+ private void spawn_and_kill_previews()
+ {
+ // TODO Extract this!
+ Process[] processes = Process.GetProcessesByName("ExeFile");
+ List processHandles = new List();
+ List addedList=new List();
+ List removedList = new List();
+ // pop new previews
+
+ foreach (Process process in processes)
+ {
+ processHandles.Add(process.MainWindowHandle);
+
+ Size sync_size = new Size();
+ sync_size.Width = (int)Properties.Settings.Default.sync_resize_x;
+ sync_size.Height = (int)Properties.Settings.Default.sync_resize_y;
+
+ if (!_previews.ContainsKey(process.MainWindowHandle) && process.MainWindowTitle != "")
+ {
+ _previews[process.MainWindowHandle] = this._thumbnailFactory.Create(this, process.MainWindowHandle, "...", sync_size);
+
+ // apply more thumbnail specific options
+ _previews[process.MainWindowHandle].SetTopMost(Properties.Settings.Default.always_on_top);
+ _previews[process.MainWindowHandle].SetWindowFrames(Properties.Settings.Default.show_thumb_frames);
+
+ // add a preview also
+ addedList.Add(_previews[process.MainWindowHandle].GetLabel());
+
+ refresh_client_window_locations(process);
+ }
+
+ else if (_previews.ContainsKey(process.MainWindowHandle) && process.MainWindowTitle != _previews[process.MainWindowHandle].GetLabel()) //or update the preview titles
+ {
+ _previews[process.MainWindowHandle].SetLabel(process.MainWindowTitle);
+ string key = _previews[process.MainWindowHandle].GetLabel();
+ string value;
+ if (_flatLayoutShortcuts.TryGetValue(key, out value))
+ {
+ _previews[process.MainWindowHandle].RegisterShortcut(value);
+ }
+ refresh_client_window_locations(process);
+ }
+
+ if (process.MainWindowHandle == DwmApiNativeMethods.GetForegroundWindow())
+ {
+ _activeClientHandle = process.MainWindowHandle;
+ _activeClientTitle = process.MainWindowTitle;
+ }
+
+ }
+
+ // TODO Check for empty list
+ _addThumbnail(addedList);
+
+ // clean up old previews
+ List to_be_pruned = new List();
+ foreach (IntPtr processHandle in _previews.Keys)
+ {
+ if (!(processHandles.Contains(processHandle)))
+ {
+ to_be_pruned.Add(processHandle);
+ }
+ }
+
+ foreach (IntPtr processHandle in to_be_pruned)
+ {
+ removedList.Add(_previews[processHandle].GetLabel());
+
+ _previews[processHandle].CloseThumbnail();
+ _previews.Remove(processHandle);
+ }
+
+ _removeThumbnail(removedList);
+ }
+
+ private void refresh_client_window_locations(Process process)
+ {
+ if (Properties.Settings.Default.track_client_windows && _clientLayout.ContainsKey(process.MainWindowTitle))
+ {
+ DwmApiNativeMethods.MoveWindow(process.MainWindowHandle, _clientLayout[process.MainWindowTitle].X,
+ _clientLayout[process.MainWindowTitle].Y, _clientLayout[process.MainWindowTitle].Width,
+ _clientLayout[process.MainWindowTitle].Height, true);
+ }
+ }
+
+ private void dispatcherTimer_Tick(object sender, EventArgs e)
+ {
+ spawn_and_kill_previews();
+ refresh_thumbnails();
+ if (_ignoringSizeSync.ElapsedMilliseconds > 500) { _ignoringSizeSync.Stop(); };
+
+ // TODO Do this once in 10 seconds
+ _setAeroStatus(DwmApiNativeMethods.DwmIsCompositionEnabled());
+ }
+
+ public void NotifyPreviewSwitch()
+ {
+ update_client_locations();
+ store_layout(); //todo: check if it actually changed ...
+ foreach (KeyValuePair entry in _previews)
+ {
+ entry.Value.SetTopMost(Properties.Settings.Default.always_on_top);
+ }
+ }
+
+
+ public void SyncPreviewSize(Size sync_size)
+ {
+ if (Properties.Settings.Default.sync_resize &&
+ Properties.Settings.Default.show_thumb_frames &&
+ _ignoringSizeSync.ElapsedMilliseconds > 500)
+ {
+ _ignoringSizeSync.Stop();
+
+ _sizeChange(sync_size.Width, sync_size.Height);
+
+ foreach (KeyValuePair entry in _previews)
+ {
+ if (entry.Value.IsPreviewHandle(DwmApiNativeMethods.GetForegroundWindow()))
+ {
+ entry.Value.SetSize(sync_size);
+ }
+ }
+
+ }
+
+ }
+
+
+ public void UpdatePreviewPosition(string preview_title, Point position)
+ {
+
+ if (Properties.Settings.Default.unique_layout)
+ {
+ Dictionary layout;
+ if (_uniqueLayouts.TryGetValue(_activeClientTitle, out layout))
+ {
+ layout[preview_title] = position;
+ }
+ else if (_activeClientTitle == "")
+ {
+ _uniqueLayouts[_activeClientTitle] = new Dictionary();
+ _uniqueLayouts[_activeClientTitle][preview_title] = position;
+ }
+ }
+ else
+ {
+ _flatLayout[preview_title] = position;
+ }
+
+ }
+
+ private string remove_nonconform_xml_characters(string entry)
+ {
+ foreach (var kv in _xmlBadToOkChars)
+ {
+ entry = entry.Replace(kv.Key, kv.Value);
+ }
+ return entry;
+ }
+
+ private string restore_nonconform_xml_characters(string entry)
+ {
+ foreach (var kv in _xmlBadToOkChars)
+ {
+ entry = entry.Replace(kv.Value, kv.Key);
+ }
+ return entry;
+ }
+
+ private XElement MakeXElement(string input)
+ {
+ string clean = remove_nonconform_xml_characters(input).Replace(" ", "_");
+ return new XElement(clean);
+ }
+
+ private string ParseXElement(XElement input)
+ {
+ return restore_nonconform_xml_characters(input.Name.ToString()).Replace("_", " ");
+ }
+
+ private void load_layout()
+ {
+ if (File.Exists("layout.xml"))
+ {
+ XElement rootElement = XElement.Load("layout.xml");
+ foreach (var el in rootElement.Elements())
+ {
+ Dictionary inner = new Dictionary();
+ foreach (var inner_el in el.Elements())
+ {
+ inner[ParseXElement(inner_el)] = new Point(Convert.ToInt32(inner_el.Element("x")?.Value), Convert.ToInt32(inner_el.Element("y")?.Value));
+ }
+ _uniqueLayouts[ParseXElement(el)] = inner;
+ }
+ }
+
+ if (File.Exists("flat_layout.xml"))
+ {
+ XElement rootElement = XElement.Load("flat_layout.xml");
+ foreach (var el in rootElement.Elements())
+ {
+ _flatLayout[ParseXElement(el)] = new Point(Convert.ToInt32(el.Element("x").Value), Convert.ToInt32(el.Element("y").Value));
+ _flatLayoutShortcuts[ParseXElement(el)] = "";
+
+ if (el.Element("shortcut") != null)
+ {
+ _flatLayoutShortcuts[ParseXElement(el)] = el.Element("shortcut").Value;
+ }
+ }
+ }
+
+ if (File.Exists("client_layout.xml"))
+ {
+ XElement rootElement = XElement.Load("client_layout.xml");
+ foreach (var el in rootElement.Elements())
+ {
+ ClientLocation clientLocation = new ClientLocation();
+ clientLocation.X = Convert.ToInt32(el.Element("x").Value);
+ clientLocation.Y = Convert.ToInt32(el.Element("y").Value);
+ clientLocation.Width = Convert.ToInt32(el.Element("width").Value);
+ clientLocation.Height = Convert.ToInt32(el.Element("height").Value);
+
+ _clientLayout[ParseXElement(el)] = clientLocation;
+ }
+ }
+ }
+
+ private void store_layout()
+ {
+ XElement el = new XElement("layouts");
+ foreach (var client in _uniqueLayouts.Keys)
+ {
+ if (client == "")
+ {
+ continue;
+ }
+ XElement layout = MakeXElement(client);
+ foreach (var thumbnail_ in _uniqueLayouts[client])
+ {
+ string thumbnail = thumbnail_.Key;
+ if (thumbnail == "" || thumbnail == "...")
+ {
+ continue;
+ }
+ XElement position = MakeXElement(thumbnail);
+ position.Add(new XElement("x", thumbnail_.Value.X));
+ position.Add(new XElement("y", thumbnail_.Value.Y));
+ layout.Add(position);
+ }
+ el.Add(layout);
+ }
+
+ el.Save("layout.xml");
+
+ XElement el2 = new XElement("flat_layout");
+ foreach (var clientKV in _flatLayout)
+ {
+ if (clientKV.Key == "" || clientKV.Key == "...")
+ {
+ continue;
+ }
+ XElement layout = MakeXElement(clientKV.Key);
+ layout.Add(new XElement("x", clientKV.Value.X));
+ layout.Add(new XElement("y", clientKV.Value.Y));
+
+ string shortcut;
+ if (_flatLayoutShortcuts.TryGetValue(clientKV.Key, out shortcut))
+ {
+ layout.Add(new XElement("shortcut", shortcut));
+ }
+ el2.Add(layout);
+ }
+
+ el2.Save("flat_layout.xml");
+
+ XElement el3 = new XElement("client_layout");
+ foreach (var clientKV in _clientLayout)
+ {
+ if (clientKV.Key == "" || clientKV.Key == "...")
+ {
+ continue;
+ }
+ XElement layout = MakeXElement(clientKV.Key);
+ layout.Add(new XElement("x", clientKV.Value.X));
+ layout.Add(new XElement("y", clientKV.Value.Y));
+ layout.Add(new XElement("width", clientKV.Value.Width));
+ layout.Add(new XElement("height", clientKV.Value.Height));
+ el3.Add(layout);
+ }
+
+ el3.Save("client_layout.xml");
+ }
+
+ private void handle_unique_layout(IThumbnail thumbnailWindow, string last_known_active_window)
+ {
+ Dictionary layout;
+ if (_uniqueLayouts.TryGetValue(last_known_active_window, out layout))
+ {
+ Point new_loc;
+ if (Properties.Settings.Default.unique_layout && layout.TryGetValue(thumbnailWindow.GetLabel(), out new_loc))
+ {
+ thumbnailWindow.SetLocation(new_loc);
+ }
+ else
+ {
+ // create inner dict
+ layout[thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
+ }
+ }
+ else if (last_known_active_window != "")
+ {
+ // create outer dict
+ _uniqueLayouts[last_known_active_window] = new Dictionary();
+ _uniqueLayouts[last_known_active_window][thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
+ }
+ }
+
+ private void update_client_locations()
+ {
+ Process[] processes = Process.GetProcessesByName("ExeFile");
+ List processHandles = new List();
+
+ foreach (Process process in processes)
+ {
+ RECT rect = new RECT();
+ DwmApiNativeMethods.GetWindowRect(process.MainWindowHandle, out rect);
+
+ int left = Math.Abs(rect.Left);
+ int right = Math.Abs(rect.Right);
+ int client_width = Math.Abs(left - right);
+
+ int top = Math.Abs(rect.Top);
+ int bottom = Math.Abs(rect.Bottom);
+ int client_height = Math.Abs(top - bottom);
+
+ ClientLocation clientLocation = new ClientLocation();
+ clientLocation.X = rect.Left;
+ clientLocation.Y = rect.Top;
+ clientLocation.Width = client_width;
+ clientLocation.Height = client_height;
+
+
+ _clientLayout[process.MainWindowTitle] = clientLocation;
+ }
+ }
+
+ private void handle_flat_layout(IThumbnail thumbnailWindow)
+ {
+ Point layout;
+ if (_flatLayout.TryGetValue(thumbnailWindow.GetLabel(), out layout))
+ {
+ thumbnailWindow.SetLocation(layout);
+ }
+ else if (thumbnailWindow.GetLabel() != "")
+ {
+ _flatLayout[thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
+ }
+ }
+
+ private bool window_is_preview_or_client(IntPtr window)
+ {
+ bool active_window_is_right_type = false;
+ foreach (KeyValuePair entry in _previews)
+ {
+ if (entry.Key == window || entry.Value.IsPreviewHandle(window))
+ {
+ active_window_is_right_type = true;
+ }
+ }
+ return active_window_is_right_type;
+ }
+
+ public void refresh_thumbnails()
+ {
+
+ IntPtr active_window = DwmApiNativeMethods.GetForegroundWindow();
+
+ // hide, show, resize and move
+ foreach (KeyValuePair entry in _previews)
+ {
+ if (!window_is_preview_or_client(active_window) && Properties.Settings.Default.hide_all)
+ {
+ entry.Value.HideThumbnail();
+ }
+ else if (entry.Key == _activeClientHandle && Properties.Settings.Default.hide_active)
+ {
+ entry.Value.HideThumbnail();
+ }
+ else
+ {
+ entry.Value.ShowThumbnail();
+ if (Properties.Settings.Default.unique_layout)
+ {
+ handle_unique_layout(entry.Value, _activeClientTitle);
+ }
+ else
+ {
+ handle_flat_layout(entry.Value);
+ }
+ }
+ entry.Value.IsZoomEnabled = Properties.Settings.Default.zoom_on_hover;
+ entry.Value.IsOverlayEnabled = Properties.Settings.Default.show_overlay;
+ entry.Value.SetOpacity(Properties.Settings.Default.opacity);
+ }
+
+ DwmApiNativeMethods.DwmIsCompositionEnabled();
+ }
+
+ public void set_frames()
+ {
+ if (Properties.Settings.Default.show_thumb_frames)
+ {
+ _ignoringSizeSync.Stop();
+ _ignoringSizeSync.Reset();
+ _ignoringSizeSync.Start();
+ }
+
+ foreach (var thumbnail in _previews)
+ {
+ thumbnail.Value.SetWindowFrames(Properties.Settings.Default.show_thumb_frames);
+ }
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Eve-O-Preview/Thumbnail/ThumbnailWindow.cs b/Eve-O-Preview/Thumbnail/ThumbnailWindow.cs
index 71c05c9..1f24b27 100644
--- a/Eve-O-Preview/Thumbnail/ThumbnailWindow.cs
+++ b/Eve-O-Preview/Thumbnail/ThumbnailWindow.cs
@@ -9,7 +9,7 @@ namespace EveOPreview
#region Private fields
private readonly bool _isInitializing;
private readonly IntPtr _sourceWindow;
- private readonly MainForm _parentForm;
+ private readonly ThumbnailManager _manager;
private readonly ThumbnailOverlay _overlay;
private Hotkey _hotkey; // This field stores the hotkey reference
@@ -26,7 +26,7 @@ namespace EveOPreview
#endregion
// This constructor should never be used directly
- public ThumbnailWindow(MainForm parent, IntPtr sourceWindow, string title, Size size)
+ public ThumbnailWindow(ThumbnailManager manager, IntPtr sourceWindow, string title, Size size)
{
this._isInitializing = true;
@@ -34,7 +34,7 @@ namespace EveOPreview
this.IsOverlayEnabled = true;
this._sourceWindow = sourceWindow;
- this._parentForm = parent;
+ this._manager = manager;
this._isThumbnailSetUp = false;
this._ignoreMouseOverEvent = false;
@@ -248,7 +248,7 @@ namespace EveOPreview
if (e.Button == MouseButtons.Left)
{
this.ActivateClient();
- this._parentForm.NotifyPreviewSwitch();
+ this._manager.NotifyPreviewSwitch();
}
if (e.Button == MouseButtons.Right)
@@ -265,7 +265,7 @@ namespace EveOPreview
private void Hotkey_Pressed(Object sender, EventArgs e)
{
this.ActivateClient();
- this._parentForm.NotifyPreviewSwitch();
+ this._manager.NotifyPreviewSwitch();
}
protected override void OnResize(EventArgs e)
@@ -276,7 +276,7 @@ namespace EveOPreview
if (!(this._isInitializing || this._ignoreMouseOverEvent))
{
- this._parentForm.SyncPreviewSize(this.Size);
+ this._manager.SyncPreviewSize(this.Size);
}
}
@@ -286,7 +286,7 @@ namespace EveOPreview
if (!(this._isInitializing || this._ignoreMouseOverEvent))
{
- this._parentForm.UpdatePreviewPosition(this.Text, this.Location);
+ this._manager.UpdatePreviewPosition(this.Text, this.Location);
}
this.RefreshPreview();