Initial commit

This commit is contained in:
Sven Vogel 2021-06-09 18:43:27 +02:00
commit 6aab892c4a
147 changed files with 7564 additions and 0 deletions

13
.idea/.idea.Matrix App/.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/contentModel.xml
/projectSettingsUpdater.xml
/.idea.Matrix App.iml
/modules.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

View File

@ -0,0 +1 @@
Matrix App

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

Binary file not shown.

BIN
.vs/Matrix App/v16/.suo Normal file

Binary file not shown.

25
Matrix App.sln Normal file
View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31019.35
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Matrix App", "Matrix App\Matrix App.csproj", "{1B6B0187-6BD0-467C-AA23-E120717F576D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1B6B0187-6BD0-467C-AA23-E120717F576D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1B6B0187-6BD0-467C-AA23-E120717F576D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1B6B0187-6BD0-467C-AA23-E120717F576D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1B6B0187-6BD0-467C-AA23-E120717F576D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5EE2B33C-2AE6-4DFC-AEDB-FD5A688EA5B0}
EndGlobalSection
EndGlobal

99
Matrix App/BasicTheme.cs Normal file
View File

@ -0,0 +1,99 @@
using System.Drawing;
using System.Windows.Forms;
namespace Matrix_App
{
public class BasicTheme
{
public Color Foreground { get; set; }
public Color Background { get; set; }
public Color ButtonBackground { get; set; }
public Color ButtonBorder { get; set; }
public Color TextFieldBackground { get; set; }
public bool IsFlat { get; set; }
protected BasicTheme()
{
}
public void ApplyTheme(Control control)
{
foreach (Control c in control.Controls)
{
this.ApplyTheme(c);
}
control.BackColor = this.Background;
control.ForeColor = this.Foreground;
if (control is Button button)
{
button.FlatStyle = FlatStyle.Flat;
button.BackColor = this.ButtonBackground;
button.FlatAppearance.BorderColor = this.ButtonBorder;
}
else if (control is GroupBox group)
{
group.FlatStyle = FlatStyle.Flat;
}
else if (control is TextBox box)
{
box.BackColor = this.TextFieldBackground;
box.Margin = new Padding(4, 4, 4, 4);
if (this.IsFlat)
{
box.BorderStyle = BorderStyle.FixedSingle;
}
else if (!(control.Parent is ComboBox || control.Parent is NumericUpDown))
{
box.BorderStyle = BorderStyle.FixedSingle;
}
}
else if (control is NumericUpDown upDown)
{
upDown.Margin = new Padding(4, 4, 4, 4);
upDown.BackColor = this.TextFieldBackground;
if (this.IsFlat)
{
upDown.BorderStyle = BorderStyle.None;
}
else
{
upDown.BorderStyle = BorderStyle.Fixed3D;
}
}
else if (control is ComboBox combos)
{
if (this.IsFlat)
{
combos.FlatStyle = FlatStyle.Flat;
}
else
{
combos.FlatStyle = FlatStyle.System;
}
combos.Margin = new Padding(4, 4, 4, 4);
combos.BackColor = this.ButtonBackground;
}
else if (control is RichTextBox richText)
{
if (this.IsFlat)
{
richText.BorderStyle = BorderStyle.None;
}
else
{
richText.BorderStyle = BorderStyle.Fixed3D;
}
richText.BackColor = this.TextFieldBackground;
}
}
}
}

738
Matrix App/ColorWheel.Designer.cs generated Normal file
View File

@ -0,0 +1,738 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace Matrix_App
{
partial class ColorWheel
{
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.IContainer components = null;
private static readonly int WHEEL_PIXEL_RESOLUTION = 256;
private static readonly int WHEEL_BORDER_SUBDIVISIONS = 6;
private static readonly float RADIUS = WHEEL_PIXEL_RESOLUTION / (float) WHEEL_BORDER_SUBDIVISIONS * 4 * 0.5f;
private Bitmap wheel;
/// transformed triangle vertices in screen space
private PointF[] transformed = new PointF[3];
/// triangle verticies in object "local" space
private PointF[] vertices = {
new PointF(RADIUS * fcos(0), RADIUS * fsin(0) ),
new PointF(RADIUS * fcos(120), RADIUS * fsin(120)),
new PointF(RADIUS * fcos(240), RADIUS * fsin(240))
};
/// gradient between the fully saturated and brightned tone color and white (desaturated)
private LinearGradientBrush whiteGradient;
/// gradient between black and transparent, darkens the corner in which value = 0
private LinearGradientBrush colorGradient;
/// gradient between transparent and gray
private LinearGradientBrush grayGradient;
// stored HSV values
private float angle = 180;
private float saturation = 1f;
private float value = 1f;
// current cursor position
private Point cursor = new Point();
private Point origCursor = new Point();
public EventHandler handler;
private int sRGB = 0;
private Boolean entered = false;
private Boolean release = true;
/// <summary>
/// Slider types:
/// <ul>
/// <li>TRIANGLE: for the center triangle</li>
/// <li>WHEEL: for the outside "wheel" controlling the tone</li>
/// </ul>
/// </summary>
private enum Slider
{
TRIANGLE,
WHEEL
}
private Slider selection = Slider.TRIANGLE;
private System.Drawing.Drawing2D.Matrix transform;
private float ctheta;
#region Math-utils
/// convert degrees to radians
/// by mapping [0, 360] to [0, 2pi]
private static float ToRadians(float degree)
{
// about equal to pi / 180
const float PI_OVER_180 = 0.0174532925199f;
return degree * PI_OVER_180;
}
/// convert radians to degrees
/// by mapping [0, 2pi] to [0, 360]
private static float ToDegree(float radians)
{
// about equal to 180 / pi
const float HUNDERETEIGTHY_OVER_PI = 57.2957795131f;
return radians * HUNDERETEIGTHY_OVER_PI;
}
/// Calculates the cosine of degrees as a float
private static float fcos(float degree)
{
return MathF.Cos(ToRadians(degree));
}
/// Calculates the sine of degrees as a float
private static float fsin(float degree)
{
return MathF.Sin(ToRadians(degree));
}
/// <summary>
/// Dotproduct of a and b
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
private float dot(in PointF a, in PointF b)
{
return a.X * b.X + a.Y + b.Y;
}
/// Calculates the hypotenuse of a and b
/// as sqrt(a² + b²)
private static float hypot(float a, float b)
{
return MathF.Sqrt(a * a + b * b);
}
/// Divides the floor of the sum of a and b by 2
private static int floorMiddle(float a, float b)
{
return (int)(a + b) >> 1;
}
/// <summary>
/// Computes the traingle area of the pointes a,b,(x | y)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
private float triangleArea(PointF a, PointF b, float x, float y)
{
return MathF.Abs((a.X - x) * (b.Y - y)
- (b.X - x) * (a.Y - y));
}
/// <summary>
/// Tests if the point (x | y) lies inside of the transformed triangle
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
private bool triangleIntersect(double x, double y)
{
int originalArea = (int)triangleArea(transformed[1], transformed[2], transformed[0].X, transformed[0].Y);
int area1 = (int)triangleArea(transformed[0], transformed[1], (float)x, (float)y);
int area2 = (int)triangleArea(transformed[1], transformed[2], (float)x, (float)y);
int area3 = (int)triangleArea(transformed[2], transformed[0], (float)x, (float)y);
return Math.Abs(area1 + area2 + area3 - originalArea) < 3;
}
/// <summary>
/// Convert cartesian coordinates (point p) to barycentric coordinates (u,v,w) relative to triangle with verticies a,b,c
/// </summary>
/// <param name="p"></param>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="c"></param>
/// <param name="u"></param>
/// <param name="v"></param>
/// <param name="w"></param>
private void cartesianToBarycnetric(in PointF p, in PointF a, in PointF b, in PointF c, out float u, out float v, out float w)
{
var v0 = subtract(b, a);
var v1 = subtract(c, a);
var v2 = subtract(p, a);
float denom = v0.X * v1.Y - v1.X * v0.Y;
v = (v2.X * v1.Y - v1.X * v2.Y) / denom;
w = (v0.X * v2.Y - v2.X * v0.Y) / denom;
u = 1.0f - v - w;
}
/// <summary>
/// Clamp barycentric coordinates of toClamp to the triangle specified by a,b,c, so that for every barycenttric coordinates is:
/// u + v + w == 0 and none of u,v,w is greater than 1 or less than zero.
/// </summary>
/// <param name="toClamp"></param>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="c"></param>
private void clampToBarycentricCoordinates(ref PointF toClamp, in PointF a, in PointF b, in PointF c)
{
cartesianToBarycnetric(toClamp, a, b, c, out float u, out float v, out float w);
clampBarycentric(ref u, ref v, ref w);
barycentricToCartesian(ref toClamp, a, b, c, u, v, w);
}
/// <summary>
/// Convert barycentric coordinates u,v,w relative to triangle with verticies a,b,c to cartesian coordinates.
/// </summary>
/// <param name="toClamp"></param>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="c"></param>
/// <param name="u"></param>
/// <param name="v"></param>
/// <param name="w"></param>
private void barycentricToCartesian(ref PointF toClamp, PointF a, PointF b, PointF c, float u, float v, float w)
{
toClamp.X = a.X * u + b.X * v + c.X * w;
toClamp.Y = a.Y * u + b.Y * v + c.Y * w;
}
/// <summary>
/// Clamp x to the range [0, 1]
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
private float saturate(float x)
{
return MathF.Max(MathF.Min(x, 1.0f), 0.0f);
}
/// <summary>
/// Clamp the barycentric coordinates, so that
/// u + v + w == 1
/// without any of u,v,w being greater than 1 or less than zero.
/// </summary>
/// <param name="u"></param>
/// <param name="v"></param>
/// <param name="w"></param>
private void clampBarycentric(ref float u, ref float v, ref float w)
{
u = saturate(u);
v = saturate(v);
w = 1 - u - v;
u = saturate(u);
w = saturate(w);
v = 1 - u - w;
v = saturate(v);
w = saturate(w);
u = 1 - v - w;
}
/// <summary>
/// Linearlly interpolate between x and y by factor k
/// If k == 0 then 100% of x and 0% of y
/// If k == 1 then 0% of x and 100% of y
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="k"></param>
/// <returns></returns>
private float lerp(float x, float y, float k)
{
return x * (1 - k) + y * k;
}
/// <summary>
/// Normalize point f, so that its length is 1
/// </summary>
/// <param name="b"></param>
private void normalize(ref PointF b)
{
float length = hypot(b.X, b.Y);
b.X = b.X / length;
b.Y = b.Y / length;
}
/// <summary>
/// Subtract point a from b, so that the result is (x0 - x1 | y0 - y1)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
private PointF subtract(in PointF a, in PointF b)
{
var result = new PointF();
result.X = a.X - b.X;
result.Y = a.Y - b.Y;
return result;
}
/// <summary>
/// Convert from HSV color space to sRGB.
/// s,v are expected to be in range [0, 1].
/// h is expected to be in range [0, 1].
/// Any other values results in undefiened behavior
/// </summary>
/// <param name="h"></param>
/// <param name="s"></param>
/// <param name="v"></param>
/// <returns></returns>
private int sRGBfromHSV(float h, float s, float v)
{
float c = v * s;
float x = c * (1.0f - Math.Abs((h / 60.0f) % 2.0f - 1.0f));
float m = v - c;
float r = 0, g = 0, b = 0;
if (h < 60) { r = c; g = x; b = 0; }
else if (h < 120) { r = x; g = c; b = 0; }
else if (h < 180) { r = 0; g = c; b = x; }
else if (h < 240) { r = 0; g = x; b = c; }
else if (h < 300) { r = x; g = 0; b = c; }
else { r = c; g = 0; b = x; }
return 0xFF << 24 |
(int)((r + m) * 255.0f) << 16 |
(int)((g + m) * 255.0f) << 8 |
(int)((b + m) * 255.0f);
}
/// <summary>
/// Convert sRGB color space to HSV
/// </summary>
/// <param name="r"></param>
/// <param name="g"></param>
/// <param name="b"></param>
private void HSVfromRGB(byte r, byte g, byte b)
{
const float INV_255 = 0.00392156862745f;
float R = r * INV_255;
float G = g * INV_255;
float B = b * INV_255;
byte Cmax = Math.Max(Math.Max(r, g), b);
byte Cmin = Math.Min(Math.Min(r, g), b);
float delta = (Cmax - Cmin) * INV_255;
if (delta < 1e-2)
{
angle = 0;
}
else if (Cmax == r)
{
if (G < B)
{
angle = 360 - MathF.Abs(60 * ((G - B) / delta));
}
else
{
angle = 60 * ((G - B) / delta + 0f);
}
}
else if (Cmax == g)
{
angle = 60 * ((B - R) / delta + 2f);
}
else if (Cmax == b)
{
angle = 60 * ((R - G) / delta + 4f);
}
saturation = delta / Cmax * 255.0f;
if (Cmax == 0)
{
saturation = 0;
}
value = Cmax * INV_255;
}
#endregion
protected override void OnCreateControl()
{
base.OnCreateControl();
BackColorChanged += (a, b) => generateWheel();
grayGradient = new LinearGradientBrush(
// point A
new Point((int)vertices[0].X,
(int)vertices[0].Y),
// point B
new Point(floorMiddle(vertices[2].X, vertices[1].X),
floorMiddle(vertices[2].Y, vertices[1].Y)),
Color.Red,
Color.Gray
);
whiteGradient = new LinearGradientBrush(
// point A
new Point((int)vertices[2].X,
(int)vertices[2].Y),
// point B
new Point(floorMiddle(vertices[0].X, vertices[1].X),
floorMiddle(vertices[0].Y, vertices[1].Y)),
Color.White,
Color.Transparent
);
colorGradient = new LinearGradientBrush(
// point A
new Point((int)vertices[1].X,
(int)vertices[1].Y),
// point B
new Point(floorMiddle(vertices[2].X, vertices[0].X),
floorMiddle(vertices[2].Y, vertices[0].Y)),
Color.Black,
Color.Transparent
);
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.DoubleBuffer,
true);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(OnMouseMove);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(OnMouseDown);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(OnMouseUp);
generateWheel();
setRGB(0, 0, 0);
}
private void OnMouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
release = true;
}
private void OnMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
release = false;
entered = true;
}
private void OnMouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
double u = e.X / (double)this.Width * 2.0 - 1.0;
double v = e.Y / (double)this.Height * 2.0 - 1.0;
double theta = Math.Atan2(v, u);
double radius = Math.Sqrt(u * u + v * v);
if (entered)
{
selection = Slider.WHEEL;
if (radius < 0.6)
{
selection = Slider.TRIANGLE;
}
entered = false;
}
else if (!release)
{
if (selection == Slider.TRIANGLE)
{
if (transform != null)
{
PointF tempCursor = new PointF(e.X, e.Y);
clampToBarycentricCoordinates(ref tempCursor, transformed[0], transformed[1], transformed[2]);
if (true)
{
cursor.X = (int)tempCursor.X;
cursor.Y = (int)tempCursor.Y;
origCursor.X = cursor.X;
origCursor.Y = cursor.Y;
ctheta = angle;
cartesianToBarycnetric(cursor, transformed[0], transformed[1], transformed[2], out float bu, out float bv, out float bw);
value = MathF.Round(MathF.Max(MathF.Min(1.0f - bv, 1.0f), 0.0f) * 1e2f) / 1e2f;
saturation = MathF.Round(MathF.Max(MathF.Min(bu, 1.0f), 0.0f) * 1e2f) / 1e2f;
}
}
}
else
{
angle = ToDegree((float)theta);
grayGradient = new LinearGradientBrush(
new Point((int)vertices[0].X,
(int)vertices[0].Y),
new Point(floorMiddle(vertices[2].X, vertices[1].X),
floorMiddle(vertices[2].Y, vertices[1].Y)
),
Color.FromArgb(sRGBfromHSV(180 + angle, 1, 1)),
Color.Gray
);
PointF[] c = { new PointF(origCursor.X, origCursor.Y) };
transform.Reset();
transform.RotateAt(angle - ctheta, new Point(this.Width >> 1, this.Height >> 1));
transform.TransformPoints(c);
cursor.X = (int)c[0].X;
cursor.Y = (int)c[0].Y;
}
sRGB = sRGBfromHSV(angle + 180, saturation, value);
this.Refresh();
handler.Invoke(this, null);
}
}
/// <summary>
/// Generate the color wheel "wheel" texture
/// </summary>
private void generateWheel()
{
wheel = new Bitmap(WHEEL_PIXEL_RESOLUTION, WHEEL_PIXEL_RESOLUTION);
wheel.MakeTransparent(); // make transparent
var g = Graphics.FromImage(wheel);
// draw tone gradient by varying hue by the current angle of the pixel relative to the origin
for (int x = wheel.Width; x-- > -1;)
{
float u = x / (float)wheel.Width * 2.0f - 1.0f;
for (int y = wheel.Height; y-- > -1;)
{
float v = y / (float)wheel.Height * 2.0f - 1.0f;
// cartesian to polar
float theta = ToDegree(MathF.Atan2(v, u) + MathF.PI);
int rgb = sRGBfromHSV(theta, 1.0f, 1.0f);
// draw pixel
g.FillRectangle(new SolidBrush(Color.FromArgb(rgb)), x, y, 1, 1);
}
}
var step = wheel.Width / WHEEL_BORDER_SUBDIVISIONS;
var strip = (int)Math.Sqrt(wheel.Width * wheel.Width + wheel.Height * wheel.Height) - wheel.Width;
// cut out center circle
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.FillEllipse(new SolidBrush(this.BackColor), new Rectangle(step, step, step * (WHEEL_BORDER_SUBDIVISIONS - 2), step * (WHEEL_BORDER_SUBDIVISIONS - 2)));
g.DrawEllipse(new Pen(new SolidBrush(this.BackColor), strip), new Rectangle(-strip / 2, -strip / 2, wheel.Width + strip, wheel.Height + strip));
g.Dispose();
}
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
/// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
var g = e.Graphics;
// adjust for arbitrary component scale
float scaleX = this.Width / (float) wheel.Width;
float scaleY = this.Height / (float) wheel.Height;
// transform local verticies to screen space
g.ScaleTransform(scaleX, scaleY);
g.DrawImage(wheel, new Point(0, 0));
g.ResetTransform();
g.RotateTransform(angle);
float step = (wheel.Width / (float) WHEEL_BORDER_SUBDIVISIONS * (WHEEL_BORDER_SUBDIVISIONS - 3));
float off = WHEEL_PIXEL_RESOLUTION / (float)(WHEEL_BORDER_SUBDIVISIONS - 2) * scaleX;
g.ScaleTransform(wheel.Width / (float) Width * 4 / 6, wheel.Width / (float) Width * 4 / 6);
g.TranslateTransform(wheel.Width * scaleX * 0.5f, wheel.Width * scaleX * 0.5f, MatrixOrder.Append);
transformed[0].X = vertices[0].X;
transformed[0].Y = vertices[0].Y;
transformed[1].X = vertices[1].X;
transformed[1].Y = vertices[1].Y;
transformed[2].X = vertices[2].X;
transformed[2].Y = vertices[2].Y;
g.Transform.TransformPoints(transformed);
// draw triangle
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.FillPolygon(grayGradient, vertices);
g.FillPolygon(whiteGradient, vertices);
g.FillPolygon(colorGradient, vertices);
// paint hue line
g.DrawLine(new Pen(new SolidBrush(Color.Black), 2.0f), vertices[0].X, vertices[0].Y, vertices[0].X + RADIUS / 2, vertices[0].Y);
// paint bordered shadowed cursor
g.ResetTransform();
transform = g.Transform;
g.FillEllipse(new SolidBrush(Color.FromArgb(-2013265920)), new Rectangle(cursor.X - 10, cursor.Y - 10, 22, 22));
g.FillEllipse(new SolidBrush(Color.White), new Rectangle(cursor.X - 10, cursor.Y - 10, 20, 20));
g.FillEllipse(new SolidBrush(Color.FromArgb(sRGB)), new Rectangle(cursor.X - 8, cursor.Y - 8, 16, 16));
}
#region Getter-Setter
public int getRGB()
{
return sRGB;
}
public int getRed()
{
return sRGB >> 16 & 0xFF;
}
public int getGreen()
{
return sRGB >> 8 & 0xFF;
}
public int getBlue()
{
return sRGB & 0xFF;
}
public float getHue()
{
return angle;
}
public float getSaturation()
{
return saturation;
}
public float getValue()
{
return value;
}
public void setHue(float hue)
{
angle = hue;
showHSV();
}
public void setSaturation(float s)
{
saturation = s;
showHSV();
}
public void setValue(float v)
{
value = v;
showHSV();
}
public void setRGB(byte red, byte green, byte blue)
{
HSVfromRGB(red, green, blue);
showHSV();
}
#endregion
/// <summary>
/// Show the color wheel and recompute triangle gradient
/// and calculate new cursor position
/// </summary>
private void showHSV()
{
// get sRGB color
sRGB = sRGBfromHSV(angle, saturation, value);
// recompute correct triangle vertex transformation
// to screen space
System.Drawing.Drawing2D.Matrix m = new System.Drawing.Drawing2D.Matrix();
transformed[0].X = vertices[0].X;
transformed[0].Y = vertices[0].Y;
transformed[1].X = vertices[1].X;
transformed[1].Y = vertices[1].Y;
transformed[2].X = vertices[2].X;
transformed[2].Y = vertices[2].Y;
// adjust for custom component width
float scaleX = this.Width / (float)wheel.Width;
float scaleY = this.Height / (float)wheel.Height;
m.Rotate(angle - 180);
float step = (wheel.Width / (float)WHEEL_BORDER_SUBDIVISIONS * (WHEEL_BORDER_SUBDIVISIONS - 3));
float off = WHEEL_PIXEL_RESOLUTION / (float)(WHEEL_BORDER_SUBDIVISIONS - 2) * scaleX;
m.Scale(wheel.Width / (float)Width * 4 / 6, wheel.Width / (float)Width * 4 / 6);
m.Translate(wheel.Width * scaleX * 0.5f, wheel.Width * scaleX * 0.5f, MatrixOrder.Append);
transformed[0].X = vertices[0].X;
transformed[0].Y = vertices[0].Y;
transformed[1].X = vertices[1].X;
transformed[1].Y = vertices[1].Y;
transformed[2].X = vertices[2].X;
transformed[2].Y = vertices[2].Y;
m.TransformPoints(transformed);
// linearly interpolate cursor location according to saturation
origCursor.X = (int)lerp(transformed[2].X, transformed[0].X, saturation);
origCursor.Y = (int)lerp(transformed[2].Y, transformed[0].Y, saturation);
// linearly interpolate cursor location according to value
origCursor.X = (int)lerp(transformed[1].X, origCursor.X, value);
origCursor.Y = (int)lerp(transformed[1].Y, origCursor.Y, value);
// apply cursor location
cursor.X = origCursor.X;
cursor.Y = origCursor.Y;
// recompute new gradient for mixing fully saturated color with gray
sRGB = sRGBfromHSV(angle, saturation, value);
grayGradient = new LinearGradientBrush(new Point((int)vertices[0].X, (int)vertices[0].Y), new Point((int)(vertices[2].X + vertices[1].X) / 2, (int)(vertices[2].Y + vertices[1].Y) / 2), Color.FromArgb(sRGBfromHSV(angle, 1f, 1f)), Color.Gray);
// adjust angle values
angle -= 180;
ctheta = angle;
// repaint
this.Refresh();
}
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
}
}
}

