[MouseJump][CQ]Refactor "common" classes into a separate project (#34333)

* [Mouse Jump] - moving common code to MouseJump.Common project - #25482

* [Mouse Jump] - fixing warnings in MouseJump.Common - #25482

* [MouseJump] - cherrypick 5653b4 - Exclude MouseJump Common tests from the checks

# Conflicts:
#	src/modules/MouseUtils/MouseJump.Common.UnitTests/MouseJump.Common.UnitTests.csproj

* [mOuSEjUMP] - cherry pick 61aab9 - Fix ci build issues

# Conflicts:
#	src/modules/MouseUtils/MouseJump.Common.UnitTests/MouseJump.Common.UnitTests.csproj

* [Mouse Jump] - remove project type guids - #25482

* [Mouse Jump] - simplify mousejump *.csproj files - #25482

* [Mouse Jump] - fixing broken tests - #25482

* [Mouse Jump] - fixing broken build - #25482

* [Mouse Jump] - editing MouseJump.Common.UnitTests.csproj - #25482

* [Mouse Jump] - editing MouseJump.Common.csproj (UseWindowsForms=true) - #25482

* [Mouse Jump] - fixing spellcheck - #25482

* [MouseJump] - enabled implicit usings - #25482

* [Mouse Jump] - re-add csproj attributes - #27511

* ci: Fix signing of Common dll

---------

Co-authored-by: Clayton <mike.clayton@delinian.com>
This commit is contained in:
Michael Clayton
2024-10-21 17:38:07 +01:00
committed by GitHub
parent db3c8e621e
commit dc7c7ef2b7
87 changed files with 281 additions and 308 deletions

View File

@@ -0,0 +1,73 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace MouseJump.Common.Models.Drawing;
public sealed class BoxBounds
{
/*
see https://www.w3schools.com/css/css_boxmodel.asp
+--------------[bounds]---------------+
|▒▒▒▒▒▒▒▒▒▒▒▒▒▒[margin]▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒|
|▒▒▓▓▓▓▓▓▓▓▓▓▓▓[border]▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒|
|▒▒▓▓░░░░░░░░░░[padding]░░░░░░░░░░▓▓▒▒|
|▒▒▓▓░░ ░░▓▓▒▒|
|▒▒▓▓░░ ░░▓▓▒▒|
|▒▒▓▓░░ [content] ░░▓▓▒▒|
|▒▒▓▓░░ ░░▓▓▒▒|
|▒▒▓▓░░ ░░▓▓▒▒|
|▒▒▓▓░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▓▓▒▒|
|▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒|
|▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒|
+-------------------------------------+
*/
public BoxBounds(
RectangleInfo outerBounds,
RectangleInfo marginBounds,
RectangleInfo borderBounds,
RectangleInfo paddingBounds,
RectangleInfo contentBounds)
{
this.OuterBounds = outerBounds ?? throw new ArgumentNullException(nameof(outerBounds));
this.MarginBounds = marginBounds ?? throw new ArgumentNullException(nameof(marginBounds));
this.BorderBounds = borderBounds ?? throw new ArgumentNullException(nameof(borderBounds));
this.PaddingBounds = paddingBounds ?? throw new ArgumentNullException(nameof(paddingBounds));
this.ContentBounds = contentBounds ?? throw new ArgumentNullException(nameof(contentBounds));
}
/// <summary>
/// Gets the outer bounds of this layout box.
/// </summary>
public RectangleInfo OuterBounds
{
get;
}
public RectangleInfo MarginBounds
{
get;
}
public RectangleInfo BorderBounds
{
get;
}
public RectangleInfo PaddingBounds
{
get;
}
/// <summary>
/// Gets the bounds of the content area for this layout box.
/// </summary>
public RectangleInfo ContentBounds
{
get;
}
}

View File

@@ -0,0 +1,77 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace MouseJump.Common.Models.Drawing;
/// <summary>
/// Immutable version of a System.Drawing.Point object with some extra utility methods.
/// </summary>
public sealed class PointInfo
{
public PointInfo(decimal x, decimal y)
{
this.X = x;
this.Y = y;
}
public PointInfo(Point point)
: this(point.X, point.Y)
{
}
public decimal X
{
get;
}
public decimal Y
{
get;
}
/// <summary>
/// Moves this PointInfo inside the specified RectangleInfo.
/// </summary>
public PointInfo Clamp(RectangleInfo outer)
{
return new(
x: Math.Clamp(this.X, outer.X, outer.Right),
y: Math.Clamp(this.Y, outer.Y, outer.Bottom));
}
public PointInfo Scale(decimal scalingFactor) => new(this.X * scalingFactor, this.Y * scalingFactor);
public PointInfo Offset(PointInfo amount) => new(this.X + amount.X, this.Y + amount.Y);
public Point ToPoint() => new((int)this.X, (int)this.Y);
public SizeInfo ToSize()
{
return new((int)this.X, (int)this.Y);
}
/// <summary>
/// Stretches the point to the same proportional position in targetBounds as
/// it currently is in sourceBounds
/// </summary>
public PointInfo Stretch(RectangleInfo source, RectangleInfo target)
{
return new PointInfo(
x: ((this.X - source.X) / source.Width * target.Width) + target.X,
y: ((this.Y - source.Y) / source.Height * target.Height) + target.Y);
}
public PointInfo Truncate() =>
new(
(int)this.X,
(int)this.Y);
public override string ToString()
{
return "{" +
$"{nameof(this.X)}={this.X}," +
$"{nameof(this.Y)}={this.Y}" +
"}";
}
}

View File

@@ -0,0 +1,299 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Text.Json.Serialization;
using MouseJump.Common.Models.Styles;
using BorderStyle = MouseJump.Common.Models.Styles.BorderStyle;
namespace MouseJump.Common.Models.Drawing;
/// <summary>
/// Immutable version of a System.Drawing.Rectangle object with some extra utility methods.
/// </summary>
public sealed class RectangleInfo
{
public static readonly RectangleInfo Empty = new(0, 0, 0, 0);
public RectangleInfo(decimal x, decimal y, decimal width, decimal height)
{
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
}
public RectangleInfo(Rectangle rectangle)
: this(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height)
{
}
public RectangleInfo(Point location, SizeInfo size)
: this(location.X, location.Y, size.Width, size.Height)
{
}
public RectangleInfo(SizeInfo size)
: this(0, 0, size.Width, size.Height)
{
}
public decimal X
{
get;
}
public decimal Y
{
get;
}
public decimal Width
{
get;
}
public decimal Height
{
get;
}
[JsonIgnore]
public decimal Left =>
this.X;
[JsonIgnore]
public decimal Top =>
this.Y;
[JsonIgnore]
public decimal Right =>
this.X + this.Width;
[JsonIgnore]
public decimal Bottom =>
this.Y + this.Height;
[JsonIgnore]
public decimal Area =>
this.Width * this.Height;
[JsonIgnore]
public PointInfo Location =>
new(this.X, this.Y);
[JsonIgnore]
public PointInfo Midpoint =>
new(
x: this.X + (this.Width / 2),
y: this.Y + (this.Height / 2));
[JsonIgnore]
public SizeInfo Size => new(this.Width, this.Height);
/// <summary>
/// Centers the rectangle around a specified point.
/// </summary>
/// <param name="point">The <see cref="PointInfo"/> around which the rectangle will be centered.</param>
/// <returns>A new <see cref="RectangleInfo"/> that is centered around the specified point.</returns>
public RectangleInfo Center(PointInfo point) =>
new(
x: point.X - (this.Width / 2),
y: point.Y - (this.Height / 2),
width: this.Width,
height: this.Height);
/// <summary>
/// Returns a new <see cref="RectangleInfo"/> that is moved within the bounds of the specified outer rectangle.
/// If the current rectangle is larger than the outer rectangle, an exception is thrown.
/// </summary>
/// <param name="outer">The outer <see cref="RectangleInfo"/> within which to confine this rectangle.</param>
/// <returns>A new <see cref="RectangleInfo"/> that is the result of moving this rectangle within the bounds of the outer rectangle.</returns>
/// <exception cref="ArgumentException">Thrown when the current rectangle is larger than the outer rectangle.</exception>
public RectangleInfo Clamp(RectangleInfo outer)
{
if ((this.Width > outer.Width) || (this.Height > outer.Height))
{
throw new ArgumentException($"Value cannot be larger than {nameof(outer)}.");
}
return new(
x: Math.Clamp(this.X, outer.X, outer.Right - this.Width),
y: Math.Clamp(this.Y, outer.Y, outer.Bottom - this.Height),
width: this.Width,
height: this.Height);
}
/// <remarks>
/// Adapted from https://github.com/dotnet/runtime
/// See https://github.com/dotnet/runtime/blob/dfd618dc648ba9b11dd0f8034f78113d69f223cd/src/libraries/System.Drawing.Primitives/src/System/Drawing/Rectangle.cs
/// </remarks>
public bool Contains(decimal x, decimal y) =>
this.X <= x && x < this.X + this.Width && this.Y <= y && y < this.Y + this.Height;
/// <remarks>
/// Adapted from https://github.com/dotnet/runtime
/// See https://github.com/dotnet/runtime/blob/dfd618dc648ba9b11dd0f8034f78113d69f223cd/src/libraries/System.Drawing.Primitives/src/System/Drawing/Rectangle.cs
/// </remarks>
public bool Contains(PointInfo pt) =>
this.Contains(pt.X, pt.Y);
/// <remarks>
/// Adapted from https://github.com/dotnet/runtime
/// See https://github.com/dotnet/runtime/blob/dfd618dc648ba9b11dd0f8034f78113d69f223cd/src/libraries/System.Drawing.Primitives/src/System/Drawing/Rectangle.cs
/// </remarks>
public bool Contains(RectangleInfo rect) =>
(this.X <= rect.X) && (rect.X + rect.Width <= this.X + this.Width) &&
(this.Y <= rect.Y) && (rect.Y + rect.Height <= this.Y + this.Height);
/// <summary>
/// Returns a new <see cref="RectangleInfo"/> that is larger than the current rectangle.
/// The dimensions of the new rectangle are calculated by enlarging the current rectangle's dimensions by the size of the border.
/// </summary>
/// <param name="border">The <see cref="BorderStyle"/> that specifies the amount to enlarge the rectangle on each side.</param>
/// <returns>A new <see cref="RectangleInfo"/> that is larger than the current rectangle by the specified border amounts.</returns>
public RectangleInfo Enlarge(BorderStyle border) =>
new(
this.X - border.Left,
this.Y - border.Top,
this.Width + border.Horizontal,
this.Height + border.Vertical);
/// <summary>
/// Returns a new <see cref="RectangleInfo"/> that is larger than the current rectangle.
/// The dimensions of the new rectangle are calculated by enlarging the current rectangle's dimensions by the size of the margin.
/// </summary>
/// <param name="margin">The <see cref="MarginStyle"/> that specifies the amount to enlarge the rectangle on each side.</param>
/// <returns>A new <see cref="RectangleInfo"/> that is larger than the current rectangle by the specified margin amounts.</returns>
public RectangleInfo Enlarge(MarginStyle margin) =>
new(
this.X - margin.Left,
this.Y - margin.Top,
this.Width + margin.Horizontal,
this.Height + margin.Vertical);
/// <summary>
/// Returns a new <see cref="RectangleInfo"/> that is larger than the current rectangle.
/// The dimensions of the new rectangle are calculated by enlarging the current rectangle's dimensions by the size of the padding.
/// </summary>
/// <param name="padding">The <see cref="PaddingStyle"/> that specifies the amount to enlarge the rectangle on each side.</param>
/// <returns>A new <see cref="RectangleInfo"/> that is larger than the current rectangle by the specified padding amounts.</returns>
public RectangleInfo Enlarge(PaddingStyle padding) =>
new(
this.X - padding.Left,
this.Y - padding.Top,
this.Width + padding.Horizontal,
this.Height + padding.Vertical);
/// <summary>
/// Returns a new <see cref="RectangleInfo"/> that is offset by the specified amount.
/// </summary>
/// <param name="amount">The <see cref="SizeInfo"/> representing the amount to offset in both the X and Y directions.</param>
/// <returns>A new <see cref="RectangleInfo"/> that is offset by the specified amount.</returns>
public RectangleInfo Offset(SizeInfo amount) =>
this.Offset(amount.Width, amount.Height);
/// <summary>
/// Returns a new <see cref="RectangleInfo"/> that is offset by the specified X and Y distances.
/// </summary>
/// <param name="dx">The distance to offset the rectangle along the X-axis.</param>
/// <param name="dy">The distance to offset the rectangle along the Y-axis.</param>
/// <returns>A new <see cref="RectangleInfo"/> that is offset by the specified X and Y distances.</returns>
public RectangleInfo Offset(decimal dx, decimal dy) =>
new(this.X + dx, this.Y + dy, this.Width, this.Height);
/// <summary>
/// Returns a new <see cref="RectangleInfo"/> that is a scaled version of the current rectangle.
/// The dimensions of the new rectangle are calculated by multiplying the current rectangle's dimensions by the scaling factor.
/// </summary>
/// <param name="scalingFactor">The factor by which to scale the rectangle's dimensions.</param>
/// <returns>A new <see cref="RectangleInfo"/> that is a scaled version of the current rectangle.</returns>
public RectangleInfo Scale(decimal scalingFactor) =>
new(
this.X * scalingFactor,
this.Y * scalingFactor,
this.Width * scalingFactor,
this.Height * scalingFactor);
/// <summary>
/// Returns a new <see cref="RectangleInfo"/> that is smaller than the current rectangle.
/// The dimensions of the new rectangle are calculated by shrinking the current rectangle's dimensions by the size of the border.
/// </summary>
/// <param name="border">The <see cref="BorderStyle"/> that specifies the amount to shrink the rectangle on each side.</param>
/// <returns>A new <see cref="RectangleInfo"/> that is smaller than the current rectangle by the specified border amounts.</returns>
public RectangleInfo Shrink(BorderStyle border) =>
new(
this.X + border.Left,
this.Y + border.Top,
this.Width - border.Horizontal,
this.Height - border.Vertical);
/// <summary>
/// Returns a new <see cref="RectangleInfo"/> that is smaller than the current rectangle.
/// The dimensions of the new rectangle are calculated by shrinking the current rectangle's dimensions by the size of the margin.
/// </summary>
/// <param name="margin">The <see cref="MarginStyle"/> that specifies the amount to shrink the rectangle on each side.</param>
/// <returns>A new <see cref="RectangleInfo"/> that is smaller than the current rectangle by the specified margin amounts.</returns>
public RectangleInfo Shrink(MarginStyle margin) =>
new(
this.X + margin.Left,
this.Y + margin.Top,
this.Width - margin.Horizontal,
this.Height - margin.Vertical);
/// <summary>
/// Returns a new <see cref="RectangleInfo"/> that is smaller than the current rectangle.
/// The dimensions of the new rectangle are calculated by shrinking the current rectangle's dimensions by the size of the padding.
/// </summary>
/// <param name="padding">The <see cref="PaddingStyle"/> that specifies the amount to shrink the rectangle on each side.</param>
/// <returns>A new <see cref="RectangleInfo"/> that is smaller than the current rectangle by the specified padding amounts.</returns>
public RectangleInfo Shrink(PaddingStyle padding) =>
new(
this.X + padding.Left,
this.Y + padding.Top,
this.Width - padding.Horizontal,
this.Height - padding.Vertical);
/// <summary>
/// Returns a new <see cref="RectangleInfo"/> where the X, Y, Width, and Height properties of the current rectangle are truncated to integers.
/// </summary>
/// <returns>A new <see cref="RectangleInfo"/> with the X, Y, Width, and Height properties of the current rectangle truncated to integers.</returns>
public RectangleInfo Truncate() =>
new(
(int)this.X,
(int)this.Y,
(int)this.Width,
(int)this.Height);
/// <remarks>
/// Adapted from https://github.com/dotnet/runtime
/// See https://github.com/dotnet/runtime/blob/dfd618dc648ba9b11dd0f8034f78113d69f223cd/src/libraries/System.Drawing.Primitives/src/System/Drawing/Rectangle.cs
/// </remarks>
public RectangleInfo Union(RectangleInfo rect)
{
var x1 = Math.Min(this.X, rect.X);
var x2 = Math.Max(this.X + this.Width, rect.X + rect.Width);
var y1 = Math.Min(this.Y, rect.Y);
var y2 = Math.Max(this.Y + this.Height, rect.Y + rect.Height);
return new RectangleInfo(x1, y1, x2 - x1, y2 - y1);
}
public Rectangle ToRectangle() =>
new(
(int)this.X,
(int)this.Y,
(int)this.Width,
(int)this.Height);
public override string ToString()
{
return "{" +
$"{nameof(this.Left)}={this.Left}," +
$"{nameof(this.Top)}={this.Top}," +
$"{nameof(this.Width)}={this.Width}," +
$"{nameof(this.Height)}={this.Height}" +
"}";
}
}

View File

@@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace MouseJump.Common.Models.Drawing;
/// <summary>
/// Immutable version of a System.Windows.Forms.Screen object so we don't need to
/// take a dependency on WinForms just for screen info.
/// </summary>
public sealed class ScreenInfo
{
public ScreenInfo(int handle, bool primary, RectangleInfo displayArea, RectangleInfo workingArea)
{
this.Handle = handle;
this.Primary = primary;
this.DisplayArea = displayArea ?? throw new ArgumentNullException(nameof(displayArea));
this.WorkingArea = workingArea ?? throw new ArgumentNullException(nameof(workingArea));
}
public int Handle
{
get;
}
public bool Primary
{
get;
}
public RectangleInfo DisplayArea
{
get;
}
public RectangleInfo WorkingArea
{
get;
}
}

View File

@@ -0,0 +1,154 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using MouseJump.Common.Models.Styles;
using BorderStyle = MouseJump.Common.Models.Styles.BorderStyle;
namespace MouseJump.Common.Models.Drawing;
/// <summary>
/// Immutable version of a System.Drawing.Size object with some extra utility methods.
/// </summary>
public sealed class SizeInfo
{
public SizeInfo(decimal width, decimal height)
{
this.Width = width;
this.Height = height;
}
public SizeInfo(Size size)
: this(size.Width, size.Height)
{
}
public decimal Width
{
get;
}
public decimal Height
{
get;
}
public SizeInfo Enlarge(BorderStyle border) =>
new(
this.Width + border.Horizontal,
this.Height + border.Vertical);
public SizeInfo Enlarge(PaddingStyle padding) =>
new(
this.Width + padding.Horizontal,
this.Height + padding.Vertical);
/// <summary>
/// Calculates the intersection of this size with another size, resulting in a size that represents
/// the overlapping dimensions. Both sizes must be non-negative.
/// </summary>
/// <param name="size">The size to intersect with this instance.</param>
/// <returns>A new <see cref="SizeInfo"/> instance representing the intersection of the two sizes.</returns>
/// <exception cref="ArgumentException">Thrown when either this size or the specified size has negative dimensions.</exception>
public SizeInfo Intersect(SizeInfo size)
{
if ((this.Width < 0) || (this.Height < 0) || (size.Width < 0) || (size.Height < 0))
{
throw new ArgumentException("Sizes must be non-negative");
}
return new(
Math.Min(this.Width, size.Width),
Math.Min(this.Height, size.Height));
}
/// <summary>
/// Creates a new <see cref="SizeInfo"/> instance with the width and height negated, effectively inverting its dimensions.
/// </summary>
/// <returns>A new <see cref="SizeInfo"/> instance with inverted dimensions.</returns>
public SizeInfo Invert() =>
new(-this.Width, -this.Height);
public SizeInfo Scale(decimal scalingFactor) => new(
this.Width * scalingFactor,
this.Height * scalingFactor);
public SizeInfo Shrink(BorderStyle border) =>
new(this.Width - border.Horizontal, this.Height - border.Vertical);
public SizeInfo Shrink(MarginStyle margin) =>
new(this.Width - margin.Horizontal, this.Height - margin.Vertical);
public SizeInfo Shrink(PaddingStyle padding) =>
new(this.Width - padding.Horizontal, this.Height - padding.Vertical);
/// <summary>
/// Creates a new <see cref="RectangleInfo"/> instance representing a rectangle with this size,
/// positioned at the specified coordinates.
/// </summary>
/// <param name="x">The x-coordinate of the upper-left corner of the rectangle.</param>
/// <param name="y">The y-coordinate of the upper-left corner of the rectangle.</param>
/// <returns>A new <see cref="RectangleInfo"/> instance representing the positioned rectangle.</returns>
public RectangleInfo PlaceAt(decimal x, decimal y) =>
new(x, y, this.Width, this.Height);
/// <summary>
/// Scales this size to fit within the bounds of another size, while maintaining the aspect ratio.
/// </summary>
/// <param name="bounds">The size to fit this size into.</param>
/// <returns>A new <see cref="SizeInfo"/> instance representing the scaled size.</returns>
public SizeInfo ScaleToFit(SizeInfo bounds)
{
var widthRatio = bounds.Width / this.Width;
var heightRatio = bounds.Height / this.Height;
return widthRatio.CompareTo(heightRatio) switch
{
< 0 => new(bounds.Width, this.Height * widthRatio),
0 => bounds,
> 0 => new(this.Width * heightRatio, bounds.Height),
};
}
/// <summary>
/// Rounds down the width and height of this size to the nearest whole number.
/// </summary>
/// <returns>A new <see cref="SizeInfo"/> instance with floored dimensions.</returns>
public SizeInfo Floor()
{
return new SizeInfo(
Math.Floor(this.Width),
Math.Floor(this.Height));
}
/// <summary>
/// Calculates the scaling ratio needed to fit this size within the bounds of another size without distorting the aspect ratio.
/// </summary>
/// <param name="bounds">The size to fit this size into.</param>
/// <returns>The scaling ratio as a decimal.</returns>
/// <exception cref="ArgumentException">Thrown if the width or height of the bounds is zero.</exception>
public decimal ScaleToFitRatio(SizeInfo bounds)
{
if (bounds.Width == 0 || bounds.Height == 0)
{
throw new ArgumentException($"{nameof(bounds.Width)} or {nameof(bounds.Height)} cannot be zero", nameof(bounds));
}
var widthRatio = bounds.Width / this.Width;
var heightRatio = bounds.Height / this.Height;
var scalingRatio = Math.Min(widthRatio, heightRatio);
return scalingRatio;
}
public Size ToSize() => new((int)this.Width, (int)this.Height);
public Point ToPoint() => new((int)this.Width, (int)this.Height);
public override string ToString()
{
return "{" +
$"{nameof(this.Width)}={this.Width}," +
$"{nameof(this.Height)}={this.Height}" +
"}";
}
}

View File

@@ -0,0 +1,131 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.ObjectModel;
using MouseJump.Common.Models.Drawing;
using MouseJump.Common.Models.Styles;
namespace MouseJump.Common.Models.Layout;
public sealed class PreviewLayout
{
public sealed class Builder
{
public Builder()
{
this.Screens = new();
this.ScreenshotBounds = new();
}
public PreviewStyle? PreviewStyle
{
get;
set;
}
public RectangleInfo? VirtualScreen
{
get;
set;
}
public List<RectangleInfo> Screens
{
get;
set;
}
public int ActivatedScreenIndex
{
get;
set;
}
public RectangleInfo? FormBounds
{
get;
set;
}
public BoxBounds? PreviewBounds
{
get;
set;
}
public List<BoxBounds> ScreenshotBounds
{
get;
set;
}
public PreviewLayout Build()
{
return new PreviewLayout(
previewStyle: this.PreviewStyle ?? throw new InvalidOperationException($"{nameof(this.PreviewStyle)} must be initialized before calling {nameof(this.Build)}."),
virtualScreen: this.VirtualScreen ?? throw new InvalidOperationException($"{nameof(this.VirtualScreen)} must be initialized before calling {nameof(this.Build)}."),
screens: this.Screens ?? throw new InvalidOperationException($"{nameof(this.Screens)} must be initialized before calling {nameof(this.Build)}."),
activatedScreenIndex: this.ActivatedScreenIndex,
formBounds: this.FormBounds ?? throw new InvalidOperationException($"{nameof(this.FormBounds)} must be initialized before calling {nameof(this.Build)}."),
previewBounds: this.PreviewBounds ?? throw new InvalidOperationException($"{nameof(this.PreviewBounds)} must be initialized before calling {nameof(this.Build)}."),
screenshotBounds: this.ScreenshotBounds ?? throw new InvalidOperationException($"{nameof(this.ScreenshotBounds)} must be initialized before calling {nameof(this.Build)}."));
}
}
public PreviewLayout(
PreviewStyle previewStyle,
RectangleInfo virtualScreen,
List<RectangleInfo> screens,
int activatedScreenIndex,
RectangleInfo formBounds,
BoxBounds previewBounds,
List<BoxBounds> screenshotBounds)
{
this.PreviewStyle = previewStyle ?? throw new ArgumentNullException(nameof(previewStyle));
this.VirtualScreen = virtualScreen ?? throw new ArgumentNullException(nameof(virtualScreen));
this.Screens = (screens ?? throw new ArgumentNullException(nameof(screens)))
.ToList().AsReadOnly();
this.ActivatedScreenIndex = activatedScreenIndex;
this.FormBounds = formBounds ?? throw new ArgumentNullException(nameof(formBounds));
this.PreviewBounds = previewBounds ?? throw new ArgumentNullException(nameof(previewBounds));
this.ScreenshotBounds = (screenshotBounds ?? throw new ArgumentNullException(nameof(screenshotBounds)))
.ToList().AsReadOnly();
}
public PreviewStyle PreviewStyle
{
get;
}
public RectangleInfo VirtualScreen
{
get;
}
public ReadOnlyCollection<RectangleInfo> Screens
{
get;
}
public int ActivatedScreenIndex
{
get;
}
public RectangleInfo FormBounds
{
get;
}
public BoxBounds PreviewBounds
{
get;
}
public ReadOnlyCollection<BoxBounds> ScreenshotBounds
{
get;
}
}

View File

@@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace MouseJump.Common.Models.Styles;
/// <summary>
/// Represents the background fill style for a drawing object.
/// </summary>
public sealed class BackgroundStyle
{
public static readonly BackgroundStyle Empty = new(
Color.Transparent,
Color.Transparent
);
public BackgroundStyle(
Color? color1,
Color? color2)
{
this.Color1 = color1;
this.Color2 = color2;
}
public Color? Color1
{
get;
}
public Color? Color2
{
get;
}
public override string ToString()
{
return "{" +
$"{nameof(this.Color1)}={this.Color1}," +
$"{nameof(this.Color2)}={this.Color2}" +
"}";
}
}

View File

@@ -0,0 +1,77 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace MouseJump.Common.Models.Styles;
/// <summary>
/// Represents the border style for a drawing object.
/// </summary>
public sealed class BorderStyle
{
public static readonly BorderStyle Empty = new(Color.Transparent, 0, 0);
public BorderStyle(Color color, decimal all, decimal depth)
: this(color, all, all, all, all, depth)
{
}
public BorderStyle(Color color, decimal left, decimal top, decimal right, decimal bottom, decimal depth)
{
this.Color = color;
this.Left = left;
this.Top = top;
this.Right = right;
this.Bottom = bottom;
this.Depth = depth;
}
public Color Color
{
get;
}
public decimal Left
{
get;
}
public decimal Top
{
get;
}
public decimal Right
{
get;
}
public decimal Bottom
{
get;
}
/// <summary>
/// Gets the "depth" of the 3d highlight and shadow effect on the border.
/// </summary>
public decimal Depth
{
get;
}
public decimal Horizontal => this.Left + this.Right;
public decimal Vertical => this.Top + this.Bottom;
public override string ToString()
{
return "{" +
$"{nameof(this.Color)}={this.Color}," +
$"{nameof(this.Left)}={this.Left}," +
$"{nameof(this.Top)}={this.Top}," +
$"{nameof(this.Right)}={this.Right}," +
$"{nameof(this.Bottom)}={this.Bottom}," +
$"{nameof(this.Depth)}={this.Depth}" +
"}";
}
}

View File

@@ -0,0 +1,77 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace MouseJump.Common.Models.Styles;
/// <summary>
/// Represents the styles to apply to a simple box-layout based drawing object.
/// </summary>
public sealed class BoxStyle
{
/*
see https://www.w3schools.com/css/css_boxmodel.asp
+--------------[bounds]---------------+
|▒▒▒▒▒▒▒▒▒▒▒▒▒▒[margin]▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒|
|▒▒▓▓▓▓▓▓▓▓▓▓▓▓[border]▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒|
|▒▒▓▓░░░░░░░░░░[padding]░░░░░░░░░░▓▓▒▒|
|▒▒▓▓░░ ░░▓▓▒▒|
|▒▒▓▓░░ ░░▓▓▒▒|
|▒▒▓▓░░ [content] ░░▓▓▒▒|
|▒▒▓▓░░ ░░▓▓▒▒|
|▒▒▓▓░░ ░░▓▓▒▒|
|▒▒▓▓░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▓▓▒▒|
|▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒|
|▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒|
+-------------------------------------+
*/
public static readonly BoxStyle Empty = new(MarginStyle.Empty, BorderStyle.Empty, PaddingStyle.Empty, BackgroundStyle.Empty);
public BoxStyle(
MarginStyle marginStyle,
BorderStyle borderStyle,
PaddingStyle paddingStyle,
BackgroundStyle backgroundStyle)
{
this.MarginStyle = marginStyle ?? throw new ArgumentNullException(nameof(marginStyle));
this.BorderStyle = borderStyle ?? throw new ArgumentNullException(nameof(borderStyle));
this.PaddingStyle = paddingStyle ?? throw new ArgumentNullException(nameof(paddingStyle));
this.BackgroundStyle = backgroundStyle ?? throw new ArgumentNullException(nameof(backgroundStyle));
}
/// <summary>
/// Gets the margin style for this layout box.
/// </summary>
public MarginStyle MarginStyle
{
get;
}
/// <summary>
/// Gets the border style for this layout box.
/// </summary>
public BorderStyle BorderStyle
{
get;
}
/// <summary>
/// Gets the padding style for this layout box.
/// </summary>
public PaddingStyle PaddingStyle
{
get;
}
/// <summary>
/// Gets the background fill style for the content area of this layout box.
/// </summary>
public BackgroundStyle BackgroundStyle
{
get;
}
}

View File

@@ -0,0 +1,60 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace MouseJump.Common.Models.Styles;
/// <summary>
/// Represents the margin style for a drawing object.
/// </summary>
public sealed class MarginStyle
{
public static readonly MarginStyle Empty = new(0);
public MarginStyle(decimal all)
: this(all, all, all, all)
{
}
public MarginStyle(decimal left, decimal top, decimal right, decimal bottom)
{
this.Left = left;
this.Top = top;
this.Right = right;
this.Bottom = bottom;
}
public decimal Left
{
get;
}
public decimal Top
{
get;
}
public decimal Right
{
get;
}
public decimal Bottom
{
get;
}
public decimal Horizontal => this.Left + this.Right;
public decimal Vertical => this.Top + this.Bottom;
public override string ToString()
{
return "{" +
$"{nameof(this.Left)}={this.Left}," +
$"{nameof(this.Top)}={this.Top}," +
$"{nameof(this.Right)}={this.Right}," +
$"{nameof(this.Bottom)}={this.Bottom}" +
"}";
}
}

View File

@@ -0,0 +1,60 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace MouseJump.Common.Models.Styles;
/// <summary>
/// Represents the margin style for a drawing object.
/// </summary>
public sealed class PaddingStyle
{
public static readonly PaddingStyle Empty = new(0);
public PaddingStyle(decimal all)
: this(all, all, all, all)
{
}
public PaddingStyle(decimal left, decimal top, decimal right, decimal bottom)
{
this.Left = left;
this.Top = top;
this.Right = right;
this.Bottom = bottom;
}
public decimal Left
{
get;
}
public decimal Top
{
get;
}
public decimal Right
{
get;
}
public decimal Bottom
{
get;
}
public decimal Horizontal => this.Left + this.Right;
public decimal Vertical => this.Top + this.Bottom;
public override string ToString()
{
return "{" +
$"{nameof(this.Left)}={this.Left}," +
$"{nameof(this.Top)}={this.Top}," +
$"{nameof(this.Right)}={this.Right}," +
$"{nameof(this.Bottom)}={this.Bottom}" +
"}";
}
}

View File

@@ -0,0 +1,35 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using MouseJump.Common.Models.Drawing;
namespace MouseJump.Common.Models.Styles;
public sealed class PreviewStyle
{
public PreviewStyle(
SizeInfo canvasSize,
BoxStyle canvasStyle,
BoxStyle screenStyle)
{
this.CanvasSize = canvasSize ?? throw new ArgumentNullException(nameof(canvasSize));
this.CanvasStyle = canvasStyle ?? throw new ArgumentNullException(nameof(canvasStyle));
this.ScreenStyle = screenStyle ?? throw new ArgumentNullException(nameof(screenStyle));
}
public SizeInfo CanvasSize
{
get;
}
public BoxStyle CanvasStyle
{
get;
}
public BoxStyle ScreenStyle
{
get;
}
}