Extreact Thumbnail and Settings management code from main form
This commit is contained in:
7
Eve-O-Preview/Configuration/Configuration.cs
Normal file
7
Eve-O-Preview/Configuration/Configuration.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace EveOPreview
|
||||||
|
{
|
||||||
|
public class Configuration
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
7
Eve-O-Preview/Configuration/ConfigurationStorage.cs
Normal file
7
Eve-O-Preview/Configuration/ConfigurationStorage.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace EveOPreview.Managers
|
||||||
|
{
|
||||||
|
public class ConfigurationStorage
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -110,6 +110,7 @@
|
|||||||
<Compile Include="DwmAPI\RECT.cs" />
|
<Compile Include="DwmAPI\RECT.cs" />
|
||||||
<Compile Include="GUI\ClientLocation.cs" />
|
<Compile Include="GUI\ClientLocation.cs" />
|
||||||
<Compile Include="GUI\ZoomAnchor.cs" />
|
<Compile Include="GUI\ZoomAnchor.cs" />
|
||||||
|
<Compile Include="Configuration\Configuration.cs" />
|
||||||
<Compile Include="Hotkeys\Hotkey.cs" />
|
<Compile Include="Hotkeys\Hotkey.cs" />
|
||||||
<Compile Include="Hotkeys\HotkeyNativeMethods.cs" />
|
<Compile Include="Hotkeys\HotkeyNativeMethods.cs" />
|
||||||
<Compile Include="GUI\MainForm.cs">
|
<Compile Include="GUI\MainForm.cs">
|
||||||
@@ -118,8 +119,10 @@
|
|||||||
<Compile Include="GUI\MainForm.Designer.cs">
|
<Compile Include="GUI\MainForm.Designer.cs">
|
||||||
<DependentUpon>MainForm.cs</DependentUpon>
|
<DependentUpon>MainForm.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Configuration\ConfigurationStorage.cs" />
|
||||||
<Compile Include="Thumbnail\IThumbnail.cs" />
|
<Compile Include="Thumbnail\IThumbnail.cs" />
|
||||||
<Compile Include="Thumbnail\ThumbnailFactory.cs" />
|
<Compile Include="Thumbnail\ThumbnailFactory.cs" />
|
||||||
|
<Compile Include="Thumbnail\ThumbnailManager.cs" />
|
||||||
<Compile Include="Thumbnail\ThumbnailOverlay.cs">
|
<Compile Include="Thumbnail\ThumbnailOverlay.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@@ -12,29 +12,13 @@ namespace EveOPreview
|
|||||||
{
|
{
|
||||||
public partial class MainForm : Form
|
public partial class MainForm : Form
|
||||||
{
|
{
|
||||||
private readonly ThumbnailFactory _thumbnailFactory;
|
|
||||||
|
|
||||||
public event EventHandler Minimized;
|
public event EventHandler Minimized;
|
||||||
public event EventHandler Maximized;
|
public event EventHandler Maximized;
|
||||||
public event EventHandler Restored;
|
public event EventHandler Restored;
|
||||||
|
|
||||||
|
|
||||||
private readonly Dictionary<IntPtr, IThumbnail> _previews;
|
|
||||||
private DispatcherTimer _dispatcherTimer;
|
|
||||||
|
|
||||||
private IntPtr _activeClientHandle;
|
|
||||||
private string _activeClientTitle;
|
|
||||||
|
|
||||||
private readonly Dictionary<string, Dictionary<string, Point>> _uniqueLayouts;
|
|
||||||
private readonly Dictionary<string, Point> _flatLayout;
|
|
||||||
private readonly Dictionary<string, string> _flatLayoutShortcuts;
|
|
||||||
private readonly Dictionary<string, ClientLocation> _clientLayout;
|
|
||||||
|
|
||||||
private readonly bool _isInitialized;
|
private readonly bool _isInitialized;
|
||||||
|
private readonly ThumbnailManager _manager;
|
||||||
|
|
||||||
private readonly Stopwatch _ignoringSizeSync;
|
|
||||||
|
|
||||||
private readonly Dictionary<string, string> _xmlBadToOkChars;
|
|
||||||
|
|
||||||
private Dictionary<ZoomAnchor, RadioButton> _zoomAnchorButtonMap;
|
private Dictionary<ZoomAnchor, RadioButton> _zoomAnchorButtonMap;
|
||||||
|
|
||||||
@@ -42,49 +26,63 @@ namespace EveOPreview
|
|||||||
{
|
{
|
||||||
_isInitialized = false;
|
_isInitialized = false;
|
||||||
|
|
||||||
this._activeClientHandle = (IntPtr)0;
|
|
||||||
this._activeClientTitle = "";
|
|
||||||
|
|
||||||
this._previews = new Dictionary<IntPtr, IThumbnail>();
|
|
||||||
|
|
||||||
_xmlBadToOkChars = new Dictionary<string, string>();
|
|
||||||
_xmlBadToOkChars["<"] = "---lt---";
|
|
||||||
_xmlBadToOkChars["&"] = "---amp---";
|
|
||||||
_xmlBadToOkChars[">"] = "---gt---";
|
|
||||||
_xmlBadToOkChars["\""] = "---quot---";
|
|
||||||
_xmlBadToOkChars["\'"] = "---apos---";
|
|
||||||
_xmlBadToOkChars[","] = "---comma---";
|
|
||||||
_xmlBadToOkChars["."] = "---dot---";
|
|
||||||
|
|
||||||
_uniqueLayouts = new Dictionary<string, Dictionary<string, Point>>();
|
|
||||||
_flatLayout = new Dictionary<string, Point>();
|
|
||||||
_flatLayoutShortcuts = new Dictionary<string, string>();
|
|
||||||
_clientLayout = new Dictionary<string, ClientLocation>();
|
|
||||||
|
|
||||||
_ignoringSizeSync = new Stopwatch();
|
|
||||||
_ignoringSizeSync.Start();
|
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
init_options();
|
init_options();
|
||||||
|
|
||||||
// DispatcherTimer setup
|
// TODO Fix this
|
||||||
_dispatcherTimer = new DispatcherTimer();
|
previews_check_listbox.DisplayMember = "Text";
|
||||||
_dispatcherTimer.Tick += dispatcherTimer_Tick;
|
|
||||||
_dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
|
|
||||||
_dispatcherTimer.Start();
|
|
||||||
|
|
||||||
this._thumbnailFactory = new ThumbnailFactory();
|
this._manager = new ThumbnailManager(add_thumbnail,remove_thumbnail, set_aero_status, set_size);
|
||||||
|
|
||||||
_isInitialized = true;
|
_isInitialized = true;
|
||||||
|
|
||||||
previews_check_listbox.DisplayMember = "Text";
|
this._manager.Activate();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void add_thumbnail(IList<string> 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<string> 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)
|
private void GlassForm_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
refresh_thumbnails();
|
this._manager.refresh_thumbnails();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init_options()
|
private void init_options()
|
||||||
@@ -131,470 +129,60 @@ namespace EveOPreview
|
|||||||
}
|
}
|
||||||
|
|
||||||
opacity_bar.Value = Math.Min(100, (int)(100.0 * Properties.Settings.Default.opacity));
|
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<IntPtr> processHandles = new List<IntPtr>();
|
|
||||||
|
|
||||||
// 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<IntPtr> to_be_pruned = new List<IntPtr>();
|
|
||||||
foreach (IntPtr processHandle in _previews.Keys)
|
|
||||||
{
|
|
||||||
if (!(processHandles.Contains(processHandle)))
|
|
||||||
{
|
|
||||||
to_be_pruned.Add(processHandle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (IntPtr processHandle in to_be_pruned)
|
|
||||||
{
|
|
||||||
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<string, Point> inner = new Dictionary<string, Point>();
|
|
||||||
foreach (var inner_el in el.Elements())
|
|
||||||
{
|
|
||||||
inner[ParseXElement(inner_el)] = new Point(Convert.ToInt32(inner_el.Element("x")?.Value), Convert.ToInt32(inner_el.Element("y")?.Value));
|
|
||||||
}
|
|
||||||
_uniqueLayouts[ParseXElement(el)] = inner;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (File.Exists("flat_layout.xml"))
|
|
||||||
{
|
|
||||||
XElement rootElement = XElement.Load("flat_layout.xml");
|
|
||||||
foreach (var el in rootElement.Elements())
|
|
||||||
{
|
|
||||||
_flatLayout[ParseXElement(el)] = new Point(Convert.ToInt32(el.Element("x").Value), Convert.ToInt32(el.Element("y").Value));
|
|
||||||
_flatLayoutShortcuts[ParseXElement(el)] = "";
|
|
||||||
|
|
||||||
if (el.Element("shortcut") != null)
|
|
||||||
{
|
|
||||||
_flatLayoutShortcuts[ParseXElement(el)] = el.Element("shortcut").Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (File.Exists("client_layout.xml"))
|
|
||||||
{
|
|
||||||
XElement rootElement = XElement.Load("client_layout.xml");
|
|
||||||
foreach (var el in rootElement.Elements())
|
|
||||||
{
|
|
||||||
ClientLocation clientLocation = new ClientLocation();
|
|
||||||
clientLocation.X = Convert.ToInt32(el.Element("x").Value);
|
|
||||||
clientLocation.Y = Convert.ToInt32(el.Element("y").Value);
|
|
||||||
clientLocation.Width = Convert.ToInt32(el.Element("width").Value);
|
|
||||||
clientLocation.Height = Convert.ToInt32(el.Element("height").Value);
|
|
||||||
|
|
||||||
_clientLayout[ParseXElement(el)] = clientLocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void store_layout()
|
|
||||||
{
|
|
||||||
XElement el = new XElement("layouts");
|
|
||||||
foreach (var client in _uniqueLayouts.Keys)
|
|
||||||
{
|
|
||||||
if (client == "")
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
XElement layout = MakeXElement(client);
|
|
||||||
foreach (var thumbnail_ in _uniqueLayouts[client])
|
|
||||||
{
|
|
||||||
string thumbnail = thumbnail_.Key;
|
|
||||||
if (thumbnail == "" || thumbnail == "...")
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
XElement position = MakeXElement(thumbnail);
|
|
||||||
position.Add(new XElement("x", thumbnail_.Value.X));
|
|
||||||
position.Add(new XElement("y", thumbnail_.Value.Y));
|
|
||||||
layout.Add(position);
|
|
||||||
}
|
|
||||||
el.Add(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
el.Save("layout.xml");
|
|
||||||
|
|
||||||
XElement el2 = new XElement("flat_layout");
|
|
||||||
foreach (var clientKV in _flatLayout)
|
|
||||||
{
|
|
||||||
if (clientKV.Key == "" || clientKV.Key == "...")
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
XElement layout = MakeXElement(clientKV.Key);
|
|
||||||
layout.Add(new XElement("x", clientKV.Value.X));
|
|
||||||
layout.Add(new XElement("y", clientKV.Value.Y));
|
|
||||||
|
|
||||||
string shortcut;
|
|
||||||
if (_flatLayoutShortcuts.TryGetValue(clientKV.Key, out shortcut))
|
|
||||||
{
|
|
||||||
layout.Add(new XElement("shortcut", shortcut));
|
|
||||||
}
|
|
||||||
el2.Add(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
el2.Save("flat_layout.xml");
|
|
||||||
|
|
||||||
XElement el3 = new XElement("client_layout");
|
|
||||||
foreach (var clientKV in _clientLayout)
|
|
||||||
{
|
|
||||||
if (clientKV.Key == "" || clientKV.Key == "...")
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
XElement layout = MakeXElement(clientKV.Key);
|
|
||||||
layout.Add(new XElement("x", clientKV.Value.X));
|
|
||||||
layout.Add(new XElement("y", clientKV.Value.Y));
|
|
||||||
layout.Add(new XElement("width", clientKV.Value.Width));
|
|
||||||
layout.Add(new XElement("height", clientKV.Value.Height));
|
|
||||||
el3.Add(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
el3.Save("client_layout.xml");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handle_unique_layout(IThumbnail thumbnailWindow, string last_known_active_window)
|
|
||||||
{
|
|
||||||
Dictionary<string, Point> layout;
|
|
||||||
if (_uniqueLayouts.TryGetValue(last_known_active_window, out layout))
|
|
||||||
{
|
|
||||||
Point new_loc;
|
|
||||||
if (Properties.Settings.Default.unique_layout && layout.TryGetValue(thumbnailWindow.GetLabel(), out new_loc))
|
|
||||||
{
|
|
||||||
thumbnailWindow.SetLocation(new_loc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// create inner dict
|
|
||||||
layout[thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (last_known_active_window != "")
|
|
||||||
{
|
|
||||||
// create outer dict
|
|
||||||
_uniqueLayouts[last_known_active_window] = new Dictionary<string, Point>();
|
|
||||||
_uniqueLayouts[last_known_active_window][thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void update_client_locations()
|
|
||||||
{
|
|
||||||
Process[] processes = Process.GetProcessesByName("ExeFile");
|
|
||||||
List<IntPtr> processHandles = new List<IntPtr>();
|
|
||||||
|
|
||||||
foreach (Process process in processes)
|
|
||||||
{
|
|
||||||
RECT rect = new RECT();
|
|
||||||
DwmApiNativeMethods.GetWindowRect(process.MainWindowHandle, out rect);
|
|
||||||
|
|
||||||
int left = Math.Abs(rect.Left);
|
|
||||||
int right = Math.Abs(rect.Right);
|
|
||||||
int client_width = Math.Abs(left - right);
|
|
||||||
|
|
||||||
int top = Math.Abs(rect.Top);
|
|
||||||
int bottom = Math.Abs(rect.Bottom);
|
|
||||||
int client_height = Math.Abs(top - bottom);
|
|
||||||
|
|
||||||
ClientLocation clientLocation = new ClientLocation();
|
|
||||||
clientLocation.X = rect.Left;
|
|
||||||
clientLocation.Y = rect.Top;
|
|
||||||
clientLocation.Width = client_width;
|
|
||||||
clientLocation.Height = client_height;
|
|
||||||
|
|
||||||
|
|
||||||
_clientLayout[process.MainWindowTitle] = clientLocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void NotifyPreviewSwitch()
|
|
||||||
{
|
|
||||||
update_client_locations();
|
|
||||||
store_layout(); //todo: check if it actually changed ...
|
|
||||||
foreach (KeyValuePair<IntPtr, IThumbnail> entry in _previews)
|
|
||||||
{
|
|
||||||
entry.Value.SetTopMost(Properties.Settings.Default.always_on_top);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void handle_flat_layout(IThumbnail thumbnailWindow)
|
|
||||||
{
|
|
||||||
Point layout;
|
|
||||||
if (_flatLayout.TryGetValue(thumbnailWindow.GetLabel(), out layout))
|
|
||||||
{
|
|
||||||
thumbnailWindow.SetLocation(layout);
|
|
||||||
}
|
|
||||||
else if (thumbnailWindow.GetLabel() != "")
|
|
||||||
{
|
|
||||||
_flatLayout[thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool window_is_preview_or_client(IntPtr window)
|
|
||||||
{
|
|
||||||
bool active_window_is_right_type = false;
|
|
||||||
foreach (KeyValuePair<IntPtr, IThumbnail> entry in _previews)
|
|
||||||
{
|
|
||||||
if (entry.Key == window || entry.Value.IsPreviewHandle(window))
|
|
||||||
{
|
|
||||||
active_window_is_right_type = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return active_window_is_right_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void refresh_thumbnails()
|
|
||||||
{
|
|
||||||
|
|
||||||
IntPtr active_window = DwmApiNativeMethods.GetForegroundWindow();
|
|
||||||
|
|
||||||
// hide, show, resize and move
|
|
||||||
foreach (KeyValuePair<IntPtr, IThumbnail> entry in _previews)
|
|
||||||
{
|
|
||||||
if (!window_is_preview_or_client(active_window) && Properties.Settings.Default.hide_all)
|
|
||||||
{
|
|
||||||
entry.Value.HideThumbnail();
|
|
||||||
}
|
|
||||||
else if (entry.Key == _activeClientHandle && Properties.Settings.Default.hide_active)
|
|
||||||
{
|
|
||||||
entry.Value.HideThumbnail();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entry.Value.ShowThumbnail();
|
|
||||||
if (Properties.Settings.Default.unique_layout)
|
|
||||||
{
|
|
||||||
handle_unique_layout(entry.Value, _activeClientTitle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
handle_flat_layout(entry.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entry.Value.IsZoomEnabled = Properties.Settings.Default.zoom_on_hover;
|
|
||||||
entry.Value.IsOverlayEnabled = Properties.Settings.Default.show_overlay;
|
|
||||||
entry.Value.SetOpacity(Properties.Settings.Default.opacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
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<IntPtr, IThumbnail> 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<string, Point> layout;
|
|
||||||
if (_uniqueLayouts.TryGetValue(_activeClientTitle, out layout))
|
|
||||||
{
|
|
||||||
layout[preview_title] = position;
|
|
||||||
}
|
|
||||||
else if (_activeClientTitle == "")
|
|
||||||
{
|
|
||||||
_uniqueLayouts[_activeClientTitle] = new Dictionary<string, Point>();
|
|
||||||
_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)
|
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.hide_all = option_hide_all_if_not_right_type.Checked;
|
||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
refresh_thumbnails();
|
this._manager.refresh_thumbnails();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void option_unique_layout_CheckedChanged(object sender, EventArgs e)
|
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.unique_layout = option_unique_layout.Checked;
|
||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
refresh_thumbnails();
|
this._manager.refresh_thumbnails();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void option_hide_active_CheckedChanged(object sender, EventArgs e)
|
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.hide_active = option_hide_active.Checked;
|
||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
refresh_thumbnails();
|
this._manager.refresh_thumbnails();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void option_sync_size_CheckedChanged(object sender, EventArgs e)
|
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.sync_resize = option_sync_size.Checked;
|
||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
refresh_thumbnails();
|
this._manager.refresh_thumbnails();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -622,51 +210,59 @@ namespace EveOPreview
|
|||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
|
|
||||||
// resize
|
// 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));
|
(int)Properties.Settings.Default.sync_resize_y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void option_sync_size_x_TextChanged(object sender, EventArgs e)
|
private void option_sync_size_x_TextChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
if (!_isInitialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
parse_size_entry();
|
parse_size_entry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void option_sync_size_y_TextChanged(object sender, EventArgs e)
|
private void option_sync_size_y_TextChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
if (!_isInitialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
parse_size_entry();
|
parse_size_entry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void option_always_on_top_CheckedChanged(object sender, EventArgs e)
|
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.always_on_top = option_always_on_top.Checked;
|
||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
refresh_thumbnails();
|
this._manager.refresh_thumbnails();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void option_show_thumbnail_frames_CheckedChanged(object sender, EventArgs e)
|
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.show_thumb_frames = option_show_thumbnail_frames.Checked;
|
||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
|
|
||||||
if (Properties.Settings.Default.show_thumb_frames)
|
this._manager.set_frames();
|
||||||
{
|
|
||||||
_ignoringSizeSync.Stop();
|
|
||||||
_ignoringSizeSync.Reset();
|
|
||||||
_ignoringSizeSync.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var thumbnail in _previews)
|
|
||||||
{
|
|
||||||
thumbnail.Value.SetWindowFrames(Properties.Settings.Default.show_thumb_frames);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void list_running_clients_SelectedIndexChanged(object sender, EventArgs e) { }
|
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)
|
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.zoom_on_hover = option_zoom_on_hover.Checked;
|
||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
refresh_thumbnails();
|
this._manager.refresh_thumbnails();
|
||||||
option_zoom_factor.Enabled = Properties.Settings.Default.zoom_on_hover;
|
option_zoom_factor.Enabled = Properties.Settings.Default.zoom_on_hover;
|
||||||
if (_isInitialized)
|
|
||||||
{
|
|
||||||
foreach (var kv in _zoomAnchorButtonMap)
|
foreach (var kv in _zoomAnchorButtonMap)
|
||||||
{
|
{
|
||||||
kv.Value.Enabled = Properties.Settings.Default.zoom_on_hover;
|
kv.Value.Enabled = Properties.Settings.Default.zoom_on_hover;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void option_show_overlay_CheckedChanged(object sender, EventArgs e)
|
private void option_show_overlay_CheckedChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Properties.Settings.Default.show_overlay = option_show_overlay.Checked;
|
Properties.Settings.Default.show_overlay = option_show_overlay.Checked;
|
||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
refresh_thumbnails();
|
this._manager.refresh_thumbnails();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -746,14 +343,14 @@ namespace EveOPreview
|
|||||||
|
|
||||||
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
|
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
refresh_thumbnails();
|
this._manager.refresh_thumbnails();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkedListBox1_SelectedIndexChanged2(object sender, EventArgs e)
|
private void checkedListBox1_SelectedIndexChanged2(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
System.Windows.Forms.ItemCheckEventArgs arg = (System.Windows.Forms.ItemCheckEventArgs)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);
|
((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)
|
private void flowLayoutPanel1_Paint(object sender, PaintEventArgs e)
|
||||||
@@ -763,18 +360,26 @@ namespace EveOPreview
|
|||||||
|
|
||||||
private void checkBox1_CheckedChanged(object sender, EventArgs e)
|
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.track_client_windows = option_track_client_windows.Checked;
|
||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
refresh_thumbnails();
|
this._manager.refresh_thumbnails();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void opacity_bar_Scroll(object sender, ScrollEventArgs e)
|
private void opacity_bar_Scroll(object sender, ScrollEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (!_isInitialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
// fire off opacity change
|
// fire off opacity change
|
||||||
Properties.Settings.Default.opacity = Math.Min((float)e.NewValue / 100.0f, 1.0f);
|
Properties.Settings.Default.opacity = Math.Min((float)e.NewValue / 100.0f, 1.0f);
|
||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
refresh_thumbnails();
|
this._manager.refresh_thumbnails();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -5,9 +5,9 @@ namespace EveOPreview
|
|||||||
{
|
{
|
||||||
public class ThumbnailFactory
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
507
Eve-O-Preview/Thumbnail/ThumbnailManager.cs
Normal file
507
Eve-O-Preview/Thumbnail/ThumbnailManager.cs
Normal file
@@ -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<IntPtr, IThumbnail> _previews;
|
||||||
|
|
||||||
|
private IntPtr _activeClientHandle;
|
||||||
|
private string _activeClientTitle;
|
||||||
|
|
||||||
|
private readonly Dictionary<string, Dictionary<string, Point>> _uniqueLayouts;
|
||||||
|
private readonly Dictionary<string, Point> _flatLayout;
|
||||||
|
private readonly Dictionary<string, string> _flatLayoutShortcuts;
|
||||||
|
private readonly Dictionary<string, ClientLocation> _clientLayout;
|
||||||
|
|
||||||
|
private readonly Dictionary<string, string> _xmlBadToOkChars;
|
||||||
|
|
||||||
|
private readonly Action<IList<string>> _addThumbnail;
|
||||||
|
private readonly Action<IList<string>> _removeThumbnail;
|
||||||
|
private readonly Action<bool> _setAeroStatus;
|
||||||
|
private readonly Action<int,int> _sizeChange;
|
||||||
|
|
||||||
|
public ThumbnailManager(Action<IList<string>> addThumbnail, Action<IList<string>> removeThumbnail, Action<bool> setAeroStatus, Action<int,int> sizeChange)
|
||||||
|
{
|
||||||
|
_addThumbnail = addThumbnail;
|
||||||
|
_removeThumbnail = removeThumbnail;
|
||||||
|
_setAeroStatus = setAeroStatus;
|
||||||
|
_sizeChange = sizeChange;
|
||||||
|
|
||||||
|
_ignoringSizeSync = new Stopwatch();
|
||||||
|
_ignoringSizeSync.Start();
|
||||||
|
|
||||||
|
this._activeClientHandle = (IntPtr)0;
|
||||||
|
this._activeClientTitle = "";
|
||||||
|
|
||||||
|
_xmlBadToOkChars = new Dictionary<string, string>();
|
||||||
|
_xmlBadToOkChars["<"] = "---lt---";
|
||||||
|
_xmlBadToOkChars["&"] = "---amp---";
|
||||||
|
_xmlBadToOkChars[">"] = "---gt---";
|
||||||
|
_xmlBadToOkChars["\""] = "---quot---";
|
||||||
|
_xmlBadToOkChars["\'"] = "---apos---";
|
||||||
|
_xmlBadToOkChars[","] = "---comma---";
|
||||||
|
_xmlBadToOkChars["."] = "---dot---";
|
||||||
|
|
||||||
|
_uniqueLayouts = new Dictionary<string, Dictionary<string, Point>>();
|
||||||
|
_flatLayout = new Dictionary<string, Point>();
|
||||||
|
_flatLayoutShortcuts = new Dictionary<string, string>();
|
||||||
|
_clientLayout = new Dictionary<string, ClientLocation>();
|
||||||
|
|
||||||
|
this._previews = new Dictionary<IntPtr, IThumbnail>();
|
||||||
|
|
||||||
|
// DispatcherTimer setup
|
||||||
|
_dispatcherTimer = new DispatcherTimer();
|
||||||
|
_dispatcherTimer.Tick += dispatcherTimer_Tick;
|
||||||
|
_dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
|
||||||
|
|
||||||
|
this._thumbnailFactory = new ThumbnailFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
public 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<IntPtr> processHandles = new List<IntPtr>();
|
||||||
|
List<string> addedList=new List<string>();
|
||||||
|
List<string> removedList = new List<string>();
|
||||||
|
// 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<IntPtr> to_be_pruned = new List<IntPtr>();
|
||||||
|
foreach (IntPtr processHandle in _previews.Keys)
|
||||||
|
{
|
||||||
|
if (!(processHandles.Contains(processHandle)))
|
||||||
|
{
|
||||||
|
to_be_pruned.Add(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (IntPtr processHandle in to_be_pruned)
|
||||||
|
{
|
||||||
|
removedList.Add(_previews[processHandle].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<IntPtr, IThumbnail> 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<IntPtr, IThumbnail> 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<string, Point> layout;
|
||||||
|
if (_uniqueLayouts.TryGetValue(_activeClientTitle, out layout))
|
||||||
|
{
|
||||||
|
layout[preview_title] = position;
|
||||||
|
}
|
||||||
|
else if (_activeClientTitle == "")
|
||||||
|
{
|
||||||
|
_uniqueLayouts[_activeClientTitle] = new Dictionary<string, Point>();
|
||||||
|
_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<string, Point> inner = new Dictionary<string, Point>();
|
||||||
|
foreach (var inner_el in el.Elements())
|
||||||
|
{
|
||||||
|
inner[ParseXElement(inner_el)] = new Point(Convert.ToInt32(inner_el.Element("x")?.Value), Convert.ToInt32(inner_el.Element("y")?.Value));
|
||||||
|
}
|
||||||
|
_uniqueLayouts[ParseXElement(el)] = inner;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists("flat_layout.xml"))
|
||||||
|
{
|
||||||
|
XElement rootElement = XElement.Load("flat_layout.xml");
|
||||||
|
foreach (var el in rootElement.Elements())
|
||||||
|
{
|
||||||
|
_flatLayout[ParseXElement(el)] = new Point(Convert.ToInt32(el.Element("x").Value), Convert.ToInt32(el.Element("y").Value));
|
||||||
|
_flatLayoutShortcuts[ParseXElement(el)] = "";
|
||||||
|
|
||||||
|
if (el.Element("shortcut") != null)
|
||||||
|
{
|
||||||
|
_flatLayoutShortcuts[ParseXElement(el)] = el.Element("shortcut").Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists("client_layout.xml"))
|
||||||
|
{
|
||||||
|
XElement rootElement = XElement.Load("client_layout.xml");
|
||||||
|
foreach (var el in rootElement.Elements())
|
||||||
|
{
|
||||||
|
ClientLocation clientLocation = new ClientLocation();
|
||||||
|
clientLocation.X = Convert.ToInt32(el.Element("x").Value);
|
||||||
|
clientLocation.Y = Convert.ToInt32(el.Element("y").Value);
|
||||||
|
clientLocation.Width = Convert.ToInt32(el.Element("width").Value);
|
||||||
|
clientLocation.Height = Convert.ToInt32(el.Element("height").Value);
|
||||||
|
|
||||||
|
_clientLayout[ParseXElement(el)] = clientLocation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void store_layout()
|
||||||
|
{
|
||||||
|
XElement el = new XElement("layouts");
|
||||||
|
foreach (var client in _uniqueLayouts.Keys)
|
||||||
|
{
|
||||||
|
if (client == "")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
XElement layout = MakeXElement(client);
|
||||||
|
foreach (var thumbnail_ in _uniqueLayouts[client])
|
||||||
|
{
|
||||||
|
string thumbnail = thumbnail_.Key;
|
||||||
|
if (thumbnail == "" || thumbnail == "...")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
XElement position = MakeXElement(thumbnail);
|
||||||
|
position.Add(new XElement("x", thumbnail_.Value.X));
|
||||||
|
position.Add(new XElement("y", thumbnail_.Value.Y));
|
||||||
|
layout.Add(position);
|
||||||
|
}
|
||||||
|
el.Add(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
el.Save("layout.xml");
|
||||||
|
|
||||||
|
XElement el2 = new XElement("flat_layout");
|
||||||
|
foreach (var clientKV in _flatLayout)
|
||||||
|
{
|
||||||
|
if (clientKV.Key == "" || clientKV.Key == "...")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
XElement layout = MakeXElement(clientKV.Key);
|
||||||
|
layout.Add(new XElement("x", clientKV.Value.X));
|
||||||
|
layout.Add(new XElement("y", clientKV.Value.Y));
|
||||||
|
|
||||||
|
string shortcut;
|
||||||
|
if (_flatLayoutShortcuts.TryGetValue(clientKV.Key, out shortcut))
|
||||||
|
{
|
||||||
|
layout.Add(new XElement("shortcut", shortcut));
|
||||||
|
}
|
||||||
|
el2.Add(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
el2.Save("flat_layout.xml");
|
||||||
|
|
||||||
|
XElement el3 = new XElement("client_layout");
|
||||||
|
foreach (var clientKV in _clientLayout)
|
||||||
|
{
|
||||||
|
if (clientKV.Key == "" || clientKV.Key == "...")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
XElement layout = MakeXElement(clientKV.Key);
|
||||||
|
layout.Add(new XElement("x", clientKV.Value.X));
|
||||||
|
layout.Add(new XElement("y", clientKV.Value.Y));
|
||||||
|
layout.Add(new XElement("width", clientKV.Value.Width));
|
||||||
|
layout.Add(new XElement("height", clientKV.Value.Height));
|
||||||
|
el3.Add(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
el3.Save("client_layout.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handle_unique_layout(IThumbnail thumbnailWindow, string last_known_active_window)
|
||||||
|
{
|
||||||
|
Dictionary<string, Point> layout;
|
||||||
|
if (_uniqueLayouts.TryGetValue(last_known_active_window, out layout))
|
||||||
|
{
|
||||||
|
Point new_loc;
|
||||||
|
if (Properties.Settings.Default.unique_layout && layout.TryGetValue(thumbnailWindow.GetLabel(), out new_loc))
|
||||||
|
{
|
||||||
|
thumbnailWindow.SetLocation(new_loc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// create inner dict
|
||||||
|
layout[thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (last_known_active_window != "")
|
||||||
|
{
|
||||||
|
// create outer dict
|
||||||
|
_uniqueLayouts[last_known_active_window] = new Dictionary<string, Point>();
|
||||||
|
_uniqueLayouts[last_known_active_window][thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void update_client_locations()
|
||||||
|
{
|
||||||
|
Process[] processes = Process.GetProcessesByName("ExeFile");
|
||||||
|
List<IntPtr> processHandles = new List<IntPtr>();
|
||||||
|
|
||||||
|
foreach (Process process in processes)
|
||||||
|
{
|
||||||
|
RECT rect = new RECT();
|
||||||
|
DwmApiNativeMethods.GetWindowRect(process.MainWindowHandle, out rect);
|
||||||
|
|
||||||
|
int left = Math.Abs(rect.Left);
|
||||||
|
int right = Math.Abs(rect.Right);
|
||||||
|
int client_width = Math.Abs(left - right);
|
||||||
|
|
||||||
|
int top = Math.Abs(rect.Top);
|
||||||
|
int bottom = Math.Abs(rect.Bottom);
|
||||||
|
int client_height = Math.Abs(top - bottom);
|
||||||
|
|
||||||
|
ClientLocation clientLocation = new ClientLocation();
|
||||||
|
clientLocation.X = rect.Left;
|
||||||
|
clientLocation.Y = rect.Top;
|
||||||
|
clientLocation.Width = client_width;
|
||||||
|
clientLocation.Height = client_height;
|
||||||
|
|
||||||
|
|
||||||
|
_clientLayout[process.MainWindowTitle] = clientLocation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handle_flat_layout(IThumbnail thumbnailWindow)
|
||||||
|
{
|
||||||
|
Point layout;
|
||||||
|
if (_flatLayout.TryGetValue(thumbnailWindow.GetLabel(), out layout))
|
||||||
|
{
|
||||||
|
thumbnailWindow.SetLocation(layout);
|
||||||
|
}
|
||||||
|
else if (thumbnailWindow.GetLabel() != "")
|
||||||
|
{
|
||||||
|
_flatLayout[thumbnailWindow.GetLabel()] = thumbnailWindow.GetLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool window_is_preview_or_client(IntPtr window)
|
||||||
|
{
|
||||||
|
bool active_window_is_right_type = false;
|
||||||
|
foreach (KeyValuePair<IntPtr, IThumbnail> entry in _previews)
|
||||||
|
{
|
||||||
|
if (entry.Key == window || entry.Value.IsPreviewHandle(window))
|
||||||
|
{
|
||||||
|
active_window_is_right_type = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return active_window_is_right_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh_thumbnails()
|
||||||
|
{
|
||||||
|
|
||||||
|
IntPtr active_window = DwmApiNativeMethods.GetForegroundWindow();
|
||||||
|
|
||||||
|
// hide, show, resize and move
|
||||||
|
foreach (KeyValuePair<IntPtr, IThumbnail> entry in _previews)
|
||||||
|
{
|
||||||
|
if (!window_is_preview_or_client(active_window) && Properties.Settings.Default.hide_all)
|
||||||
|
{
|
||||||
|
entry.Value.HideThumbnail();
|
||||||
|
}
|
||||||
|
else if (entry.Key == _activeClientHandle && Properties.Settings.Default.hide_active)
|
||||||
|
{
|
||||||
|
entry.Value.HideThumbnail();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry.Value.ShowThumbnail();
|
||||||
|
if (Properties.Settings.Default.unique_layout)
|
||||||
|
{
|
||||||
|
handle_unique_layout(entry.Value, _activeClientTitle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handle_flat_layout(entry.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entry.Value.IsZoomEnabled = Properties.Settings.Default.zoom_on_hover;
|
||||||
|
entry.Value.IsOverlayEnabled = Properties.Settings.Default.show_overlay;
|
||||||
|
entry.Value.SetOpacity(Properties.Settings.Default.opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -9,7 +9,7 @@ namespace EveOPreview
|
|||||||
#region Private fields
|
#region Private fields
|
||||||
private readonly bool _isInitializing;
|
private readonly bool _isInitializing;
|
||||||
private readonly IntPtr _sourceWindow;
|
private readonly IntPtr _sourceWindow;
|
||||||
private readonly MainForm _parentForm;
|
private readonly ThumbnailManager _manager;
|
||||||
private readonly ThumbnailOverlay _overlay;
|
private readonly ThumbnailOverlay _overlay;
|
||||||
private Hotkey _hotkey; // This field stores the hotkey reference
|
private Hotkey _hotkey; // This field stores the hotkey reference
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ namespace EveOPreview
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
// This constructor should never be used directly
|
// 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;
|
this._isInitializing = true;
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ namespace EveOPreview
|
|||||||
this.IsOverlayEnabled = true;
|
this.IsOverlayEnabled = true;
|
||||||
|
|
||||||
this._sourceWindow = sourceWindow;
|
this._sourceWindow = sourceWindow;
|
||||||
this._parentForm = parent;
|
this._manager = manager;
|
||||||
|
|
||||||
this._isThumbnailSetUp = false;
|
this._isThumbnailSetUp = false;
|
||||||
this._ignoreMouseOverEvent = false;
|
this._ignoreMouseOverEvent = false;
|
||||||
@@ -248,7 +248,7 @@ namespace EveOPreview
|
|||||||
if (e.Button == MouseButtons.Left)
|
if (e.Button == MouseButtons.Left)
|
||||||
{
|
{
|
||||||
this.ActivateClient();
|
this.ActivateClient();
|
||||||
this._parentForm.NotifyPreviewSwitch();
|
this._manager.NotifyPreviewSwitch();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.Button == MouseButtons.Right)
|
if (e.Button == MouseButtons.Right)
|
||||||
@@ -265,7 +265,7 @@ namespace EveOPreview
|
|||||||
private void Hotkey_Pressed(Object sender, EventArgs e)
|
private void Hotkey_Pressed(Object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
this.ActivateClient();
|
this.ActivateClient();
|
||||||
this._parentForm.NotifyPreviewSwitch();
|
this._manager.NotifyPreviewSwitch();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnResize(EventArgs e)
|
protected override void OnResize(EventArgs e)
|
||||||
@@ -276,7 +276,7 @@ namespace EveOPreview
|
|||||||
|
|
||||||
if (!(this._isInitializing || this._ignoreMouseOverEvent))
|
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))
|
if (!(this._isInitializing || this._ignoreMouseOverEvent))
|
||||||
{
|
{
|
||||||
this._parentForm.UpdatePreviewPosition(this.Text, this.Location);
|
this._manager.UpdatePreviewPosition(this.Text, this.Location);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.RefreshPreview();
|
this.RefreshPreview();
|
||||||
|
Reference in New Issue
Block a user