using System;
using System .Collections .Generic;
using System .ComponentModel;
using System .Drawing;
using System .Drawing .Drawing2D;
using System .Windows .Forms;
using Microsoft .Win32;
using MoveGraphLibrary;
namespace GraphicalPrimitives
{
public class Ring_SimpleCover : GraphicalObject
{
int m_version = 620;
Form form;
Mover supervisor;
PointF m_center;
float rOuter;
float rInner;
double m_angle;
double [] vals;
List<Color> clrs = new List<Color> (); // one color per each sector
Rotation dirDrawing;
double [] sweep;
double compensation;
PointF ptInnerLimit, ptOuterLimit;
Color clrBorder;
static int minInner = 10;
static int minWidth = 15;
int delta = 4; // 3;
// -------------------------------------------------
public Ring_SimpleCover (Form frm, Mover mvr, PointF ptC, float rOut, float rIn, double angleDegree, double [] fVals)
{
form = frm;
supervisor = mvr;
m_center = ptC;
rInner = Math .Max (rIn, minInner);
rOuter = Math .Max (rOut, rInner + minWidth);
vals = CheckedValues (fVals);
DefaultColors ();
clrBorder = Color .DarkGray;
dirDrawing = Rotation .Clockwise;
m_angle = Auxi_Convert .DegreeToRadian (angleDegree);
sweep = new double [vals .Length];
SweepAngles ();
}
// -------------------------------------------------
public Ring_SimpleCover (Form frm, Mover mvr, PointF ptC, float rOut, float rIn, Color clr)
: this (frm, mvr, ptC, rOut, rIn, 0, new double [] { 5 })
{
clrs [0] = clr;
}
// -------------------------------------------------
public Ring_SimpleCover (Form frm, Mover mvr, PointF ptC, float rOut, float rIn, double [] fVals, Color clr_0, Color clr_1)
: this (frm, mvr, ptC, rOut, rIn, 0, fVals)
{
SetColors (Auxi_Colours .SmoothColorsList (fVals .Length, clr_0, clr_1));
}
// ------------------------------------------------- CheckedValues
private double [] CheckedValues (double [] fVals)
{
if (fVals == null || fVals .Length < 1 || Auxi_Common .SumArray (fVals, true) == 0.0)
{
return (new double [] { 1, 2, 3, 4 });
}
else
{
double [] vs = new double [fVals .Length];
for (int i = 0; i < vs .Length; i++)
{
vs [i] = Math .Abs (fVals [i]);
}
return (vs);
}
}
// ------------------------------------------------- DefaultColors
public void DefaultColors ()
{
clrs .Clear ();
for (int i = 0; i < vals .Length; i++)
{
clrs .Add (Auxi_Colours .ColorPredefined (i + 1));
}
}
// ------------------------------------------------- SweepAngles
private void SweepAngles ()
{
double fSum = Auxi_Common .SumArray (vals, false);
for (int i = 0; i < vals .Length; i++)
{
sweep [i] = 2 * Math .PI * vals [i] / fSum;
}
if (dirDrawing == Rotation .Clockwise)
{
for (int i = 0; i < vals .Length; i++)
{
sweep [i] *= -1;
}
}
}
// ------------------------------------------------- Copy
public Ring_SimpleCover Copy (PointF pt)
{
double [] valsNew = new double [vals .Length];
for (int i = 0; i < vals .Length; i++)
{
valsNew [i] = vals [i];
}
Ring_SimpleCover elem = new Ring_SimpleCover (form, supervisor, pt, rOuter, rInner, Auxi_Convert .RadianToDegree (m_angle), valsNew);
for (int i = 0; i < vals .Length; i++)
{
elem .SetColor (i, clrs [i]);
}
elem .DrawingDirection = DrawingDirection;
return (elem);
}
// ------------------------------------------------- Center
public PointF Center
{
get { return (m_center); }
set
{
m_center = value;
DefineCover ();
}
}
// ------------------------------------------------- InnerRadius
public float InnerRadius
{
get { return (rInner); }
set
{
if (minInner <= value && value + minWidth <= rOuter)
{
rInner = value;
DefineCover ();
}
}
}
// ------------------------------------------------- OuterRadius
public float OuterRadius
{
get { return (rOuter); }
set
{
if (rInner + minWidth <= value)
{
rOuter = value;
DefineCover ();
}
}
}
// ------------------------------------------------- MinimumInnerRadius
static public int MinimumInnerRadius
{
get { return (minInner); }
}
// ------------------------------------------------- MinimumWidth
static public int MinimumWidth
{
get { return (minWidth); }
}
// ------------------------------------------------- RectAround
new public RectangleF RectAround
{
get { return (new RectangleF (m_center .X - rOuter, m_center .Y - rOuter, 2 * rOuter, 2 * rOuter)); }
}
// ------------------------------------------------- Values
public double [] Values
{
get { return (vals); }
}
// ------------------------------------------------- Angle
public double Angle
{
get { return (m_angle); }
set { m_angle = Auxi_Common .LimitedRadian (value); }
}
// ------------------------------------------------- Color
public Color Color
{
get { return (clrs [0]); }
set { clrs [0] = value; }
}
// ------------------------------------------------- Colors
public List<Color> Colors
{
get { return (clrs); }
}
// ------------------------------------------------- SetColors
public void SetColors (List<Color> colors)
{
for (int i = 0; i < clrs .Count; i++)
{
clrs [i] = colors [i % clrs .Count];
}
}
// ------------------------------------------------- SetColors
public void SetColors (Color [] clrsNew)
{
if (clrs .Count == clrsNew .Length)
{
for (int i = 0; i < clrs .Count; i++)
{
clrs [i] = clrsNew [i];
}
}
}
// ------------------------------------------------- SetColor
public void SetColor (int i, Color clr)
{
if (0 <= i && i < clrs .Count)
{
clrs [i] = clr;
}
}
// ------------------------------------------------- DrawingDirection
public Rotation DrawingDirection
{
get { return (dirDrawing); }
set
{
dirDrawing = value;
SweepAngles ();
}
}
// ------------------------------------------------- ChangeDrawingDirection
public void ChangeDrawingDirection ()
{
dirDrawing = (dirDrawing == Rotation .Clockwise) ? Rotation .Counterclock : Rotation .Clockwise;
SweepAngles ();
}
// ------------------------------------------------- Draw
public void Draw (Graphics grfx)
{
DrawSectors (grfx);
}
// ------------------------------------------------- DrawSectors
public void DrawSectors (Graphics grfx)
{
Rectangle rcIn = new Rectangle (Convert .ToInt32 (m_center .X - rInner), Convert .ToInt32 (m_center .Y - rInner),
Convert .ToInt32 (2 * rInner), Convert .ToInt32 (2 * rInner));
Rectangle rcOut = new Rectangle (Convert .ToInt32 (m_center .X - rOuter), Convert .ToInt32 (m_center .Y - rOuter),
Convert .ToInt32 (2 * rOuter), Convert .ToInt32 (2 * rOuter));
Pen penBorder = new Pen (clrBorder);
Point pt0, pt1;
SolidBrush brush;
GraphicsPath path = new GraphicsPath ();
// for Drawing fStart[] and fSweep[] are used in Microsoft way, which means changing of sign
float fStartDegree, fSweepDegree;
fStartDegree = -(float) Auxi_Convert .RadianToDegree (m_angle);
for (int i = 0; i < vals .Length; i++)
{
brush = new SolidBrush (clrs [i]);
fSweepDegree = -(float) Auxi_Convert .RadianToDegree (sweep [i]);
path .AddArc (rcIn, fStartDegree, fSweepDegree);
path .AddArc (rcOut, fStartDegree + fSweepDegree, -fSweepDegree);
grfx .FillPath (brush, path);
path .Reset ();
grfx .DrawArc (penBorder, rcIn, fStartDegree, fSweepDegree);
grfx .DrawArc (penBorder, rcOut, fStartDegree, fSweepDegree);
pt0 = Auxi_Geometry .EllipsePoint (rcIn, -fStartDegree, 1);
pt1 = Auxi_Geometry .EllipsePoint (rcOut, -fStartDegree, 1);
grfx .DrawLine (penBorder, pt0, pt1);
fStartDegree += fSweepDegree;
}
}
// ------------------------------------------------- StartResizing
public void StartResizing (Point ptMouse, int iNode)
{
double angleBeam = Auxi_Geometry .Line_Angle (Center, ptMouse);
float rad;
if (iNode == 1)
{
rad = InnerRadius;
ptInnerLimit = Auxi_Geometry .PointToPoint (Center, angleBeam, MinimumInnerRadius);
ptOuterLimit = Auxi_Geometry .PointToPoint (Center, angleBeam, OuterRadius - MinimumWidth);
}
else
{
rad = OuterRadius;
ptInnerLimit = Auxi_Geometry .PointToPoint (Center, angleBeam, InnerRadius + MinimumWidth);
ptOuterLimit = Auxi_Geometry .PointToPoint (Center, angleBeam, 4000);
}
Cursor .Position = form .PointToScreen (Point .Round (Auxi_Geometry .PointToPoint (Center, angleBeam, rad)));
}
// ------------------------------------------------- StartRotation
public void StartRotation (Point ptMouse)
{
double angleMouse = Auxi_Geometry .Line_Angle (m_center, ptMouse);
compensation = Auxi_Common .LimitedRadian (angleMouse - m_angle);
}
// ------------------------------------------------- DefineCover
// order of nodes (all circular): (rInner - delta), (rInner + delta), (rOuter - delta), (rOuter + delta)
public override void DefineCover ()
{
CoverNode [] nodes = new CoverNode [] { new CoverNode (0, Center, InnerRadius - delta, Behaviour .Transparent),
new CoverNode (1, Center, InnerRadius + delta),
new CoverNode (2, Center, OuterRadius - delta, Cursors .SizeAll),
new CoverNode (3, Center, OuterRadius + delta)};
cover = new Cover (nodes);
cover .SetClearance (false);
}
// -------------------------------------------------
public override void Move (int dx, int dy)
{
Center += new Size (dx, dy);
}
// ------------------------------------------------- MoveNode
public override bool MoveNode (int i, int dx, int dy, Point ptM, MouseButtons catcher)
{
bool bRet = false;
if (catcher == MouseButtons .Left)
{
if (i == 2)
{
Move (dx, dy);
}
else
{
PointF ptBase, ptNearest;
PointOfSegment typeOfNearest;
Auxi_Geometry .Distance_PointSegment (ptM, ptInnerLimit, ptOuterLimit, out ptBase, out typeOfNearest, out ptNearest);
if (i == 1) // inner border
{
InnerRadius = Convert .ToSingle (Auxi_Geometry .Distance (Center, ptNearest));
}
else // outer border
{
OuterRadius = Convert .ToSingle (Auxi_Geometry .Distance (Center, ptNearest));
}
Cursor .Position = form .PointToScreen (Point .Round (ptNearest));
bRet = true;
}
}
else if (catcher == MouseButtons .Right)
{
double angleMouse = Auxi_Geometry .Line_Angle (Center, ptM);
Angle = angleMouse - compensation;
bRet = true;
}
return (bRet);
}
const string nameMain = "RingSimple_";
// ------------------------------------------------- IntoRegistry
public void IntoRegistry (RegistryKey regkey, string strAdd)
{
try
{
string [] strs = new string [6 + vals .Length + 4 * vals .Length + 1];
strs [0] = m_version .ToString ();
strs [1] = m_center .X .ToString (); // center
strs [2] = m_center .Y .ToString ();
strs [3] = rOuter .ToString (); // rOuter
strs [4] = rInner .ToString (); // rInner
strs [5] = Auxi_Convert .RadianToDegree (Angle) .ToString (); // angle
for (int i = 0; i < vals .Length; i++) // vals
{
strs [6 + i] = vals [i] .ToString ();
}
int k = 6 + vals .Length;
for (int i = 0; i < vals .Length; i++) // clrs
{
strs [k + i * 4] = ((int) (clrs [i] .A)) .ToString ();
strs [k + i * 4 + 1] = ((int) (clrs [i] .R)) .ToString ();
strs [k + i * 4 + 2] = ((int) (clrs [i] .G)) .ToString ();
strs [k + i * 4 + 3] = ((int) (clrs [i] .B)) .ToString ();
}
k += 4 * vals .Length;
strs [k] = ((int) dirDrawing) .ToString ();
regkey .SetValue (nameMain + strAdd, strs, RegistryValueKind .MultiString);
}
catch
{
}
finally
{
}
}
// ------------------------------------------------- FromRegistry
public static Ring_SimpleCover FromRegistry (Form frm, Mover mvr, RegistryKey regkey, string strAdd)
{
try
{
string [] strs = (string []) regkey .GetValue (nameMain + strAdd);
if (frm == null || mvr == null ||
strs == null || strs .Length < 12 || Convert .ToInt32 (strs [0]) != 620)
{
return (null);
}
int nVals = (strs .Length - 7) / 5;
double [] fVals = new double [nVals];
List<Color> colors = new List<Color> ();
int j_vals = 6;
int j_clrs = j_vals + nVals;
int j_dir = j_clrs + 4 * nVals;
for (int i = 0; i < nVals; i++)
{
fVals [i] = Convert .ToDouble (strs [j_vals + i]);
colors .Add (Auxi_Convert .ToColor (strs, j_clrs + i * 4));
}
Ring_SimpleCover ring = new Ring_SimpleCover (frm, mvr,
Auxi_Convert .ToPointF (strs, 1), // center
Convert .ToSingle (strs [3]), // rOuter
Convert .ToSingle (strs [4]), // rInner
Convert .ToDouble (strs [5]), // angle
fVals);
if (ring != null)
{
ring .SetColors (colors);
ring .DrawingDirection = (Rotation) Convert .ToInt32 (strs [j_dir]);
}
return (ring);
}
catch
{
return (null);
}
finally
{
}
}
}
}