13
Matrix App/ColorWheel.cs Normal file
View File

@ -0,0 +1,13 @@

using System.Windows.Forms;
namespace Matrix_App
{
public partial class ColorWheel : UserControl
{
public ColorWheel()
{
InitializeComponent();
}
}
}

120
Matrix App/ColorWheel.resx Normal file
View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

49
Matrix App/Defaults.cs Normal file
View File

@ -0,0 +1,49 @@

namespace MatrixDesigner
{
public sealed class Defaults
{
public static readonly int PORT_NAME_UPDATE_INTERVAL = 5000;
public static readonly int MATRIX_START_WIDTH = 10;
public static readonly int MATRIX_START_HEIGHT = 10;
public static readonly int MATRIX_START_FRAMES = 1;
public static readonly int MATRIX_LIMITED_WIDTH = 512;
public static readonly int MATRIX_LIMITED_HEIGHT = 512;
public static readonly int BAUD_RATE = 9600;
public static readonly int READ_TIMEOUT_MS = 5500;
public static readonly int WRITE_TIMEOUT_MS = 5500;
/// <summary>
/// Total count of LEDs at start
/// </summary>
public static readonly int MATRIX_START_LED_COUNT = MATRIX_START_WIDTH * MATRIX_START_HEIGHT * BPP;
/// <summary>
/// Number of Bytes Per Pixel: 3 cause Red (1 byte) + Blue (1 Byte) + Green (1 byte) = 3
/// </summary>
public static readonly int BPP = 3;
public static readonly int FILTER_PREVIEW_WIDTH = 32;
public static readonly int FILTER_PREVIEW_HEIGHT = 32;
public static readonly int ARDUINO_SUCCESS_BYTE = 21;
public static readonly int ARDUINO_COMMAND_QUEUE_SIZE = 5;
public static readonly int ARDUINO_RECIVCE_BUFFER_SIZE = 1 + 1 + 1 + MATRIX_LIMITED_WIDTH * MATRIX_LIMITED_HEIGHT;
public static readonly int DEQUEUE_WAIT_TIMEOUT_COUNTER = 2;
}
public sealed class ArduinoInstruction
{
public static readonly byte OPCODE_SCALE = 0;
// public static readonly byte OPCODE_SINGLE = 1;
public static readonly byte OPCODE_IMAGE = 2;
public static readonly byte OPCODE_FILL = 3;
public static readonly byte OPCODE_CONFIG = 4;
}
}

View File

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Text;
namespace Matrix_App
{
class DirectBitmap : IDisposable
{
public Bitmap Bitmap { get; private set; }
public Int32[] Bits { get; private set; }
public bool Disposed { get; private set; }
public int Height { get; private set; }
public int Width { get; private set; }
protected GCHandle BitsHandle { get; private set; }
public DirectBitmap(int width, int height)
{
Width = width;
Height = height;
Bits = new Int32[width * height];
BitsHandle = GCHandle.Alloc(Bits, GCHandleType.Pinned);
Bitmap = new Bitmap(width, height, width * 4, PixelFormat.Format32bppPArgb, BitsHandle.AddrOfPinnedObject());
}
public void SetPixel(int x, int y, Color colour)
{
int index = x + (y * Width);
int col = colour.ToArgb();
Bits[index] = col;
}
public void SetImage(Bitmap image)
{
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
Bits[x + y * Width] = image.GetPixel(x, y).ToArgb();
}
}
}
public Color GetPixel(int x, int y)
{
int index = x + (y * Width);
int col = Bits[index];
Color result = Color.FromArgb(col);
return result;
}
public void Dispose()
{
if (Disposed) return;
Disposed = true;
Bitmap.Dispose();
BitsHandle.Free();
}
}
}

View File

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Text;
using static MatrixDesigner.Defaults;
namespace Matrix_App
{
public static class GifGeneratorUtils
{
public static float Dot(in float x0, in float y0, in float x1, in float y1)
{
return x0 * x1 + y0 * y1;
}
public static void CartesianToPolar(in float x, in float y, out float theta, out float r)
{
r = MathF.Sqrt(x * x + y * y);
theta = MathF.Atan2(y, x);
}
public static void PolarToCartesian(in float theta, in float r, out float x, out float y)
{
x = MathF.Sin(theta) * r;
y = MathF.Cos(theta) * r;
}
public static void Normalize(ref float x, ref float y)
{
var len = MathF.Sqrt(x * x + y * y);
x /= len;
y /= len;
}
public static void RgbFromHsv(float h, float s, float v, out float r, out float g, out float b)
{
var c = v * s;
var x = c * (1.0f - Math.Abs((h / 60.0f) % 2.0f - 1.0f));
var m = v - c;
if (h < 60) { r = c; g = x; b = 0; }
else if (h < 120) { r = x; g = c; b = 0; }
else if (h < 180) { r = 0; g = c; b = x; }
else if (h < 240) { r = 0; g = x; b = c; }
else if (h < 300) { r = x; g = 0; b = c; }
else { r = c; g = 0; b = x; }
r += m;
g += m;
b += m;
}
public static void HsvFromRgb(float r, float g, float b, out float h, out float s, out float v)
{
var cmax = Math.Max(Math.Max(r, g), b);
var cmin = Math.Min(Math.Min(r, g), b);
var delta = cmax - cmin;
if (delta < 1e-2)
{
h = 0;
}
else if (MathF.Abs(cmax - r) < 1e-3)
{
if (r < b)
{
h = 360 - MathF.Abs(60 * ((g - b) / delta));
}
else
{
h = 60 * ((g - b) / delta + 0f);
}
}
else if (MathF.Abs(cmax - g) < 1e-3)
{
h = 60 * ((b - r) / delta + 2f);
}
else if (MathF.Abs(cmax - b) < 1e-3)
{
h = 60 * ((r - g) / delta + 4f);
} else
{
h = 0;
}
s = delta / cmax;
if (cmax == 0)
{
s = 0;
}
v = cmax;
}
public static void SampleFrame(in byte[][] sampler, int frame, int x, int y, int width, out float r, out float g, out float b)
{
var index = (x + y * width) * BPP;
// normalize pixel value to [0, 1]
r = sampler[frame][index + 0] * 0.00392156862745f;
g = sampler[frame][index + 1] * 0.00392156862745f;
b = sampler[frame][index + 2] * 0.00392156862745f;
}
public static float Saturate(float x)
{
return x < 0.0f ? 0.0f : x > 1.0f ? 1.0f : x;
}
}
}

206
Matrix App/GifWriter.cs Normal file
View File

@ -0,0 +1,206 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Matrix_App
{
/// <summary>
/// Creates a GIF using .Net GIF encoding and additional animation headers.
/// </summary>
public class GifWriter : IDisposable
{
#region Fields
const long SourceGlobalColorInfoPosition = 10,
SourceImageBlockPosition = 789;
readonly BinaryWriter _writer;
bool _firstFrame = true;
readonly object _syncLock = new object();
#endregion
/// <summary>
/// Creates a new instance of GifWriter.
/// </summary>
/// <param name="OutStream">The <see cref="Stream"/> to output the Gif to.</param>
/// <param name="DefaultFrameDelay">Default Delay between consecutive frames... FrameRate = 1000 / DefaultFrameDelay.</param>
/// <param name="Repeat">No of times the Gif should repeat... -1 not to repeat, 0 to repeat indefinitely.</param>
public GifWriter(Stream OutStream, int DefaultFrameDelay = 500, int Repeat = 0)
{
if (OutStream == null)
throw new ArgumentNullException(nameof(OutStream));
if (DefaultFrameDelay <= 0)
throw new ArgumentOutOfRangeException(nameof(DefaultFrameDelay));
if (Repeat < -1)
throw new ArgumentOutOfRangeException(nameof(Repeat));
_writer = new BinaryWriter(OutStream);
this.DefaultFrameDelay = DefaultFrameDelay;
this.Repeat = Repeat;
}
/// <summary>
/// Creates a new instance of GifWriter.
/// </summary>
/// <param name="FileName">The path to the file to output the Gif to.</param>
/// <param name="DefaultFrameDelay">Default Delay between consecutive frames... FrameRate = 1000 / DefaultFrameDelay.</param>
/// <param name="Repeat">No of times the Gif should repeat... -1 not to repeat, 0 to repeat indefinitely.</param>
public GifWriter(string FileName, int DefaultFrameDelay = 500, int Repeat = -1)
: this(new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read), DefaultFrameDelay, Repeat) { }
#region Properties
/// <summary>
/// Gets or Sets the Default Width of a Frame. Used when unspecified.
/// </summary>
public int DefaultWidth { get; set; }
/// <summary>
/// Gets or Sets the Default Height of a Frame. Used when unspecified.
/// </summary>
public int DefaultHeight { get; set; }
/// <summary>
/// Gets or Sets the Default Delay in Milliseconds.
/// </summary>
public int DefaultFrameDelay { get; set; }
/// <summary>
/// The Number of Times the Animation must repeat.
/// -1 indicates no repeat. 0 indicates repeat indefinitely
/// </summary>
public int Repeat { get; }
#endregion
/// <summary>
/// Adds a frame to this animation.
/// </summary>
/// <param name="Image">The image to add</param>
/// <param name="Delay">Delay in Milliseconds between this and last frame... 0 = <see cref="DefaultFrameDelay"/></param>
public void WriteFrame(Image Image, int Delay = 0)
{
lock (_syncLock)
using (var gifStream = new MemoryStream())
{
Image.Save(gifStream, ImageFormat.Gif);
// Steal the global color table info
if (_firstFrame)
InitHeader(gifStream, _writer, Image.Width, Image.Height);
WriteGraphicControlBlock(gifStream, _writer, Delay == 0 ? DefaultFrameDelay : Delay);
WriteImageBlock(gifStream, _writer, !_firstFrame, 0, 0, Image.Width, Image.Height);
}
if (_firstFrame)
_firstFrame = false;
}
#region Write
void InitHeader(Stream SourceGif, BinaryWriter Writer, int Width, int Height)
{
// File Header
Writer.Write("GIF".ToCharArray()); // File type
Writer.Write("89a".ToCharArray()); // File Version
Writer.Write((short)(DefaultWidth == 0 ? Width : DefaultWidth)); // Initial Logical Width
Writer.Write((short)(DefaultHeight == 0 ? Height : DefaultHeight)); // Initial Logical Height
SourceGif.Position = SourceGlobalColorInfoPosition;
Writer.Write((byte)SourceGif.ReadByte()); // Global Color Table Info
Writer.Write((byte)0); // Background Color Index
Writer.Write((byte)0); // Pixel aspect ratio
WriteColorTable(SourceGif, Writer);
// App Extension Header for Repeating
if (Repeat == -1)
return;
Writer.Write(unchecked((short)0xff21)); // Application Extension Block Identifier
Writer.Write((byte)0x0b); // Application Block Size
Writer.Write("NETSCAPE2.0".ToCharArray()); // Application Identifier
Writer.Write((byte)3); // Application block length
Writer.Write((byte)1);
Writer.Write((short)Repeat); // Repeat count for images.
Writer.Write((byte)0); // terminator
}
static void WriteColorTable(Stream SourceGif, BinaryWriter Writer)
{
SourceGif.Position = 13; // Locating the image color table
var colorTable = new byte[768];
SourceGif.Read(colorTable, 0, colorTable.Length);
Writer.Write(colorTable, 0, colorTable.Length);
}
static void WriteGraphicControlBlock(Stream SourceGif, BinaryWriter Writer, int FrameDelay)
{
SourceGif.Position = 781; // Locating the source GCE
var blockhead = new byte[8];
SourceGif.Read(blockhead, 0, blockhead.Length); // Reading source GCE
Writer.Write(unchecked((short)0xf921)); // Identifier
Writer.Write((byte)0x04); // Block Size
Writer.Write((byte)(blockhead[3] & 0xf7 | 0x08)); // Setting disposal flag
Writer.Write((short)(FrameDelay / 10)); // Setting frame delay
Writer.Write(blockhead[6]); // Transparent color index
Writer.Write((byte)0); // Terminator
}
static void WriteImageBlock(Stream SourceGif, BinaryWriter Writer, bool IncludeColorTable, int X, int Y, int Width, int Height)
{
SourceGif.Position = SourceImageBlockPosition; // Locating the image block
var header = new byte[11];
SourceGif.Read(header, 0, header.Length);
Writer.Write(header[0]); // Separator
Writer.Write((short)X); // Position X
Writer.Write((short)Y); // Position Y
Writer.Write((short)Width); // Width
Writer.Write((short)Height); // Height
if (IncludeColorTable) // If first frame, use global color table - else use local
{
SourceGif.Position = SourceGlobalColorInfoPosition;
Writer.Write((byte)(SourceGif.ReadByte() & 0x3f | 0x80)); // Enabling local color table
WriteColorTable(SourceGif, Writer);
}
else Writer.Write((byte)(header[9] & 0x07 | 0x07)); // Disabling local color table
Writer.Write(header[10]); // LZW Min Code Size
// Read/Write image data
SourceGif.Position = SourceImageBlockPosition + header.Length;
var dataLength = SourceGif.ReadByte();
while (dataLength > 0)
{
var imgData = new byte[dataLength];
SourceGif.Read(imgData, 0, dataLength);
Writer.Write((byte)dataLength);
Writer.Write(imgData, 0, dataLength);
dataLength = SourceGif.ReadByte();
}
Writer.Write((byte)0); // Terminator
}
#endregion
/// <summary>
/// Frees all resources used by this object.
/// </summary>
public void Dispose()
{
// Complete File
_writer.Write((byte)0x3b); // File Trailer
_writer.BaseStream.Dispose();
_writer.Dispose();
}
}
}

View File

@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>Matrix_App</RootNamespace>
<UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon>MatrixIcon.ico</ApplicationIcon>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<Optimize>true</Optimize>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.IO.Ports" Version="3.1.0" />
<PackageReference Include="System.Management" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Compile Update="ColorWheel.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="MatrixDesigner.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="Matrix.cs">
<SubType>UserControl</SubType>
</Compile>
</ItemGroup>
</Project>

403
Matrix App/Matrix.Designer.cs generated Normal file
View File

@ -0,0 +1,403 @@

using System;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
namespace Matrix_App
{
partial class Matrix
{
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.IContainer components = null;
private bool Editable = true;
public bool DrawGrid = true;
public float brushSize = 1f;
private bool HasFocus = false;
private int oldX;
private int oldY;
private int mouseX;
private int mouseY;
private bool toggled = false;
private float pixelScale;
protected override void OnCreateControl()
{
base.OnCreateControl();
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.DoubleBuffer,
true);
}
public void Instance(MatrixDesignerMain form1)
{
this.form = form1;
}
public void SetEditable(bool b) => Editable = b;
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
/// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private DirectBitmap matrix = new DirectBitmap(10, 10);
private Rectangle bounds = new Rectangle();
private Color paintColor = Color.Black;
private Color inverseAverage = Color.White;
private Rectangle cursorPoint = new Rectangle();
private Rectangle focusPoint = new Rectangle();
private float pixelWidth;
private float pixelHeight;
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
if (matrix.Bitmap.Width > 20 || matrix.Bitmap.Height > 20)
{
if (form != null)
{
form.showGridCheckbox.Checked = false;
}
DrawGrid = false;
}
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
e.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
e.Graphics.DrawImageUnscaledAndClipped(matrix.Bitmap, bounds);
if (HasFocus)
{
e.Graphics.DrawRectangle(new Pen(new SolidBrush(Color.Aquamarine), 4f), this.bounds);
}
if (Editable && DrawGrid)
{
var linePen = new Pen(new SolidBrush(inverseAverage));
int r = 0;
int g = 0;
int b = 0;
for (int x = 0; x < matrix.Width; x++)
{
int px = (int)(x * pixelWidth) + bounds.X;
for (int y = 0; y < matrix.Height; y++)
{
int py = (int)(y * pixelHeight) + bounds.Y;
e.Graphics.DrawLine(linePen, new Point(px, bounds.Y), new Point(px, bounds.Y + bounds.Height));
e.Graphics.DrawLine(linePen, new Point(bounds.X, py), new Point(bounds.X + bounds.Width, py));
var pixel = matrix.GetPixel(x, y);
r += pixel.R;
g += pixel.G;
b += pixel.B;
}
}
e.Graphics.DrawRectangle(new Pen(new SolidBrush(inverseAverage), 3.5f), cursorPoint);
e.Graphics.DrawRectangle(new Pen(new SolidBrush(inverseAverage), 2.0f), focusPoint);
int count = matrix.Width * matrix.Height;
r = 255 - r / count;
g = 255 - g / count;
b = 255 - b / count;
inverseAverage = Color.FromArgb(r, g, b);
}
if (Editable)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
int brushSizeHalf = (int)(brushSize * 0.5f * pixelScale);
int brushSizeI = (int)(brushSize * pixelScale);
e.Graphics.DrawEllipse(new Pen(new SolidBrush(inverseAverage), 2f), new Rectangle(mouseX - brushSizeHalf, mouseY - brushSizeHalf, brushSizeI, brushSizeI));
}
}
public void SetPaintColor(Color color)
{
paintColor = color;
}
private bool mouseDown;
private bool leftDown;
protected override void OnMouseDown(MouseEventArgs e)
{
toggled = true;
mouseDown = true;
leftDown = e.Button == MouseButtons.Left;
processMouse(e);
if (Editable && !leftDown)
{
float u = (e.X - bounds.X) / (float)bounds.Width;
float v = (e.Y - bounds.Y) / (float)bounds.Height;
if (u < 1.0f && v < 1.0f && u > 0.0f && v > 0.0f)
{
// remap to pixel coordinates
int x = (int)(u * matrix.Width);
int y = (int)(v * matrix.Height);
paintColor = matrix.GetPixel(x, y);
form.SetColor(paintColor);
}
}
HasFocus = true;
Refresh();
}
protected override void OnMouseUp(MouseEventArgs e)
{
mouseDown = false;
if (Editable)
{
form.EnqueuePixelSet();
}
}
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
HasFocus = true;
Refresh();
}
protected override void OnLostFocus(EventArgs e)
{
base.OnGotFocus(e);
HasFocus = false;
Refresh();
}
protected override void OnKeyUp(KeyEventArgs e)
{
HasFocus = true;
DrawGrid ^= e.KeyCode == Keys.Space;
Refresh();
}
public Int32[] getPixels()
{
return matrix.Bits;
}
protected override void OnMouseMove(MouseEventArgs e)
{
processMouse(e);
}
private void processMouse(MouseEventArgs e)
{
float u = (e.X - bounds.X) / (float)bounds.Width;
float v = (e.Y - bounds.Y) / (float)bounds.Height;
mouseX = e.X;
mouseY = e.Y;
if (u < 1.0f && v < 1.0f && u > 0.0f && v > 0.0f)
{
// remap to pixel coordinates
int x = (int)(u * matrix.Width);
int y = (int)(v * matrix.Height);
focusPoint.X = (int)(x * pixelWidth) + bounds.X;
focusPoint.Y = (int)(y * pixelHeight) + bounds.Y;
if (Editable && mouseDown && leftDown)
{
cursorPoint.X = focusPoint.X;
cursorPoint.Y = focusPoint.Y;
var g = Graphics.FromImage(matrix.Bitmap);
if (toggled)
{
if (brushSize < 2.0f)
{
SetPixel(x, y, paintColor);
} else
{
int brushSizeHalf = (int)(brushSize * 0.5f);
g.FillEllipse(new SolidBrush(paintColor), new Rectangle(x - brushSizeHalf, y - brushSizeHalf, (int)brushSize, (int)brushSize));
}
} else
{
int brushSizeHalf = (int)(brushSize * 0.5f);
g.FillEllipse(new SolidBrush(paintColor), new Rectangle(x - brushSizeHalf, y - brushSizeHalf, (int)brushSize, (int)brushSize));
g.FillEllipse(new SolidBrush(paintColor), new Rectangle(oldX - brushSizeHalf, oldY - brushSizeHalf, (int)brushSize, (int)brushSize));
g.DrawLine(new Pen(new SolidBrush(paintColor), brushSize), new Point(oldX, oldY), new Point(x, y));
}
toggled = false;
g.Dispose();
oldX = x;
oldY = y;
// SetPixel(x, y, paintColor);
}
} else
{
oldX = mouseX = e.X;
oldY = mouseY = e.Y;
}
Refresh();
}
protected override void OnResize(EventArgs e)
{
if (e != null)
{
base.OnResize(e);
}
float aspect = matrix.Height / (float)matrix.Width;
if ((int)(aspect * Width) < Height)
{
bounds.Width = Width;
bounds.Height = (int)(aspect * Width);
}
else
{
bounds.Height = Height;
bounds.Width = (int)(Height / aspect);
}
pixelScale = bounds.Width / (float) matrix.Width;
bounds.X = Width / 2 - bounds.Width / 2;
bounds.Y = Height / 2 - bounds.Height / 2;
pixelWidth = bounds.Width / (float)matrix.Width;
pixelHeight = bounds.Height / (float)matrix.Height;
cursorPoint.Width = (int)pixelWidth;
cursorPoint.Height = (int)pixelHeight;
cursorPoint.X = bounds.X;
cursorPoint.Y = bounds.Y;
focusPoint.Width = cursorPoint.Width;
focusPoint.Height = cursorPoint.Height;
focusPoint.X = bounds.X;
focusPoint.Y = bounds.Y;
Refresh();
}
public void Fill(Color color)
{
for (int x = 0; x < matrix.Width; x++)
{
for (int y = 0; y < matrix.Height; y++)
{
matrix.SetPixel(x, y, color);
}
}
Refresh();
}
public void SetPixel(int x, int y, Color color)
{
matrix.SetPixel(x, y, color);
Refresh();
}
public void SetPixelNoRefresh(int x, int y, Color color)
{
matrix.SetPixel(x, y, color);
}
public void SetPixel(int i, Color color)
{
int y = i / matrix.Width;
int x = matrix.Width - y * matrix.Width; // better than i % matrix.Width
SetPixel(x, y, color);
}
public void SetImage(byte[] buffer)
{
for (int y = 0; y < matrix.Height; y++)
{
int index = y * matrix.Width;
for (int x = 0; x < matrix.Width; x++)
{
int tmp = (index + x) * 3;
matrix.SetPixel(x, y, Color.FromArgb(
buffer[tmp + 0],
buffer[tmp + 1],
buffer[tmp + 2]
));
}
}
Refresh();
}
public void resize(int width, int height)
{
matrix = new DirectBitmap(width, height);
if (width > 16 || height > 16)
{
if (form != null)
{
form.showGridCheckbox.Checked = false;
}
DrawGrid = false;
}
Fill(Color.Black);
OnResize(null);
Refresh();
}
public void SetImage(Bitmap image)
{
matrix.SetImage(image);
}
public int matrixWidth()
{
return matrix.Width;
}
public int matrixHeight()
{
return matrix.Height;
}
}
}

