Added relative border padding to command line parsing.

Improved command line documentation.
Refactored some command line type conversion classes.
This commit is contained in:
Lorenz Cuno Klopfenstein 2012-11-14 16:46:20 +01:00
parent 9544a97d4b
commit 7e1daf59d2
5 changed files with 112 additions and 54 deletions

View file

@ -179,6 +179,8 @@
<Compile Include="SidePanels\GroupSwitchPanel.Designer.cs">
<DependentUpon>GroupSwitchPanel.cs</DependentUpon>
</Compile>
<Compile Include="StartupOptions\FourValueTypeConverter.cs" />
<Compile Include="StartupOptions\PaddingConverter.cs" />
<Compile Include="Strings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>

View file

@ -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<long>("windowId=", "Window handle ({HWND}) to be cloned.", id => {
options.WindowId = new IntPtr(id);
})
.Add<string>("windowTitle=", "{TITLE} of the window to be cloned.", s => {
.Add<string>("windowTitle=", "Partial {TITLE} of the window to be cloned.", s => {
options.WindowTitle = s;
})
.Add<string>("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>("size=", "Target {SIZE} of the cloned thumbnail.", s => {
.Add<Size>("size=", "Target {WIDTH,HEIGHT} of the cloned thumbnail.", s => {
options.StartSize = s;
})
.Add<Size>("position=", "Target {COORDINATES} of the OnTopReplica window.", s => {
.Add<Size>("position=", "Target {X,Y} of the OnTopReplica window.", s => {
options.StartLocation = new Point(s.Width, s.Height);
options.StartScreenPosition = null;
})
.Add<ScreenPosition>("screenPosition=", "Resolution independent window position on current screen, with locking (TR|TL|C|BR|BL).", pos => {
.Add<ScreenPosition>("screenPosition=", "Resolution independent window position on current screen, with locking. Values: {TR|TL|C|BR|BL}.", pos => {
options.StartLocation = null;
options.StartScreenPosition = pos;
})
.Add<Rectangle>("r|region=", "Region {BOUNDS} of the cloned window.", region => {
.Add<Rectangle>("r|region=", "Region {X,Y,W,H} of the cloned window.", region => {
options.Region = new ThumbnailRegion(region);
})
.Add<System.Windows.Forms.Padding>("p|padding=", "Padding {BOUNDS} of the clone.", padding => {
.Add<System.Windows.Forms.Padding>("p|padding=", "Region padding {LEFT,TOP,RIGHT,BOTTOM} of the clone.", padding => {
options.Region = new ThumbnailRegion(padding);
})
.Add<byte>("o|opacity=", "Opacity of the window (0-255).", opacity => {
.Add<byte>("o|opacity=", "Opacity of the window: {0-255}.", opacity => {
options.Opacity = opacity;
})
.Add("clickForwarding", "Enables click forwarding.", s => {

View file

@ -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<T> : 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*(?<one>\\d*)\\s*,\\s*(?<two>\\d*)\\s*,\\s*(?<three>\\d*)\\s*,\\s*(?<four>\\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);
}
}

View file

@ -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<Padding> {
protected override Padding CreateValue(int v1, int v2, int v3, int v4) {
return new Padding {
Left = v1,
Top = v2,
Right = v3,
Bottom = v4
};
}
}
}

View file

@ -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<Rectangle> {
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*(?<x>\\d*)\\s*,\\s*(?<y>\\d*)\\s*,\\s*(?<width>\\d*)\\s*,\\s*(?<height>\\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
};
}
}
}