mirror of
https://github.com/LorenzCK/OnTopReplica.git
synced 2024-05-20 20:33:06 +12:00
Added ThumbnailRegion class to support relative regions.
Refactored XML serialization for stored regions. Refactored several thumbnail cloning (and region) methods. Removed PluginRegionLocator. Moved to System.Diagnostics.Trace for debug messaging.
This commit is contained in:
parent
726879dfdf
commit
6dfa6615d3
|
@ -111,6 +111,10 @@ namespace OnTopReplica {
|
|||
/// <param name="forceRefresh">True if the size of the form should be refreshed to match the new aspect ratio.</param>
|
||||
public void SetAspectRatio(Size aspectRatioSource, bool forceRefresh) {
|
||||
AspectRatio = ((double)aspectRatioSource.Width / (double)aspectRatioSource.Height);
|
||||
|
||||
#if DEBUG
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Setting aspect ratio of {0} (for {1}).", AspectRatio, aspectRatioSource));
|
||||
#endif
|
||||
|
||||
if (forceRefresh) {
|
||||
KeepAspectRatio = true;
|
||||
|
|
|
@ -50,6 +50,25 @@ namespace OnTopReplica {
|
|||
ctrl.MinimumSize = minimumClientSize.Expand(offset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to fit a size structure to another fixed destination size, by maintaining
|
||||
/// the original aspect ratio.
|
||||
/// </summary>
|
||||
public static Size Fit(this Size sourceSize, Size destinationSize) {
|
||||
double sourceRatio = (double)sourceSize.Width / (double)sourceSize.Height;
|
||||
double clientRatio = (double)destinationSize.Width / (double)destinationSize.Height;
|
||||
|
||||
Size ret;
|
||||
if (sourceRatio >= clientRatio) {
|
||||
ret = new Size(destinationSize.Width, (int)((double)destinationSize.Width / sourceRatio));
|
||||
}
|
||||
else {
|
||||
ret = new Size((int)((double)destinationSize.Height * sourceRatio), destinationSize.Height);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -229,11 +229,6 @@ namespace OnTopReplica {
|
|||
|
||||
//ESCAPE
|
||||
else if (e.KeyCode == Keys.Escape) {
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine("Received ESCAPE");
|
||||
#endif
|
||||
|
||||
//Disable click-through
|
||||
if (ClickThroughEnabled) {
|
||||
ClickThroughEnabled = false;
|
||||
|
@ -307,27 +302,22 @@ namespace OnTopReplica {
|
|||
/// Sets a new thumbnail.
|
||||
/// </summary>
|
||||
/// <param name="handle">Handle to the window to clone.</param>
|
||||
/// <param name="region">Region of the window to clone.</param>
|
||||
public void SetThumbnail(WindowHandle handle, Rectangle? region) {
|
||||
/// <param name="region">Region of the window to clone or null.</param>
|
||||
public void SetThumbnail(WindowHandle handle, ThumbnailRegion region) {
|
||||
try {
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Cloning window HWND {0} of class {1}.", handle.Handle, handle.Class));
|
||||
|
||||
CurrentThumbnailWindowHandle = handle;
|
||||
_thumbnailPanel.SetThumbnailHandle(handle);
|
||||
|
||||
#if DEBUG
|
||||
string windowClass = WindowMethods.GetWindowClass(handle.Handle);
|
||||
Console.WriteLine("Cloning window HWND {0} of class {1}.", handle.Handle, windowClass);
|
||||
#endif
|
||||
|
||||
if (region.HasValue)
|
||||
_thumbnailPanel.SelectedRegion = region.Value;
|
||||
else
|
||||
_thumbnailPanel.ConstrainToRegion = false;
|
||||
_thumbnailPanel.SetThumbnailHandle(handle, region);
|
||||
|
||||
//Set aspect ratio (this will resize the form), do not refresh if in fullscreen
|
||||
SetAspectRatio(_thumbnailPanel.ThumbnailOriginalSize, !IsFullscreen);
|
||||
SetAspectRatio(_thumbnailPanel.ThumbnailPixelSize, !IsFullscreen);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.Diagnostics.Trace.Fail("Unable to set thumbnail.", ex.ToString());
|
||||
|
||||
ThumbnailError(ex, false, Strings.ErrorUnableToCreateThumbnail);
|
||||
_thumbnailPanel.UnsetThumbnail();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,7 +355,7 @@ namespace OnTopReplica {
|
|||
/// <summary>
|
||||
/// Gets or sets the region displayed of the current thumbnail.
|
||||
/// </summary>
|
||||
public Rectangle? SelectedThumbnailRegion {
|
||||
public ThumbnailRegion SelectedThumbnailRegion {
|
||||
get {
|
||||
if (!_thumbnailPanel.IsShowingThumbnail || !_thumbnailPanel.ConstrainToRegion)
|
||||
return null;
|
||||
|
@ -376,14 +366,9 @@ namespace OnTopReplica {
|
|||
if (!_thumbnailPanel.IsShowingThumbnail)
|
||||
return;
|
||||
|
||||
if (value.HasValue) {
|
||||
_thumbnailPanel.SelectedRegion = value.Value;
|
||||
SetAspectRatio(value.Value.Size, true);
|
||||
}
|
||||
else {
|
||||
_thumbnailPanel.ConstrainToRegion = false;
|
||||
SetAspectRatio(_thumbnailPanel.ThumbnailOriginalSize, true);
|
||||
}
|
||||
_thumbnailPanel.SelectedRegion = value;
|
||||
|
||||
SetAspectRatio(_thumbnailPanel.ThumbnailPixelSize, true);
|
||||
|
||||
FixPositionAndSize();
|
||||
}
|
||||
|
@ -423,7 +408,7 @@ namespace OnTopReplica {
|
|||
/// <param name="p">Scale of the thumbnail to consider.</param>
|
||||
private void FitToThumbnail(double p) {
|
||||
try {
|
||||
Size originalSize = _thumbnailPanel.ThumbnailOriginalSize;
|
||||
Size originalSize = _thumbnailPanel.ThumbnailPixelSize;
|
||||
Size fittedSize = new Size((int)(originalSize.Width * p), (int)(originalSize.Height * p));
|
||||
ClientSize = fittedSize;
|
||||
}
|
||||
|
|
|
@ -15,9 +15,7 @@ namespace OnTopReplica {
|
|||
_processors[processor.GetType()] = processor;
|
||||
processor.Initialize(form);
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine("Registered message pump processor: {0}", processor.GetType());
|
||||
#endif
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Registered message pump processor: {0}", processor.GetType()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -32,18 +30,13 @@ namespace OnTopReplica {
|
|||
Console.Error.WriteLine("Failed to register shell hook window.");
|
||||
}
|
||||
else {
|
||||
#if DEBUG
|
||||
Console.WriteLine("Shell hook window registered successfully.");
|
||||
#endif
|
||||
System.Diagnostics.Trace.WriteLine("Shell hook window registered successfully.");
|
||||
}
|
||||
|
||||
//Register message pump processors
|
||||
Register(new WindowKeeper(), form);
|
||||
Register(new HotKeyManager(), form);
|
||||
Register(new GroupSwitchManager(), form);
|
||||
#if DEBUG
|
||||
//Register(new ShellInterceptProcessor(), form);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -75,9 +68,7 @@ namespace OnTopReplica {
|
|||
Console.Error.WriteLine("Failed to deregister shell hook window.");
|
||||
}
|
||||
else {
|
||||
#if DEBUG
|
||||
Console.WriteLine("Deregistered shell hook window successfully.");
|
||||
#endif
|
||||
System.Diagnostics.Trace.WriteLine("Deregistered shell hook window successfully.");
|
||||
}
|
||||
|
||||
foreach (var processor in _processors.Values) {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
@ -72,9 +71,7 @@ namespace OnTopReplica.MessagePumpProcessors {
|
|||
}
|
||||
|
||||
private void HandleForegroundWindowChange(IntPtr activeWindow) {
|
||||
#if DEBUG
|
||||
Console.Write("New active window (h {0}). ", activeWindow);
|
||||
#endif
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("New active window (h {0}). ", activeWindow));
|
||||
|
||||
//Seek window in tracked handles
|
||||
WindowHandleWrapper activated = null;
|
||||
|
@ -84,10 +81,8 @@ namespace OnTopReplica.MessagePumpProcessors {
|
|||
}
|
||||
|
||||
if (activated == null) {
|
||||
#if DEBUG
|
||||
//new foreground window is not tracked
|
||||
Console.WriteLine("Active window is not tracked.");
|
||||
#endif
|
||||
//New foreground window is not tracked
|
||||
System.Diagnostics.Trace.WriteLine("Active window is not tracked.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -98,9 +93,7 @@ namespace OnTopReplica.MessagePumpProcessors {
|
|||
//Get least recently used
|
||||
var next = _lruHandles[0];
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine("Tracked. Switching to {0} (last use: {1}).", next.WindowHandle.Title, next.LastTimeUsed);
|
||||
#endif
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Tracked. Switching to {0} (last use: {1}).", next.WindowHandle.Title, next.LastTimeUsed));
|
||||
|
||||
Form.SetThumbnail(next.WindowHandle, null);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace OnTopReplica.MessagePumpProcessors {
|
|||
if (msg.Msg == HookMethods.WM_SHELLHOOKMESSAGE) {
|
||||
int hookCode = msg.WParam.ToInt32();
|
||||
|
||||
Console.WriteLine("Hook msg #{0}: {1}", hookCode, msg.LParam);
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Hook msg #{0}: {1}", hookCode, msg.LParam));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -72,7 +72,8 @@
|
|||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DefineConstants>
|
||||
</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DocumentationFile>
|
||||
|
@ -91,11 +92,10 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="WindowsFormsAero">
|
||||
<HintPath>..\Lib\WindowsFormsAero.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -184,6 +184,7 @@
|
|||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Strings.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ThumbnailRegion.cs" />
|
||||
<Compile Include="WindowListMenuManager.cs" />
|
||||
<Compile Include="WindowSeekers\BaseWindowSeeker.cs" />
|
||||
<Compile Include="WindowSeekers\ByClassWindowSeeker.cs" />
|
||||
|
|
|
@ -9,8 +9,12 @@
|
|||
</trustInfo>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- Windows Vista -->
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
|
||||
<!-- Windows 8 -->
|
||||
<!--<supportedOS ID="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
|
||||
</application>
|
||||
</compatibility>
|
||||
<description>Lightweight clone of a window.</description>
|
||||
|
|
|
@ -12,10 +12,18 @@ namespace OnTopReplica {
|
|||
|
||||
static PluginRegionLocator() {
|
||||
_pluginClassNames = new HashSet<string>() {
|
||||
"aPluginWinClass", //Opera 11 Flash plugin
|
||||
"MacromediaFlashPlayerActiveX", //IE 9 Flash plugin
|
||||
"NativeWindowClass", //Google Chrome Flash plugin
|
||||
"GeckoPluginWindow", //Firefox 9 Flash plugin
|
||||
//Opera 11 Flash plugin
|
||||
"aPluginWinClass",
|
||||
|
||||
//IE 9 Flash plugin
|
||||
"MacromediaFlashPlayerActiveX",
|
||||
|
||||
//Google Chrome
|
||||
"NativeWindowClass", //Flash plugin
|
||||
"Chrome_RenderWidgetHostHWND", //Tab content
|
||||
|
||||
//Firefox 9 Flash plugin
|
||||
"GeckoPluginWindow",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -79,10 +87,7 @@ namespace OnTopReplica {
|
|||
|
||||
//Class name check
|
||||
string cl = WindowMethods.GetWindowClass(handle);
|
||||
|
||||
#if DEBUG
|
||||
Console.Out.WriteLine("Child window, class {0}", cl);
|
||||
#endif
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Child window, class {0}", cl));
|
||||
|
||||
if (_pluginClassNames.Contains(cl)) {
|
||||
//Found plugin window, stop now
|
||||
|
|
|
@ -76,9 +76,7 @@ namespace OnTopReplica {
|
|||
|
||||
var move = end.Difference(start);
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine("From {0} to {1} => {2}.", start, end, move);
|
||||
#endif
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("From {0} to {1} => {2}.", start, end, move));
|
||||
|
||||
var original = form.Location;
|
||||
form.Location = new Point(original.X + move.X, original.Y + move.Y);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using WindowsFormsAero.Dwm;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using OnTopReplica.Update;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using OnTopReplica.Properties;
|
||||
|
|
57
OnTopReplica/SidePanels/RegionPanel.Designer.cs
generated
57
OnTopReplica/SidePanels/RegionPanel.Designer.cs
generated
|
@ -25,6 +25,7 @@
|
|||
private void InitializeComponent() {
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.groupRegions = new System.Windows.Forms.GroupBox();
|
||||
this.checkRelative = new System.Windows.Forms.CheckBox();
|
||||
this.textRegionName = new OnTopReplica.FocusedTextBox();
|
||||
this.numH = new System.Windows.Forms.NumericUpDown();
|
||||
this.numW = new System.Windows.Forms.NumericUpDown();
|
||||
|
@ -50,6 +51,7 @@
|
|||
//
|
||||
// groupRegions
|
||||
//
|
||||
this.groupRegions.Controls.Add(this.checkRelative);
|
||||
this.groupRegions.Controls.Add(this.textRegionName);
|
||||
this.groupRegions.Controls.Add(this.numH);
|
||||
this.groupRegions.Controls.Add(this.numW);
|
||||
|
@ -68,11 +70,25 @@
|
|||
this.groupRegions.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.groupRegions.Location = new System.Drawing.Point(6, 6);
|
||||
this.groupRegions.Name = "groupRegions";
|
||||
this.groupRegions.Size = new System.Drawing.Size(218, 158);
|
||||
this.groupRegions.Size = new System.Drawing.Size(218, 180);
|
||||
this.groupRegions.TabIndex = 0;
|
||||
this.groupRegions.TabStop = false;
|
||||
this.groupRegions.Text = "Regions:";
|
||||
//
|
||||
// checkRelative
|
||||
//
|
||||
this.checkRelative.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.checkRelative.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
this.checkRelative.Location = new System.Drawing.Point(6, 119);
|
||||
this.checkRelative.Name = "checkRelative";
|
||||
this.checkRelative.Size = new System.Drawing.Size(206, 18);
|
||||
this.checkRelative.TabIndex = 12;
|
||||
this.checkRelative.Text = "Relative to border";
|
||||
this.checkRelative.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
this.checkRelative.UseVisualStyleBackColor = true;
|
||||
this.checkRelative.CheckedChanged += new System.EventHandler(this.CheckRelative_checked);
|
||||
//
|
||||
// textRegionName
|
||||
//
|
||||
this.textRegionName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
|
@ -89,8 +105,9 @@
|
|||
//
|
||||
// numH
|
||||
//
|
||||
this.numH.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.numH.Enabled = false;
|
||||
this.numH.Location = new System.Drawing.Point(150, 93);
|
||||
this.numH.Location = new System.Drawing.Point(169, 93);
|
||||
this.numH.Maximum = new decimal(new int[] {
|
||||
100000,
|
||||
0,
|
||||
|
@ -108,8 +125,9 @@
|
|||
//
|
||||
// numW
|
||||
//
|
||||
this.numW.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.numW.Enabled = false;
|
||||
this.numW.Location = new System.Drawing.Point(150, 67);
|
||||
this.numW.Location = new System.Drawing.Point(169, 67);
|
||||
this.numW.Maximum = new decimal(new int[] {
|
||||
100000,
|
||||
0,
|
||||
|
@ -128,7 +146,7 @@
|
|||
// numY
|
||||
//
|
||||
this.numY.Enabled = false;
|
||||
this.numY.Location = new System.Drawing.Point(29, 93);
|
||||
this.numY.Location = new System.Drawing.Point(55, 93);
|
||||
this.numY.Maximum = new decimal(new int[] {
|
||||
100000,
|
||||
0,
|
||||
|
@ -147,7 +165,7 @@
|
|||
// numX
|
||||
//
|
||||
this.numX.Enabled = false;
|
||||
this.numX.Location = new System.Drawing.Point(29, 67);
|
||||
this.numX.Location = new System.Drawing.Point(55, 67);
|
||||
this.numX.Maximum = new decimal(new int[] {
|
||||
100000,
|
||||
0,
|
||||
|
@ -165,10 +183,10 @@
|
|||
//
|
||||
// buttonDone
|
||||
//
|
||||
this.buttonDone.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonDone.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonDone.Image = global::OnTopReplica.Properties.Resources.xiao_ok;
|
||||
this.buttonDone.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
this.buttonDone.Location = new System.Drawing.Point(142, 129);
|
||||
this.buttonDone.Location = new System.Drawing.Point(142, 151);
|
||||
this.buttonDone.Name = "buttonDone";
|
||||
this.buttonDone.Size = new System.Drawing.Size(70, 23);
|
||||
this.buttonDone.TabIndex = 9;
|
||||
|
@ -179,8 +197,8 @@
|
|||
//
|
||||
// buttonReset
|
||||
//
|
||||
this.buttonReset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonReset.Location = new System.Drawing.Point(66, 129);
|
||||
this.buttonReset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonReset.Location = new System.Drawing.Point(66, 151);
|
||||
this.buttonReset.Name = "buttonReset";
|
||||
this.buttonReset.Size = new System.Drawing.Size(70, 23);
|
||||
this.buttonReset.TabIndex = 8;
|
||||
|
@ -190,20 +208,22 @@
|
|||
//
|
||||
// labelHeight
|
||||
//
|
||||
this.labelHeight.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.labelHeight.ForeColor = System.Drawing.SystemColors.ControlDark;
|
||||
this.labelHeight.Location = new System.Drawing.Point(81, 96);
|
||||
this.labelHeight.Location = new System.Drawing.Point(104, 95);
|
||||
this.labelHeight.Name = "labelHeight";
|
||||
this.labelHeight.Size = new System.Drawing.Size(63, 17);
|
||||
this.labelHeight.Size = new System.Drawing.Size(60, 18);
|
||||
this.labelHeight.TabIndex = 9;
|
||||
this.labelHeight.Text = "Height";
|
||||
this.labelHeight.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
//
|
||||
// labelWidth
|
||||
//
|
||||
this.labelWidth.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.labelWidth.ForeColor = System.Drawing.SystemColors.ControlDark;
|
||||
this.labelWidth.Location = new System.Drawing.Point(81, 70);
|
||||
this.labelWidth.Location = new System.Drawing.Point(107, 69);
|
||||
this.labelWidth.Name = "labelWidth";
|
||||
this.labelWidth.Size = new System.Drawing.Size(63, 17);
|
||||
this.labelWidth.Size = new System.Drawing.Size(57, 18);
|
||||
this.labelWidth.TabIndex = 8;
|
||||
this.labelWidth.Text = "Width";
|
||||
this.labelWidth.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
|
@ -213,7 +233,7 @@
|
|||
this.labelY.ForeColor = System.Drawing.SystemColors.ControlDark;
|
||||
this.labelY.Location = new System.Drawing.Point(6, 96);
|
||||
this.labelY.Name = "labelY";
|
||||
this.labelY.Size = new System.Drawing.Size(17, 17);
|
||||
this.labelY.Size = new System.Drawing.Size(43, 17);
|
||||
this.labelY.TabIndex = 5;
|
||||
this.labelY.Text = "Y";
|
||||
this.labelY.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
|
@ -223,7 +243,7 @@
|
|||
this.labelX.ForeColor = System.Drawing.SystemColors.ControlDark;
|
||||
this.labelX.Location = new System.Drawing.Point(6, 70);
|
||||
this.labelX.Name = "labelX";
|
||||
this.labelX.Size = new System.Drawing.Size(17, 17);
|
||||
this.labelX.Size = new System.Drawing.Size(43, 17);
|
||||
this.labelX.TabIndex = 4;
|
||||
this.labelX.Text = "X";
|
||||
this.labelX.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
|
@ -259,7 +279,7 @@
|
|||
this.buttonSave.Name = "buttonSave";
|
||||
this.buttonSave.Size = new System.Drawing.Size(23, 23);
|
||||
this.buttonSave.TabIndex = 1;
|
||||
this.buttonSave.UseVisualStyleBackColor = true;
|
||||
this.buttonSave.UseVisualStyleBackColor = false;
|
||||
this.buttonSave.Click += new System.EventHandler(this.Save_click);
|
||||
//
|
||||
// comboRegions
|
||||
|
@ -281,10 +301,10 @@
|
|||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.groupRegions);
|
||||
this.MinimumSize = new System.Drawing.Size(230, 170);
|
||||
this.MinimumSize = new System.Drawing.Size(230, 185);
|
||||
this.Name = "RegionPanel";
|
||||
this.Padding = new System.Windows.Forms.Padding(6);
|
||||
this.Size = new System.Drawing.Size(230, 170);
|
||||
this.Size = new System.Drawing.Size(230, 192);
|
||||
this.groupRegions.ResumeLayout(false);
|
||||
this.groupRegions.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.numH)).EndInit();
|
||||
|
@ -314,5 +334,6 @@
|
|||
private System.Windows.Forms.NumericUpDown numX;
|
||||
private FocusedTextBox textRegionName;
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
private System.Windows.Forms.CheckBox checkRelative;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,18 +22,18 @@ namespace OnTopReplica.SidePanels {
|
|||
_regionDrawnHandler = new ThumbnailPanel.RegionDrawnHandler(ThumbnailPanel_RegionDrawn);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Localizes the dialog's labels.
|
||||
/// </summary>
|
||||
private void Localize() {
|
||||
this.SuspendLayout();
|
||||
|
||||
groupRegions.Text = Strings.RegionsTitle;
|
||||
comboRegions.CueBannerText = Strings.RegionsStoredRegions;
|
||||
labelCurrentRegion.Text = Strings.RegionsCurrentRegion;
|
||||
//labelX
|
||||
//labelY
|
||||
labelWidth.Text = Strings.RegionsWidth;
|
||||
labelHeight.Text = Strings.RegionsHeight;
|
||||
buttonReset.Text = Strings.RegionsResetButton;
|
||||
buttonDone.Text = Strings.RegionsDoneButton;
|
||||
UpdateRegionLabels();
|
||||
|
||||
toolTip.SetToolTip(buttonSave, Strings.RegionsSaveButton);
|
||||
toolTip.SetToolTip(buttonDelete, Strings.RegionsDeleteButton);
|
||||
|
@ -41,6 +41,48 @@ namespace OnTopReplica.SidePanels {
|
|||
this.ResumeLayout();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the labels for the region value selectors and the relative mode checkbox.
|
||||
/// </summary>
|
||||
private void UpdateRegionControls(ThumbnailRegion region) {
|
||||
checkRelative.Checked = region.Relative;
|
||||
|
||||
if (region.Relative) {
|
||||
Padding p = region.BoundsAsPadding;
|
||||
numX.Value = p.Left;
|
||||
numY.Value = p.Top;
|
||||
numW.Value = p.Right;
|
||||
numH.Value = p.Bottom;
|
||||
}
|
||||
else {
|
||||
Rectangle r = region.Bounds;
|
||||
numX.Value = r.X;
|
||||
numY.Value = r.Y;
|
||||
numW.Value = r.Width;
|
||||
numH.Value = r.Height;
|
||||
}
|
||||
|
||||
UpdateRegionLabels();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the labels of region selectors based on the dialog's state.
|
||||
/// </summary>
|
||||
private void UpdateRegionLabels() {
|
||||
if (checkRelative.Checked) {
|
||||
labelX.Text = Strings.RegionsLeft;
|
||||
labelY.Text = Strings.RegionsTop;
|
||||
labelWidth.Text = Strings.RegionsRight;
|
||||
labelHeight.Text = Strings.RegionsBottom;
|
||||
}
|
||||
else {
|
||||
labelX.Text = Strings.RegionsX;
|
||||
labelY.Text = Strings.RegionsY;
|
||||
labelWidth.Text = Strings.RegionsWidth;
|
||||
labelHeight.Text = Strings.RegionsHeight;
|
||||
}
|
||||
}
|
||||
|
||||
public override string Title {
|
||||
get {
|
||||
return Strings.MenuRegion;
|
||||
|
@ -52,22 +94,25 @@ namespace OnTopReplica.SidePanels {
|
|||
public override void OnFirstShown(MainForm form) {
|
||||
base.OnFirstShown(form);
|
||||
|
||||
//Init shown region if needed
|
||||
if (form.SelectedThumbnailRegion.HasValue)
|
||||
SetRegion(form.SelectedThumbnailRegion.Value);
|
||||
//Init shown region if current thumbnail is clipped to region
|
||||
if (form.SelectedThumbnailRegion != null) {
|
||||
SetRegion(form.SelectedThumbnailRegion);
|
||||
}
|
||||
|
||||
//Enable region drawing
|
||||
form.ThumbnailPanel.DrawMouseRegions = true;
|
||||
form.ThumbnailPanel.RegionDrawn += _regionDrawnHandler;
|
||||
}
|
||||
|
||||
public override void OnClosing(MainForm form) {
|
||||
base.OnClosing(form);
|
||||
|
||||
|
||||
//Reset region drawing
|
||||
form.ThumbnailPanel.DrawMouseRegions = false;
|
||||
form.ThumbnailPanel.RegionDrawn -= _regionDrawnHandler;
|
||||
}
|
||||
|
||||
void ThumbnailPanel_RegionDrawn(object sender, Rectangle region) {
|
||||
void ThumbnailPanel_RegionDrawn(object sender, ThumbnailRegion region) {
|
||||
SetRegion(region);
|
||||
}
|
||||
|
||||
|
@ -83,7 +128,7 @@ namespace OnTopReplica.SidePanels {
|
|||
return;
|
||||
}
|
||||
|
||||
SetRegion(region.Bounds);
|
||||
SetRegion(region.Region);
|
||||
|
||||
//Select right combobox
|
||||
if (comboRegions.Items.Contains(region)) {
|
||||
|
@ -95,16 +140,13 @@ namespace OnTopReplica.SidePanels {
|
|||
/// Sets the current selected region to a specific region rectangle.
|
||||
/// </summary>
|
||||
/// <param name="region">The region boundaries.</param>
|
||||
public void SetRegion(Rectangle region) {
|
||||
public void SetRegion(ThumbnailRegion region) {
|
||||
try {
|
||||
_ignoreValueChanges = true;
|
||||
|
||||
numX.Enabled = numY.Enabled = numW.Enabled = numH.Enabled = true;
|
||||
UpdateRegionControls(region);
|
||||
|
||||
numX.Value = region.Left;
|
||||
numY.Value = region.Top;
|
||||
numW.Value = region.Width;
|
||||
numH.Value = region.Height;
|
||||
numX.Enabled = numY.Enabled = numW.Enabled = numH.Enabled = true;
|
||||
}
|
||||
finally {
|
||||
_ignoreValueChanges = false;
|
||||
|
@ -122,6 +164,8 @@ namespace OnTopReplica.SidePanels {
|
|||
|
||||
numX.Value = numY.Value = numW.Value = numH.Value = 0;
|
||||
numX.Enabled = numY.Enabled = numW.Enabled = numH.Enabled = false;
|
||||
checkRelative.Checked = false;
|
||||
UpdateRegionLabels();
|
||||
|
||||
buttonSave.Enabled = false;
|
||||
|
||||
|
@ -134,30 +178,48 @@ namespace OnTopReplica.SidePanels {
|
|||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a ThumbnailRegion from the dialog's current state.
|
||||
/// </summary>
|
||||
protected ThumbnailRegion ConstructCurrentRegion() {
|
||||
Rectangle bounds = new Rectangle {
|
||||
X = (int)numX.Value,
|
||||
Y = (int)numY.Value,
|
||||
Width = (int)numW.Value,
|
||||
Height = (int)numH.Value
|
||||
};
|
||||
|
||||
ThumbnailRegion newRegion = new ThumbnailRegion(bounds, checkRelative.Checked);
|
||||
|
||||
return newRegion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new stored region.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">Region bounds.</param>
|
||||
/// <param name="regionName">Name of the region.</param>
|
||||
private void AddRegion(Rectangle rectangle, string regionName) {
|
||||
var region = new StoredRegion(rectangle, regionName);
|
||||
/// <param name="isRelative">Whether the region is relative to the border.</param>
|
||||
private void StoreCurrentRegion(string regionName) {
|
||||
StoredRegion storedRegion = new StoredRegion(this.ConstructCurrentRegion(), regionName);
|
||||
|
||||
int index = comboRegions.Items.Add(region);
|
||||
int index = comboRegions.Items.Add(storedRegion);
|
||||
comboRegions.SelectedIndex = index;
|
||||
|
||||
if (Settings.Default.SavedRegions == null)
|
||||
Settings.Default.SavedRegions = new StoredRegionArray();
|
||||
Settings.Default.SavedRegions.Add(region);
|
||||
Settings.Default.SavedRegions.Add(storedRegion);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal event raised when a change occurs in the selected region.
|
||||
/// </summary>
|
||||
/// <param name="regionBounds">Region bounds.</param>
|
||||
protected virtual void OnRegionSet(Rectangle regionBounds) {
|
||||
protected virtual void OnRegionSet(ThumbnailRegion region) {
|
||||
//Forward region to thumbnail
|
||||
ParentForm.SelectedThumbnailRegion = regionBounds;
|
||||
ParentForm.SelectedThumbnailRegion = region;
|
||||
|
||||
//Have region, allowed to save
|
||||
buttonSave.Enabled = true;
|
||||
}
|
||||
|
||||
|
@ -193,10 +255,7 @@ namespace OnTopReplica.SidePanels {
|
|||
|
||||
private void Save_confirm(object sender, EventArgs e) {
|
||||
if (!string.IsNullOrEmpty(textRegionName.Text)) {
|
||||
AddRegion(
|
||||
new Rectangle((int)numX.Value, (int)numY.Value, (int)numW.Value, (int)numH.Value),
|
||||
textRegionName.Text
|
||||
);
|
||||
StoreCurrentRegion(textRegionName.Text);
|
||||
}
|
||||
|
||||
//Hide textbox and show button again
|
||||
|
@ -222,7 +281,7 @@ namespace OnTopReplica.SidePanels {
|
|||
if (_ignoreValueChanges)
|
||||
return;
|
||||
|
||||
OnRegionSet(new Rectangle((int)numX.Value, (int)numY.Value, (int)numW.Value, (int)numH.Value));
|
||||
OnRegionSet(ConstructCurrentRegion());
|
||||
}
|
||||
|
||||
private void RegionCombo_index_change(object sender, EventArgs e) {
|
||||
|
@ -235,10 +294,26 @@ namespace OnTopReplica.SidePanels {
|
|||
if (region == null)
|
||||
return;
|
||||
|
||||
SetRegion(region.Bounds);
|
||||
SetRegion(region.Region);
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckRelative_checked(object sender, EventArgs e) {
|
||||
if (_ignoreValueChanges)
|
||||
return;
|
||||
|
||||
//Get current region and switch mode
|
||||
var region = ConstructCurrentRegion();
|
||||
region.Relative = !region.Relative; //this must be reversed because the GUI has already switched state when calling ConstructCurrentRegion()
|
||||
if (checkRelative.Checked)
|
||||
region.SwitchToRelative(ParentForm.ThumbnailPanel.ThumbnailOriginalSize);
|
||||
else
|
||||
region.SwitchToAbsolute(ParentForm.ThumbnailPanel.ThumbnailOriginalSize);
|
||||
|
||||
//Update GUI
|
||||
SetRegion(region);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
|
|
@ -112,12 +112,12 @@
|
|||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
|
|
@ -47,11 +47,9 @@ namespace OnTopReplica.StartupOptions {
|
|||
//Load window
|
||||
options.WindowId = resultHandle.Handle;
|
||||
}
|
||||
#if DEBUG
|
||||
else {
|
||||
Console.WriteLine("Couldn't find window to restore.");
|
||||
System.Diagnostics.Trace.WriteLine("Couldn't find window to restore.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,8 +78,11 @@ namespace OnTopReplica.StartupOptions {
|
|||
options.StartLocation = null;
|
||||
options.StartScreenPosition = pos;
|
||||
})
|
||||
.Add<Rectangle>("r|region=", "Region {BOUNDS} of the original window.", region => {
|
||||
options.Region = region;
|
||||
.Add<Rectangle>("r|region=", "Region {BOUNDS} of the cloned window.", region => {
|
||||
options.Region = new ThumbnailRegion(region);
|
||||
})
|
||||
.Add<System.Windows.Forms.Padding>("p|padding=", "Padding {BOUNDS} of the clone.", padding => {
|
||||
options.Region = new ThumbnailRegion(padding);
|
||||
})
|
||||
.Add<byte>("o|opacity=", "Opacity of the window (0-255).", opacity => {
|
||||
options.Opacity = opacity;
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace OnTopReplica.StartupOptions {
|
|||
|
||||
public string WindowClass { get; set; }
|
||||
|
||||
public Rectangle? Region { get; set; }
|
||||
public ThumbnailRegion Region { get; set; }
|
||||
|
||||
public bool MustBeVisible { get; set; }
|
||||
|
||||
|
|
|
@ -6,21 +6,17 @@ using System.Drawing;
|
|||
|
||||
namespace OnTopReplica {
|
||||
|
||||
[Serializable]
|
||||
public class StoredRegion : IXmlSerializable {
|
||||
public class StoredRegion {
|
||||
|
||||
public StoredRegion() {
|
||||
}
|
||||
public StoredRegion(ThumbnailRegion r, string name) {
|
||||
Region = r;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public StoredRegion(Rectangle r, string n) {
|
||||
Bounds = r;
|
||||
Name = n;
|
||||
}
|
||||
|
||||
public Rectangle Bounds {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public ThumbnailRegion Region {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get;
|
||||
|
@ -31,33 +27,6 @@ namespace OnTopReplica {
|
|||
return Name;
|
||||
}
|
||||
|
||||
|
||||
#region IXmlSerializable Members
|
||||
|
||||
public System.Xml.Schema.XmlSchema GetSchema() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void ReadXml(System.Xml.XmlReader reader) {
|
||||
if (reader.MoveToAttribute("name"))
|
||||
Name = reader.Value;
|
||||
else
|
||||
throw new Exception();
|
||||
|
||||
reader.Read();
|
||||
|
||||
XmlSerializer x = new XmlSerializer(typeof(Rectangle));
|
||||
Bounds = (Rectangle)x.Deserialize(reader);
|
||||
}
|
||||
|
||||
public void WriteXml(System.Xml.XmlWriter writer) {
|
||||
writer.WriteAttributeString("name", Name);
|
||||
|
||||
XmlSerializer x = new XmlSerializer(typeof(Rectangle));
|
||||
x.Serialize(writer, Bounds);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,10 +3,18 @@ using System.Collections.Generic;
|
|||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Xml.Serialization;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace OnTopReplica {
|
||||
|
||||
public class StoredRegionArray : ArrayList, IXmlSerializable {
|
||||
/// <summary>
|
||||
/// Strongly styped array of StoredRegion elements.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Handles XML serialization.
|
||||
/// </remarks>
|
||||
public class StoredRegionArray : List<StoredRegion>, IXmlSerializable {
|
||||
|
||||
#region IXmlSerializable Members
|
||||
|
||||
|
@ -16,22 +24,122 @@ namespace OnTopReplica {
|
|||
|
||||
public void ReadXml(System.Xml.XmlReader reader) {
|
||||
this.Clear();
|
||||
XmlSerializer x = new XmlSerializer(typeof(StoredRegion));
|
||||
while (reader.ReadToFollowing("StoredRegion")) {
|
||||
object o = x.Deserialize(reader);
|
||||
|
||||
if (o is StoredRegion)
|
||||
this.Add(o);
|
||||
}
|
||||
var doc = XDocument.Load(reader);
|
||||
foreach (var xmlRegion in doc.Descendants("StoredRegion")) {
|
||||
System.Diagnostics.Debug.WriteLine(string.Format("Found region '{0}'.", xmlRegion.Attribute("name")));
|
||||
|
||||
StoredRegion parsedRegion = ParseStoredRegion(xmlRegion);
|
||||
if (parsedRegion != null) {
|
||||
this.Add(parsedRegion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private StoredRegion ParseStoredRegion(XElement xmlRegion) {
|
||||
var xName = xmlRegion.Attribute("name");
|
||||
if (xName == null || string.IsNullOrWhiteSpace(xName.Value)) {
|
||||
System.Diagnostics.Debug.Fail("Parsed stored region has no name attribute.");
|
||||
return null;
|
||||
}
|
||||
|
||||
ThumbnailRegion region = ParseRegion(xmlRegion);
|
||||
if (region == null) {
|
||||
System.Diagnostics.Debug.Fail("Parsed stored region has no valid region.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new StoredRegion(region, xName.Value);
|
||||
}
|
||||
|
||||
private ThumbnailRegion ParseRegion(XElement xmlRegion) {
|
||||
var xRectangle = xmlRegion.Element("Rectangle");
|
||||
if (xRectangle != null) {
|
||||
System.Drawing.Rectangle rectangle = ParseRectangle(xRectangle);
|
||||
return new ThumbnailRegion(rectangle);
|
||||
}
|
||||
|
||||
var xPadding = xmlRegion.Element("Padding");
|
||||
if (xPadding != null) {
|
||||
System.Windows.Forms.Padding padding = ParsePadding(xPadding);
|
||||
return new ThumbnailRegion(padding);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private System.Windows.Forms.Padding ParsePadding(XElement xPadding) {
|
||||
var p = new System.Windows.Forms.Padding();
|
||||
try {
|
||||
p.Left = Int32.Parse(xPadding.Element("Left").Value);
|
||||
p.Top = Int32.Parse(xPadding.Element("Top").Value);
|
||||
p.Right = Int32.Parse(xPadding.Element("Right").Value);
|
||||
p.Bottom = Int32.Parse(xPadding.Element("Bottom").Value);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.Diagnostics.Debug.Fail("Failure while parsing padding data.", ex.ToString());
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
private System.Drawing.Rectangle ParseRectangle(XElement xRectangle) {
|
||||
var r = new System.Drawing.Rectangle();
|
||||
try {
|
||||
r.X = Int32.Parse(xRectangle.Element("X").Value);
|
||||
r.Y = Int32.Parse(xRectangle.Element("Y").Value);
|
||||
r.Width = Int32.Parse(xRectangle.Element("Width").Value);
|
||||
r.Height = Int32.Parse(xRectangle.Element("Height").Value);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.Diagnostics.Debug.Fail("Failure while parsing rectangle data.", ex.ToString());
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public void WriteXml(System.Xml.XmlWriter writer) {
|
||||
XmlSerializer x = new XmlSerializer(typeof(StoredRegion));
|
||||
foreach (StoredRegion sr in this) {
|
||||
x.Serialize(writer, sr);
|
||||
}
|
||||
foreach (var region in this) {
|
||||
WriteRegion(writer, region);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteRegion(XmlWriter writer, StoredRegion region) {
|
||||
writer.WriteStartElement("StoredRegion");
|
||||
writer.WriteAttributeString("name", region.Name);
|
||||
|
||||
if (region.Region.Relative) {
|
||||
WriteRelativeRegion(writer, region);
|
||||
}
|
||||
else {
|
||||
WriteAbsoluteRegion(writer, region);
|
||||
}
|
||||
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
private void WriteAbsoluteRegion(XmlWriter writer, StoredRegion region) {
|
||||
writer.WriteStartElement("Rectangle");
|
||||
|
||||
var bounds = region.Region.Bounds;
|
||||
writer.WriteElementString("X", bounds.X.ToString());
|
||||
writer.WriteElementString("Y", bounds.Y.ToString());
|
||||
writer.WriteElementString("Width", bounds.Width.ToString());
|
||||
writer.WriteElementString("Height", bounds.Height.ToString());
|
||||
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
private void WriteRelativeRegion(XmlWriter writer, StoredRegion region) {
|
||||
writer.WriteStartElement("Padding");
|
||||
|
||||
var padding = region.Region.BoundsAsPadding;
|
||||
writer.WriteElementString("Left", padding.Left.ToString());
|
||||
writer.WriteElementString("Top", padding.Top.ToString());
|
||||
writer.WriteElementString("Right", padding.Right.ToString());
|
||||
writer.WriteElementString("Bottom", padding.Bottom.ToString());
|
||||
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,7 +14,6 @@ namespace OnTopReplica {
|
|||
|
||||
//DWM Thumbnail stuff
|
||||
Thumbnail _thumbnail = null;
|
||||
Rectangle _regionCurrent;
|
||||
|
||||
//Labels
|
||||
ThemedLabel _labelGlass;
|
||||
|
@ -42,16 +41,19 @@ namespace OnTopReplica {
|
|||
|
||||
#region Properties and settings
|
||||
|
||||
ThumbnailRegion _currentRegion;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the region that is currently shown on the thumbnail. When set, also enabled region constrain.
|
||||
/// Gets or sets the region that is currently shown on the thumbnail. When set, also enables region constrain.
|
||||
/// </summary>
|
||||
public Rectangle SelectedRegion {
|
||||
public ThumbnailRegion SelectedRegion {
|
||||
get {
|
||||
return _regionCurrent;
|
||||
return _currentRegion;
|
||||
}
|
||||
set {
|
||||
_regionCurrent = value;
|
||||
ConstrainToRegion = true;
|
||||
_currentRegion = value;
|
||||
_regionEnabled = (value != null);
|
||||
UpdateThubmnail();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,8 +67,10 @@ namespace OnTopReplica {
|
|||
return _regionEnabled;
|
||||
}
|
||||
set {
|
||||
_regionEnabled = value;
|
||||
UpdateThubmnail();
|
||||
if (_regionEnabled != value) {
|
||||
_regionEnabled = value;
|
||||
UpdateThubmnail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,18 +116,50 @@ namespace OnTopReplica {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the thumbnail's original size.
|
||||
/// Gets the thumbnail's size (in effectively thumbnailed pixels).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This size varies if the thumbnail has been cropped to a region.
|
||||
/// </remarks>
|
||||
public Size ThumbnailPixelSize {
|
||||
get {
|
||||
if (_thumbnail != null && !_thumbnail.IsInvalid) {
|
||||
if (_regionEnabled) {
|
||||
return _currentRegion.ComputeRegionSize(_thumbnail.SourceSize);
|
||||
}
|
||||
else {
|
||||
//Thumbnail is not cropped, return full thumbnail source size
|
||||
return _thumbnail.SourceSize;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if DEBUG
|
||||
throw new InvalidOperationException(Strings.ErrorNoThumbnail);
|
||||
#else
|
||||
return Size.Empty;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the thumbnailed window's original size.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This size is not influenced by the region cropping applied to the thumbnail.
|
||||
/// </remarks>
|
||||
public Size ThumbnailOriginalSize {
|
||||
get {
|
||||
if (_thumbnail != null && !_thumbnail.IsInvalid) {
|
||||
if (_regionEnabled)
|
||||
return _regionCurrent.Size;
|
||||
|
||||
return _thumbnail.SourceSize;
|
||||
}
|
||||
else
|
||||
throw new Exception(Strings.ErrorNoThumbnail);
|
||||
else {
|
||||
#if DEBUG
|
||||
throw new InvalidOperationException(Strings.ErrorNoThumbnail);
|
||||
#else
|
||||
return Size.Empty;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,9 +192,14 @@ namespace OnTopReplica {
|
|||
/// Creates a new thumbnail of a certain window.
|
||||
/// </summary>
|
||||
/// <param name="handle">Handle of the window to clone.</param>
|
||||
public void SetThumbnailHandle(WindowHandle handle) {
|
||||
if (_thumbnail != null && !_thumbnail.IsInvalid)
|
||||
_thumbnail.Close();
|
||||
/// <param name="region">Optional region.</param>
|
||||
public void SetThumbnailHandle(WindowHandle handle, ThumbnailRegion region) {
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Setting thumbnail to handle {0}, with region {1}.", handle, region), "ThumbnailPanel");
|
||||
|
||||
if (_thumbnail != null && !_thumbnail.IsInvalid) {
|
||||
_thumbnail.Close();
|
||||
_thumbnail = null;
|
||||
}
|
||||
|
||||
//Get form and register thumbnail on it
|
||||
Form owner = this.TopLevelControl as Form;
|
||||
|
@ -167,16 +208,22 @@ namespace OnTopReplica {
|
|||
|
||||
_labelGlass.Visible = false;
|
||||
|
||||
//Register new thumbnail, disable regioning directly and refresh
|
||||
_thumbnail = DwmManager.Register(owner, handle.Handle);
|
||||
ConstrainToRegion = false; //this also invokes a thumbnail update
|
||||
_currentRegion = region;
|
||||
_regionEnabled = (region != null);
|
||||
UpdateThubmnail();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes current thumbnail and enters stand-by mode.
|
||||
/// </summary>
|
||||
public void UnsetThumbnail() {
|
||||
if (_thumbnail != null && !_thumbnail.IsInvalid)
|
||||
_thumbnail.Close();
|
||||
System.Diagnostics.Trace.WriteLine("Unsetting thumbnail.");
|
||||
|
||||
if (_thumbnail != null && !_thumbnail.IsInvalid) {
|
||||
_thumbnail.Close();
|
||||
}
|
||||
|
||||
_thumbnail = null;
|
||||
_labelGlass.Visible = true;
|
||||
|
@ -201,14 +248,16 @@ namespace OnTopReplica {
|
|||
private void UpdateThubmnail() {
|
||||
if (_thumbnail != null && !_thumbnail.IsInvalid){
|
||||
try {
|
||||
Size sourceSize = ThumbnailOriginalSize;
|
||||
_thumbnailSize = ComputeIdealSize(sourceSize, Size);
|
||||
|
||||
//Get thumbnail size and attempt to fit to control, with padding
|
||||
Size sourceSize = ThumbnailPixelSize;
|
||||
_thumbnailSize = sourceSize.Fit(Size);
|
||||
_padWidth = (Size.Width - _thumbnailSize.Width) / 2;
|
||||
_padHeight = (Size.Height - _thumbnailSize.Height) / 2;
|
||||
|
||||
System.Diagnostics.Debug.WriteLine("Fitting {0} inside {1} as {2}. Padding {3},{4}.", sourceSize, Size, _thumbnailSize, _padWidth, _padHeight);
|
||||
|
||||
var target = new Rectangle(_padWidth, _padHeight, _thumbnailSize.Width, _thumbnailSize.Height);
|
||||
Rectangle source = (_regionEnabled) ? _regionCurrent : new Rectangle(Point.Empty, _thumbnail.SourceSize);
|
||||
Rectangle source = (_regionEnabled) ? _currentRegion.ComputeRegionRectangle(_thumbnail.SourceSize) : new Rectangle(Point.Empty, _thumbnail.SourceSize);
|
||||
|
||||
_thumbnail.Update(target, source, ThumbnailOpacity, true, true);
|
||||
}
|
||||
|
@ -220,30 +269,12 @@ namespace OnTopReplica {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes ideal thumbnail size given an original size and a target to fit.
|
||||
/// </summary>
|
||||
/// <param name="sourceSize">Size of the original thumbnail.</param>
|
||||
/// <param name="clientSize">Size of the client area to fit.</param>
|
||||
private Size ComputeIdealSize(Size sourceSize, Size clientSize) {
|
||||
double sourceRatio = (double)sourceSize.Width / (double)sourceSize.Height;
|
||||
double clientRatio = (double)clientSize.Width / (double)clientSize.Height;
|
||||
|
||||
Size ret;
|
||||
if (sourceRatio >= clientRatio) {
|
||||
ret = new Size(clientSize.Width, (int)((double)clientSize.Width / sourceRatio));
|
||||
}
|
||||
else {
|
||||
ret = new Size((int)((double)clientSize.Height * sourceRatio), clientSize.Height);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Region drawing
|
||||
|
||||
const int MinimumRegionSize = 1;
|
||||
|
||||
//Set if currently drawing a window (first click/drag was initiated)
|
||||
bool _drawingRegion = false;
|
||||
//Set if drawing was suspended because the mouse left the control
|
||||
|
@ -251,18 +282,20 @@ namespace OnTopReplica {
|
|||
Point _regionStartPoint;
|
||||
Point _regionLastPoint;
|
||||
|
||||
public delegate void RegionDrawnHandler(object sender, Rectangle region);
|
||||
public delegate void RegionDrawnHandler(object sender, ThumbnailRegion region);
|
||||
|
||||
public event RegionDrawnHandler RegionDrawn;
|
||||
|
||||
protected virtual void OnRegionDrawn(Rectangle region) {
|
||||
//Fix region if necessary (bug report by Gunter, via comment)
|
||||
if (region.Width < 1) region.Width = 1;
|
||||
if (region.Height < 1) region.Height = 1;
|
||||
if (region.Width < MinimumRegionSize)
|
||||
region.Width = MinimumRegionSize;
|
||||
if (region.Height < MinimumRegionSize)
|
||||
region.Height = MinimumRegionSize;
|
||||
|
||||
var evt = RegionDrawn;
|
||||
if (evt != null)
|
||||
evt(this, region);
|
||||
evt(this, new ThumbnailRegion(region));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -272,7 +305,7 @@ namespace OnTopReplica {
|
|||
if (_thumbnailSize.Width < 1 || _thumbnailSize.Height < 1) //causes DivBy0
|
||||
return;
|
||||
|
||||
//Compute bounds
|
||||
//Compute bounds and clip to boundaries
|
||||
int left = Math.Min(start.X, end.X);
|
||||
int right = Math.Max(start.X, end.X);
|
||||
int top = Math.Min(start.Y, end.Y);
|
||||
|
@ -288,12 +321,15 @@ namespace OnTopReplica {
|
|||
var startPoint = ClientToThumbnail(new Point(left, top));
|
||||
var endPoint = ClientToThumbnail(new Point(right, bottom));
|
||||
var final = new Rectangle(
|
||||
startPoint,
|
||||
new Size(endPoint.X - startPoint.X, endPoint.Y - startPoint.Y)
|
||||
startPoint.X,
|
||||
startPoint.Y,
|
||||
endPoint.X - startPoint.X,
|
||||
endPoint.Y - startPoint.Y
|
||||
);
|
||||
|
||||
//Update region
|
||||
SelectedRegion = final;
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Drawn from {0} to {1}, as region {2}.", start, end, final));
|
||||
|
||||
//Signal
|
||||
OnRegionDrawn(final);
|
||||
}
|
||||
|
||||
|
@ -356,7 +392,7 @@ namespace OnTopReplica {
|
|||
base.OnMouseMove(e);
|
||||
}
|
||||
|
||||
Pen penRed = new Pen(Color.FromArgb(255, Color.Red), 1.0f);
|
||||
readonly static Pen RedPen = new Pen(Color.FromArgb(255, Color.Red), 1.5f); //TODO: check width
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e) {
|
||||
if (_drawingRegion) {
|
||||
|
@ -366,12 +402,12 @@ namespace OnTopReplica {
|
|||
int top = Math.Min(_regionStartPoint.Y, _regionLastPoint.Y);
|
||||
int bottom = Math.Max(_regionStartPoint.Y, _regionLastPoint.Y);
|
||||
|
||||
e.Graphics.DrawRectangle(penRed, left, top, right - left, bottom - top);
|
||||
e.Graphics.DrawRectangle(RedPen, left, top, right - left, bottom - top);
|
||||
}
|
||||
else if (DrawMouseRegions && ! _drawingSuspended) {
|
||||
//Show cursor coordinates
|
||||
e.Graphics.DrawLine(penRed, new Point(0, _regionLastPoint.Y), new Point(ClientSize.Width, _regionLastPoint.Y));
|
||||
e.Graphics.DrawLine(penRed, new Point(_regionLastPoint.X, 0), new Point(_regionLastPoint.X, ClientSize.Height));
|
||||
e.Graphics.DrawLine(RedPen, new Point(0, _regionLastPoint.Y), new Point(ClientSize.Width, _regionLastPoint.Y));
|
||||
e.Graphics.DrawLine(RedPen, new Point(_regionLastPoint.X, 0), new Point(_regionLastPoint.X, ClientSize.Height));
|
||||
}
|
||||
|
||||
base.OnPaint(e);
|
||||
|
@ -427,14 +463,15 @@ namespace OnTopReplica {
|
|||
position.X -= _padWidth;
|
||||
position.Y -= _padHeight;
|
||||
|
||||
//Determine position in fractional terms (on the size of the thumbnail control)
|
||||
PointF proportionalPosition = new PointF(
|
||||
(float)position.X / _thumbnailSize.Width,
|
||||
(float)position.Y / _thumbnailSize.Height
|
||||
);
|
||||
|
||||
//Get real pixel region info
|
||||
Size source = (_regionEnabled) ? _regionCurrent.Size : _thumbnail.SourceSize;
|
||||
Point offset = (_regionEnabled) ? _regionCurrent.Location : Point.Empty;
|
||||
Size source = ThumbnailPixelSize;
|
||||
Point offset = (_regionEnabled) ? SelectedRegion.Offset : Point.Empty;
|
||||
|
||||
return new Point(
|
||||
(int)((proportionalPosition.X * source.Width) + offset.X),
|
||||
|
|
222
OnTopReplica/ThumbnailRegion.cs
Normal file
222
OnTopReplica/ThumbnailRegion.cs
Normal file
|
@ -0,0 +1,222 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace OnTopReplica {
|
||||
|
||||
/// <summary>
|
||||
/// Represents a thumbnail region.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A ThumbnailRegion can work in absolute or in relative mode.
|
||||
/// In absolute mode, the region is expressed in absolute pixel values, as expressed by the value of the
|
||||
/// <see cref="Bounds"/> property.
|
||||
/// In relative mode, the region is expressed in padding pixels from the borders of the source. Internally this
|
||||
/// is still represented by the <see cref="Bounds"/> property. Properties of the Rectangle value are mapped as follows:
|
||||
/// Rectangle.X = Padding.Left
|
||||
/// Rectangle.Y = Padding.Top
|
||||
/// Rectangle.Width = Padding.Right
|
||||
/// Rectangle.Height = Padding.Bottom
|
||||
/// </remarks>
|
||||
public class ThumbnailRegion {
|
||||
|
||||
/// <summary>
|
||||
/// Creates a ThumbnailRegion from a padding value relative to the thumbnail borders.
|
||||
/// </summary>
|
||||
public ThumbnailRegion(Padding padding) {
|
||||
_bounds = new Rectangle {
|
||||
X = padding.Left,
|
||||
Y = padding.Top,
|
||||
Width = padding.Right,
|
||||
Height = padding.Bottom
|
||||
};
|
||||
Relative = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a ThumbnailRegion from a bounds rectangle (in absolute terms).
|
||||
/// </summary>
|
||||
public ThumbnailRegion(Rectangle rectangle) {
|
||||
_bounds = rectangle;
|
||||
Relative = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a ThumbnailRegion from a rectangle, either expressing values in relative or in absolute terms.
|
||||
/// </summary>
|
||||
public ThumbnailRegion(Rectangle paddingOrBounds, bool relative) {
|
||||
_bounds = paddingOrBounds;
|
||||
Relative = relative;
|
||||
}
|
||||
|
||||
private Rectangle _bounds;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bounds of the thumbnail region.
|
||||
/// </summary>
|
||||
public Rectangle Bounds {
|
||||
get {
|
||||
#if DEBUG
|
||||
if (Relative)
|
||||
throw new InvalidOperationException("Not allowed to use ThumbnailRegion Bounds as Rectangle value (in relative mode).");
|
||||
#endif
|
||||
|
||||
return _bounds;
|
||||
}
|
||||
set {
|
||||
_bounds = value;
|
||||
Relative = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the bounds are expressed relative to the thumbnail borders.
|
||||
/// </summary>
|
||||
public bool Relative {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the relative bounds of the region. Switches to relative mode.
|
||||
/// </summary>
|
||||
/// <param name="padding">Padding in relative terms from the borders.</param>
|
||||
public void SetRelativeBounds(Padding padding) {
|
||||
Bounds = new Rectangle {
|
||||
X = padding.Left,
|
||||
Y = padding.Top,
|
||||
Width = padding.Right,
|
||||
Height = padding.Bottom
|
||||
};
|
||||
Relative = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bounds of the thumbnail region as relative padding from the thumbnail borders.
|
||||
/// </summary>
|
||||
/// <remarks>Makes sense only in relative mode.</remarks>
|
||||
public Padding BoundsAsPadding {
|
||||
get {
|
||||
#if DEBUG
|
||||
if (!Relative)
|
||||
throw new InvalidOperationException("Not allowed to use ThumbnailRegion Bounds as Padding value (not in relative mode).");
|
||||
#endif
|
||||
|
||||
return new Padding {
|
||||
Left = _bounds.X,
|
||||
Top = _bounds.Y,
|
||||
Right = _bounds.Width,
|
||||
Bottom = _bounds.Height
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the offset of the region.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The offset is expressed as a point of displacement from the up-right corner (0,0) of the original source.
|
||||
/// </remarks>
|
||||
public Point Offset {
|
||||
get {
|
||||
//This is equal in both absolute and relative mode
|
||||
return _bounds.Location;
|
||||
}
|
||||
}
|
||||
|
||||
const int MinimumRegionSize = 8;
|
||||
|
||||
/// <summary>
|
||||
/// Computes the effective region representing the bounds inside a source thumbnail of a certain size.
|
||||
/// </summary>
|
||||
/// <param name="sourceSize">Size of the full thumbnail source.</param>
|
||||
/// <returns>Bounds inside the thumbnail.</returns>
|
||||
protected Rectangle ComputeRegion(Size sourceSize) {
|
||||
Rectangle ret;
|
||||
|
||||
//Compute
|
||||
if (Relative) {
|
||||
ret = new Rectangle {
|
||||
X = _bounds.X,
|
||||
Y = _bounds.Y,
|
||||
Width = sourceSize.Width - _bounds.X - _bounds.Width,
|
||||
Height = sourceSize.Height - _bounds.Y - _bounds.Height
|
||||
};
|
||||
}
|
||||
else {
|
||||
ret = _bounds;
|
||||
}
|
||||
|
||||
//Constrain to bounds
|
||||
if (ret.X + ret.Width > sourceSize.Width)
|
||||
ret.Width = sourceSize.Width - ret.X;
|
||||
if (ret.Y + ret.Height > sourceSize.Height)
|
||||
ret.Height = sourceSize.Height - ret.Y;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes a rectangle representing the bounds of the region inside a source thumbnail of a certain size.
|
||||
/// </summary>
|
||||
/// <param name="sourceSize">Size of the full thumbnail source.</param>
|
||||
/// <returns>Bounds inside the thumbnail.</returns>
|
||||
public Rectangle ComputeRegionRectangle(Size sourceSize) {
|
||||
return ComputeRegion(sourceSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes a value representing the size of the region inside a source thumbnail of a certain size.
|
||||
/// </summary>
|
||||
/// <param name="sourceSize">Size of the full thumbnail source.</param>
|
||||
/// <returns>Size of the bounds inside the thumbnail.</returns>
|
||||
public Size ComputeRegionSize(Size sourceSize) {
|
||||
return ComputeRegion(sourceSize).Size;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Switches the region to relative mode, according to a source thumbnail of a given size.
|
||||
/// </summary>
|
||||
/// <param name="sourceSize">Size of the full thumbnail source.</param>
|
||||
public void SwitchToRelative(Size sourceSize) {
|
||||
if (Relative)
|
||||
return;
|
||||
|
||||
var relativeBounds = new Padding {
|
||||
Left = _bounds.X,
|
||||
Top = _bounds.Y,
|
||||
Right = sourceSize.Width - (_bounds.X + _bounds.Width),
|
||||
Bottom = sourceSize.Height - (_bounds.Y + _bounds.Height)
|
||||
};
|
||||
|
||||
this.SetRelativeBounds(relativeBounds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Switches the region to absolute mode, according to a source thumbnail of a given size.
|
||||
/// </summary>
|
||||
/// <param name="sourceSize">Size of the full thumbnail source.</param>
|
||||
public void SwitchToAbsolute(Size sourceSize) {
|
||||
if (!Relative)
|
||||
return;
|
||||
|
||||
var absoluteBounds = new Rectangle {
|
||||
X = _bounds.X,
|
||||
Y = _bounds.Y,
|
||||
Width = (sourceSize.Width - _bounds.Width) - _bounds.X,
|
||||
Height = (sourceSize.Height - _bounds.Height) - _bounds.Y
|
||||
};
|
||||
|
||||
Bounds = absoluteBounds;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format("({0}, {1})", _bounds, (Relative) ? "relative" : "absolute");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -49,7 +49,7 @@ namespace OnTopReplica {
|
|||
MessagingMethods.PostMessage(child, WM.LBUTTONUP, new IntPtr(MK.LBUTTON), lParamClickLocation);
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine("Left click on window #" + child.ToString() + " at " + clientLocation.ToString());
|
||||
System.Diagnostics.Debug.WriteLine("Left click on window #" + child.ToString() + " at " + clientLocation.ToString());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ namespace OnTopReplica {
|
|||
MessagingMethods.PostMessage(child, WM.RBUTTONUP, new IntPtr(MK.RBUTTON), lParamClickLocation);
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine("Right click on window #" + child.ToString() + " at " + clientLocation.ToString());
|
||||
System.Diagnostics.Debug.WriteLine("Right click on window #" + child.ToString() + " at " + clientLocation.ToString());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ namespace OnTopReplica {
|
|||
MessagingMethods.PostMessage(child, WM.LBUTTONDBLCLK, new IntPtr(MK.LBUTTON), lParamClickLocation);
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine("Double left click on window #" + child.ToString() + " at " + clientLocation.ToString());
|
||||
System.Diagnostics.Debug.WriteLine("Double left click on window #" + child.ToString() + " at " + clientLocation.ToString());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ namespace OnTopReplica {
|
|||
MessagingMethods.PostMessage(child, WM.RBUTTONDBLCLK, new IntPtr(MK.RBUTTON), lParamClickLocation);
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine("Double right click on window #" + child.ToString() + " at " + clientLocation.ToString());
|
||||
System.Diagnostics.Debug.WriteLine("Double right click on window #" + child.ToString() + " at " + clientLocation.ToString());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -95,7 +95,12 @@ namespace OnTopReplica {
|
|||
#region Object override
|
||||
|
||||
public override string ToString() {
|
||||
return _title;
|
||||
if (string.IsNullOrWhiteSpace(_title)) {
|
||||
return string.Format("#{0}", _handle.ToInt64());
|
||||
}
|
||||
else {
|
||||
return string.Format("#{0} ({1})", _handle.ToInt64(), _title);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) {
|
||||
|
|
|
@ -96,10 +96,10 @@ namespace OnTopReplica {
|
|||
parent.DropDownItems.Add(nullRegionItem);
|
||||
|
||||
//Video detector
|
||||
var detectorItem = new ToolStripMenuItem("Autodetect plugin");
|
||||
/*var detectorItem = new ToolStripMenuItem("Autodetect plugin");
|
||||
detectorItem.Tag = parentHandle;
|
||||
detectorItem.Click += MenuVideoCropperClickHandler;
|
||||
parent.DropDownItems.Add(detectorItem);
|
||||
parent.DropDownItems.Add(detectorItem);*/
|
||||
|
||||
//Regions (if any)
|
||||
if (regions == null || regions.Length == 0)
|
||||
|
@ -135,10 +135,10 @@ namespace OnTopReplica {
|
|||
var tsi = (ToolStripMenuItem)sender;
|
||||
var tuple = (Tuple<WindowHandle, StoredRegion>)tsi.Tag;
|
||||
_owner.SetThumbnail(tuple.Item1,
|
||||
(tuple.Item2 != null) ? (System.Drawing.Rectangle?)tuple.Item2.Bounds : null);
|
||||
(tuple.Item2 != null) ? (ThumbnailRegion)tuple.Item2.Region : null);
|
||||
}
|
||||
|
||||
PluginRegionLocator _pluginRegionLocator = null;
|
||||
/*PluginRegionLocator _pluginRegionLocator = null;
|
||||
|
||||
private void MenuVideoCropperClickHandler(object sender, EventArgs args){
|
||||
CommonClickHandler();
|
||||
|
@ -151,7 +151,7 @@ namespace OnTopReplica {
|
|||
|
||||
var detectedRegion = _pluginRegionLocator.LocatePluginRegion(handle);
|
||||
_owner.SetThumbnail(handle, detectedRegion);
|
||||
}
|
||||
}*/
|
||||
|
||||
private void CommonClickHandler() {
|
||||
_windowsMenu.Close();
|
||||
|
|
Loading…
Reference in a new issue