36
Matrix App/Matrix.cs Normal file
View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Matrix_App
{
public partial class Matrix : UserControl
{
private MatrixDesignerMain form;
public Matrix()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// Matrix
//
this.Name = "Matrix";
this.Size = new System.Drawing.Size(104, 102);
this.ResumeLayout(false);
}
internal Color GetPixel(int x, int y)
{
return matrix.GetPixel(x, y);
}
}
}

60
Matrix App/Matrix.resx Normal file
View File

@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

803
Matrix App/MatrixDesigner.Designer.cs generated Normal file
View File

@ -0,0 +1,803 @@
using System.IO.Ports;
using System.Drawing;
namespace Matrix_App
{
partial class MatrixDesignerMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
MatrixGifGenerator.Close();
commandQueue.Close();
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MatrixDesignerMain));
this.Ports = new System.Windows.Forms.ComboBox();
this.Modus = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.panel4 = new System.Windows.Forms.Panel();
this.button2 = new System.Windows.Forms.Button();
this.button1 = new System.Windows.Forms.Button();
this.label7 = new System.Windows.Forms.Label();
this.Save = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
this.FramesLabel = new System.Windows.Forms.Label();
this.configButton = new System.Windows.Forms.Button();
this.read_me = new System.Windows.Forms.RichTextBox();
this.DelayLabel = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.FrameCount = new System.Windows.Forms.NumericUpDown();
this.Delay = new System.Windows.Forms.NumericUpDown();
this.label1 = new System.Windows.Forms.Label();
this.matrixHeight = new System.Windows.Forms.NumericUpDown();
this.matrixWidth = new System.Windows.Forms.NumericUpDown();
this.Zeichnen = new System.Windows.Forms.TabPage();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.label6 = new System.Windows.Forms.Label();
this.BrushSizeSlider = new System.Windows.Forms.TrackBar();
this.showGridCheckbox = new System.Windows.Forms.CheckBox();
this.label5 = new System.Windows.Forms.Label();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.ZeichnenTextBoxRed = new System.Windows.Forms.TextBox();
this.ZeichnenTrackBarRed = new System.Windows.Forms.TrackBar();
this.ZeichnenTrackBarGreen = new System.Windows.Forms.TrackBar();
this.ZeichnenTrackBarBlue = new System.Windows.Forms.TrackBar();
this.ZeichnenTextBoxBlue = new System.Windows.Forms.TextBox();
this.ZeichnenTextBoxGreen = new System.Windows.Forms.TextBox();
this.Clear = new System.Windows.Forms.Button();
this.fill = new System.Windows.Forms.Button();
this.ZeichnenFarbRad = new ColorWheel();
this.pregeneratedMods = new System.Windows.Forms.TabPage();
this.pregeneratedModsBase = new System.Windows.Forms.FlowLayoutPanel();
this.ToolBar = new System.Windows.Forms.Panel();
this.panel2 = new System.Windows.Forms.Panel();
this.Timeline = new System.Windows.Forms.TrackBar();
this.panel1 = new System.Windows.Forms.Panel();
this.Play = new System.Windows.Forms.Button();
this.Apply = new System.Windows.Forms.Button();
this.DragDropButton = new System.Windows.Forms.Button();
this.matrixView = new Matrix_App.Matrix();
this.panel3 = new System.Windows.Forms.Panel();
this.Modus.SuspendLayout();
this.tabPage1.SuspendLayout();
this.groupBox3.SuspendLayout();
this.panel4.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.FrameCount)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.Delay)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.matrixHeight)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.matrixWidth)).BeginInit();
this.Zeichnen.SuspendLayout();
this.groupBox2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.BrushSizeSlider)).BeginInit();
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.ZeichnenTrackBarRed)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.ZeichnenTrackBarGreen)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.ZeichnenTrackBarBlue)).BeginInit();
this.pregeneratedMods.SuspendLayout();
this.ToolBar.SuspendLayout();
this.panel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.Timeline)).BeginInit();
this.panel1.SuspendLayout();
this.panel3.SuspendLayout();
this.SuspendLayout();
//
// Ports
//
this.Ports.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Ports.Location = new System.Drawing.Point(62, 130);
this.Ports.Name = "Ports";
this.Ports.Size = new System.Drawing.Size(163, 23);
this.Ports.TabIndex = 0;
this.Ports.SelectedIndexChanged += new System.EventHandler(this.Ports_SelectedIndexChanged);
//
// Modus
//
this.Modus.Controls.Add(this.tabPage1);
this.Modus.Controls.Add(this.Zeichnen);
this.Modus.Controls.Add(this.pregeneratedMods);
this.Modus.Dock = System.Windows.Forms.DockStyle.Left;
this.Modus.HotTrack = true;
this.Modus.ItemSize = new System.Drawing.Size(75, 0);
this.Modus.Location = new System.Drawing.Point(0, 0);
this.Modus.Margin = new System.Windows.Forms.Padding(0);
this.Modus.Name = "Modus";
this.Modus.Padding = new System.Drawing.Point(0, 0);
this.Modus.SelectedIndex = 0;
this.Modus.Size = new System.Drawing.Size(240, 663);
this.Modus.SizeMode = System.Windows.Forms.TabSizeMode.Fixed;
this.Modus.TabIndex = 1;
//
// tabPage1
//
this.tabPage1.Controls.Add(this.groupBox3);
this.tabPage1.Controls.Add(this.label7);
this.tabPage1.Controls.Add(this.Save);
this.tabPage1.Controls.Add(this.label3);
this.tabPage1.Controls.Add(this.FramesLabel);
this.tabPage1.Controls.Add(this.configButton);
this.tabPage1.Controls.Add(this.read_me);
this.tabPage1.Controls.Add(this.DelayLabel);
this.tabPage1.Controls.Add(this.label4);
this.tabPage1.Controls.Add(this.label2);
this.tabPage1.Controls.Add(this.FrameCount);
this.tabPage1.Controls.Add(this.Ports);
this.tabPage1.Controls.Add(this.Delay);
this.tabPage1.Controls.Add(this.label1);
this.tabPage1.Controls.Add(this.matrixHeight);
this.tabPage1.Controls.Add(this.matrixWidth);
this.tabPage1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.tabPage1.Location = new System.Drawing.Point(4, 24);
this.tabPage1.Margin = new System.Windows.Forms.Padding(0);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Size = new System.Drawing.Size(232, 635);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Properties";
this.tabPage1.UseVisualStyleBackColor = true;
//
// groupBox3
//
this.groupBox3.Controls.Add(this.panel4);
this.groupBox3.Location = new System.Drawing.Point(3, 243);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Size = new System.Drawing.Size(226, 89);
this.groupBox3.TabIndex = 15;
this.groupBox3.TabStop = false;
this.groupBox3.Text = "Appearance";
//
// panel4
//
this.panel4.Controls.Add(this.button2);
this.panel4.Controls.Add(this.button1);
this.panel4.Location = new System.Drawing.Point(4, 22);
this.panel4.Name = "panel4";
this.panel4.Size = new System.Drawing.Size(218, 54);
this.panel4.TabIndex = 1;
//
// button2
//
this.button2.Location = new System.Drawing.Point(1, 0);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(216, 23);
this.button2.TabIndex = 2;
this.button2.Text = "Light Mode (Default)";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.ApplyLightModeButton_Click);
//
// button1
//
this.button1.Location = new System.Drawing.Point(1, 28);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(216, 23);
this.button1.TabIndex = 1;
this.button1.Text = "Dark Mode (Experimental)";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.ApplyDarkModeButton_Click);
//
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(5, 208);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(51, 15);
this.label7.TabIndex = 14;
this.label7.Text = "Save GIF";
//
// Save
//
this.Save.Image = ((System.Drawing.Image)(resources.GetObject("Save.Image")));
this.Save.Location = new System.Drawing.Point(62, 196);
this.Save.Name = "Save";
this.Save.Size = new System.Drawing.Size(163, 38);
this.Save.TabIndex = 13;
this.Save.Text = "Save";
this.Save.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.Save.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
this.Save.UseVisualStyleBackColor = true;
this.Save.Click += new System.EventHandler(this.Save_Click);
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(5, 160);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(43, 15);
this.label3.TabIndex = 7;
this.label3.Text = "Config";
//
// FramesLabel
//
this.FramesLabel.AutoSize = true;
this.FramesLabel.Location = new System.Drawing.Point(5, 71);
this.FramesLabel.Name = "FramesLabel";
this.FramesLabel.Size = new System.Drawing.Size(45, 15);
this.FramesLabel.TabIndex = 12;
this.FramesLabel.Text = "Frames";
//
// configButton
//
this.configButton.Location = new System.Drawing.Point(62, 159);
this.configButton.Name = "configButton";
this.configButton.Size = new System.Drawing.Size(163, 23);
this.configButton.TabIndex = 6;
this.configButton.Text = "Load";
this.configButton.UseVisualStyleBackColor = true;
this.configButton.Click += new System.EventHandler(this.ConfigButton_Click);
//
// read_me
//
this.read_me.Dock = System.Windows.Forms.DockStyle.Bottom;
this.read_me.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.read_me.Location = new System.Drawing.Point(0, 344);
this.read_me.Name = "read_me";
this.read_me.ReadOnly = true;
this.read_me.Size = new System.Drawing.Size(232, 291);
this.read_me.TabIndex = 5;
this.read_me.Text = "Reads Me";
//
// DelayLabel
//
this.DelayLabel.AutoSize = true;
this.DelayLabel.Location = new System.Drawing.Point(5, 100);
this.DelayLabel.Name = "DelayLabel";
this.DelayLabel.Size = new System.Drawing.Size(36, 15);
this.DelayLabel.TabIndex = 11;
this.DelayLabel.Text = "Delay";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(5, 130);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(29, 15);
this.label4.TabIndex = 4;
this.label4.Text = "Port";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(5, 40);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(43, 15);
this.label2.TabIndex = 3;
this.label2.Text = "Height";
//
// FrameCount
//
this.FrameCount.Location = new System.Drawing.Point(62, 72);
this.FrameCount.Maximum = new decimal(new int[] {
120,
0,
0,
0});
this.FrameCount.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.FrameCount.Name = "FrameCount";
this.FrameCount.Size = new System.Drawing.Size(163, 23);
this.FrameCount.TabIndex = 10;
this.FrameCount.Value = new decimal(new int[] {
1,
0,
0,
0});
this.FrameCount.ValueChanged += new System.EventHandler(this.FrameCount_ValueChanged);
//
// Delay
//
this.Delay.Location = new System.Drawing.Point(62, 101);
this.Delay.Maximum = new decimal(new int[] {
5000,
0,
0,
0});
this.Delay.Minimum = new decimal(new int[] {
50,
0,
0,
0});
this.Delay.Name = "Delay";
this.Delay.Size = new System.Drawing.Size(163, 23);
this.Delay.TabIndex = 9;
this.Delay.Value = new decimal(new int[] {
500,
0,
0,
0});
this.Delay.ValueChanged += new System.EventHandler(this.Delay_ValueChanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(5, 11);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(39, 15);
this.label1.TabIndex = 2;
this.label1.Text = "Width";
//
// matrixHeight
//
this.matrixHeight.Location = new System.Drawing.Point(62, 43);
this.matrixHeight.Maximum = new decimal(new int[] {
20,
0,
0,
0});
this.matrixHeight.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.matrixHeight.Name = "matrixHeight";
this.matrixHeight.Size = new System.Drawing.Size(163, 23);
this.matrixHeight.TabIndex = 1;
this.matrixHeight.Value = new decimal(new int[] {
10,
0,
0,
0});
this.matrixHeight.ValueChanged += new System.EventHandler(this.Height_ValueChanged);
//
// matrixWidth
//
this.matrixWidth.Location = new System.Drawing.Point(62, 14);
this.matrixWidth.Maximum = new decimal(new int[] {
20,
0,
0,
0});
this.matrixWidth.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.matrixWidth.Name = "matrixWidth";
this.matrixWidth.Size = new System.Drawing.Size(163, 23);
this.matrixWidth.TabIndex = 0;
this.matrixWidth.Value = new decimal(new int[] {
10,
0,
0,
0});
this.matrixWidth.ValueChanged += new System.EventHandler(this.Width_ValueChanged);
//
// Zeichnen
//
this.Zeichnen.BackColor = System.Drawing.Color.Transparent;
this.Zeichnen.Controls.Add(this.groupBox2);
this.Zeichnen.Controls.Add(this.groupBox1);
this.Zeichnen.Controls.Add(this.Clear);
this.Zeichnen.Controls.Add(this.fill);
this.Zeichnen.Controls.Add(this.ZeichnenFarbRad);
this.Zeichnen.Location = new System.Drawing.Point(4, 24);
this.Zeichnen.Margin = new System.Windows.Forms.Padding(0);
this.Zeichnen.Name = "Zeichnen";
this.Zeichnen.Size = new System.Drawing.Size(232, 635);
this.Zeichnen.TabIndex = 1;
this.Zeichnen.Text = "Edit/Paint";
//
// groupBox2
//
this.groupBox2.Controls.Add(this.label6);
this.groupBox2.Controls.Add(this.BrushSizeSlider);
this.groupBox2.Controls.Add(this.showGridCheckbox);
this.groupBox2.Controls.Add(this.label5);
this.groupBox2.Location = new System.Drawing.Point(3, 481);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(222, 113);
this.groupBox2.TabIndex = 15;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Brush Settings";
//
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(5, 75);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(60, 15);
this.label6.TabIndex = 7;
this.label6.Text = "Show grid";
//
// trackBar1
//
this.BrushSizeSlider.Location = new System.Drawing.Point(63, 27);
this.BrushSizeSlider.Maximum = 64;
this.BrushSizeSlider.Minimum = 1;
this.BrushSizeSlider.Name = "BrushSizeSlider";
this.BrushSizeSlider.Size = new System.Drawing.Size(159, 45);
this.BrushSizeSlider.TabIndex = 5;
this.BrushSizeSlider.TickFrequency = 8;
this.BrushSizeSlider.Value = 1;
this.BrushSizeSlider.Scroll += new System.EventHandler(this.BrushSizeSlider_Scroll);
//
// showGridCheckbox
//
this.showGridCheckbox.AutoSize = true;
this.showGridCheckbox.BackColor = System.Drawing.Color.Transparent;
this.showGridCheckbox.Checked = true;
this.showGridCheckbox.CheckState = System.Windows.Forms.CheckState.Checked;
this.showGridCheckbox.ImageAlign = System.Drawing.ContentAlignment.MiddleRight;
this.showGridCheckbox.Location = new System.Drawing.Point(72, 76);
this.showGridCheckbox.Name = "showGridCheckbox";
this.showGridCheckbox.RightToLeft = System.Windows.Forms.RightToLeft.No;
this.showGridCheckbox.Size = new System.Drawing.Size(15, 14);
this.showGridCheckbox.TabIndex = 4;
this.showGridCheckbox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.showGridCheckbox.UseVisualStyleBackColor = false;
this.showGridCheckbox.CheckedChanged += new System.EventHandler(this.showGridCheckbox_CheckedChanged);
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(6, 32);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(59, 15);
this.label5.TabIndex = 6;
this.label5.Text = "Brush size";
//
// groupBox1
//
this.groupBox1.Controls.Add(this.ZeichnenTextBoxRed);
this.groupBox1.Controls.Add(this.ZeichnenTrackBarRed);
this.groupBox1.Controls.Add(this.ZeichnenTrackBarGreen);
this.groupBox1.Controls.Add(this.ZeichnenTrackBarBlue);
this.groupBox1.Controls.Add(this.ZeichnenTextBoxBlue);
this.groupBox1.Controls.Add(this.ZeichnenTextBoxGreen);
this.groupBox1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.groupBox1.ForeColor = System.Drawing.SystemColors.ActiveCaptionText;
this.groupBox1.Location = new System.Drawing.Point(4, 225);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(223, 152);
this.groupBox1.TabIndex = 14;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "RGB";
//
// ZeichnenTextBoxRed
//
this.ZeichnenTextBoxRed.Location = new System.Drawing.Point(6, 22);
this.ZeichnenTextBoxRed.Name = "ZeichnenTextBoxRed";
this.ZeichnenTextBoxRed.Size = new System.Drawing.Size(44, 23);
this.ZeichnenTextBoxRed.TabIndex = 4;
this.ZeichnenTextBoxRed.Text = "0";
this.ZeichnenTextBoxRed.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.ZeichnenTextBoxRed.KeyUp += new System.Windows.Forms.KeyEventHandler(this.ZeichnenTextBoxRed_KeyUp);
//
// ZeichnenTrackBarRed
//
this.ZeichnenTrackBarRed.BackColor = System.Drawing.Color.White;
this.ZeichnenTrackBarRed.Location = new System.Drawing.Point(53, 22);
this.ZeichnenTrackBarRed.Maximum = 255;
this.ZeichnenTrackBarRed.Name = "ZeichnenTrackBarRed";
this.ZeichnenTrackBarRed.Size = new System.Drawing.Size(169, 45);
this.ZeichnenTrackBarRed.TabIndex = 1;
this.ZeichnenTrackBarRed.TickFrequency = 15;
this.ZeichnenTrackBarRed.Scroll += new System.EventHandler(this.ZeichnenTrackBarRed_Scroll);
//
// ZeichnenTrackBarGreen
//
this.ZeichnenTrackBarGreen.BackColor = System.Drawing.Color.White;
this.ZeichnenTrackBarGreen.Location = new System.Drawing.Point(53, 63);
this.ZeichnenTrackBarGreen.Maximum = 255;
this.ZeichnenTrackBarGreen.Name = "ZeichnenTrackBarGreen";
this.ZeichnenTrackBarGreen.Size = new System.Drawing.Size(169, 45);
this.ZeichnenTrackBarGreen.TabIndex = 3;
this.ZeichnenTrackBarGreen.TickFrequency = 15;
this.ZeichnenTrackBarGreen.Scroll += new System.EventHandler(this.ZeichnenTrackBarGreen_Scroll);
//
// ZeichnenTrackBarBlue
//
this.ZeichnenTrackBarBlue.BackColor = System.Drawing.Color.White;
this.ZeichnenTrackBarBlue.Location = new System.Drawing.Point(54, 104);
this.ZeichnenTrackBarBlue.Maximum = 255;
this.ZeichnenTrackBarBlue.Name = "ZeichnenTrackBarBlue";
this.ZeichnenTrackBarBlue.Size = new System.Drawing.Size(168, 45);
this.ZeichnenTrackBarBlue.TabIndex = 2;
this.ZeichnenTrackBarBlue.TickFrequency = 15;
this.ZeichnenTrackBarBlue.Scroll += new System.EventHandler(this.ZeichnenTrackBarBlue_Scroll);
//
// ZeichnenTextBoxBlue
//
this.ZeichnenTextBoxBlue.Location = new System.Drawing.Point(6, 104);
this.ZeichnenTextBoxBlue.Name = "ZeichnenTextBoxBlue";
this.ZeichnenTextBoxBlue.Size = new System.Drawing.Size(44, 23);
this.ZeichnenTextBoxBlue.TabIndex = 6;
this.ZeichnenTextBoxBlue.Text = "0";
this.ZeichnenTextBoxBlue.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.ZeichnenTextBoxBlue.KeyUp += new System.Windows.Forms.KeyEventHandler(this.ZeichnenTextBoxBlue_KeyUp);
//
// ZeichnenTextBoxGreen
//
this.ZeichnenTextBoxGreen.Location = new System.Drawing.Point(6, 63);
this.ZeichnenTextBoxGreen.Name = "ZeichnenTextBoxGreen";
this.ZeichnenTextBoxGreen.Size = new System.Drawing.Size(44, 23);
this.ZeichnenTextBoxGreen.TabIndex = 5;
this.ZeichnenTextBoxGreen.Text = "0";
this.ZeichnenTextBoxGreen.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.ZeichnenTextBoxGreen.KeyUp += new System.Windows.Forms.KeyEventHandler(this.ZeichnenTextBoxGreen_KeyUp);
//
// Clear
//
this.Clear.Image = ((System.Drawing.Image)(resources.GetObject("Clear.Image")));
this.Clear.Location = new System.Drawing.Point(4, 428);
this.Clear.Name = "Clear";
this.Clear.Size = new System.Drawing.Size(222, 36);
this.Clear.TabIndex = 8;
this.Clear.Text = "Clear";
this.Clear.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.Clear.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
this.Clear.UseVisualStyleBackColor = true;
this.Clear.Click += new System.EventHandler(this.ZeichnenClear_Click);
//
// fill
//
this.fill.Image = ((System.Drawing.Image)(resources.GetObject("fill.Image")));
this.fill.Location = new System.Drawing.Point(3, 383);
this.fill.Name = "fill";
this.fill.Size = new System.Drawing.Size(223, 39);
this.fill.TabIndex = 7;
this.fill.Text = "Fill";
this.fill.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.fill.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
this.fill.UseVisualStyleBackColor = true;
this.fill.Click += new System.EventHandler(this.ZeichnenFill_Click);
//
// ZeichnenFarbRad
//
this.ZeichnenFarbRad.BackColor = System.Drawing.SystemColors.Control;
this.ZeichnenFarbRad.Location = new System.Drawing.Point(8, 12);
this.ZeichnenFarbRad.Name = "ZeichnenFarbRad";
this.ZeichnenFarbRad.Size = new System.Drawing.Size(209, 209);
this.ZeichnenFarbRad.TabIndex = 0;
//
// pregeneratedMods
//
this.pregeneratedMods.Controls.Add(this.pregeneratedModsBase);
this.pregeneratedMods.Location = new System.Drawing.Point(4, 24);
this.pregeneratedMods.Margin = new System.Windows.Forms.Padding(0);
this.pregeneratedMods.Name = "pregeneratedMods";
this.pregeneratedMods.Size = new System.Drawing.Size(232, 635);
this.pregeneratedMods.TabIndex = 2;
this.pregeneratedMods.Text = "Filter";
this.pregeneratedMods.UseVisualStyleBackColor = true;
//
// pregeneratedModsBase
//
this.pregeneratedModsBase.Dock = System.Windows.Forms.DockStyle.Top;
this.pregeneratedModsBase.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.pregeneratedModsBase.Location = new System.Drawing.Point(0, 0);
this.pregeneratedModsBase.Name = "pregeneratedModsBase";
this.pregeneratedModsBase.Size = new System.Drawing.Size(232, 635);
this.pregeneratedModsBase.TabIndex = 0;
//
// ToolBar
//
this.ToolBar.Controls.Add(this.panel2);
this.ToolBar.Controls.Add(this.panel1);
this.ToolBar.Controls.Add(this.DragDropButton);
this.ToolBar.Dock = System.Windows.Forms.DockStyle.Bottom;
this.ToolBar.Location = new System.Drawing.Point(240, 589);
this.ToolBar.Name = "ToolBar";
this.ToolBar.Padding = new System.Windows.Forms.Padding(6);
this.ToolBar.Size = new System.Drawing.Size(659, 74);
this.ToolBar.TabIndex = 2;
//
// panel2
//
this.panel2.Controls.Add(this.Timeline);
this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel2.Location = new System.Drawing.Point(161, 6);
this.panel2.Name = "panel2";
this.panel2.Padding = new System.Windows.Forms.Padding(0, 18, 0, 0);
this.panel2.Size = new System.Drawing.Size(337, 62);
this.panel2.TabIndex = 5;
//
// Timeline
//
this.Timeline.Cursor = System.Windows.Forms.Cursors.Default;
this.Timeline.Dock = System.Windows.Forms.DockStyle.Fill;
this.Timeline.Enabled = false;
this.Timeline.LargeChange = 1;
this.Timeline.Location = new System.Drawing.Point(0, 18);
this.Timeline.Maximum = 1;
this.Timeline.Name = "Timeline";
this.Timeline.Size = new System.Drawing.Size(337, 44);
this.Timeline.TabIndex = 5;
this.Timeline.ValueChanged += new System.EventHandler(this.Timeline_ValueChanged);
this.Timeline.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Timeline_MouseDown);
//
// panel1
//
this.panel1.Controls.Add(this.Play);
this.panel1.Controls.Add(this.Apply);
this.panel1.Dock = System.Windows.Forms.DockStyle.Left;
this.panel1.Location = new System.Drawing.Point(6, 6);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(155, 62);
this.panel1.TabIndex = 4;
//
// Play
//
this.Play.Dock = System.Windows.Forms.DockStyle.Right;
this.Play.Image = ((System.Drawing.Image)(resources.GetObject("Play.Image")));
this.Play.Location = new System.Drawing.Point(85, 0);
this.Play.Name = "Play";
this.Play.Size = new System.Drawing.Size(70, 62);
this.Play.TabIndex = 3;
this.Play.Text = "Play";
this.Play.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
this.Play.UseVisualStyleBackColor = true;
this.Play.Click += new System.EventHandler(this.Play_Click);
//
// Apply
//
this.Apply.Dock = System.Windows.Forms.DockStyle.Left;
this.Apply.Image = ((System.Drawing.Image)(resources.GetObject("Apply.Image")));
this.Apply.Location = new System.Drawing.Point(0, 0);
this.Apply.Name = "Apply";
this.Apply.Size = new System.Drawing.Size(85, 62);
this.Apply.TabIndex = 2;
this.Apply.Text = "Apply Frame";
this.Apply.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
this.Apply.UseVisualStyleBackColor = true;
this.Apply.Click += new System.EventHandler(this.Apply_Click);
//
// DragDropButton
//
this.DragDropButton.AllowDrop = true;
this.DragDropButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.DragDropButton.Cursor = System.Windows.Forms.Cursors.Arrow;
this.DragDropButton.Dock = System.Windows.Forms.DockStyle.Right;
this.DragDropButton.ForeColor = System.Drawing.Color.Black;
this.DragDropButton.Image = ((System.Drawing.Image)(resources.GetObject("DragDropButton.Image")));
this.DragDropButton.Location = new System.Drawing.Point(498, 6);
this.DragDropButton.Name = "DragDropButton";
this.DragDropButton.Size = new System.Drawing.Size(155, 62);
this.DragDropButton.TabIndex = 0;
this.DragDropButton.Text = "Image/Gif\r\ndrag drop";
this.DragDropButton.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.DragDropButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
this.DragDropButton.UseVisualStyleBackColor = true;
this.DragDropButton.Click += new System.EventHandler(this.DragDrop_Click);
this.DragDropButton.DragDrop += new System.Windows.Forms.DragEventHandler(this.DragDrop_DragDrop);
this.DragDropButton.DragEnter += new System.Windows.Forms.DragEventHandler(this.DragDrop_DragEnter);
//
// matrixView
//
this.matrixView.Dock = System.Windows.Forms.DockStyle.Fill;
this.matrixView.Location = new System.Drawing.Point(16, 16);
this.matrixView.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
this.matrixView.Name = "matrixView";
this.matrixView.Size = new System.Drawing.Size(627, 557);
this.matrixView.TabIndex = 3;
//
// panel3
//
this.panel3.Controls.Add(this.matrixView);
this.panel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel3.Location = new System.Drawing.Point(240, 0);
this.panel3.Name = "panel3";
this.panel3.Padding = new System.Windows.Forms.Padding(16);
this.panel3.Size = new System.Drawing.Size(659, 589);
this.panel3.TabIndex = 0;
//
// MatrixDesignerMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(899, 663);
this.Controls.Add(this.panel3);
this.Controls.Add(this.ToolBar);
this.Controls.Add(this.Modus);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MinimumSize = new System.Drawing.Size(915, 702);
this.Name = "MatrixDesignerMain";
this.Text = "Matrix Designer";
this.Modus.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tabPage1.PerformLayout();
this.groupBox3.ResumeLayout(false);
this.panel4.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.FrameCount)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.Delay)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.matrixHeight)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.matrixWidth)).EndInit();
this.Zeichnen.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.BrushSizeSlider)).EndInit();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.ZeichnenTrackBarRed)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.ZeichnenTrackBarGreen)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.ZeichnenTrackBarBlue)).EndInit();
this.pregeneratedMods.ResumeLayout(false);
this.ToolBar.ResumeLayout(false);
this.panel2.ResumeLayout(false);
this.panel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.Timeline)).EndInit();
this.panel1.ResumeLayout(false);
this.panel3.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ComboBox Ports;
private System.Windows.Forms.TabControl Modus;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabPage Zeichnen;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.RichTextBox read_me;
private System.Windows.Forms.Panel ToolBar;
private System.Windows.Forms.NumericUpDown matrixHeight;
private System.Windows.Forms.NumericUpDown matrixWidth;
private ColorWheel ZeichnenFarbRad;
private System.Windows.Forms.TrackBar ZeichnenTrackBarGreen;
private System.Windows.Forms.TrackBar ZeichnenTrackBarBlue;
private System.Windows.Forms.TrackBar ZeichnenTrackBarRed;
private System.Windows.Forms.TextBox ZeichnenTextBoxGreen;
private System.Windows.Forms.TextBox ZeichnenTextBoxRed;
private System.Windows.Forms.TextBox ZeichnenTextBoxBlue;
private System.Windows.Forms.Button Clear;
private System.Windows.Forms.Button fill;
private System.Windows.Forms.Button DragDropButton;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button Play;
private System.Windows.Forms.Button Apply;
private System.Windows.Forms.TrackBar Timeline;
private System.Windows.Forms.NumericUpDown FrameCount;
private System.Windows.Forms.NumericUpDown Delay;
private System.Windows.Forms.Label FramesLabel;
private System.Windows.Forms.Label DelayLabel;
private System.Windows.Forms.Button Save;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button configButton;
private Matrix matrixView;
private System.Windows.Forms.TabPage pregeneratedMods;
private System.Windows.Forms.FlowLayoutPanel pregeneratedModsBase;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.Panel panel3;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Panel panel4;
private System.Windows.Forms.Button button2;
public System.Windows.Forms.CheckBox showGridCheckbox;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.TrackBar BrushSizeSlider;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.GroupBox groupBox3;
}
}

