From 7e1daf59d277d4e4006664a0b53bcf712bed5126 Mon Sep 17 00:00:00 2001 From: Lorenz Cuno Klopfenstein Date: Wed, 14 Nov 2012 16:46:20 +0100 Subject: [PATCH] Added relative border padding to command line parsing. Improved command line documentation. Refactored some command line type conversion classes. --- OnTopReplica/OnTopReplica.csproj | 2 + OnTopReplica/StartupOptions/Factory.cs | 16 +++-- .../StartupOptions/FourValueTypeConverter.cs | 71 +++++++++++++++++++ .../StartupOptions/PaddingConverter.cs | 21 ++++++ .../StartupOptions/RectangleConverter.cs | 56 +++------------ 5 files changed, 112 insertions(+), 54 deletions(-) create mode 100644 OnTopReplica/StartupOptions/FourValueTypeConverter.cs create mode 100644 OnTopReplica/StartupOptions/PaddingConverter.cs diff --git a/OnTopReplica/OnTopReplica.csproj b/OnTopReplica/OnTopReplica.csproj index 851ded4..3d0c03b 100644 --- a/OnTopReplica/OnTopReplica.csproj +++ b/OnTopReplica/OnTopReplica.csproj @@ -179,6 +179,8 @@ GroupSwitchPanel.cs + + True True diff --git a/OnTopReplica/StartupOptions/Factory.cs b/OnTopReplica/StartupOptions/Factory.cs index dbc0a5e..9bc3ec5 100644 --- a/OnTopReplica/StartupOptions/Factory.cs +++ b/OnTopReplica/StartupOptions/Factory.cs @@ -6,6 +6,7 @@ using System.Drawing; using System.ComponentModel; using OnTopReplica.Properties; using OnTopReplica.WindowSeekers; +using System.Windows.Forms; namespace OnTopReplica.StartupOptions { class Factory { @@ -15,6 +16,7 @@ namespace OnTopReplica.StartupOptions { TypeDescriptor.AddAttributes(typeof(Size), new TypeConverterAttribute(typeof(SizeConverter))); TypeDescriptor.AddAttributes(typeof(ScreenPosition), new TypeConverterAttribute(typeof(ScreenPositionConverter))); TypeDescriptor.AddAttributes(typeof(Rectangle), new TypeConverterAttribute(typeof(RectangleConverter))); + TypeDescriptor.AddAttributes(typeof(Padding), new TypeConverterAttribute(typeof(PaddingConverter))); } public static Options CreateOptions(string[] args) { @@ -58,7 +60,7 @@ namespace OnTopReplica.StartupOptions { .Add("windowId=", "Window handle ({HWND}) to be cloned.", id => { options.WindowId = new IntPtr(id); }) - .Add("windowTitle=", "{TITLE} of the window to be cloned.", s => { + .Add("windowTitle=", "Partial {TITLE} of the window to be cloned.", s => { options.WindowTitle = s; }) .Add("windowClass=", "{CLASS} of the window to be cloned.", s => { @@ -67,24 +69,24 @@ namespace OnTopReplica.StartupOptions { .Add("v|visible", "If set, only clones windows that are visible.", s => { options.MustBeVisible = true; }) - .Add("size=", "Target {SIZE} of the cloned thumbnail.", s => { + .Add("size=", "Target {WIDTH,HEIGHT} of the cloned thumbnail.", s => { options.StartSize = s; }) - .Add("position=", "Target {COORDINATES} of the OnTopReplica window.", s => { + .Add("position=", "Target {X,Y} of the OnTopReplica window.", s => { options.StartLocation = new Point(s.Width, s.Height); options.StartScreenPosition = null; }) - .Add("screenPosition=", "Resolution independent window position on current screen, with locking (TR|TL|C|BR|BL).", pos => { + .Add("screenPosition=", "Resolution independent window position on current screen, with locking. Values: {TR|TL|C|BR|BL}.", pos => { options.StartLocation = null; options.StartScreenPosition = pos; }) - .Add("r|region=", "Region {BOUNDS} of the cloned window.", region => { + .Add("r|region=", "Region {X,Y,W,H} of the cloned window.", region => { options.Region = new ThumbnailRegion(region); }) - .Add("p|padding=", "Padding {BOUNDS} of the clone.", padding => { + .Add("p|padding=", "Region padding {LEFT,TOP,RIGHT,BOTTOM} of the clone.", padding => { options.Region = new ThumbnailRegion(padding); }) - .Add("o|opacity=", "Opacity of the window (0-255).", opacity => { + .Add("o|opacity=", "Opacity of the window: {0-255}.", opacity => { options.Opacity = opacity; }) .Add("clickForwarding", "Enables click forwarding.", s => { diff --git a/OnTopReplica/StartupOptions/FourValueTypeConverter.cs b/OnTopReplica/StartupOptions/FourValueTypeConverter.cs new file mode 100644 index 0000000..17029d4 --- /dev/null +++ b/OnTopReplica/StartupOptions/FourValueTypeConverter.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel; +using System.Text.RegularExpressions; + +namespace OnTopReplica.StartupOptions { + abstract class FourValueTypeConverter : TypeConverter { + + public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { + if (value != null) { + var sVal = value.ToString(); + return Convert(sVal); + } + else + return base.ConvertFrom(context, culture, value); + } + + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { + return sourceType == typeof(string); + } + + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { + return destinationType == typeof(T); + } + + public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { + if (value != null && destinationType == typeof(T)) { + var sVal = value.ToString(); + return Convert(sVal); + } + else + return base.ConvertTo(context, culture, value, destinationType); + } + + static Regex _sizeRegex = new Regex("^\\D*(?\\d*)\\s*,\\s*(?\\d*)\\s*,\\s*(?\\d*)\\s*,\\s*(?\\d*)\\D*$", + RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.Singleline); + + private T Convert(string s) { + var match = _sizeRegex.Match(s); + + var v1 = match.Groups["one"]; + var v2 = match.Groups["two"]; + var v3 = match.Groups["three"]; + var v4 = match.Groups["four"]; + + if (match.Success && v1.Success && v2.Success && v3.Success && v4.Success) { + int v1v, v2v, v3v, v4v; + bool v1b, v2b, v3b, v4b; + v1b = Int32.TryParse(v1.Value, out v1v); + v2b = Int32.TryParse(v2.Value, out v2v); + v3b = Int32.TryParse(v3.Value, out v3v); + v4b = Int32.TryParse(v4.Value, out v4v); + + if (v1b && v2b && v3b && v4b) { + return CreateValue(v1v, v2v, v3v, v4v); + } + else { + throw new ArgumentException("Argument '" + s + "' contains a non numeric value."); + } + } + else { + throw new ArgumentException("Argument '" + s + "' is in the wrong format."); + } + } + + protected abstract T CreateValue(int v1, int v2, int v3, int v4); + + } +} diff --git a/OnTopReplica/StartupOptions/PaddingConverter.cs b/OnTopReplica/StartupOptions/PaddingConverter.cs new file mode 100644 index 0000000..777394f --- /dev/null +++ b/OnTopReplica/StartupOptions/PaddingConverter.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel; +using System.Windows.Forms; + +namespace OnTopReplica.StartupOptions { + class PaddingConverter : FourValueTypeConverter { + + protected override Padding CreateValue(int v1, int v2, int v3, int v4) { + return new Padding { + Left = v1, + Top = v2, + Right = v3, + Bottom = v4 + }; + } + + } +} diff --git a/OnTopReplica/StartupOptions/RectangleConverter.cs b/OnTopReplica/StartupOptions/RectangleConverter.cs index 00c8608..624fee1 100644 --- a/OnTopReplica/StartupOptions/RectangleConverter.cs +++ b/OnTopReplica/StartupOptions/RectangleConverter.cs @@ -6,56 +6,18 @@ using System.Drawing; using System.Text.RegularExpressions; namespace OnTopReplica.StartupOptions { - class RectangleConverter : TypeConverter { - public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { - if (value != null) { - var sVal = value.ToString(); - return Convert(sVal); - } - else - return base.ConvertFrom(context, culture, value); - } + class RectangleConverter : FourValueTypeConverter { - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { - return sourceType == typeof(string); - } - - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { - return destinationType == typeof(Rectangle); - } - - public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { - if (value != null && destinationType == typeof(Rectangle)) { - var sVal = value.ToString(); - return Convert(sVal); - } - else - return base.ConvertTo(context, culture, value, destinationType); - } - - static Regex _sizeRegex = new Regex("^\\D*(?\\d*)\\s*,\\s*(?\\d*)\\s*,\\s*(?\\d*)\\s*,\\s*(?\\d*)\\D*$", - RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.Singleline); - - private Rectangle Convert(string s) { - var match = _sizeRegex.Match(s); - - var x = match.Groups["x"]; - var y = match.Groups["y"]; - var width = match.Groups["width"]; - var height = match.Groups["height"]; - - if (match.Success && x.Success && y.Success && width.Success && height.Success) { - var xVal = int.Parse(x.Value); - var yVal = int.Parse(y.Value); - var widthVal = int.Parse(width.Value); - var heightVal = int.Parse(height.Value); - - return new Rectangle(xVal, yVal, widthVal, heightVal); - } - else - throw new ArgumentException("Cannot convert '" + s + "' to rectangle."); + protected override Rectangle CreateValue(int v1, int v2, int v3, int v4) { + return new Rectangle { + X = v1, + Y = v2, + Width = v3, + Height = v4 + }; } } + }