integrating offline changes

This commit is contained in:
Lars Brubaker 2023-03-10 17:15:55 -08:00
parent 121623bad3
commit 3f8eeda65b
125 changed files with 5442 additions and 5434 deletions

View file

@ -38,175 +38,175 @@ using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.CustomWidgets.ColorPicker
{
public class RadialColorPicker : GuiWidget
{
private (double h, double s, double l) hsl;
private float alpha;
private Color downColor;
public class RadialColorPicker : GuiWidget
{
private (double h, double s, double l) hsl;
private float alpha;
private Color downColor;
private enum DownState
{
None,
OnRing,
OnTriangle,
}
private enum DownState
{
None,
OnRing,
OnTriangle,
}
private DownState downState = DownState.None;
private DownState downState = DownState.None;
public RadialColorPicker()
{
BackgroundColor = Color.White;
public RadialColorPicker()
{
BackgroundColor = Color.White;
this.Width = 100;
this.Height = 100;
}
this.Width = 100;
this.Height = 100;
}
public event EventHandler IncrementalColorChanged;
public event EventHandler IncrementalColorChanged;
public event EventHandler SelectedColorChanged;
public event EventHandler SelectedColorChanged;
public double RingWidth { get => Width / 10; }
public double RingWidth { get => Width / 10; }
public void SetColorWithoutChangeEvent(Color color)
{
color.ToColorF().GetHSL(out double h, out double s, out double l);
// if the color is not white or black, set the angle (otherwise leave it where it is)
if ((color.red != color.green || color.green != color.blue || color.blue != 0)
&& (color.red != color.green || color.green != color.blue || color.blue != 255))
{
hsl.h = h;
}
hsl.s = s;
hsl.l = l;
alpha = color.Alpha0To1;
public void SetColorWithoutChangeEvent(Color color)
{
color.ToColorF().GetHSL(out double h, out double s, out double l);
// if the color is not white or black, set the angle (otherwise leave it where it is)
if ((color.red != color.green || color.green != color.blue || color.blue != 0)
&& (color.red != color.green || color.green != color.blue || color.blue != 255))
{
hsl.h = h;
}
hsl.s = s;
hsl.l = l;
alpha = color.Alpha0To1;
Invalidate();
}
Invalidate();
}
public override void OnKeyDown(KeyEventArgs keyEvent)
{
if (downState != DownState.None
&& keyEvent.KeyCode == Keys.Escape)
{
downState = DownState.None;
SelectedColor = downColor;
}
public override void OnKeyDown(KeyEventArgs keyEvent)
{
if (downState != DownState.None
&& keyEvent.KeyCode == Keys.Escape)
{
downState = DownState.None;
SelectedColor = downColor;
}
base.OnKeyDown(keyEvent);
}
base.OnKeyDown(keyEvent);
}
public Color SelectedColor
{
get
{
return ColorF.FromHSL(hsl.h, hsl.s, hsl.l, alpha).ToColor();
}
public Color SelectedColor
{
get
{
return ColorF.FromHSL(hsl.h, hsl.s, hsl.l, alpha).ToColor();
}
set
{
if (value != SelectedColor)
{
SetColorWithoutChangeEvent(value);
set
{
if (value != SelectedColor)
{
SetColorWithoutChangeEvent(value);
SelectedColorChanged?.Invoke(this, null);
}
}
}
SelectedColorChanged?.Invoke(this, null);
}
}
}
public Color SelectedHueColor
{
get
{
return ColorF.FromHSL(hsl.h, 1, .5).ToColor();
}
public Color SelectedHueColor
{
get
{
return ColorF.FromHSL(hsl.h, 1, .5).ToColor();
}
set
{
value.ToColorF().GetHSL(out double h, out _, out _);
hsl.h = h;
}
}
set
{
value.ToColorF().GetHSL(out double h, out _, out _);
hsl.h = h;
}
}
private double InnerRadius
{
get
{
return RingRadius - RingWidth / 2;
}
}
private double InnerRadius
{
get
{
return RingRadius - RingWidth / 2;
}
}
private double RingRadius
{
get
{
return Width / 2 - RingWidth / 2 - 2;
}
}
private double RingRadius
{
get
{
return Width / 2 - RingWidth / 2 - 2;
}
}
public override void OnDraw(Graphics2D graphics2D)
{
var center = new Vector2(Width / 2, Height / 2);
public override void OnDraw(Graphics2D graphics2D)
{
var center = new Vector2(Width / 2, Height / 2);
// draw the big outside ring (color part)
DrawColorRing(graphics2D, RingRadius, RingWidth);
// draw the big outside ring (color part)
DrawColorRing(graphics2D, RingRadius, RingWidth);
// draw the inner triangle (color part)
DrawColorTriangle(graphics2D, InnerRadius, SelectedHueColor);
// draw the inner triangle (color part)
DrawColorTriangle(graphics2D, InnerRadius, SelectedHueColor);
// draw the big ring outline
graphics2D.Ring(center, RingRadius + RingWidth / 2, 1, Color.Black);
graphics2D.Ring(center, RingRadius - RingWidth / 2, 1, Color.Black);
// draw the big ring outline
graphics2D.Ring(center, RingRadius + RingWidth / 2, 1, Color.Black);
graphics2D.Ring(center, RingRadius - RingWidth / 2, 1, Color.Black);
// draw the triangle outline
var colorAngle = hsl.h * MathHelper.Tau;
graphics2D.Line(GetTrianglePoint(0, InnerRadius, colorAngle), GetTrianglePoint(1, InnerRadius, colorAngle), Color.Black);
graphics2D.Line(GetTrianglePoint(1, InnerRadius, colorAngle), GetTrianglePoint(2, InnerRadius, colorAngle), Color.Black);
graphics2D.Line(GetTrianglePoint(2, InnerRadius, colorAngle), GetTrianglePoint(0, InnerRadius, colorAngle), Color.Black);
// draw the triangle outline
var colorAngle = hsl.h * MathHelper.Tau;
graphics2D.Line(GetTrianglePoint(0, InnerRadius, colorAngle), GetTrianglePoint(1, InnerRadius, colorAngle), Color.Black);
graphics2D.Line(GetTrianglePoint(1, InnerRadius, colorAngle), GetTrianglePoint(2, InnerRadius, colorAngle), Color.Black);
graphics2D.Line(GetTrianglePoint(2, InnerRadius, colorAngle), GetTrianglePoint(0, InnerRadius, colorAngle), Color.Black);
// draw the color circle on the triangle
var unitPosition = new Vector2(hsl.s, hsl.l);
unitPosition.Y = agg_basics.Clamp(unitPosition.Y, .5 - (1 - unitPosition.X) / 2, .5 + (1 - unitPosition.X) / 2);
// draw the color circle on the triangle
var unitPosition = new Vector2(hsl.s, hsl.l);
unitPosition.Y = Util.Clamp(unitPosition.Y, .5 - (1 - unitPosition.X) / 2, .5 + (1 - unitPosition.X) / 2);
var triangleColorCenter = TriangleToWidgetTransform().Transform(unitPosition);
graphics2D.Circle(triangleColorCenter, RingWidth / 2 - 2, new Color(SelectedColor, 255));
graphics2D.Ring(triangleColorCenter, RingWidth / 2 - 2, 2, Color.White);
var triangleColorCenter = TriangleToWidgetTransform().Transform(unitPosition);
graphics2D.Circle(triangleColorCenter, RingWidth / 2 - 2, new Color(SelectedColor, 255));
graphics2D.Ring(triangleColorCenter, RingWidth / 2 - 2, 2, Color.White);
// draw the color circle on the ring
var ringColorCenter = center + Vector2.Rotate(new Vector2(RingRadius, 0), colorAngle);
graphics2D.Circle(ringColorCenter,
RingWidth / 2 - 2,
SelectedHueColor);
graphics2D.Ring(ringColorCenter,
RingWidth / 2 - 2,
2,
Color.White);
// draw the color circle on the ring
var ringColorCenter = center + Vector2.Rotate(new Vector2(RingRadius, 0), colorAngle);
graphics2D.Circle(ringColorCenter,
RingWidth / 2 - 2,
SelectedHueColor);
graphics2D.Ring(ringColorCenter,
RingWidth / 2 - 2,
2,
Color.White);
base.OnDraw(graphics2D);
}
base.OnDraw(graphics2D);
}
public override void OnMouseDown(MouseEventArgs mouseEvent)
{
downColor = SelectedColor;
public override void OnMouseDown(MouseEventArgs mouseEvent)
{
downColor = SelectedColor;
var center = new Vector2(Width / 2, Height / 2);
var direction = mouseEvent.Position - center;
var startColor = SelectedColor;
var center = new Vector2(Width / 2, Height / 2);
var direction = mouseEvent.Position - center;
var startColor = SelectedColor;
if (mouseEvent.Button == MouseButtons.Left)
{
if (direction.Length > RingRadius - RingWidth / 2
&& direction.Length < RingRadius + RingWidth / 2)
{
downState = DownState.OnRing;
if (mouseEvent.Button == MouseButtons.Left)
{
if (direction.Length > RingRadius - RingWidth / 2
&& direction.Length < RingRadius + RingWidth / 2)
{
downState = DownState.OnRing;
var colorAngle = Math.Atan2(direction.Y, direction.X);
if (colorAngle < 0)
{
colorAngle += MathHelper.Tau;
}
var colorAngle = Math.Atan2(direction.Y, direction.X);
if (colorAngle < 0)
{
colorAngle += MathHelper.Tau;
}
hsl.h = colorAngle / MathHelper.Tau;
hsl.h = colorAngle / MathHelper.Tau;
if (hsl.s == 0)
{
@ -215,34 +215,34 @@ namespace MatterHackers.MatterControl.CustomWidgets.ColorPicker
}
Invalidate();
}
else
{
var (inside, position) = WidgetToUnitTriangle(mouseEvent.Position);
}
else
{
var (inside, position) = WidgetToUnitTriangle(mouseEvent.Position);
if (inside)
{
downState = DownState.OnTriangle;
SetSLFromUnitPosition(position);
}
if (inside)
{
downState = DownState.OnTriangle;
SetSLFromUnitPosition(position);
}
Invalidate();
}
}
Invalidate();
}
}
if (startColor != SelectedColor)
{
IncrementalColorChanged?.Invoke(this, null);
}
if (startColor != SelectedColor)
{
IncrementalColorChanged?.Invoke(this, null);
}
base.OnMouseDown(mouseEvent);
}
base.OnMouseDown(mouseEvent);
}
private void SetSLFromUnitPosition(Vector2 position)
{
hsl.s = position.X;
hsl.l = position.Y;
/*
private void SetSLFromUnitPosition(Vector2 position)
{
hsl.s = position.X;
hsl.l = position.Y;
/*
if (hsl.l > hsl.s)
{
@ -251,183 +251,183 @@ namespace MatterHackers.MatterControl.CustomWidgets.ColorPicker
agg_basics.Clamp(unitPosition.Y, .5 - (1 - unitPosition.X) / 2, .5 + (1 - unitPosition.X) / 2);
unitTrianglePosition = position;
*/
}
}
public override void OnMouseMove(MouseEventArgs mouseEvent)
{
var startColor = SelectedColor;
public override void OnMouseMove(MouseEventArgs mouseEvent)
{
var startColor = SelectedColor;
switch (downState)
{
case DownState.OnRing:
var center = new Vector2(Width / 2, Height / 2);
switch (downState)
{
case DownState.OnRing:
var center = new Vector2(Width / 2, Height / 2);
var direction = mouseEvent.Position - center;
var colorAngle = Math.Atan2(direction.Y, direction.X);
if (colorAngle < 0)
{
colorAngle += MathHelper.Tau;
}
hsl.h = colorAngle / MathHelper.Tau;
var direction = mouseEvent.Position - center;
var colorAngle = Math.Atan2(direction.Y, direction.X);
if (colorAngle < 0)
{
colorAngle += MathHelper.Tau;
}
hsl.h = colorAngle / MathHelper.Tau;
Invalidate();
break;
Invalidate();
break;
case DownState.OnTriangle:
SetSLFromUnitPosition(WidgetToUnitTriangle(mouseEvent.Position).position);
Invalidate();
break;
}
case DownState.OnTriangle:
SetSLFromUnitPosition(WidgetToUnitTriangle(mouseEvent.Position).position);
Invalidate();
break;
}
if (startColor != SelectedColor)
{
IncrementalColorChanged?.Invoke(this, null);
}
if (startColor != SelectedColor)
{
IncrementalColorChanged?.Invoke(this, null);
}
base.OnMouseMove(mouseEvent);
}
base.OnMouseMove(mouseEvent);
}
public override void OnMouseUp(MouseEventArgs mouseEvent)
{
downState = DownState.None;
public override void OnMouseUp(MouseEventArgs mouseEvent)
{
downState = DownState.None;
if (downColor != SelectedColor)
{
SelectedColorChanged?.Invoke(this, null);
}
if (downColor != SelectedColor)
{
SelectedColorChanged?.Invoke(this, null);
}
base.OnMouseUp(mouseEvent);
}
base.OnMouseUp(mouseEvent);
}
private void DrawColorRing(Graphics2D graphics2D, double radius, double width)
{
if (graphics2D is Graphics2DOpenGL graphicsGL)
{
graphicsGL.PushOrthoProjection();
private void DrawColorRing(Graphics2D graphics2D, double radius, double width)
{
if (graphics2D is Graphics2DOpenGL graphicsGL)
{
graphicsGL.PushOrthoProjection();
GL.Disable(EnableCap.Texture2D);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
GL.Enable(EnableCap.Blend);
GL.Disable(EnableCap.Texture2D);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
GL.Enable(EnableCap.Blend);
var outer = radius + width / 2;
var inner = radius - width / 2;
GL.Begin(BeginMode.TriangleStrip);
var outer = radius + width / 2;
var inner = radius - width / 2;
GL.Begin(BeginMode.TriangleStrip);
for (int i = 0; i <= 360; i++)
{
var color = ColorF.FromHSL(i / 360.0, 1, .5);
var angle = MathHelper.DegreesToRadians(i);
for (int i = 0; i <= 360; i++)
{
var color = ColorF.FromHSL(i / 360.0, 1, .5);
var angle = MathHelper.DegreesToRadians(i);
GL.Color4(color.Red0To255, color.Green0To255, color.Blue0To255, color.Alpha0To255);
GL.Vertex2(GetAtAngle(angle, outer, true));
GL.Vertex2(GetAtAngle(angle, inner, true));
}
GL.Color4(color.Red0To255, color.Green0To255, color.Blue0To255, color.Alpha0To255);
GL.Vertex2(GetAtAngle(angle, outer, true));
GL.Vertex2(GetAtAngle(angle, inner, true));
}
GL.End();
GL.End();
graphicsGL.PopOrthoProjection();
}
}
graphicsGL.PopOrthoProjection();
}
}
private void DrawColorTriangle(Graphics2D graphics2D, double radius, Color color)
{
if (graphics2D is Graphics2DOpenGL graphicsGL)
{
graphicsGL.PushOrthoProjection();
private void DrawColorTriangle(Graphics2D graphics2D, double radius, Color color)
{
if (graphics2D is Graphics2DOpenGL graphicsGL)
{
graphicsGL.PushOrthoProjection();
GL.Disable(EnableCap.Texture2D);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
GL.Enable(EnableCap.Blend);
GL.Disable(EnableCap.Texture2D);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
GL.Enable(EnableCap.Blend);
GL.Begin(BeginMode.Triangles);
GL.Color4(color.Red0To255, color.Green0To255, color.Blue0To255, color.Alpha0To255);
var colorAngle = hsl.h * MathHelper.Tau;
GL.Vertex2(GetTrianglePoint(0, radius, colorAngle, true));
GL.Color4(Color.White);
GL.Vertex2(GetTrianglePoint(1, radius, colorAngle, true));
GL.Color4(Color.Black);
GL.Vertex2(GetTrianglePoint(2, radius, colorAngle, true));
GL.Begin(BeginMode.Triangles);
GL.Color4(color.Red0To255, color.Green0To255, color.Blue0To255, color.Alpha0To255);
var colorAngle = hsl.h * MathHelper.Tau;
GL.Vertex2(GetTrianglePoint(0, radius, colorAngle, true));
GL.Color4(Color.White);
GL.Vertex2(GetTrianglePoint(1, radius, colorAngle, true));
GL.Color4(Color.Black);
GL.Vertex2(GetTrianglePoint(2, radius, colorAngle, true));
GL.End();
GL.End();
graphicsGL.PopOrthoProjection();
}
}
graphicsGL.PopOrthoProjection();
}
}
private Vector2 GetAtAngle(double angle, double radius, bool screenSpace)
{
var start = new Vector2(radius, 0);
private Vector2 GetAtAngle(double angle, double radius, bool screenSpace)
{
var start = new Vector2(radius, 0);
var position = default(Vector2);
if (screenSpace)
{
position = this.TransformToScreenSpace(this.Position);
}
var position = default(Vector2);
if (screenSpace)
{
position = this.TransformToScreenSpace(this.Position);
}
var center = new Vector2(Width / 2, Height / 2);
return position + center + Vector2.Rotate(start, angle);
}
var center = new Vector2(Width / 2, Height / 2);
return position + center + Vector2.Rotate(start, angle);
}
private Vector2 GetTrianglePoint(int index, double radius, double pontingAngle, bool screenSpace = false)
{
switch (index)
{
case 0:
return GetAtAngle(pontingAngle, radius, screenSpace);
private Vector2 GetTrianglePoint(int index, double radius, double pontingAngle, bool screenSpace = false)
{
switch (index)
{
case 0:
return GetAtAngle(pontingAngle, radius, screenSpace);
case 1:
return GetAtAngle(pontingAngle + MathHelper.DegreesToRadians(120), radius, screenSpace);
case 1:
return GetAtAngle(pontingAngle + MathHelper.DegreesToRadians(120), radius, screenSpace);
case 2:
return GetAtAngle(pontingAngle + MathHelper.DegreesToRadians(240), radius, screenSpace);
}
case 2:
return GetAtAngle(pontingAngle + MathHelper.DegreesToRadians(240), radius, screenSpace);
}
return Vector2.Zero;
}
return Vector2.Zero;
}
private Affine TriangleToWidgetTransform()
{
var center = new Vector2(Width / 2, Height / 2);
var leftSize = .5;
var sizeToTop = Math.Sin(MathHelper.DegreesToRadians(60));
private Affine TriangleToWidgetTransform()
{
var center = new Vector2(Width / 2, Height / 2);
var leftSize = .5;
var sizeToTop = Math.Sin(MathHelper.DegreesToRadians(60));
Affine total = Affine.NewIdentity();
// scale to -1 to 1 coordinates
total *= Affine.NewScaling(1 + leftSize, sizeToTop * 2);
// center
total *= Affine.NewTranslation(-leftSize, -sizeToTop);
// rotate to correct color
var colorAngle = hsl.h * MathHelper.Tau;
total *= Affine.NewRotation(colorAngle);
// scale to radius
total *= Affine.NewScaling(InnerRadius);
// move to center
total *= Affine.NewTranslation(center);
return total;
}
Affine total = Affine.NewIdentity();
// scale to -1 to 1 coordinates
total *= Affine.NewScaling(1 + leftSize, sizeToTop * 2);
// center
total *= Affine.NewTranslation(-leftSize, -sizeToTop);
// rotate to correct color
var colorAngle = hsl.h * MathHelper.Tau;
total *= Affine.NewRotation(colorAngle);
// scale to radius
total *= Affine.NewScaling(InnerRadius);
// move to center
total *= Affine.NewTranslation(center);
return total;
}
private (bool inside, Vector2 position) WidgetToUnitTriangle(Vector2 widgetPosition)
{
var trianglePosition = TriangleToWidgetTransform()
.InverseTransform(widgetPosition);
private (bool inside, Vector2 position) WidgetToUnitTriangle(Vector2 widgetPosition)
{
var trianglePosition = TriangleToWidgetTransform()
.InverseTransform(widgetPosition);
bool changed = ClampTrianglePosition(ref trianglePosition);
bool changed = ClampTrianglePosition(ref trianglePosition);
return (!changed, trianglePosition);
}
return (!changed, trianglePosition);
}
private static bool ClampTrianglePosition(ref Vector2 trianglePosition)
{
bool changed = false;
trianglePosition.X = agg_basics.Clamp(trianglePosition.X, 0, 1, ref changed);
trianglePosition.Y = agg_basics.Clamp(trianglePosition.Y, 0, 1, ref changed);
private static bool ClampTrianglePosition(ref Vector2 trianglePosition)
{
bool changed = false;
trianglePosition.X = Util.Clamp(trianglePosition.X, 0, 1, ref changed);
trianglePosition.Y = Util.Clamp(trianglePosition.Y, 0, 1, ref changed);
trianglePosition.Y = agg_basics.Clamp(trianglePosition.Y,
.5 - (1 - trianglePosition.X) / 2,
.5 + (1 - trianglePosition.X) / 2,
ref changed);
trianglePosition.Y = Util.Clamp(trianglePosition.Y,
.5 - (1 - trianglePosition.X) / 2,
.5 + (1 - trianglePosition.X) / 2,
ref changed);
return changed;
}
}
return changed;
}
}
}