View File

@ -0,0 +1,841 @@
#define DEBUG_ENABLED
#define DEBUG_ENABLED
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Timers;
using System.Diagnostics;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Runtime.CompilerServices;
using System.IO;
using System.Management;
using System.Text.RegularExpressions;
using static MatrixDesigner.Defaults;
using static MatrixDesigner.ArduinoInstruction;
using static Matrix_App.Utils;
using Matrix_App.Themes;
namespace Matrix_App
{
public partial class MatrixDesignerMain : Form
{
#region Private-Members
/// <summary>
/// Port update Timer
/// Reloads available port names at consecutive rates
/// </summary>
private System.Timers.Timer portNameUpdater;
private System.Timers.Timer delay;
private static SerialPort port = new SerialPort();
private uint portNumber;
private bool runningGif = false;
private PortCommandQueue commandQueue = new PortCommandQueue(ref port);
private Regex comRegex = new Regex(@"COM[\d]+");
/// <summary>
/// Gif like frame video buffer
/// </summary>
public byte[][] Gif = CreateImageRGB_NT(MATRIX_START_WIDTH, MATRIX_START_HEIGHT, MATRIX_START_FRAMES);
#endregion
#region Setup
public MatrixDesignerMain()
{
// generate UI
InitializeComponent();
// Set Parent of our matrix
matrixView.Instance(this);
// Generate filter access buttons
MatrixGifGenerator.GenerateBaseUi(pregeneratedModsBase, matrixView, this);
init();
// apply lightmode by default
new LightMode().ApplyTheme(this);
}
private void init()
{
// Create port name update timer
portNameUpdater = new System.Timers.Timer(PORT_NAME_UPDATE_INTERVAL);
portNameUpdater.Elapsed += updatePortNames;
portNameUpdater.AutoReset = true;
portNameUpdater.Enabled = true;
// create gif playback timer
delay = new System.Timers.Timer((int) Delay.Value);
delay.Elapsed += timelineupdate;
delay.AutoReset = true;
// Set color wheel event handler
ZeichnenFarbRad.handler = new EventHandler(FarbRad_Handler);
// setup port settings
port.BaudRate = BAUD_RATE;
port.ReadTimeout = READ_TIMEOUT_MS;
port.WriteTimeout = WRITE_TIMEOUT_MS;
// setup matrix
AdjustMatrixTable();
// search for inital ports
GatherPortNames();
HideEasterEgg();
}
private void HideEasterEgg()
{
Random better = new Random();
int Brandom = better.Next(0, 9);
if (Brandom < 1)
{
if (((int)DateTime.Now.DayOfWeek) == 3)
{
matrixWidth.Value = 16;
matrixHeight.Value = 16;
ResizeGif();
Bitmap WednesdayFrog = new Bitmap(Matrix_App.Properties.Resources.Frosch);
for (int x = 0; x < WednesdayFrog.Width; x++)
{
for (int y = 0; y < WednesdayFrog.Height; y++)
{
var pixel = WednesdayFrog.GetPixel(x, y);
int index = x + y * WednesdayFrog.Width;
matrixView.SetPixelNoRefresh(x, y, pixel);
}
}
matrixView.Refresh();
}
}
}
#endregion
#region UI-Methods
#region Port-ComboBox
/// <summary>
/// Updates the port names to newest available ports.
/// Called by <see cref="portNameUpdater"/>.
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
private void updatePortNames(Object source, ElapsedEventArgs e)
{
if (Ports.InvokeRequired)
{
// invoke on the comboboxes thread
Ports.Invoke(new Action(() => GatherPortNames()));
}
else
{
// run on this thread
GatherPortNames();
}
}
/// <summary>
/// Gathers all availbale ports and sets them to the combobox <see cref="Ports"/>
/// </summary>
private void GatherPortNames()
{
var ports = SerialPort.GetPortNames();
// save previously selected
var selected = this.Ports.SelectedItem;
// get device names from ports
var newPorts = GetDeviceNames(ports);
// add virtual port
newPorts.AddLast("Virtual-Unlimited (COM257)");
// search for new port
foreach (var newPort in newPorts)
{
// find any new port
var found = Ports.Items.Cast<object?>().Any(oldPort => (string) oldPort! == newPort);
// some port wasn't found, recreate list
if (!found)
{
commandQueue.InvalidatePort();
Ports.Items.Clear();
Ports.Items.AddRange(newPorts.ToArray());
// select previously selected port if port is still accessible
if (selected != null && this.Ports.Items.Contains(selected))
{
this.Ports.SelectedItem = selected;
} else
{
this.Ports.SelectedIndex = 0;
}
break;
}
}
}
private static LinkedList<string> GetDeviceNames(string[] ports)
{
ManagementClass processClass = new ManagementClass("Win32_PnPEntity");
ManagementObjectCollection Ports = processClass.GetInstances();
var newPorts = new LinkedList<string>();
for (var x = 0; x < ports.Length; x++)
{
foreach (ManagementObject property in Ports)
{
var name = property.GetPropertyValue("Name");
if (name != null && name.ToString().Contains(ports[x]))
{
newPorts.AddLast(name.ToString());
break;
}
}
}
return newPorts;
}
/// <summary>
/// Invoked when the selected port has changed.
/// Applies the new port settings.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Ports_SelectedIndexChanged(object sender, EventArgs e)
{
lock (port)
{
if (!port.IsOpen)
{
var item = (string)((ComboBox)sender).SelectedItem;
if (item != null)
{
// extract port
var matches = comRegex.Matches(item);
if(matches.Count > 0)
{
// only select valid port numbers (up to (including) 256)
portNumber = UInt32.Parse(matches[0].Value.Split('M')[1]);
if (portNumber <= 256)
{
// set valid port
port.PortName = matches[0].Value;
commandQueue.ValidatePort();
} else if (portNumber == 257)
{
// virtual mode, increase limitations as no real arduino is connected
matrixWidth.Maximum = MATRIX_LIMITED_WIDTH;
matrixHeight.Maximum = MATRIX_LIMITED_HEIGHT;
} else
{
// no port selected reset settings
matrixWidth.Maximum = MATRIX_START_WIDTH;
matrixHeight.Maximum = MATRIX_START_HEIGHT;
}
}
}
}
}
}
#endregion
#region Scale
/// <summary>
/// Applies a new size to the gif and matrix
/// </summary>
private void AdjustMatrixTable()
{
int width = (int)this.matrixWidth.Value;
int height = (int)this.matrixHeight.Value;
matrixView.resize(width, height);
ResizeGif();
// Delay.Minimum = Math.Min(Width.Value * Height.Value * 5, 500);
}
private void Width_ValueChanged(object sender, EventArgs e)
{
AdjustMatrixTable();
commandQueue.EnqueueArduinoCommand(
OPCODE_SCALE, // opcode
(byte)matrixWidth.Value,
(byte)matrixHeight.Value
);
}
private void Height_ValueChanged(object sender, EventArgs e)
{
AdjustMatrixTable();
commandQueue.EnqueueArduinoCommand(
OPCODE_SCALE, // opcode
(byte)matrixWidth.Value,
(byte)matrixHeight.Value
);
}
#endregion
#region Edit/Draw
#region TextBoxen
private void ZeichnenTextBoxRed_KeyUp(object sender, KeyEventArgs e)
{
if (int.TryParse(ZeichnenTextBoxRed.Text, out var value) && value < 256 && value >= 0)
{
ZeichnenTrackBarRed.Value = value;
ZeichnenFarbRad.setRGB((byte)ZeichnenTrackBarRed.Value, (byte)ZeichnenTrackBarGreen.Value, (byte)ZeichnenTrackBarBlue.Value);
}
else if (value >= 256)
{
ZeichnenTrackBarRed.Value = 255;
ZeichnenTextBoxRed.Text = "255";
ZeichnenFarbRad.setRGB((byte)ZeichnenTrackBarRed.Value, (byte)ZeichnenTrackBarGreen.Value, (byte)ZeichnenTrackBarBlue.Value);
}
matrixView.SetPaintColor(Color.FromArgb(ZeichnenTrackBarRed.Value, ZeichnenTrackBarGreen.Value, ZeichnenTrackBarBlue.Value));
}
private void ZeichnenTextBoxGreen_KeyUp(object sender, KeyEventArgs e)
{
if (int.TryParse(ZeichnenTextBoxGreen.Text, out var value) && value < 256 && value >= 0)
{
ZeichnenTrackBarGreen.Value = value;
ZeichnenFarbRad.setRGB((byte)ZeichnenTrackBarRed.Value, (byte)ZeichnenTrackBarGreen.Value, (byte)ZeichnenTrackBarBlue.Value);
}
else if (value >= 256)
{
ZeichnenTrackBarGreen.Value = 255;
ZeichnenTextBoxGreen.Text = "255";
ZeichnenFarbRad.setRGB((byte)ZeichnenTrackBarRed.Value, (byte)ZeichnenTrackBarGreen.Value, (byte)ZeichnenTrackBarBlue.Value);
}
matrixView.SetPaintColor(Color.FromArgb(ZeichnenTrackBarRed.Value, ZeichnenTrackBarGreen.Value, ZeichnenTrackBarBlue.Value));
}
private void ZeichnenTextBoxBlue_KeyUp(object sender, KeyEventArgs e)
{
if (int.TryParse(ZeichnenTextBoxBlue.Text, out var value) && value < 256 && value >= 0)
{
ZeichnenTrackBarBlue.Value = value;
ZeichnenFarbRad.setRGB((byte)ZeichnenTrackBarRed.Value, (byte)ZeichnenTrackBarGreen.Value, (byte)ZeichnenTrackBarBlue.Value);
}
else if (value >= 256)
{
ZeichnenTrackBarBlue.Value = 255;
ZeichnenTextBoxBlue.Text = "255";
ZeichnenFarbRad.setRGB((byte)ZeichnenTrackBarRed.Value, (byte)ZeichnenTrackBarGreen.Value, (byte)ZeichnenTrackBarBlue.Value);
}
matrixView.SetPaintColor(Color.FromArgb(ZeichnenTrackBarRed.Value, ZeichnenTrackBarGreen.Value, ZeichnenTrackBarBlue.Value));
}
#endregion
#region TackBars
private void ZeichnenTrackBarRed_Scroll(object sender, EventArgs e)
{
ZeichnenTextBoxRed.Text = ZeichnenTrackBarRed.Value.ToString();
ZeichnenFarbRad.setRGB((byte)ZeichnenTrackBarRed.Value, (byte)ZeichnenTrackBarGreen.Value, (byte)ZeichnenTrackBarBlue.Value);
matrixView.SetPaintColor(Color.FromArgb(ZeichnenTrackBarRed.Value, ZeichnenTrackBarGreen.Value, ZeichnenTrackBarBlue.Value));
}
private void ZeichnenTrackBarGreen_Scroll(object sender, EventArgs e)
{
ZeichnenTextBoxGreen.Text = ZeichnenTrackBarGreen.Value.ToString();
ZeichnenFarbRad.setRGB((byte)ZeichnenTrackBarRed.Value, (byte)ZeichnenTrackBarGreen.Value, (byte)ZeichnenTrackBarBlue.Value);
matrixView.SetPaintColor(Color.FromArgb(ZeichnenTrackBarRed.Value, ZeichnenTrackBarGreen.Value, ZeichnenTrackBarBlue.Value));
}
private void ZeichnenTrackBarBlue_Scroll(object sender, EventArgs e)
{
ZeichnenTextBoxBlue.Text = ZeichnenTrackBarBlue.Value.ToString();
ZeichnenFarbRad.setRGB((byte)ZeichnenTrackBarRed.Value, (byte)ZeichnenTrackBarGreen.Value, (byte)ZeichnenTrackBarBlue.Value);
matrixView.SetPaintColor(Color.FromArgb(ZeichnenTrackBarRed.Value, ZeichnenTrackBarGreen.Value, ZeichnenTrackBarBlue.Value));
}
#endregion
/// <summary>
/// Sets a new color to the edit tab
/// </summary>
/// <param name="color"></param>
public void SetColor(Color color)
{
ZeichnenTrackBarRed.Value = color.R;
ZeichnenTrackBarGreen.Value = color.G;
ZeichnenTrackBarBlue.Value = color.B;
ZeichnenTextBoxRed.Text = color.R.ToString();
ZeichnenTextBoxGreen.Text = color.G.ToString();
ZeichnenTextBoxBlue.Text = color.B.ToString();
ZeichnenFarbRad.setRGB(color.R, color.G, color.B);
}
/// <summary>
/// Updates trackbars and RGB-textboxes according to color wheel settings
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FarbRad_Handler(object sender, EventArgs e)
{
ZeichnenTrackBarRed.Value = ZeichnenFarbRad.getRed();
ZeichnenTrackBarGreen.Value = ZeichnenFarbRad.getGreen();
ZeichnenTrackBarBlue.Value = ZeichnenFarbRad.getBlue();
ZeichnenTextBoxRed.Text = ZeichnenFarbRad.getRed().ToString();
ZeichnenTextBoxGreen.Text = ZeichnenFarbRad.getGreen().ToString();
ZeichnenTextBoxBlue.Text = ZeichnenFarbRad.getBlue().ToString();
matrixView.SetPaintColor(Color.FromArgb(ZeichnenTrackBarRed.Value, ZeichnenTrackBarGreen.Value, ZeichnenTrackBarBlue.Value));
}
/// <summary>
/// Fills the entire Matrix with a color
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ZeichnenFill_Click(object sender, EventArgs e)
{
var color = Color.FromArgb(ZeichnenTrackBarRed.Value, ZeichnenTrackBarGreen.Value, ZeichnenTrackBarBlue.Value);
matrixView.SetPaintColor(color);
matrixView.Fill(color);
commandQueue.EnqueueArduinoCommand(
OPCODE_FILL, // Opcode
(byte)ZeichnenTrackBarRed.Value, // Red
(byte)ZeichnenTrackBarGreen.Value,// Green
(byte)ZeichnenTrackBarBlue.Value // Blue
);
}
/// <summary>
/// Sets the entire Matrix to black
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ZeichnenClear_Click(object sender, EventArgs e)
{
matrixView.Fill(Color.Black);
commandQueue.EnqueueArduinoCommand(
OPCODE_FILL, // opcode
0, // red
0, // green
0 // blue
);
}
#endregion
#region Image-Drag-Drop
/// <summary>
/// Handles click event, opens a file dialog to choose and image file
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DragDrop_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.InitialDirectory = "c:\\";
openFileDialog.Filter = "image files (*.PNG;*.JPG;*.GIF)|*.*";
openFileDialog.FilterIndex = 2;
openFileDialog.RestoreDirectory = true;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string filePath = openFileDialog.FileName;
loadFromFile(filePath);
}
}
}
/// <summary>
/// Loads an image file froim disk and sets the matrix to it.
/// If the image is an gif, the gif buffer will be set to the gif, as well as the matrix itself.
/// </summary>
/// <param name="filePath"></param>
private void loadFromFile(string filePath)
{
// load gif
if (filePath.ToLower().EndsWith(".gif"))
{
var gif = Image.FromFile(filePath);
int frames = Math.Min(gif.GetFrameCount(FrameDimension.Time), 120);
if (gif.GetFrameCount(FrameDimension.Time) > 120)
{
MessageBox.Show("Das Gif ist zu Groß. Die Maximalgröße sind 120 Frames. Das Gif wird abgeschnitten sein, damit es in die Maximalgröße passt.", "Gif to large");
}
FrameCount.Value = frames;
Timeline.Maximum = frames - 1;
// resize gif buffer to fit loaded gif frame count
ResizeGif();
// fetch and store frames
for (int i = 0; i < frames; i++)
{
gif.SelectActiveFrame(FrameDimension.Time, i);
// resize gif to fit scale
var bitmap = ResizeImage(gif, matrixView.matrixWidth(), matrixView.matrixHeight());
// fetch each pixel and store
for (int x = 0; x < bitmap.Width; x++)
{
for (int y = 0; y < bitmap.Height; y++)
{
var pixel = bitmap.GetPixel(x, y);
int index = x + y * bitmap.Width;
matrixView.SetPixelNoRefresh(x, y, pixel);
Gif[i][index * 3] = pixel.G;
Gif[i][index * 3 + 1] = pixel.R;
Gif[i][index * 3 + 2] = pixel.B;
}
}
}
matrixView.Refresh();
Timeline.Value = 0;
}
else
{
Bitmap bitmap = new Bitmap(filePath);
bitmap = ResizeImage(bitmap, matrixView.matrixWidth(), matrixView.matrixHeight());
matrixView.SetImage(bitmap);
for (int x = 0; x < bitmap.Width; x++)
{
for (int y = 0; y < bitmap.Height; y++)
{
var pixel = bitmap.GetPixel(x, y);
int index = x + y * bitmap.Width;
Gif[Timeline.Value][index * 3] = pixel.G;
Gif[Timeline.Value][index * 3 + 1] = pixel.R;
Gif[Timeline.Value][index * 3 + 2] = pixel.B;
}
}
}
writeImage(Gif[Timeline.Value]);
}
private void DragDrop_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void DragDrop_DragDrop(object sender, DragEventArgs e)
{
string[] picturePath = (string[])e.Data.GetData(DataFormats.FileDrop);
loadFromFile(picturePath[0]);
}
#endregion
#region Timeline
public void ResetTimeline()
{
Timeline.Value = 1;
Timeline.Value = 0;
}
public int GetDelayTime()
{
return (int)Delay.Value;
}
private void FrameCount_ValueChanged(object sender, EventArgs e)
{
ResizeGif();
Timeline.Value = 0;
if (FrameCount.Value == 1)
{
Timeline.Enabled = false;
}
else
{
Timeline.Enabled = true;
Timeline.Maximum = (int)FrameCount.Value - 1;
}
}
private void Timeline_ValueChanged(object sender, EventArgs e)
{
int width = matrixView.matrixWidth();
int height = matrixView.matrixHeight();
for (int y = 0; y < height; y++)
{
int index = y * width;
for (int x = 0; x < width; x++)
{
int tmp = (index + x) * 3;
var color = Color.FromArgb(Gif[Timeline.Value][tmp + 1], Gif[Timeline.Value][tmp], Gif[Timeline.Value][tmp + 2]);
matrixView.SetPixelNoRefresh(x, y, color);
}
}
matrixView.Refresh();
writeImage(Gif[Timeline.Value]);
}
/// <summary>
/// Stores the current matrix at the index noted by the timeline into the Gif
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Apply_Click(object sender, EventArgs e)
{
int width = matrixView.matrixWidth();
int height = matrixView.matrixHeight();
for (int y = 0; y < height; y++)
{
int i = y * width;
for (int x = 0; x < width; x++)
{
int tmp = (i + x) * 3;
var color = matrixView.GetPixel(x, y);
Gif[Timeline.Value][tmp] = color.G;
Gif[Timeline.Value][tmp + 1] = color.R;
Gif[Timeline.Value][tmp + 2] = color.B;
}
}
}
private void timelineupdate(Object source, ElapsedEventArgs e)
{
if (Timeline.InvokeRequired)
{
// invoke on the comboboxes thread
Timeline.Invoke(new Action(() =>
{
if (Timeline.Value < Timeline.Maximum)
{
Timeline.Value = Timeline.Value + 1;
}
else
{
Timeline.Value = 0;
}
}));
}
}
/// <summary>
/// Starts playing the timeline
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Play_Click(object sender, EventArgs e)
{
if (!(FrameCount.Value == 1))
{
if (!runningGif)
{
Play.Text = "Stop";
Timeline.Value = 0;
runningGif = true;
delay.Enabled = true;
Play.Image = new Bitmap(Matrix_App.Properties.Resources.Stop);
}
else
{
Play.Image = new Bitmap(Matrix_App.Properties.Resources.Play);
Play.Text = "Play";
runningGif = false;
delay.Enabled = false;
}
}
}
private void Timeline_MouseDown(object sender, MouseEventArgs e)
{
if (runningGif)
{
Play.Image = new Bitmap(Matrix_App.Properties.Resources.Play);
Play.Text = "Play";
runningGif = false;
delay.Enabled = false;
}
}
private void Delay_ValueChanged(object sender, EventArgs e)
{
delay.Interval = (int)Delay.Value;
}
#endregion
#region Properties
private void Save_Click(object sender, EventArgs e)
{
SaveFileDialog save = new SaveFileDialog();
save.InitialDirectory = "c:\\";
save.Filter = "image files (*.PNG;*.JPG;*.GIF)|*.*";
save.FilterIndex = 2;
save.RestoreDirectory = true;
if (save.ShowDialog() == DialogResult.OK)
{
string filePath = save.FileName;
Bitmap[] gifBitmap = new Bitmap[Gif.Length];
GifWriter writer = new GifWriter(File.Create(filePath));
for (int i = 0; i < FrameCount.Value; i++)
{
gifBitmap[i] = new Bitmap((int)matrixWidth.Value, (int)matrixHeight.Value);
for (int j = 0; j < Gif[i].Length / 3; j++)
{
int y = j / (int)matrixWidth.Value;
int x = j % (int)matrixWidth.Value;
gifBitmap[i].SetPixel(x, y, Color.FromArgb(Gif[i][j * 3 + 1], Gif[i][j * 3], Gif[i][j * 3 + 2]));
}
writer.WriteFrame(gifBitmap[i], (int)Delay.Value);
}
writer.Dispose();
}
}
private void ConfigButton_Click(object sender, EventArgs e)
{
commandQueue.EnqueueArduinoCommand(4);
commandQueue.WaitForLastDequeue();
byte[] data = commandQueue.GetLastData();
if (commandQueue.GetMark() > 0)
{
int width = data[0];
int height = data[1];
this.matrixWidth.Value = width;
this.matrixHeight.Value = height;
for (int x = 0; x < width * height * 3; x++)
{
Gif[0][x] = data[2 + x];
}
Timeline.Value = 1;
Timeline.Value = 0;
}
}
private void showGridCheckbox_CheckedChanged(object sender, EventArgs e)
{
matrixView.DrawGrid = showGridCheckbox.Checked;
matrixView.Refresh();
}
private void BrushSizeSlider_Scroll(object sender, EventArgs e)
{
matrixView.brushSize = BrushSizeSlider.Value;
}
/// <summary>
/// Resizes the Gif image buffer
/// </summary>
private void ResizeGif()
{
int frames = (int)FrameCount.Value;
Gif = new byte[frames + 1][];
for (int i = 0; i <= frames; i++)
{
Gif[i] = new byte[matrixView.matrixWidth() * matrixView.matrixHeight() * 3];
}
}
#endregion
#region Appearance
private void ApplyDarkModeButton_Click(object sender, EventArgs e)
{
new DarkMode().ApplyTheme(this);
}
private void ApplyLightModeButton_Click(object sender, EventArgs e)
{
new LightMode().ApplyTheme(this);
}
#endregion
#endregion
#region IO-Utils
private void writeImage(byte[] RGBimageData)
{
commandQueue.EnqueueArduinoCommand(OPCODE_IMAGE, RGBimageData);
}
/// <summary>
/// Converts the matrix's pixel ARGB buffer to an 3-byte RGB tuple array and sends them to the arduino
/// </summary>
public void EnqueuePixelSet()
{
var pixels = matrixView.getPixels();
byte[] image = new byte[pixels.Length * 3];
for (int x = 0; x < pixels.Length; x++)
{
image[x * 3] = (byte)(pixels[x] >> 8 & 0xFF);
image[x * 3 + 1] = (byte)(pixels[x] >> 16 & 0xFF);
image[x * 3 + 2] = (byte)(pixels[x] & 0xFF);
}
writeImage(image);
}
#endregion
}
}

