using System;
using System .Collections .Generic;
using System .Drawing;
using System .Drawing .Drawing2D;
using System .Windows .Forms;
using Microsoft .Win32;
using MoveGraphLibrary;
namespace GraphicalPrimitives
{
public class Ring_ColoredSectors
{
int m_version = 618;
PointF m_center;
float rOuter;
float rInner;
double m_angle;
double [] vals;
double [] sweep;
List<Color> clrs = new List<Color> (); // one color per each sector
Rotation dirDrawing;
bool bShowRingBorders, bShowInnerBorders;
Pen penRingBorders, penInnerBorders;
double m_compensation;
static float minInnerRadius = 10;
static float minWidth = 15;
// -------------------------------------------------
public Ring_ColoredSectors (PointF ptC, float rOut, float rIn, double angleDegree, double [] fVals)
{
m_center = ptC;
rInner = Math .Max (rIn, minInnerRadius);
rOuter = Math .Max (rOut, rInner + minWidth);
m_angle = Auxi_Convert .DegreeToRadian (angleDegree);
dirDrawing = Rotation .Clockwise;
CheckedValues (fVals);
DefaultColors ();
bShowRingBorders = true;
penRingBorders = new Pen (Color .DarkGray);
bShowInnerBorders = true;
penInnerBorders = new Pen (Color .DarkGray);
}
// -------------------------------------------------
public Ring_ColoredSectors (PointF ptC, float rOut, float rIn, double angleDegree, double [] fVals, Color [] colors)
: this (ptC, rOut, rIn, angleDegree, fVals)
{
SetColors (colors);
}
// -------------------------------------------------
public Ring_ColoredSectors (PointF ptC, float rOut, float rIn, double angleDegree, double [] fVals, List<Color> colors)
: this (ptC, rOut, rIn, angleDegree, fVals)
{
SetColors (colors);
}
// -------------------------------------------------
public Ring_ColoredSectors (PointF ptC, float rOut, float rIn, Color clr)
: this (ptC, rOut, rIn, 0, new double [] { 5 })
{
clrs [0] = clr;
}
// -------------------------------------------------
public Ring_ColoredSectors (PointF ptC, float rOut, float rIn, double [] fVals, Color clr_0, Color clr_1)
: this (ptC, rOut, rIn, 0, fVals)
{
SetColors (Auxi_Colours .SmoothColorsList (fVals .Length, clr_0, clr_1));
}
// ------------------------------------------------- CheckedValues
private void CheckedValues (double [] fVals)
{
bool bCorrect = true;
if (fVals == null || fVals .Length < 1 || Auxi_Common .SumArray (fVals, true) == 0.0)
{
bCorrect = false;
}
else
{
foreach (double val in fVals)
{
if (val <= 0.0)
{
bCorrect = false;
break;
}
}
}
if (!bCorrect)
{
vals = new double [] { 1, 2, 3, 4 };
}
else
{
vals = new double [fVals .Length];
for (int i = 0; i < vals .Length; i++)
{
vals [i] = fVals [i];
}
}
sweep = new double [vals .Length];
SweepAngles ();
}
// ------------------------------------------------- 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;
}
}
}
// ------------------------------------------------- GetSweepAngles
public double [] GetSweepAngles ()
{
return (sweep);
}
// ------------------------------------------------- MinimumInnerRadius
static public float MinimumInnerRadius
{
get { return (minInnerRadius); }
}
// ------------------------------------------------- MinimumWidth
static public float MinimumWidth
{
get { return (minWidth); }
}
// ------------------------------------------------- Center
public PointF Center
{
get { return (m_center); }
set { m_center = value; }
}
// ------------------------------------------------- InnerRadius
public float InnerRadius
{
get { return (rInner); }
set
{
if (minInnerRadius <= value && value + minWidth <= rOuter)
{
rInner = value;
}
}
}
// ------------------------------------------------- OuterRadius
public float OuterRadius
{
get { return (rOuter); }
set
{
if (rInner + minWidth <= value)
{
rOuter = value;
}
}
}
// ------------------------------------------------- Width
public float Width
{
get { return (rOuter - rInner); }
}
// ------------------------------------------------- Contains
public bool Contains (PointF pt)
{
float r = Convert .ToSingle (Auxi_Geometry .Distance (m_center, pt));
return (rInner <= r && r <= rOuter);
}
// ------------------------------------------------- RectAround
public RectangleF RectAround
{
get { return (new RectangleF (m_center .X - rOuter, m_center .Y - rOuter, 2 * rOuter, 2 * rOuter)); }
}
// ------------------------------------------------- Angle
public double Angle
{
get { return (m_angle); }
set { m_angle = Auxi_Common .LimitedRadian (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];
}
}
}
// ------------------------------------------------- GetSectorColor
public Color GetSectorColor (int iSector)
{
return (clrs [iSector % clrs .Count]);
}
// ------------------------------------------------- SetSectorColor
public void SetSectorColor (int iSector, Color color)
{
clrs [iSector % clrs .Count] = color;
}
// ------------------------------------------------- DrawingDirection
public Rotation DrawingDirection
{
get { return (dirDrawing); }
set
{
dirDrawing = value;
SweepAngles ();
}
}
// ------------------------------------------------- ChangeDrawingDirection
public void ChangeDrawingDirection ()
{
dirDrawing = (dirDrawing == Rotation .Clockwise) ? Rotation .Counterclock : Rotation .Clockwise;
SweepAngles ();
}
// ------------------------------------------------- ShowRingBorders
public bool ShowRingBorders
{
get { return (bShowRingBorders); }
set { bShowRingBorders = value; }
}
// ------------------------------------------------- ShowInnerBorders
public bool ShowInnerBorders
{
get { return (bShowInnerBorders); }
set { bShowInnerBorders = value; }
}
// ------------------------------------------------- RingBordersColor
public Color RingBordersColor
{
get { return (penRingBorders .Color); }
set { penRingBorders .Color = value; }
}
// ------------------------------------------------- InnerBordersColor
public Color InnerBordersColor
{
get { return (penInnerBorders .Color); }
set { penInnerBorders .Color = value; }
}
// ------------------------------------------------- Values
public double [] Values
{
get { return (vals); }
}
// ------------------------------------------------- Draw
public void Draw (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));
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 ();
fStartDegree += fSweepDegree;
}
if (bShowInnerBorders)
{
double angleLine = m_angle;
for (int i = 0; i < sweep .Length; i++)
{
angleLine += sweep [i];
grfx .DrawLine (penInnerBorders, Auxi_Geometry .PointToPoint (m_center, angleLine, rInner),
Auxi_Geometry .PointToPoint (m_center, angleLine, rOuter));
}
}
if (bShowRingBorders)
{
grfx .DrawEllipse (penRingBorders, m_center .X - rInner, m_center .Y - rInner, 2 * rInner, 2 * rInner);
grfx .DrawEllipse (penRingBorders, m_center .X - rOuter, m_center .Y - rOuter, 2 * rOuter, 2 * rOuter);
}
}
// ------------------------------------------------- Compensation
public double Compensation
{
get { return (m_compensation); }
set { m_compensation = value; }
}
// ------------------------------------------------- AdjustToRotation
public void AdjustToRotation (Point ptMouse)
{
double angleMouse = Auxi_Geometry .Line_Angle (m_center, ptMouse);
m_angle = angleMouse - m_compensation;
}
const string nameMain = "Ring_ColoredSectors_";
// ------------------------------------------------- IntoRegistry
public void IntoRegistry (RegistryKey regkey, string strAdd)
{
try
{
regkey .SetValue (nameMain + strAdd, new string [] {m_version .ToString (), // 0
m_center .X .ToString (), // 1
m_center .Y .ToString (), // 2
rOuter .ToString (), // 3
rInner .ToString (), // 4
m_angle .ToString (), // 5
((int) DrawingDirection) .ToString (), // 6
bShowRingBorders .ToString (), // 7
((int) RingBordersColor .A) .ToString (), // 8
((int) RingBordersColor .R) .ToString (), // 9
((int) RingBordersColor .G) .ToString (), // 10
((int) RingBordersColor .B) .ToString (), // 11
bShowInnerBorders .ToString (), // 12
((int) InnerBordersColor .A) .ToString (), // 13
((int) InnerBordersColor .R) .ToString (), // 14
((int) InnerBordersColor .G) .ToString (), // 15
((int) InnerBordersColor .B) .ToString (), // 16
},
RegistryValueKind .MultiString);
string [] strs = new string [vals .Length]; // vals []
for (int i = 0; i < vals .Length; i++)
{
strs [i] = vals [i] .ToString ();
}
regkey .SetValue (nameMain + strAdd + "_values", strs, RegistryValueKind .MultiString);
string [] strClrs = new string [clrs .Count * 4];
for (int i = 0; i < clrs .Count; i++)
{
strClrs [i * 4] = ((int) (clrs [i] .A)) .ToString ();
strClrs [i * 4 + 1] = ((int) (clrs [i] .R)) .ToString ();
strClrs [i * 4 + 2] = ((int) (clrs [i] .G)) .ToString ();
strClrs [i * 4 + 3] = ((int) (clrs [i] .B)) .ToString ();
}
regkey .SetValue (nameMain + strAdd + "_colors", strClrs, RegistryValueKind .MultiString);
}
catch
{
}
finally
{
}
}
// ------------------------------------------------- FromRegistry
public static Ring_ColoredSectors FromRegistry (RegistryKey regkey, string strAdd)
{
try
{
string [] strGeneral = (string []) regkey .GetValue (nameMain + strAdd);
string [] strValues = (string []) regkey .GetValue (nameMain + strAdd + "_values");
string [] strColors = (string []) regkey .GetValue (nameMain + strAdd + "_colors");
if (strGeneral != null && strGeneral .Length >= 17 && Convert .ToInt32 (strGeneral [0]) >= 618 &&
strValues != null &&
strColors != null && strColors .Length == 4 * strValues .Length)
{
double [] fVals = new double [strValues .Length];
for (int i = 0; i < strValues .Length; i++)
{
fVals [i] = Convert .ToDouble (strValues [i]);
}
Color [] colors = new Color [strColors .Length / 4];
for (int i = 0; i < colors .Length; i++)
{
colors [i] = Auxi_Convert .ToColor (strColors, i * 4);
}
Ring_ColoredSectors ring = new Ring_ColoredSectors (Auxi_Convert .ToPointF (strGeneral, 1), // ptC
Convert .ToSingle (strGeneral [3]), // rOuter
Convert .ToSingle (strGeneral [4]), // rInner
Auxi_Convert .RadianToDegree (Convert .ToDouble (strGeneral [5])),
fVals,
colors);
if (ring != null)
{
ring .DrawingDirection = (Rotation) (Convert .ToInt32 (strGeneral [6]));
ring .ShowRingBorders = Convert .ToBoolean (strGeneral [7]);
ring .RingBordersColor = Auxi_Convert .ToColor (strGeneral, 8);
ring .ShowInnerBorders = Convert .ToBoolean (strGeneral [12]);
ring .InnerBordersColor = Auxi_Convert .ToColor (strGeneral, 13);
}
return (ring);
}
return (null);
}
catch
{
return (null);
}
finally
{
}
}
}
}