View File

@ -0,0 +1,254 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing.Common" name="System.Drawing.Common, Version=4.0.2.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" />
<data name="Save.Image" type="System.Drawing.Bitmap, System.Drawing.Common" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAACAAAAAdCAYAAADLnm6HAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAA
jAAAAIwBFCEVQAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAFOSURBVEhLY0AC
nECsRCUsBcQkA2cg/k8VzMj4F0hHATFJwJmVT/qLbuP//4Wr/v///IN4/On7PzAGsdOX/P+vGLfzPyMz
2y+gmTEQo4kDcAeUrvlPNDh79izc51+/fv2fs/z/f5AZSI6IBhlODKCqA0BYIXYHzBFERQfVHUCqI2ji
AIgjtsMcEQmyCBegmQNAGMkRESDLsAGaOgCEFWK24XUEWQ74+fPn/zt37oDxv3//8DoAhOUjNwAdwfoT
aJ8NxFoEgDvAsuP/f/+p5GHzduwWI2MuedvPQPtSIdYiANwBtMY88nZDwAH6TdTHesQ6AJSQaAG6d446
YNQBow4YdcCoA4h0AKhKxVbVUoptuoh0AK0xLgf4MDKx/GEX0/6KFYtqfWEXUf9ICmYTUv7Mwiv1DR0D
m2V/gPZhOADUpwulAg4BYhcisDQDAwMDAPDxdBOTD9GgAAAAAElFTkSuQmCC
</value>
</data>
<data name="Clear.Image" type="System.Drawing.Bitmap, System.Drawing.Common" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAACAAAAAbCAYAAAAdx42aAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAA
gwAAAIMBYu+7WgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAALVSURBVEhLvZZL
bxJRFMeP4gMl9f2Kmho1Kj421lg3LmyTxpWv1NiFbnVlYpS48gOw8Fv4AYyJEV3hwrjTgtpqfKZGioXy
qMizKTP+/3TuZGaAwlDhJL8Fw9zzO/fecy/If4oV4BKYAkf5oJexElwGFaCDBDgBehKUXwFKruhJEZRf
BfNA3yxSfigSx0ONn0EcdG071MzLQN+IFZgQycGqP8fsPSJVPgddWQm156b8o8gc5YoXIjPdKoJydrsp
nxTJWuWKbhTRtlzxROS3pSdYxHHQUbiWKxxFzADXRdjkGxYbri25YjlFUH4RdCxXPO6gCMrNG86QZ5yJ
3cB7grkMeG17QcOwzdwHeUQkZU3mlp8ofpsxGcCVuAPoqQs+vABq8r6+vsqr/v6EM6EbMiKxnSIF5jN4
BHaBugJscp/PV4lEIulcJjNX9vvj1qTtkhOZ3o1bkvkMQuAkWA/4K2qGUz5PuW6EtrCQ1AcGvlqTt+Iv
5Hvs8tfgDEBL2WdfJ49Go6bcjGp1Vh8c/GyVNAPrndiPE8N8BuPgLNgEbHIuQ2u5Ck3L6kNDE1aZkyLk
B9B0zGfwCZwDWwBuaHuo2deaxOv1VsPh8LShaxya9kcfGflglSogTx60y3+A82ArqJMzWMB2cA9gvOge
j0cLhULvDV2zyOujo+NWeQnywyJp5jCIAR7nHWAVaBjcAl4IR8ADkAe1BMFg8B1E2qKvYRS0sbG3lONf
SRpX26waC5LgGsAJrMltHe8MrgKPhR/cB2bnBgKByVQq9S2bzX5RFIvFX6VSKUYK+fzU9+HhN8fscm7B
DYATKKvBknIVLGIdOARuA+tSugGnT26BvWANaEuugi+zCPSR3ARcxkaSZrCH7oJ9wLVcBQetBUxyHTwF
YfCyBc8A73cc/9r4juQqOJgzYPdie+UUOL0E/J5/uXi/L1uugknYF+xgNhILaga/53t834Vc5B/O9+1Z
yiBWVQAAAABJRU5ErkJggg==
</value>
</data>
<data name="fill.Image" type="System.Drawing.Bitmap, System.Drawing.Common" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAA
jAAAAIwBFCEVQAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAASrSURBVFhHvdcJ
iFVVGMDxo046WqajlpOtmllSZIstIKOUJUU1NTGaZcE0rbbQajPqPLMkTMKkiMLCFi3LdtoIor0Y2yEK
k4pooVKQxMZJbWZu//+8OXjfm/dm1NQDP3rdufd85373O4thJ7U9MA0l6Ike2C3NQFPwPRJcg6EoxS4f
xOn4CgaO/kAVDoTZ2CXtVKxEOnBr6vcrGI/+6I3rsC8cUC/scGZOxGtIB96ML/AiNnVc24DpuABfd1x7
GCOwH7b78xyFl9CGGPhffIkVWI6H8A7i3/9M/dZa3IjzMAxmott2KJYhnV4H4Vs9hxi4HufiLDiwdOAW
fIzHsAQ34wj4aYq2/WHHW5AOvAqm2sCmdDbOxxjcgPy3Xo/X8QwMfie8/wA4bTu1wbgHG5Hu6Ae8DAM/
gjlw6hnY4lqK9P3RP7Bm7kUNToLptwZcK3KaRfEd0h38jFdh4PgGF+E4lMOO/JbOCu//G+8iPTU/wxUw
7Xui6Czw4gzEB7+BBfY47sIlOAG+QV/E1U6m08/RADP0IJwJ9tOMWzEKBdMemx35CdbAB02fA7Byx8Hv
1g+F3sBrDswiNNVn4D7El3kPEzEAnVKfbo5wLuKDLjZ+a+euf8sPHJvX+8Al2IGWwQG5KtqPWbD6R6LL
LDg6O8lWc0np5jDhjqWhtvH6MKt5apiTTC4q0zIlR33ThWFU5dPt/WR9AJfugeg2C1Z59sFJCxMC7JiG
LUkoGxEH4CppjR2GbrOwD35HEvoNSUL9hsIBtkXlo3EAckGahC6yUPOTU8tVaiayD068u3Dn2yLTkoTB
h8cBmIU6FJkRc5OBIdPmTuY0sxZ+RRL6Dv5/WahaFgegRjhLLNS8LGRaF7Q/MO2NWv7PnWtrFk6ZV7jz
bTFjXRL6DIgDcPechbwszGgq5+aN7Q/csuZHrniocBf8BUkoLUtC3frCAYqZuTEJpy0gg4Ni8Oh9mIVU
LWRa5+U8fOzlT3C1Arch++CE23MDFGP1n704Cf2H5QdeB7fwJ2GW3fQYwNyklAfX5nRS2+ibu6odCTOS
TaPpTN+XlmlNQvWzSRg0Mj/wX3CPcGV1e58Pt2/rjAE0tFR36qyhpY2OFnHDybgJ2c4qZufeF138VhKG
jskP3ISP4IJk4IW4Ch7XPDN2nIwyrfMLdjqm5k1usBYsSLfkJPTeyxrZek/Nh0k4qCI/sPvIp/AcYGBf
5Fq4aw7H3vB82LG0z950ZU7gdm1JKD/Gw8TVcAD+NxtgXF0SLluZhOET8wM7zz+Bgf3O98ODikuw+4CB
rfy86Ve5pH+Y2bw6ZwDVK37jL34zD5eHwHm7GknoWZIf2GPY5/D+p/AA3HzOhNPNai8QeGvrFQ4ePzpU
LV8RJj+/KoydTqX28CDiG1RiCOzAyk0H9pjmIeYFxPOhs+YcjIaD7jJwbN7gGX4sfGOrNJ5+PJi61cZ7
voXB3Wrfhm+9GC4uce1wwC7n3QZOtxjAIjkadhTPb/EcYOGYEQfnycdjmjtnNTwfuonFwRY7O3TZfMjT
jWmLqUt35G/PdcfjUkzt+B3/LbjDgbenGcRqdh4b2GPabgmcbgY0UzshcAj/Af9S0PU0RyajAAAAAElF
TkSuQmCC
</value>
</data>
<data name="Play.Image" type="System.Drawing.Bitmap, System.Drawing.Common" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAACIAAAAhCAYAAAC803lsAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAA
jAAAAIwBFCEVQAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMQSURBVFhHtddZ
qE1RHMfxSxkzJkOGZHgxTylDhkwPIl4MDx5IeDRlSJSiZC5EHiQKD4gSCnlAMr0pZUwJkXmW8fs7+Wnd
be999t7n+tXn4f7P2uv+zzlrr71OVcE0xEBMxFwswgyMQlf81zTGbBzHR/xKcQ+bMRg1ljrQu36KuH9a
zlkMQEXph/uITv4GR7ARCzAPq7ADN/AT4Xj9vRN1kTvTEP0KTmMcyk3YHovxDOH1F9EamTMH4bu6hZHI
m0ZYg+/wXFo/LVE2w/EVvvAUmqGS6FN8Bc95CfWQmA54CV9wELXhNIcWb5H0gNaW596FxOyDB16H9osw
43EbU0p/5Y8+mW/Q/D/QH/+kD/SiBn1GR0SjRtzoOfRG3myA5zijQjSH4AHrVYhJ2Iio8f1ohazRensB
z6Ed+m+0cN5BL3yB1kJcoo3YayxD6gIMoj3H165TwZkAv3BShYQkNWJ3kWX9dIOvuaOCswV+Qdt5Uso1
YufRF2nRovd4bYClaK9wMXYl/0nWRsTrpw3icgAeO1oFRbeqi2kLL08j9gGrUR9hdEN4zHQVlJtwsYkK
CSnSiGiLX44was6vz1JBuQIX26qQkCKNaL1oj4pmEzxmqgrKMbg4RIWE5GlEd0PaHXQUHjtUBWUtXFyq
QkKyNJJlT9Hz6wk0Xk/5FihFHXmiyyokJK0RPUN2I8suq0/d11X7f+rQR0Hddp0Rl6RGdBzshazZBl+r
T69atsMv6vEfl2gjRZ7EnaDHiK7X3dQF1dIOPhrqexuEaNyIDjl6J0XOoIfhN7JHhbiEi/Yx1FyYsdiK
pIdiuSyE5/8EHcRio98uOp968FVUekx0JiM8u85HavQdPocv0BO1O4qmFvQ1hk3sRaaMwHv4wrdYggbI
E91J+gnieUSnslxrS5M8QDjJI6xATyRF59xJ0InPR0/TD7BCh2/teOFWHHqIE9AmJjp462eCFmF0rI6G
M1FxtBNeQPQflKMjgO7EpqjR6Cm6EtcQ/dhNe4y+Fp0xauqOS40eavrRNAxjoNN4dN/JmKqq3wbLh9D2
aVoAAAAAAElFTkSuQmCC
</value>
</data>
<data name="Apply.Image" type="System.Drawing.Bitmap, System.Drawing.Common" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAA
jAAAAIwBFCEVQAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAQoSURBVFhH7Zdb
aBxVGMdP5szlzO6kbXbZZpPmstlc6sZFm6ReajD2IWCND1rqZV9EJd4QsT7Ey0OLL+LlxYBIFY0PBQUR
DIoWEooiaAJCyUPBkDYxWmMrdRMJS6Jx0+zxf87OxsnODMk0r/ngx8yc7zvf99+ZM/OdJToh6aRhvLUZ
hJD9cVUd8PI5iWvasyFCOrx8ThKMvYmcSRKm9LG36+v5ufZ2X96oqysg+NjNpvmzl99JOhSarNa0F041
Nnr6S5yorf0XOe+RAr5saeH84EFfPk0mpYDbwuEpL7+TzlDovBBwtq3N01/iw0RiZUfAjoAdAesCXorH
+WfNzb4cr66WAtoZu+Tld5JibEoIOFlT4+kv8XQslpcCYI3gwS1QB+4tG/OiFyTLxvyIE53So426/mur
YUz7Ua/rlxB8JKaq5/z8uyj906io+AVxdwJpyP0wU5S5PZTOJwxj1jlnH2oi5K5trYHlzk7+Yjy+0MrY
j7spfQAxYVG4zKojlD6BRzM52NCQu9bVJeduexFeSKcLN5nm7C5VvVuWIYSCw+AEeBe8A14Bt4IKQUzT
Hu+xrN/nDxzYnoBJFG8xjPMYiwFR+ElwGXAfLoBjQHTf1I2MzaLBXV8zWuzoECv9Iq4jwAJfAK+iXgwB
XWwBKin9B+fBBWQikT/Q77twrYJvgKuQpmncsizXuM3HgDBKH8EhmACs5CvNhvG5SAB7DXgV4AMDA3xw
cNDTZyMembBQIAGWomRxbAX7wN/AlTwajfLFxUWey+V4U1OTy29zBRTfmCAC9ijKcTmpuLq9EvOhoSG+
srLC19bW+MjIiGeMTQbIZ/Fou2lmD1dWzvlxA2PzCJWr2LbvgCtpKpWSv7xk4k709PS44mxOA2liNYtF
tRlVoGRzwJV0bGyMFwoFu3zRZmZmuKIorljwAyg+gocikdyrtbULfhytqsoh1HkHxPWGhH19ffIXl5u4
I/39/RtibX4CwdaAnFC0WbCeTFVVPj09zZeXl3k+n7dLc766usqXlpZ4Npv1ei2/Bdct4AxYT6brOk8m
k5LR0VG7POcTExPr46ZpOosLToFgAtBw3sNRfNefAeUJJcPDw3Z5zsfHxz1jbPpAMAFouQv4/N2Bc/EJ
vgpcibcoYAqIL2kwAW2M/YbW+72cSMhTwJV8CwJEriNA3Mm9gQSIXvByTc1CFJsYXAsTzWVDge7ubp7J
ZCS9vb0bfDYnAYmqqmjbwZtRHhuKQ5YlvgMtQAHiT6bwexVzsgqeB8RU1W5sUv7vhp9glf6FNuvHR4mE
FHBLOHxRXE+l03w/Y5fN4noQdjs4C66B8sKi7w+DFCDYnt3fEQpdfb20H0CSQ22m+fVmILizwTDed47h
rfgA42JTUrK94D7wHBBvitjE7gYlS1RRelrMxb7wK0JI+j85b8sXRw5/OQAAAABJRU5ErkJggg==
</value>
</data>
<data name="DragDropButton.Image" type="System.Drawing.Bitmap, System.Drawing.Common" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAA
jAAAAIwBFCEVQAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHeSURBVFhH7dbN
K2VhAMfxG2pSjJGVlzSEJK9/gVn5BxQRzUKNkKJkYWVrw5atld1sZyfZjYUompGYESOaYiPvL9/fuefo
6XY895yj+1L86tO553HOc373vNwj9p5sSD5aM6AWTrTymAE/4SSrCvzGYopZC8xrIEk+4QsakauBkHlA
5AKTuIK3/SZUJEwiF+iFd9BxzEJl9lCAoIlcQDucoshZi2cE2k/lgiZygXP8iH98TgO037SzFiyRC6zh
BB+dtXiGoP3Scgb6oW3WMYwZXGIfhTBT4i79ErmAMoVreNtvoQVmJqAzpcvjl1cVUPTtOtCGPA0YGYM3
1zHqkZhIBcrcpS2j0OTbGMQt/qEOZkIXaMcFbDeabkZN/AulGiBdUIlD1GjATagCTTiD/qbJNGlivkGT
7qBcA0Z6cIcDVGuABC5QCbXXTadTegSV6ISXAdxjFxUa8EkfVOIPPiNQAf3abUAbf9UA0bVUCU3WDY3r
4H9RBVvMbZMW0H9Iq+66HikzerT0iN3A/FZB4p0t71i+BRbw3f08B7/o7ad3gnldg0b3i7WAfli0XEIO
XkozzDs7TKyXQJbxAamKtcB/mK/bVMRaQKe+OMWSXoJ0yZ4CuptXMsDvvfPmEos9ASmNcqObpRvyAAAA
AElFTkSuQmCC
</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing.Common" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgNUrDH7TMleA0zGYgNQwyH/U
Mel/1DH5d8cu+VqVIu9YkyHWW5gkq1yZJGlttiQOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgNU1GIDVMZaA1DH0f9Qx/3/U
Mf9/1DH/f9Qx/2+5K/9VjSH/U4og/1OKIP9TiiD/U4og/1WOIfhaliKtXZwpLAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbdskB3/UMYGA1DH0f9Qx/3/U
Mf9/1DL/gNQy/4DTMv9prSn/VIoh/1SKIf9UiiH/VIoh/1SKIf9TiiH/U4kg/1OKIP9TiyH7WpYjm1Wq
HAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHnOMRV/0zHBf9Qx/4DU
Mv+A1DL/f9My/3/UMv96zDH/XZsm/1SKIv9UiiL/VIoi/1SKIv9TiyL/U4sh/1OKIf9UiiH/VIoh/1OK
If9TiSD/VY0g1mCXKCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACA0zIuf9Mx44DU
Mv+A1DL/f9Qy/3/UM/+A1TL/dMEv/1mTI/9UiyL/VIwj/1SMI/9UjCP/VIsj/1WMIv9UiyL/VIsi/1SK
Iv9TiyH/VIoh/1SKIf9TiiD/VY0h616dKDkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgNU1GIDU
MeKA1DL/gNQy/3/UM/+A1TL/f9Qz/2qxLP9VjST/VYwk/1WNJf9VjSX/Vo0m/1WNJv9VjSX/VY0l/1WM
JP9UjCP/VYwi/1SLI/9UiiL/U4sh/1SKIf9TiiH/VIwg7VWVIyQAAAAAAAAAAAAAAAAAAAAAAAAAAIDf
QAh/0jHHgNQy/3/TMv9/1DP/gNUz/3rGMv9JaiL/N0Qd/zZAHv83QR//N0Eg/zdBIf84QiH/OEAh/zdA
If84PyD/Nz8f/zY+Hf85RB3/RGEf/1OJIv9UiiL/U4sh/1SKIf9TiiD/Vo8h1lWqHAkAAAAAAAAAAAAA
AAAAAAAAgNUyin/UMv+A1DL/f9Qz/3/UM/9oqC3/KikY/yYjGf8hIxj/HiMY/x8lGP8gJhv/IiQc/yIk
G/8jIhv/JCEa/yUhGf8kHxf/JB0W/yYeFv8pHhj/Li0Z/09/If9UiiL/U4sh/1SKIf9TiSD/WZUinQAA
AAAAAAAAAAAAAHzWMCWA1DH6gNQy/3/UMv+A1TL/ecQy/ygpF/8gIhf/DRoO/wojDv8NLBL/Dy8U/xAu
F/8SKBf/FCMX/xcgFf8cHxT/ISES/yMgEP8fHA3/FxUL/xUTDP8lHhb/LS8Y/1OKIv9TiyL/VIoh/1OK
If9TiyH7YaQrKgAAAAAAAAAAgNUxnH/UMv9/0zL/gNQy/4DUM/9LcSL/IiIX/wwbDv8LKhD/Dj8W/xFP
Gv8UVh//Fk8f/xlDH/8dNh//JjEe/zU1G/9FOxn/TDwW/0U2Ev8zKA//HhoL/xYUDP8kGxX/RGge/1SL
Iv9TiyH/VIoh/1OKIP9blyOuAAAAAIDVKwyA1DH0gNQy/3/UMv9/1DP/gNQ0/zVHHP8cIRX/CyYQ/w5C
Fv8SiSP/FuMw/xnxNv8dxjT/IWgr/ylPKf86SCf/XVMj/8CHIP/nmhz/2Y4X/3tVE/81Kg//GRYL/yMd
Ff84TBr/VYwi/1SKIv9UiiH/U4kg/1OLIPhmqiIPgNQxWH/UMf+A1DL/f9Qy/4DVM/+A1DX/Lz8c/xkk
Fv8NNBT/EmQd/xbzNP8b+jn/IPo+/yP5Qf8ovT3/NWQz/01bMP+4iiz/6qQo/+2iIv/vnx3/6JYX/1I9
Ev8kHw3/Ix4U/zNGGf9UjCP/VIsi/1OKIf9TiiD/U4og/1+gI2aA1DKaf9Mx/4DUMv+A1TL/gNU0/4DV
Nf8uQB3/GScX/xA6F/8Viyb/G/s5/yD5P/8m+ET/KvdI/y7fSf8+cjv/WWk3/9OfNP/mpy//6qUp/+2i
I//wnxz/dFMW/yokEP8jIBX/NEYa/1WMJP9UiyL/U4sh/1SKIf9TiiD/WpYirIDUMcp/1DH/f9Qy/3/U
M/+A1TX/gNU2/y1AHf8YJxn/Ejsa/xhxJf8f9zv/JfhD/yv3Sf8w9k7/NMpN/0J0Q/9ZbD//v5k7/+Oq
Nv/npy//6qQo/+qdIP9bSBr/KCUS/yEiFv8zRhv/VY0k/1WMIv9TiyL/VIoh/1OKIP9XkSHWf9Qx63/U
Mf9/1DL/f9Qz/4DUNf+B1Tf/LT8c/xokGP8UNBv/G1Mn/yKmN/8p80b/L/ZN/zXdUf86iEv/QnBJ/1Fq
Rv90dkT/zKE8/+SpM//ioiv/kXAl/0E7Hf8iIxX/Hx8V/zFFG/9VjSX/VIsi/1SKIv9UiiH/U4og/1aR
IvB/1DH5f9Qx/3/UMv9/1TP/gNQ1/4DUOP8sPhz/GSAa/xUsHf8cQi3/I1s8/ytySv8yglH/N3dU/zxw
U/9BalD/SGhP/1JsTv9ec03/bXdH/1xnQf9GUTT/LTgm/xoiGf8cHRb/MUQa/1WNJf9UjCP/VIoi/1SK
If9TiiD/VY0h+n/UMfl/1DH/f9Qy/3/VM/+A1TX/gNQ4/yo9Gv8XHhj/FiUj/x00Ov8kRlX/K1GB/zJY
lP84YXT/PGNi/z9kWP9BaVn/Q3Nh/0SIdP88o5L/OIt6/y1eT/8gPzb/FSYf/xgdF/8uRBr/VY0l/1SM
I/9UiiL/VIoh/1OKIP9hoSb6f9Qx63/UMf9/1DL/f9Qz/4DUNf+A1Df/KTkb/xQbGf8VICr/HCxP/yM1
vP8qPO3/MUbq/zZP4P86WYr/PWFk/zxvZf86nJD/M+zj/y3y6/8l8+//ILax/xpQSv8TLCj/FB8Z/yxD
Gf9VjSX/VIsj/1SKIv9UiiH/X58l/37SMemA1DHKf9Qx/3/UMv9/1DP/gNQ1/4DUN/8lNxj/EhgZ/xMd
Mf8aJnf/IC/x/yc47v8tQev/M0np/zZPyf84Xm7/N3Nw/zTYz/8w8+v/KvPt/yPz8P8c9PL/Fmxo/xAx
Lv8RHhj/KkEY/1WNJf9UiyL/U4si/2CfJv9+0jD/f9Mxx3/UMZt/0zH/f9My/4DVMv+A1DT/gNQ2/yM1
Fv8PExf/ERkx/xchhf8dKvL/IzLw/yk67f8tQev/MUfT/zJWbf8xb27/L+DZ/yvz7f8l8+7/H/Tx/xn1
9P8UeHX/DzEu/w4cF/8oQBb/VYwk/1WMIv9fnyf/f9Ix/3/UMf9/1DCZftQxWX/TMf+A1DL/gNQy/4DU
NP+A1DX/ITQT/wwRE/8PFin/FBxY/xkk5v8eK/L/IzLw/yc47v8qPan/K0pd/ypgX/8ot7L/JfPv/yD0
8f8b9fP/FuDg/xFRT/8NKSf/CxcS/yY/E/9VjCP/X54m/37SMf9/1DL/f9Qx/37TMleA2zcOf9Qx9YDU
Mv9/1DP/f9Uz/4DUNf8nQBP/Cg8O/wwSHP8QFzf/FB1t/xkkwv8dKdH/IC6j/yM0Wf8kO0X/I0lH/yFh
W/8erKj/G9TR/xbBvv8SaGX/Djg1/wodGv8IEA3/K0YV/1+dJ/9+0jH/gNQy/3/UMf+A1DH0dtgnDQAA
AAB/1TGdgNQy/3/UMv+A1TL/gNU0/0d0H/8HCgn/Cg4S/w0SH/8QFzL/FBxD/xchSf8aJUL/Gyg3/xws
Lv8cMy//Gj03/xhJRP8VTUn/EkRC/w40Mf8LIR7/CBMR/wYKCf9Hdh//fdAy/3/UM/+A1DL/f9Mx/4DV
MZYAAAAAAAAAAIDXLyZ/1DH7gNQy/3/UM/9/1TP/fM0z/xMfDP8IDQr/Cg4R/wwSGP8PFiD/ERkk/xMc
Iv8VHh//FSAd/xUhHf8UJiH/Eigk/xAoJf8NIyD/CxoY/wgSEP8HDQn/HC8Q/37QMv+A1TL/f9Qy/3/U
Mv9/1DHzgNU1GAAAAAAAAAAAAAAAAIDTMYyA1DL/f9Qy/4DVMv+A1TP/brgu/xUkDf8HCgn/Cg8O/w0T
Ef8PFhP/EBgV/xEaFP8SGxT/ERsU/xEaFP8PGhX/DhkU/wwVEf8JEA3/BgoI/x0wD/91wzD/gNUz/3/U
M/+A1DL/f9Qx/3/UMYEAAAAAAAAAAAAAAAAAAAAAgN9ACIDUMtCA1DL/f9Qy/4DVMv+A1TP/f9E0/1KI
JP8zVRj/LksY/y9MGf8vTRv/ME4c/zBOHP8wThz/L04b/y9NG/8uTRr/LUsY/zVYGP9Zkyb/gNQ0/3/U
M/9/1DP/gNQy/4DUMv+A1THMccY5CQAAAAAAAAAAAAAAAAAAAAAAAAAAfNYwJYDVMuqA1DL/f9Qy/4DV
Mv9/1DP/gNU0/4DUNf+A1DX/gdU2/4DVN/+B1Tf/gNQ3/4HVN/+B1Tf/gNU2/4DVNf+A1DX/gNQ0/4DV
M/+A1TL/f9Qz/3/TMv+A1DL/f9Mx44DVNRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfdUvMYDV
MuqA1DL/f9Qy/3/UM/+A1TL/f9Uz/4DUNP+A1DT/gNU1/4DUNf+A1DX/gNQ1/4DUNf+A1DT/gNU0/4DV
M/+A1TP/gNQy/3/UMv+A1DL/gNQy/3/UMeOA0zIuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAfNYwJX/TMtOA1DL/gNQy/3/UMv9/1DP/gNQy/4DVMv9/1DP/f9Qz/3/VM/9/1DP/f9Qz/4DV
Mv+A1TL/f9Qz/3/UMv+A1DL/gNQy/3/UMv9/0jHHetYzGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAccY5CYDTMYx/1DH7gNQy/4DUMv+A1DL/f9My/3/UMv9/1DL/f9Qy/3/U
Mv9/1DL/f9My/4DUMv+A1DL/gNQy/3/UMv+A0zH6gNUyioDfQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIDXLyZ/1TGdf9Qx9X/UMf9/0zH/f9Qx/3/U
Mf9/1DL/f9Qx/3/UMf9/1DH/f9Qx/3/UMf9/1DH1gNUxnHzWMCUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACA2zcOftQxWX/U
MZuA1DHKgNUx6oDUMfqA1DH6gNUx6oDUMcqA1DKagNQxWHbYJw0AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA/8AD//8AAP/8AAA/+AAAH/AAAA/gAAAHwAAAA8AAAAOAAAABgAAAAQAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AA
AAPgAAAH8AAAD/gAAB/8AAA//wAA///AA/8=
</value>
</data>
</root>

View File

@ -0,0 +1,404 @@
using Matrix_App.PregeneratedMods;
using System;
using System.Drawing;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using static Matrix_App.Utils;
using static MatrixDesigner.Defaults;
using Timer = System.Windows.Forms.Timer;
namespace Matrix_App
{
public abstract class MatrixGifGenerator
{
private static readonly MatrixGifGenerator[] Generators =
{
new SimpleRainbow(),
new Rain(),
new Spiral(),
new UvGrid(),
new RandomPixels(),
new Boxblur(),
new ColorAdjust(),
new Grayscale(),
new Invert()
};
private static readonly Timer PlaybackTimer = new Timer();
private static int _playbackFrame;
protected static int totalFrames;
protected static byte[][]? actualStore;
protected static int width;
protected static int height;
private static readonly byte[][] Snapshot;
private static byte[][] _initialBuffer;
private static readonly ThreadQueue Renderer;
private static MatrixGifGenerator? _generator;
static MatrixGifGenerator()
{
PlaybackTimer.Tick += PlaybackFrame;
Snapshot = CreateImageRGB_NT(FILTER_PREVIEW_WIDTH, FILTER_PREVIEW_HEIGHT, 1);
_initialBuffer = CreateImageRGB_NT(FILTER_PREVIEW_WIDTH, FILTER_PREVIEW_HEIGHT, 1);
Renderer = new ThreadQueue("Matrix Gif Renderer", 2);
}
private static void PlaybackFrame(object? sender, EventArgs e)
{
if (_playbackFrame >= _animationBuffer.Length - 1)
{
_playbackFrame = 0;
}
_preview.SetImage(_animationBuffer[_playbackFrame]);
_playbackFrame++;
}
protected abstract void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b);
private static byte[][] _animationBuffer = null!;
private static MatrixDesignerMain _form = null!;
private static Matrix _preview = null!;
public static void GenerateBaseUi(FlowLayoutPanel anchor, Matrix matrix, MatrixDesignerMain form1)
{
_form = form1;
// generate access buttons for available generators
foreach (var generator in Generators)
{
var button = new Button
{
Width = 215,
Text = GetBetterFieldName(generator.GetType().Name)
};
button.Click += (sender, e) => OpenGeneratorUi(generator, matrix);
button.Image = CreateSnapshot(generator);
button.TextImageRelation = TextImageRelation.ImageAboveText;
button.Height = FILTER_PREVIEW_HEIGHT * 2;
anchor.Controls.Add(button);
}
}
private static Image CreateSnapshot(MatrixGifGenerator matrixGifGenerator)
{
_generator = new RandomPixels();
// put some random pixels in as default initial image to operate on for filter
SetGlobalArgs(FILTER_PREVIEW_WIDTH, FILTER_PREVIEW_HEIGHT, 1, null, _initialBuffer);
InvokeGenerator();
BlockBuffer();
_generator = matrixGifGenerator;
// render filter
SetGlobalArgs(FILTER_PREVIEW_WIDTH, FILTER_PREVIEW_HEIGHT, 1, _initialBuffer, Snapshot);
InvokeGenerator();
BlockBuffer();
// convert to bitmap
return ImageWrap(Snapshot[0], width, height);
}
/// <summary>
/// Blocks this thread until no more work is done by the Renderer thread queue
/// </summary>
private static void BlockBuffer()
{
while (Renderer.HasWork())
{
Thread.Sleep(50);
}
}
private static void OpenGeneratorUi(MatrixGifGenerator matrixGifGenerator, Matrix matrix)
{
_generator = matrixGifGenerator;
if (!ShowEditDialog(matrix))
return;
FlipColorStoreRG_GR(_animationBuffer, _form.Gif);
_form.ResetTimeline();
}
private static void SetGlobalArgs(int w, int h, int f, in byte[][]? previous, in byte[][] preview)
{
totalFrames = f;
width = w;
height = h;
_animationBuffer = preview;
actualStore = previous;
}
private static bool ShowEditDialog(Matrix matrix)
{
var success = false;
Initialize(matrix);
Form prompt = new Form
{
Width = 500,
Height = 320,
Text = @"Vorgenerierter Modus: " + _generator.GetType().Name
};
var confirmation = new Button {Text = "Apply", Anchor = AnchorStyles.Top | AnchorStyles.Left};
confirmation.Click += (sender, e) => {
success = true;
prompt.Close();
};
FlowLayoutPanel controlPanel = new FlowLayoutPanel
{
Anchor = AnchorStyles.Top | AnchorStyles.Left,
FlowDirection = FlowDirection.BottomUp,
Dock = DockStyle.Top,
WrapContents = false,
AutoSize = true
};
var fields = _generator.GetType().GetFields();
PlaybackTimer.Interval = _form.GetDelayTime();
PlaybackTimer.Enabled = true;
CreateDivider(controlPanel);
foreach (var field in fields)
{
if (field.IsStatic || !field.IsPublic)
continue;
var fieldValue = field.GetValue(_generator);
controlPanel.Controls.Add(GetFieldUi(field, fieldValue, _generator));
}
if (controlPanel.Controls.Count > 1)
{
CreateDivider(controlPanel);
var label = new Label() { Text = "Settings" };
label.Font = new Font(label.Font, FontStyle.Bold);
controlPanel.Controls.Add(label);
}
controlPanel.Controls.Add(_preview);
CreateDivider(controlPanel);
var playLabel = new Label() { Text = "Playback preview" };
playLabel.Font = new Font(playLabel.Font, FontStyle.Bold);
controlPanel.Controls.Add(playLabel);
FlowLayoutPanel southPane = new FlowLayoutPanel
{
Dock = DockStyle.Bottom,
Anchor = AnchorStyles.Top | AnchorStyles.Left
};
southPane.Controls.Add(confirmation);
southPane.AutoSize = true;
// render once
InvokeGenerator();
prompt.MinimumSize = prompt.Size;
prompt.Controls.Add(controlPanel);
prompt.Controls.Add(southPane);
prompt.Height = southPane.Height * 2 + controlPanel.Height + 16;
prompt.FormBorderStyle = FormBorderStyle.FixedDialog;
prompt.MaximizeBox = false;
prompt.ShowDialog();
PlaybackTimer.Enabled = false;
return success;
}
private static Control GetFieldUi(FieldInfo field, object? fieldValue, MatrixGifGenerator generator)
{
var panel = new FlowLayoutPanel
{
FlowDirection = FlowDirection.LeftToRight,
Anchor = AnchorStyles.Top | AnchorStyles.Left,
AutoSize = true
};
panel.Controls.Add(new Label
{
TextAlign = System.Drawing.ContentAlignment.MiddleLeft,
Text = GetBetterFieldName(field.Name),
Dock = DockStyle.Left,
Anchor = AnchorStyles.Top | AnchorStyles.Left,
Width = 100
});
switch (fieldValue)
{
case int value:
{
var upDown = new NumericUpDown
{
Dock = DockStyle.Fill,
Anchor = AnchorStyles.Top | AnchorStyles.Right,
Width = 360,
Value = value
};
upDown.ValueChanged += (a, b) =>
{
field.SetValue(generator, (int) upDown.Value);
InvokeGenerator();
};
panel.Controls.Add(upDown);
break;
}
case bool value1:
{
var upDown = new CheckBox
{
Dock = DockStyle.Fill, Anchor = AnchorStyles.Top | AnchorStyles.Right, Checked = value1
};
upDown.CheckedChanged += (a, b) =>
{
field.SetValue(generator, (bool) upDown.Checked);
InvokeGenerator();
};
panel.Controls.Add(upDown);
break;
}
case float floatValue:
{
var upDown = new TrackBar
{
Dock = DockStyle.Fill,
Anchor = AnchorStyles.Top | AnchorStyles.Right,
Maximum = 100,
Minimum = 0,
Value = (int) (floatValue * 100.0f),
TickFrequency = 10,
Width = 360
};
upDown.ValueChanged += (a, b) =>
{
field.SetValue(generator, upDown.Value / 1e2f);
InvokeGenerator();
};
panel.Controls.Add(upDown);
break;
}
}
return panel;
}
/// <summary>
/// Generates a new name from standard class names
/// Example: SomeClassA --> some class a
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private static string GetBetterFieldName(string name)
{
var groups = Regex.Match(name, @"([A-Z]*[a-z]+)([A-Z]+[a-z]*)|(.*)").Groups;
var newName = "";
for (var c = 1; c < groups.Count; c++)
{
newName += groups[c].Value.ToLower() + " ";
}
return newName;
}
private static void Initialize(in Matrix matrix)
{
// Create new initial buffer and copy what ever was in the Gif buffer to it
_initialBuffer = CreateImageRGB_NT(matrix.matrixWidth(), matrix.matrixHeight(), _form.Gif.Length);
FlipColorStoreRG_GR(_form.Gif, _initialBuffer);
// Set Generator args
SetGlobalArgs(matrix.matrixWidth(),
matrix.matrixHeight(),
_form.Gif.Length - 1,
_initialBuffer,
CreateImageRGB_NT(matrix.matrixWidth(), matrix.matrixHeight(), _form.Gif.Length)
);
// Create preview matrix
_preview = new Matrix();
_preview.SetEditable(false);
_preview.Anchor = AnchorStyles.Top | AnchorStyles.Left;
_preview.Size = new Size(480, 200);
_preview.resize(matrix.matrixWidth(), matrix.matrixHeight());
}
/// <summary>
/// Adds a separating line to the controls
/// </summary>
/// <param name="controlPanel"></param>
private static void CreateDivider(Control controlPanel)
{
var divider = new Label
{
BorderStyle = BorderStyle.Fixed3D,
AutoSize = false,
Height = 2,
Width = 500
};
controlPanel.Controls.Add(divider);
}
private static void InvokeGenerator()
{
Renderer.Enqueue(delegate
{
for (var frame = 0; frame < _animationBuffer.Length; frame++)
{
for (var x = 0; x < width; x++)
{
var u = x / (float)width;
for (var y = 0; y < height; y++)
{
var v = y / (float)height;
_generator.ColorFragment(x, y, u, v, frame, out var r, out var g, out var b);
var index = (x + y * width) * 3;
_animationBuffer[frame][index] = (byte) Math.Clamp( (int)(r * 255), 0, 255);
_animationBuffer[frame][index + 1] = (byte) Math.Clamp( (int)(g * 255), 0, 255);
_animationBuffer[frame][index + 2] = (byte) Math.Clamp( (int)(b * 255), 0, 255);
}
}
}
return true;
});
}
public static void Close()
{
Renderer.Stop();
}
}
}

BIN
Matrix App/MatrixIcon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,182 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Ports;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using static MatrixDesigner.Defaults;
namespace Matrix_App
{
public class PortCommandQueue
{
private const string threadDeliverName = "Arduino Port Deliver Thread";
private Queue<byte[]> byteWriteQueue = new Queue<byte[]>();
private Thread portDeliverThread;
private SerialPort port;
private bool running = false;
private volatile bool kill = false;
private volatile bool isPortValid = false;
private byte[] recived = new byte[ARDUINO_RECIVCE_BUFFER_SIZE];
private int mark;
public PortCommandQueue(ref SerialPort port)
{
this.port = port;
portDeliverThread = new Thread(new ThreadStart(ManageQueue));
portDeliverThread.Name = threadDeliverName;
}
private void ManageQueue()
{
try
{
while (!kill)
{
if (byteWriteQueue.Count > 0)
{
byte[] bytes;
lock (byteWriteQueue)
{
bytes = byteWriteQueue.Dequeue();
}
lock (port)
{
if (isPortValid)
{
port.Open();
port.Write(bytes, 0, bytes.Length);
int b;
mark = 0;
while((b = port.ReadByte()) != ARDUINO_SUCCESS_BYTE)
{
recived[mark++] = (byte) b;
}
port.Close();
}
}
}
}
} catch (ThreadInterruptedException)
{
Thread.CurrentThread.Interrupt();
return;
}
catch (Exception)
{
// omit
}
}
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
public void Close()
{
try
{
if (running)
{
kill = true;
portDeliverThread.Interrupt();
portDeliverThread.Join(1000);
}
}
catch (ThreadStartException)
{
// omit
}
catch (ThreadInterruptedException)
{
// omit
}
}
public void EnqueueArduinoCommand(params byte[] bytes)
{
if (!running)
{
running = true;
portDeliverThread.Start();
}
if (byteWriteQueue.Count < ARDUINO_COMMAND_QUEUE_SIZE)
{
lock (byteWriteQueue)
{
byteWriteQueue.Enqueue(bytes);
}
}
}
public void EnqueueArduinoCommand(byte opcode, params byte[] data)
{
byte[] wrapper = new byte[data.Length + 1];
System.Buffer.BlockCopy(data, 0, wrapper, 1, data.Length);
wrapper[0] = opcode;
EnqueueArduinoCommand(wrapper);
}
public void DequeueAll()
{
lock (byteWriteQueue)
{
byteWriteQueue.Clear();
}
}
internal void WaitForLastDequeue()
{
int timeCount = 0;
bool wait = true;
while(wait)
{
lock(byteWriteQueue)
{
wait = byteWriteQueue.Count != 0;
}
timeCount++;
Thread.Sleep(500);
wait = timeCount == DEQUEUE_WAIT_TIMEOUT_COUNTER;
}
}
public byte[] GetLastData()
{
return recived;
}
public void ValidatePort()
{
isPortValid = true;
}
public void InvalidatePort()
{
isPortValid = false;
}
public int GetMark()
{
int tmp = mark;
mark = 0;
return tmp;
}
}
}

View File

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Text;
using static Matrix_App.GifGeneratorUtils;
namespace Matrix_App.PregeneratedMods
{
public class Boxblur : MatrixGifGenerator
{
public int blurSize = 2;
protected override void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b)
{
float avrR = 0;
float avrG = 0;
float avrB = 0;
if (blurSize > 0)
{
for (int i = -blurSize; i < blurSize; i++)
{
int s = Math.Clamp(x + i, 0, width - 1);
for (int j = -blurSize; j < blurSize; j++)
{
int t = Math.Clamp(y + j, 0, height - 1);
SampleFrame(actualStore, frame, s, t, width, out float tmpR, out float tmpG, out float tmpB);
avrR += tmpR;
avrG += tmpG;
avrB += tmpB;
}
}
float blurKernelArea = 1.0f / ((blurSize << 1) * (blurSize << 1));
r = avrR * blurKernelArea;
g = avrG * blurKernelArea;
b = avrB * blurKernelArea;
} else
{
SampleFrame(actualStore, frame, x, y, width, out float tmpR, out float tmpG, out float tmpB);
r = tmpR;
g = tmpG;
b = tmpB;
}
}
}
}

View File

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Text;
using static Matrix_App.GifGeneratorUtils;
namespace Matrix_App.PregeneratedMods
{
public sealed class ColorAdjust : MatrixGifGenerator
{
public float hueOffset = 0.0f;
public float saturationBoost = 0.5f;
public float valueBoost = 0.5f;
public float redBoost = 0.5f;
public float greenBoost = 0.5f;
public float blueBoost = 0.5f;
private float boost(float x, float y)
{
return Math.Clamp(x + (y - 0.5f) * 2.0f, 0.0f, 1.0f);
}
protected override void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b)
{
SampleFrame(actualStore, frame, x, y, width, out float tr, out float tg, out float tb);
HsvFromRgb(tr, tg, tb, out float h, out float s, out float value);
h = h / 360.0f + hueOffset;
h = (h - MathF.Floor(h)) * 360.0f;
s = boost(s, saturationBoost);
value = boost(value, valueBoost);
RgbFromHsv(h, s, value, out tr, out tg, out tb);
r = boost(tr, redBoost);
g = boost(tg, greenBoost);
b = boost(tb, blueBoost);
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Text;
using static Matrix_App.GifGeneratorUtils;
namespace Matrix_App.PregeneratedMods
{
public sealed class Grayscale : MatrixGifGenerator
{
public bool byLuminance = false;
protected override void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b)
{
SampleFrame(actualStore, frame, x, y, width, out float lr, out float lg, out float lb);
if (byLuminance)
{
float luminance = 0.2126f * lr + 0.7152f * lg + 0.0722f * lb;
r = luminance;
g = luminance;
b = luminance;
} else
{
float average = (lr + lg + lb) * 0.3333f;
r = average;
g = average;
b = average;
}
}
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;
using static Matrix_App.GifGeneratorUtils;
namespace Matrix_App.PregeneratedMods
{
class Invert : MatrixGifGenerator
{
protected override void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b)
{
SampleFrame(actualStore, frame, x, y, width, out float lr, out float lg, out float lb);
r = 1- lr;
g = 1 -lg;
b = 1 -lb;
}
}
}

View File

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Matrix_App.PregeneratedMods
{
public sealed class Rain : MatrixGifGenerator
{
private float Fract(float x)
{
return x - MathF.Floor(x);
}
private float Step(float x, float y)
{
return y > x ? 1.0f : 0.0f;
}
private float Shower(float u, float v, float x, float y, float t, float frame)
{
float movY = Fract(v - frame * t + y + MathF.Sin(u * 5.0f) * 0.3f);
float opacityX = Step(0.7f, Fract((u + x) * 93.0f));
float opacityY = Step(0.6f, movY);
float drop = MathF.Pow(movY, 6.0f);
return opacityX * opacityY * drop;
}
protected override void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b)
{
float time = frame / (totalFrames * 0.5f);
float s1 = Shower(u, v, 0.00f, 0.0f, 1.0f, time);
float s2 = Shower(u, v, 3.11f, 0.5f, 1.0f, time);
float s3 = Shower(u, v, 3.40f, 0.2f, 0.6f, time);
float s4 = Shower(u, v, 3.20f, 0.7f, 0.6f, time);
float skyLight = (Fract(MathF.Sin(u * v + v) * 67128.0f + time) * 0.3f + 0.7f) * (1.3f - v);
r = skyLight * 0.1f;
g = skyLight * 0.2f;
b = skyLight * 0.3f;
g += 0.5f * s1;
b += s1;
g += 0.4f * s2;
b += s2;
g += 0.2f * s3;
b += 0.3f * s3;
g += 0.1f * s4;
b += 0.2f * s4;
}
}
}

View File

@ -0,0 +1,22 @@
using System;
namespace Matrix_App.PregeneratedMods
{
public class RandomPixels : MatrixGifGenerator
{
public int seed = 0;
protected override void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b)
{
r = next(frame, x, y);
g = next(frame, x, y + 67);
b = next(frame, x, y + 34968);
}
private float next(int frame, int x, int y)
{
float k = MathF.Sin(frame * 2356f + (x + y) * 5334f + (y * x) * 534f + 78.0f + seed * 435f) * 567f;
return k - MathF.Floor(k);
}
}
}

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Text;
using static Matrix_App.GifGeneratorUtils;
namespace Matrix_App
{
public class SimpleRainbow : MatrixGifGenerator
{
public bool radial = false;
public float saturation = 1.0f;
public float value = 1.0f;
public float rotation = 0.0f;
protected override void ColorFragment(in int x, in int y,
in float u, in float v,
in int frame,
out float r, out float g, out float b)
{
if (radial)
{
CartesianToPolar(u - 0.5f, v - 0.5f, out float angle, out float _);
RgbFromHsv(AddHueOffset((angle + MathF.PI) / MathF.PI * 180.0f + frame / (float)totalFrames * 360.0f), saturation, value, out r, out g, out b);
} else
{
RgbFromHsv(AddHueOffset(u * 360.0f + frame / (float) (totalFrames + 0.001) * 360.0f), saturation, value, out r, out g, out b);
}
}
private float AddHueOffset(float hue)
{
return MathF.Abs(hue + rotation * 360) % 360.0f;
}
}
}

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Matrix_App.PregeneratedMods
{
public sealed class Spiral : MatrixGifGenerator
{
/**
float spiral(vec2 m) {
float r = length(m);
float a = atan(m.y, m.x);
float v = sin(100.*(sqrt(r)-0.02*a-.3*t));
return clamp(v,0.,1.);
}
*/
private float SpiralCurve(float s, float t, float time)
{
float r = MathF.Sqrt(s * s + t * t);
float a = MathF.Atan2(t, s);
float v = MathF.Sin(50 * (MathF.Sqrt(r) - 0.02f * a - time));
return v;
}
protected override void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b)
{
float sp = SpiralCurve((u - 0.5f) * 0.1f, (v - 0.5f) * 0.1f, frame / (float) totalFrames);
r = sp;
g = sp;
b = sp;
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Matrix_App.PregeneratedMods
{
class UvGrid : MatrixGifGenerator
{
protected override void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b)
{
r = u;
g = v;
b = 0.5f;
}
}
}

25
Matrix App/Program.cs Normal file
View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Matrix_App
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MatrixDesignerMain());
}
}
}

View File

@ -0,0 +1,143 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Matrix_App.Properties {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Matrix_App.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Apply {
get {
object obj = ResourceManager.GetObject("Apply", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap ClearTool {
get {
object obj = ResourceManager.GetObject("ClearTool", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap FillTool {
get {
object obj = ResourceManager.GetObject("FillTool", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Frosch {
get {
object obj = ResourceManager.GetObject("Frosch", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Gif {
get {
object obj = ResourceManager.GetObject("Gif", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Play {
get {
object obj = ResourceManager.GetObject("Play", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Save {
get {
object obj = ResourceManager.GetObject("Save", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Stop {
get {
object obj = ResourceManager.GetObject("Stop", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View File

@ -0,0 +1,145 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Stop" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Stop.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Play" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Play.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Gif" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Gif.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Apply" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Apply.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="FillTool" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\FillTool.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="ClearTool" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ClearTool.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Save" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Save.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Frosch" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\frosch.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View File

@ -0,0 +1,9 @@
{
"profiles": {
"Matrix App": {
"commandName": "Project",
"remoteDebugEnabled": false,
"nativeDebugging": true
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 819 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 B

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace Matrix_App.Themes
{
public sealed class DarkMode : BasicTheme
{
public DarkMode()
{
Foreground = Color.FromArgb(245, 245, 245);
Background = Color.FromArgb(25, 26, 28);
ButtonBackground = Color.FromArgb(39, 40, 43);
ButtonBorder = Color.FromArgb(31, 32, 36);
TextFieldBackground = Color.FromArgb(25, 25, 28);
IsFlat = true;
}
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace Matrix_App.Themes
{
class LightMode : BasicTheme
{
public LightMode()
{
Foreground = Color.FromArgb(0, 0, 0);
Background = Color.FromArgb(245, 245, 245);
ButtonBackground = Color.FromArgb(224, 223, 218);
ButtonBorder = Color.FromArgb(158, 157, 152);
TextFieldBackground = Color.FromArgb(255, 255, 255);
IsFlat = false;
}
}
}

94
Matrix App/ThreadQueue.cs Normal file
View File

@ -0,0 +1,94 @@
using System.Collections.Generic;
using System.Threading;
namespace Matrix_App
{
public class ThreadQueue
{
public delegate bool Task();
private readonly Queue<Task> taskQueue = new Queue<Task>();
private readonly Thread thread;
private volatile bool running;
private volatile bool working;
private readonly int capacity;
public ThreadQueue(string name, int capacity)
{
this.capacity = capacity;
running = true;
thread = new Thread(IdleQueue)
{
Name = name,
IsBackground = true,
Priority = ThreadPriority.BelowNormal
};
thread.Start();
}
private void IdleQueue()
{
while(running)
{
Task? task = null;
lock(taskQueue)
{
if (taskQueue.Count > 0)
{
working = true;
task = taskQueue.Dequeue();
}
else
{
working = false;
}
}
if (task != null)
{
running = task();
} else
{
try
{
Thread.Sleep(500);
} catch(ThreadInterruptedException)
{
thread.Interrupt();
running = false;
}
}
}
}
public void Enqueue(Task task)
{
lock (taskQueue)
{
if (taskQueue.Count < capacity)
{
taskQueue.Enqueue(task);
working = true;
}
}
}
public bool HasWork()
{
return working;
}
public void Stop()
{
running = false;
thread.Interrupt();
thread.Join(1500);
}
}
}

113
Matrix App/Utils.cs Normal file
View File

@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Text;
using static MatrixDesigner.Defaults;
namespace Matrix_App
{
public sealed class Utils
{
/// <summary>
/// Resizes and image to the specified size in pixels.
/// Sclaing is done via an Bicubic filter.
/// Upscaling will result in blurry images.
/// </summary>
/// <param name="image"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <returns></returns>
public static Bitmap ResizeImage(Image image, int width, int height)
{
var destRect = new Rectangle(0, 0, width, height);
var destImage = new Bitmap(width, height);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
/// <summary>
/// Stores every 3-byte tuple from source into dest, by flipping the 0st and 1st byte of each tuple.
/// </summary>
/// <param name="source"></param>
/// <param name="dest"></param>
public static void FlipColorStoreRG_GR(byte[][] source, byte[][] dest)
{
for (int f = 0; f < dest.Length; f++)
{
for (int x = 0; x < dest[0].Length; x += 3)
{
// flip r, g
dest[f][x + 0] = source[f][x + 1];
dest[f][x + 1] = source[f][x + 0];
dest[f][x + 2] = source[f][x + 2];
}
}
}
/// <summary>
/// Wraps buffer into a bitmap with width and height
/// </summary>
/// <param name="buffer"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <returns></returns>
public static Bitmap ImageWrap(byte[] buffer, int width, int height)
{
var image = new Bitmap(width, height);
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
int index = (x + y * width) * BPP;
image.SetPixel(x, y, Color.FromArgb(
(byte) buffer[index + 0],
(byte) buffer[index + 1],
(byte) buffer[index + 2]
));
}
}
return image;
}
/// <summary>
/// Creates an buffer of RGB-bytes and n-frames.
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="frames"></param>
/// <returns></returns>
public static byte[][] CreateImageRGB_NT(int width, int height, int frames)
{
byte[][] bytes = new byte[frames][];
for (int frame = 0; frame < frames; frame++)
{
bytes[frame] = new byte[width * height * BPP];
}
return bytes;
}
}
}

View File

@ -0,0 +1,187 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v3.1",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v3.1": {
"Matrix App/1.0.0": {
"dependencies": {
"System.IO.Ports": "4.4.0",
"System.Management": "5.0.0"
},
"runtime": {
"Matrix App.dll": {}
}
},
"Microsoft.NETCore.Platforms/5.0.0": {},
"Microsoft.Win32.Registry/5.0.0": {
"dependencies": {
"System.Security.AccessControl": "5.0.0",
"System.Security.Principal.Windows": "5.0.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Win32.Registry.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
},
"runtimeTargets": {
"runtimes/win/lib/netstandard2.0/Microsoft.Win32.Registry.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
},
"System.CodeDom/5.0.0": {
"runtime": {
"lib/netstandard2.0/System.CodeDom.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
},
"System.IO.Ports/4.4.0": {
"dependencies": {
"Microsoft.Win32.Registry": "5.0.0"
},
"runtime": {
"lib/netstandard2.0/System.IO.Ports.dll": {
"assemblyVersion": "4.0.0.0",
"fileVersion": "4.6.25519.3"
}
},
"runtimeTargets": {
"runtimes/win/lib/netstandard2.0/System.IO.Ports.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "4.0.0.0",
"fileVersion": "4.6.25519.3"
}
}
},
"System.Management/5.0.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "5.0.0",
"Microsoft.Win32.Registry": "5.0.0",
"System.CodeDom": "5.0.0"
},
"runtime": {
"lib/netstandard2.0/System.Management.dll": {
"assemblyVersion": "4.0.0.0",
"fileVersion": "5.0.20.51904"
}
},
"runtimeTargets": {
"runtimes/win/lib/netcoreapp2.0/System.Management.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "4.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
},
"System.Security.AccessControl/5.0.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "5.0.0",
"System.Security.Principal.Windows": "5.0.0"
},
"runtime": {
"lib/netstandard2.0/System.Security.AccessControl.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
},
"runtimeTargets": {
"runtimes/win/lib/netcoreapp2.0/System.Security.AccessControl.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
},
"System.Security.Principal.Windows/5.0.0": {
"runtime": {
"lib/netstandard2.0/System.Security.Principal.Windows.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
},
"runtimeTargets": {
"runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.dll": {
"rid": "unix",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
},
"runtimes/win/lib/netcoreapp2.1/System.Security.Principal.Windows.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
}
}
},
"libraries": {
"Matrix App/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Microsoft.NETCore.Platforms/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ==",
"path": "microsoft.netcore.platforms/5.0.0",
"hashPath": "microsoft.netcore.platforms.5.0.0.nupkg.sha512"
},
"Microsoft.Win32.Registry/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==",
"path": "microsoft.win32.registry/5.0.0",
"hashPath": "microsoft.win32.registry.5.0.0.nupkg.sha512"
},
"System.CodeDom/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-JPJArwA1kdj8qDAkY2XGjSWoYnqiM7q/3yRNkt6n28Mnn95MuEGkZXUbPBf7qc3IjwrGY5ttQon7yqHZyQJmOQ==",
"path": "system.codedom/5.0.0",
"hashPath": "system.codedom.5.0.0.nupkg.sha512"
},
"System.IO.Ports/4.4.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-izaIWbjFZdik3ypDuA6GWj6fabhB+tR5M7QLcvAqd+I+VjI8UWoVZkh68Ao8Vf8poWWrCU875r3HQZnQW6a7GA==",
"path": "system.io.ports/4.4.0",
"hashPath": "system.io.ports.4.4.0.nupkg.sha512"
},
"System.Management/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-MF1CHaRcC+MLFdnDthv4/bKWBZnlnSpkGqa87pKukQefgEdwtb9zFW6zs0GjPp73qtpYYg4q6PEKbzJbxCpKfw==",
"path": "system.management/5.0.0",
"hashPath": "system.management.5.0.0.nupkg.sha512"
},
"System.Security.AccessControl/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==",
"path": "system.security.accesscontrol/5.0.0",
"hashPath": "system.security.accesscontrol.5.0.0.nupkg.sha512"
},
"System.Security.Principal.Windows/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==",
"path": "system.security.principal.windows/5.0.0",
"hashPath": "system.security.principal.windows.5.0.0.nupkg.sha512"
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,8 @@
{
"runtimeOptions": {
"additionalProbingPaths": [
"C:\\Users\\SvenV\\.dotnet\\store\\|arch|\\|tfm|",
"C:\\Users\\SvenV\\.nuget\\packages"
]
}
}

View File

@ -0,0 +1,9 @@
{
"runtimeOptions": {
"tfm": "netcoreapp3.1",
"framework": {
"name": "Microsoft.WindowsDesktop.App",
"version": "3.1.0"
}
}
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,187 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v3.1",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v3.1": {
"Matrix App/1.0.0": {
"dependencies": {
"System.IO.Ports": "4.4.0",
"System.Management": "5.0.0"
},
"runtime": {
"Matrix App.dll": {}
}
},
"Microsoft.NETCore.Platforms/5.0.0": {},
"Microsoft.Win32.Registry/5.0.0": {
"dependencies": {
"System.Security.AccessControl": "5.0.0",
"System.Security.Principal.Windows": "5.0.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Win32.Registry.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
},
"runtimeTargets": {
"runtimes/win/lib/netstandard2.0/Microsoft.Win32.Registry.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
},
"System.CodeDom/5.0.0": {
"runtime": {
"lib/netstandard2.0/System.CodeDom.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
},
"System.IO.Ports/4.4.0": {
"dependencies": {
"Microsoft.Win32.Registry": "5.0.0"
},
"runtime": {
"lib/netstandard2.0/System.IO.Ports.dll": {
"assemblyVersion": "4.0.0.0",
"fileVersion": "4.6.25519.3"
}
},
"runtimeTargets": {
"runtimes/win/lib/netstandard2.0/System.IO.Ports.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "4.0.0.0",
"fileVersion": "4.6.25519.3"
}
}
},
"System.Management/5.0.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "5.0.0",
"Microsoft.Win32.Registry": "5.0.0",
"System.CodeDom": "5.0.0"
},
"runtime": {
"lib/netstandard2.0/System.Management.dll": {
"assemblyVersion": "4.0.0.0",
"fileVersion": "5.0.20.51904"
}
},
"runtimeTargets": {
"runtimes/win/lib/netcoreapp2.0/System.Management.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "4.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
},
"System.Security.AccessControl/5.0.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "5.0.0",
"System.Security.Principal.Windows": "5.0.0"
},
"runtime": {
"lib/netstandard2.0/System.Security.AccessControl.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
},
"runtimeTargets": {
"runtimes/win/lib/netcoreapp2.0/System.Security.AccessControl.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
},
"System.Security.Principal.Windows/5.0.0": {
"runtime": {
"lib/netstandard2.0/System.Security.Principal.Windows.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
},
"runtimeTargets": {
"runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.dll": {
"rid": "unix",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
},
"runtimes/win/lib/netcoreapp2.1/System.Security.Principal.Windows.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
}
}
},
"libraries": {
"Matrix App/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Microsoft.NETCore.Platforms/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ==",
"path": "microsoft.netcore.platforms/5.0.0",
"hashPath": "microsoft.netcore.platforms.5.0.0.nupkg.sha512"
},
"Microsoft.Win32.Registry/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==",
"path": "microsoft.win32.registry/5.0.0",
"hashPath": "microsoft.win32.registry.5.0.0.nupkg.sha512"
},
"System.CodeDom/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-JPJArwA1kdj8qDAkY2XGjSWoYnqiM7q/3yRNkt6n28Mnn95MuEGkZXUbPBf7qc3IjwrGY5ttQon7yqHZyQJmOQ==",
"path": "system.codedom/5.0.0",
"hashPath": "system.codedom.5.0.0.nupkg.sha512"
},
"System.IO.Ports/4.4.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-izaIWbjFZdik3ypDuA6GWj6fabhB+tR5M7QLcvAqd+I+VjI8UWoVZkh68Ao8Vf8poWWrCU875r3HQZnQW6a7GA==",
"path": "system.io.ports/4.4.0",
"hashPath": "system.io.ports.4.4.0.nupkg.sha512"
},
"System.Management/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-MF1CHaRcC+MLFdnDthv4/bKWBZnlnSpkGqa87pKukQefgEdwtb9zFW6zs0GjPp73qtpYYg4q6PEKbzJbxCpKfw==",
"path": "system.management/5.0.0",
"hashPath": "system.management.5.0.0.nupkg.sha512"
},
"System.Security.AccessControl/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==",
"path": "system.security.accesscontrol/5.0.0",
"hashPath": "system.security.accesscontrol.5.0.0.nupkg.sha512"
},
"System.Security.Principal.Windows/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==",
"path": "system.security.principal.windows/5.0.0",
"hashPath": "system.security.principal.windows.5.0.0.nupkg.sha512"
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,8 @@
{
"runtimeOptions": {
"additionalProbingPaths": [
"C:\\Users\\SvenV\\.dotnet\\store\\|arch|\\|tfm|",
"C:\\Users\\SvenV\\.nuget\\packages"
]
}
}

View File

@ -0,0 +1,9 @@
{
"runtimeOptions": {
"tfm": "netcoreapp3.1",
"framework": {
"name": "Microsoft.WindowsDesktop.App",
"version": "3.1.0"
}
}
}

View File

@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v5.0", FrameworkDisplayName = "")]

View File

@ -0,0 +1,25 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("Matrix App")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
[assembly: System.Reflection.AssemblyProductAttribute("Matrix App")]
[assembly: System.Reflection.AssemblyTitleAttribute("Matrix App")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
[assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")]
[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")]
// Von der MSBuild WriteCodeFragment-Klasse generiert.

View File

@ -0,0 +1 @@
19c0607f74f6f7adeef5d846ea9975d1b2986cb6

View File

@ -0,0 +1,8 @@
is_global = true
build_property.TargetFramework = net5.0-windows
build_property.TargetPlatformMinVersion = 7.0
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.PublishSingleFile =
build_property.IncludeAllContentForSelfExtract =
build_property._SupportedPlatformList = Android,iOS,Linux,macOS,Windows

View File

@ -0,0 +1,222 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v5.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v5.0": {
"Microsoft.NETCore.Platforms/5.0.0": {},
"Microsoft.Win32.Registry/5.0.0": {
"dependencies": {
"System.Security.AccessControl": "5.0.0",
"System.Security.Principal.Windows": "5.0.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Win32.Registry.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
},
"runtimeTargets": {
"runtimes/win/lib/netstandard2.0/Microsoft.Win32.Registry.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
},
"runtime.linux-arm.runtime.native.System.IO.Ports/5.0.0-rtm.20519.4": {
"runtimeTargets": {
"runtimes/linux-arm/native/libSystem.IO.Ports.Native.so": {
"rid": "linux-arm",
"assetType": "native",
"fileVersion": "0.0.0.0"
}
}
},
"runtime.linux-arm64.runtime.native.System.IO.Ports/5.0.0-rtm.20519.4": {
"runtimeTargets": {
"runtimes/linux-arm64/native/libSystem.IO.Ports.Native.so": {
"rid": "linux-arm64",
"assetType": "native",
"fileVersion": "0.0.0.0"
}
}
},
"runtime.linux-x64.runtime.native.System.IO.Ports/5.0.0-rtm.20519.4": {
"runtimeTargets": {
"runtimes/linux-x64/native/libSystem.IO.Ports.Native.so": {
"rid": "linux-x64",
"assetType": "native",
"fileVersion": "0.0.0.0"
}
}
},
"runtime.native.System.IO.Ports/5.0.0": {
"dependencies": {
"runtime.linux-arm.runtime.native.System.IO.Ports": "5.0.0-rtm.20519.4",
"runtime.linux-arm64.runtime.native.System.IO.Ports": "5.0.0-rtm.20519.4",
"runtime.linux-x64.runtime.native.System.IO.Ports": "5.0.0-rtm.20519.4",
"runtime.osx-x64.runtime.native.System.IO.Ports": "5.0.0-rtm.20519.4"
}
},
"runtime.osx-x64.runtime.native.System.IO.Ports/5.0.0-rtm.20519.4": {
"runtimeTargets": {
"runtimes/osx-x64/native/libSystem.IO.Ports.Native.dylib": {
"rid": "osx-x64",
"assetType": "native",
"fileVersion": "0.0.0.0"
}
}
},
"System.IO.Ports/5.0.0": {
"dependencies": {
"Microsoft.Win32.Registry": "5.0.0",
"runtime.native.System.IO.Ports": "5.0.0"
},
"runtime": {
"lib/netstandard2.0/System.IO.Ports.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
},
"runtimeTargets": {
"runtimes/linux/lib/netstandard2.0/System.IO.Ports.dll": {
"rid": "linux",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
},
"runtimes/osx/lib/netstandard2.0/System.IO.Ports.dll": {
"rid": "osx",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
},
"runtimes/win/lib/netstandard2.0/System.IO.Ports.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
},
"System.Security.AccessControl/5.0.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "5.0.0",
"System.Security.Principal.Windows": "5.0.0"
},
"runtime": {
"lib/netstandard2.0/System.Security.AccessControl.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
},
"runtimeTargets": {
"runtimes/win/lib/netcoreapp2.0/System.Security.AccessControl.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
},
"System.Security.Principal.Windows/5.0.0": {
"runtime": {
"lib/netstandard2.0/System.Security.Principal.Windows.dll": {
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
},
"runtimeTargets": {
"runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.dll": {
"rid": "unix",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
},
"runtimes/win/lib/netcoreapp2.1/System.Security.Principal.Windows.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "5.0.0.0",
"fileVersion": "5.0.20.51904"
}
}
}
}
},
"libraries": {
"Microsoft.NETCore.Platforms/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ==",
"path": "microsoft.netcore.platforms/5.0.0",
"hashPath": "microsoft.netcore.platforms.5.0.0.nupkg.sha512"
},
"Microsoft.Win32.Registry/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==",
"path": "microsoft.win32.registry/5.0.0",
"hashPath": "microsoft.win32.registry.5.0.0.nupkg.sha512"
},
"runtime.linux-arm.runtime.native.System.IO.Ports/5.0.0-rtm.20519.4": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Np6w3r1dSFB930GGZHIKCc5ZClRXZIqOrCAT0pzcd/zXnsZPvGqLZB1MnxAbVhvriJl71B0N0tJaaT1ICWXsyg==",
"path": "runtime.linux-arm.runtime.native.system.io.ports/5.0.0-rtm.20519.4",
"hashPath": "runtime.linux-arm.runtime.native.system.io.ports.5.0.0-rtm.20519.4.nupkg.sha512"
},
"runtime.linux-arm64.runtime.native.System.IO.Ports/5.0.0-rtm.20519.4": {
"type": "package",
"serviceable": true,
"sha512": "sha512-VnGZmQ7pzMNkcTVdmGtXUQIbytK4Xk8F4/mxm0I+n7zbrsW/WNgLrWMTv9pb2Uyq09azXazNDQhZao4R4ebWcw==",
"path": "runtime.linux-arm64.runtime.native.system.io.ports/5.0.0-rtm.20519.4",
"hashPath": "runtime.linux-arm64.runtime.native.system.io.ports.5.0.0-rtm.20519.4.nupkg.sha512"
},
"runtime.linux-x64.runtime.native.System.IO.Ports/5.0.0-rtm.20519.4": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kvMZgZjtcC6cA8Y8imKpjCpiOJKDtwlNekS86GzUol4Jmzh0FWiRwAj4E9ZKO8R7rTBGIA4rkmra9Ko8j7l6AA==",
"path": "runtime.linux-x64.runtime.native.system.io.ports/5.0.0-rtm.20519.4",
"hashPath": "runtime.linux-x64.runtime.native.system.io.ports.5.0.0-rtm.20519.4.nupkg.sha512"
},
"runtime.native.System.IO.Ports/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ME+/evR+UxVlWyGHUlLBoNTnsTdaylMbnvVwOp0Nl6XIZGGyXdqJqjlEew7e6TcKkJAA0lljhjKi3Kie+vzQ7g==",
"path": "runtime.native.system.io.ports/5.0.0",
"hashPath": "runtime.native.system.io.ports.5.0.0.nupkg.sha512"
},
"runtime.osx-x64.runtime.native.System.IO.Ports/5.0.0-rtm.20519.4": {
"type": "package",
"serviceable": true,
"sha512": "sha512-N+dbbqhT7JBnPVHa7n2+Z5fHYO4a4UUhm7cQkbuQQoNkjbxLpxYnQ4lpRjr1RuQptqYkPmunKvN5etdFOObaiw==",
"path": "runtime.osx-x64.runtime.native.system.io.ports/5.0.0-rtm.20519.4",
"hashPath": "runtime.osx-x64.runtime.native.system.io.ports.5.0.0-rtm.20519.4.nupkg.sha512"
},
"System.IO.Ports/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-MZY/0cgRg5bcuvHR4LKHqWnlxWV7GkoTgBaOdwIoWGZKsfSBC1twDz+BzG0o1Rk46WdRhhV30E2qzsBABHwGUA==",
"path": "system.io.ports/5.0.0",
"hashPath": "system.io.ports.5.0.0.nupkg.sha512"
},
"System.Security.AccessControl/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==",
"path": "system.security.accesscontrol/5.0.0",
"hashPath": "system.security.accesscontrol.5.0.0.nupkg.sha512"
},
"System.Security.Principal.Windows/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==",
"path": "system.security.principal.windows/5.0.0",
"hashPath": "system.security.principal.windows.5.0.0.nupkg.sha512"
}
}
}

View File

@ -0,0 +1,16 @@
{
"runtimeOptions": {
"tfm": "net5.0",
"framework": {
"name": "Microsoft.WindowsDesktop.App",
"version": "5.0.0"
},
"additionalProbingPaths": [
"C:\\Users\\felix\\.dotnet\\store\\|arch|\\|tfm|",
"C:\\Users\\felix\\.nuget\\packages"
],
"configProperties": {
"Microsoft.NETCore.DotNetHostPolicy.SetAppPaths": true
}
}
}

View File

@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v3.1", FrameworkDisplayName = "")]

View File

@ -0,0 +1,23 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("Matrix App")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
[assembly: System.Reflection.AssemblyProductAttribute("Matrix App")]
[assembly: System.Reflection.AssemblyTitleAttribute("Matrix App")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Von der MSBuild WriteCodeFragment-Klasse generiert.

Some files were not shown because too many files have changed in this diff Show More