#region Imports
|
|
using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Drawing;
|
using System.Drawing.Drawing2D;
|
using System.Drawing.Imaging;
|
using System.IO;
|
using System.Runtime.InteropServices;
|
using System.Windows.Forms;
|
|
#endregion
|
|
namespace DPumpHydr.WinFrmUI.RLT.Util
|
{
|
#region AirUtil
|
|
public abstract class AirLibrary : ContainerControl
|
{
|
#region " Initialization "
|
|
protected Graphics G;
|
|
protected Bitmap B;
|
public AirLibrary()
|
{
|
SetStyle((ControlStyles)139270, true);
|
|
_ImageSize = Size.Empty;
|
Font = new("Verdana", 8);
|
|
MeasureBitmap = new(1, 1);
|
MeasureGraphics = Graphics.FromImage(MeasureBitmap);
|
|
StartPosition = FormStartPosition.CenterScreen;
|
|
DrawRadialPath = new();
|
|
InvalidateCustimization();
|
}
|
|
protected sealed override void OnHandleCreated(EventArgs e)
|
{
|
if (DoneCreation)
|
{
|
InitializeMessages();
|
}
|
|
InvalidateCustimization();
|
ColorHook();
|
|
if (!(_LockWidth == 0))
|
{
|
Width = _LockWidth;
|
}
|
|
if (!(_LockHeight == 0))
|
{
|
Height = _LockHeight;
|
}
|
|
if (!_ControlMode)
|
{
|
base.Dock = DockStyle.Fill;
|
}
|
|
Transparent = _Transparent;
|
if (_Transparent && _BackColor)
|
{
|
BackColor = Color.Transparent;
|
}
|
|
base.OnHandleCreated(e);
|
}
|
|
private bool DoneCreation;
|
protected sealed override void OnParentChanged(EventArgs e)
|
{
|
base.OnParentChanged(e);
|
|
if (Parent == null)
|
{
|
return;
|
}
|
|
IsParentForm = Parent is Form;
|
|
if (!_ControlMode)
|
{
|
InitializeMessages();
|
|
if (IsParentForm)
|
{
|
ParentForm.FormBorderStyle = _BorderStyle;
|
ParentForm.TransparencyKey = _TransparencyKey;
|
|
if (!DesignMode)
|
{
|
ParentForm.Shown += FormShown;
|
}
|
}
|
|
Parent.BackColor = BackColor;
|
}
|
|
OnCreation();
|
DoneCreation = true;
|
InvalidateTimer();
|
}
|
|
#endregion
|
|
private void DoAnimationAir(bool i)
|
{
|
OnAnimation();
|
if (i)
|
{
|
Invalidate();
|
}
|
}
|
|
protected sealed override void OnPaint(PaintEventArgs e)
|
{
|
if (Width == 0 || Height == 0)
|
{
|
return;
|
}
|
|
if (_Transparent && _ControlMode)
|
{
|
PaintHook();
|
e.Graphics.DrawImage(B, 0, 0);
|
}
|
else
|
{
|
G = e.Graphics;
|
PaintHook();
|
}
|
}
|
|
protected override void OnHandleDestroyed(EventArgs e)
|
{
|
ThemeShareAir.RemoveAnimationCallback(DoAnimationAir);
|
base.OnHandleDestroyed(e);
|
}
|
|
private bool HasShown;
|
private void FormShown(object sender, EventArgs e)
|
{
|
if (_ControlMode || HasShown)
|
{
|
return;
|
}
|
|
if (_StartPosition is FormStartPosition.CenterParent or FormStartPosition.CenterScreen)
|
{
|
Rectangle SB = Screen.PrimaryScreen.Bounds;
|
Rectangle CB = ParentForm.Bounds;
|
ParentForm.Location = new((SB.Width / 2) - (CB.Width / 2), (SB.Height / 2) - (CB.Height / 2));
|
}
|
|
HasShown = true;
|
}
|
|
|
#region " Size Handling "
|
|
private Rectangle Frame;
|
protected sealed override void OnSizeChanged(EventArgs e)
|
{
|
if (Movable && !_ControlMode)
|
{
|
Frame = new(7, 7, Width - 14, _Header - 7);
|
}
|
|
InvalidateBitmap();
|
Invalidate();
|
|
base.OnSizeChanged(e);
|
}
|
|
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
|
{
|
if (!(_LockWidth == 0))
|
{
|
width = _LockWidth;
|
}
|
|
if (!(_LockHeight == 0))
|
{
|
height = _LockHeight;
|
}
|
|
base.SetBoundsCore(x, y, width, height, specified);
|
}
|
|
#endregion
|
|
#region " State Handling "
|
|
protected MouseStateAir State;
|
private void SetState(MouseStateAir current)
|
{
|
State = current;
|
Invalidate();
|
}
|
|
protected override void OnMouseMove(MouseEventArgs e)
|
{
|
if (!(IsParentForm && ParentForm.WindowState == FormWindowState.Maximized))
|
{
|
if (Sizable && !_ControlMode)
|
{
|
InvalidateMouse();
|
}
|
}
|
|
base.OnMouseMove(e);
|
}
|
|
protected override void OnEnabledChanged(EventArgs e)
|
{
|
if (Enabled)
|
{
|
SetState(MouseStateAir.None);
|
}
|
else
|
{
|
SetState(MouseStateAir.Block);
|
}
|
|
base.OnEnabledChanged(e);
|
}
|
|
protected override void OnMouseEnter(EventArgs e)
|
{
|
SetState(MouseStateAir.Over);
|
base.OnMouseEnter(e);
|
}
|
|
protected override void OnMouseUp(MouseEventArgs e)
|
{
|
SetState(MouseStateAir.Over);
|
base.OnMouseUp(e);
|
}
|
|
protected override void OnMouseLeave(EventArgs e)
|
{
|
SetState(MouseStateAir.None);
|
|
if (GetChildAtPoint(PointToClient(MousePosition)) != null)
|
{
|
if (Sizable && !_ControlMode)
|
{
|
Cursor = Cursors.Default;
|
Previous = 0;
|
}
|
}
|
|
base.OnMouseLeave(e);
|
}
|
|
protected override void OnMouseDown(MouseEventArgs e)
|
{
|
if (e.Button == MouseButtons.Left)
|
{
|
SetState(MouseStateAir.Down);
|
}
|
|
if (!((IsParentForm && ParentForm.WindowState == FormWindowState.Maximized) || _ControlMode))
|
{
|
if (Movable && Frame.Contains(e.Location))
|
{
|
if (!new Rectangle(Width - 22, 5, 15, 15).Contains(e.Location))
|
{
|
Capture = false;
|
}
|
|
WM_LMBUTTONDOWN = true;
|
DefWndProc(ref Messages[0]);
|
}
|
else if (Sizable && !(Previous == 0))
|
{
|
Capture = false;
|
WM_LMBUTTONDOWN = true;
|
DefWndProc(ref Messages[Previous]);
|
}
|
}
|
|
base.OnMouseDown(e);
|
}
|
|
private bool WM_LMBUTTONDOWN;
|
protected override void WndProc(ref Message m)
|
{
|
base.WndProc(ref m);
|
|
if (WM_LMBUTTONDOWN && m.Msg == 513)
|
{
|
WM_LMBUTTONDOWN = false;
|
|
SetState(MouseStateAir.Over);
|
if (!SmartBounds)
|
{
|
return;
|
}
|
|
if (IsParentMdi)
|
{
|
CorrectBounds(new Rectangle(Point.Empty, Parent.Parent.Size));
|
}
|
else
|
{
|
CorrectBounds(Screen.FromControl(Parent).WorkingArea);
|
}
|
}
|
}
|
|
private Point GetIndexPoint;
|
private bool B1;
|
private bool B2;
|
private bool B3;
|
private bool B4;
|
private int GetIndex()
|
{
|
GetIndexPoint = PointToClient(MousePosition);
|
B1 = GetIndexPoint.X < 7;
|
B2 = GetIndexPoint.X > Width - 7;
|
B3 = GetIndexPoint.Y < 7;
|
B4 = GetIndexPoint.Y > Height - 7;
|
|
if (B1 && B3)
|
{
|
return 4;
|
}
|
|
if (B1 && B4)
|
{
|
return 7;
|
}
|
|
if (B2 && B3)
|
{
|
return 5;
|
}
|
|
if (B2 && B4)
|
{
|
return 8;
|
}
|
|
if (B1)
|
{
|
return 1;
|
}
|
|
if (B2)
|
{
|
return 2;
|
}
|
|
if (B3)
|
{
|
return 3;
|
}
|
|
if (B4)
|
{
|
return 6;
|
}
|
|
return 0;
|
}
|
|
private int Current;
|
private int Previous;
|
private void InvalidateMouse()
|
{
|
Current = GetIndex();
|
if (Current == Previous)
|
{
|
return;
|
}
|
|
Previous = Current;
|
switch (Previous)
|
{
|
case 0:
|
Cursor = Cursors.Default;
|
break;
|
case 1:
|
case 2:
|
Cursor = Cursors.SizeWE;
|
break;
|
case 3:
|
case 6:
|
Cursor = Cursors.SizeNS;
|
break;
|
case 4:
|
case 8:
|
Cursor = Cursors.SizeNWSE;
|
break;
|
case 5:
|
case 7:
|
Cursor = Cursors.SizeNESW;
|
break;
|
}
|
}
|
|
private readonly Message[] Messages = new Message[9];
|
private void InitializeMessages()
|
{
|
Messages[0] = Message.Create(Parent.Handle, 161, new IntPtr(2), IntPtr.Zero);
|
for (int I = 1; I <= 8; I++)
|
{
|
Messages[I] = Message.Create(Parent.Handle, 161, new IntPtr(I + 9), IntPtr.Zero);
|
}
|
}
|
|
private void CorrectBounds(Rectangle bounds)
|
{
|
if (Parent.Width > bounds.Width)
|
{
|
Parent.Width = bounds.Width;
|
}
|
|
if (Parent.Height > bounds.Height)
|
{
|
Parent.Height = bounds.Height;
|
}
|
|
int X = Parent.Location.X;
|
int Y = Parent.Location.Y;
|
|
if (X < bounds.X)
|
{
|
X = bounds.X;
|
}
|
|
if (Y < bounds.Y)
|
{
|
Y = bounds.Y;
|
}
|
|
int Width = bounds.X + bounds.Width;
|
int Height = bounds.Y + bounds.Height;
|
|
if (X + Parent.Width > Width)
|
{
|
X = Width - Parent.Width;
|
}
|
|
if (Y + Parent.Height > Height)
|
{
|
Y = Height - Parent.Height;
|
}
|
|
Parent.Location = new(X, Y);
|
}
|
|
#endregion
|
|
#region " Base Properties "
|
|
public override DockStyle Dock
|
{
|
get => base.Dock;
|
set
|
{
|
if (!_ControlMode)
|
{
|
return;
|
}
|
|
base.Dock = value;
|
}
|
}
|
|
private bool _BackColor;
|
[Category("Misc")]
|
public override Color BackColor
|
{
|
get => base.BackColor;
|
set
|
{
|
if (value == base.BackColor)
|
{
|
return;
|
}
|
|
if (!IsHandleCreated && _ControlMode && value == Color.Transparent)
|
{
|
_BackColor = true;
|
return;
|
}
|
|
base.BackColor = value;
|
if (Parent != null)
|
{
|
if (!_ControlMode)
|
{
|
Parent.BackColor = value;
|
}
|
|
ColorHook();
|
}
|
}
|
}
|
|
public override Size MinimumSize
|
{
|
get => base.MinimumSize;
|
set
|
{
|
base.MinimumSize = value;
|
if (Parent != null)
|
{
|
Parent.MinimumSize = value;
|
}
|
}
|
}
|
|
public override Size MaximumSize
|
{
|
get => base.MaximumSize;
|
set
|
{
|
base.MaximumSize = value;
|
if (Parent != null)
|
{
|
Parent.MaximumSize = value;
|
}
|
}
|
}
|
|
public override string Text
|
{
|
get => base.Text;
|
set
|
{
|
base.Text = value;
|
Invalidate();
|
}
|
}
|
|
public override Font Font
|
{
|
get => base.Font;
|
set
|
{
|
base.Font = value;
|
Invalidate();
|
}
|
}
|
|
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
public override Color ForeColor
|
{
|
get => Color.Empty;
|
set { }
|
}
|
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
public override Image BackgroundImage
|
{
|
get => null;
|
set { }
|
}
|
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
public override ImageLayout BackgroundImageLayout
|
{
|
get => ImageLayout.None;
|
set { }
|
}
|
|
#endregion
|
|
#region " Public Properties "
|
|
public bool SmartBounds { get; set; } = true;
|
public bool Movable { get; set; } = true;
|
public bool Sizable { get; set; } = true;
|
|
private Color _TransparencyKey;
|
public Color TransparencyKey
|
{
|
get
|
{
|
if (IsParentForm && !_ControlMode)
|
{
|
return ParentForm.TransparencyKey;
|
}
|
else
|
{
|
return _TransparencyKey;
|
}
|
}
|
set
|
{
|
if (value == _TransparencyKey)
|
{
|
return;
|
}
|
|
_TransparencyKey = value;
|
|
if (IsParentForm && !_ControlMode)
|
{
|
ParentForm.TransparencyKey = value;
|
ColorHook();
|
}
|
}
|
}
|
|
private FormBorderStyle _BorderStyle;
|
public FormBorderStyle BorderStyle
|
{
|
get
|
{
|
if (IsParentForm && !_ControlMode)
|
{
|
return ParentForm.FormBorderStyle;
|
}
|
else
|
{
|
return _BorderStyle;
|
}
|
}
|
set
|
{
|
_BorderStyle = value;
|
|
if (IsParentForm && !_ControlMode)
|
{
|
ParentForm.FormBorderStyle = value;
|
|
if (!(value == FormBorderStyle.None))
|
{
|
Movable = false;
|
Sizable = false;
|
}
|
}
|
}
|
}
|
|
private FormStartPosition _StartPosition;
|
public FormStartPosition StartPosition
|
{
|
get
|
{
|
if (IsParentForm && !_ControlMode)
|
{
|
return ParentForm.StartPosition;
|
}
|
else
|
{
|
return _StartPosition;
|
}
|
}
|
set
|
{
|
_StartPosition = value;
|
|
if (IsParentForm && !_ControlMode)
|
{
|
ParentForm.StartPosition = value;
|
}
|
}
|
}
|
|
private bool _NoRounding;
|
public bool NoRounding
|
{
|
get => _NoRounding;
|
set
|
{
|
_NoRounding = value;
|
Invalidate();
|
}
|
}
|
|
private Image _Image;
|
public Image Image
|
{
|
get => _Image;
|
set
|
{
|
if (value == null)
|
{
|
_ImageSize = Size.Empty;
|
}
|
else
|
{
|
_ImageSize = value.Size;
|
}
|
|
_Image = value;
|
Invalidate();
|
}
|
}
|
|
private readonly Dictionary<string, Color> Items = new();
|
public BloomAir[] Colors
|
{
|
get
|
{
|
List<BloomAir> T = new();
|
Dictionary<string, Color>.Enumerator E = Items.GetEnumerator();
|
|
while (E.MoveNext())
|
{
|
T.Add(new BloomAir(E.Current.Key, E.Current.Value));
|
}
|
|
return T.ToArray();
|
}
|
set
|
{
|
foreach (BloomAir B in value)
|
{
|
if (Items.ContainsKey(B.Name))
|
{
|
Items[B.Name] = B.Value;
|
}
|
}
|
|
InvalidateCustimization();
|
ColorHook();
|
Invalidate();
|
}
|
}
|
|
private string _Customization;
|
public string Customization
|
{
|
get => _Customization;
|
set
|
{
|
if (value == _Customization)
|
{
|
return;
|
}
|
|
BloomAir[] Items = Colors;
|
|
try
|
{
|
byte[] Data = Convert.FromBase64String(value);
|
for (int I = 0; I <= Items.Length - 1; I++)
|
{
|
Items[I].Value = Color.FromArgb(BitConverter.ToInt32(Data, I * 4));
|
}
|
}
|
catch
|
{
|
return;
|
}
|
|
_Customization = value;
|
|
Colors = Items;
|
ColorHook();
|
Invalidate();
|
}
|
}
|
|
private bool _Transparent;
|
public bool Transparent
|
{
|
get => _Transparent;
|
set
|
{
|
_Transparent = value;
|
if (!(IsHandleCreated || _ControlMode))
|
{
|
return;
|
}
|
|
if (!value && !(BackColor.A == 255))
|
{
|
throw new Exception("Unable to change value to false while a transparent BackColor is in use.");
|
}
|
|
SetStyle(ControlStyles.Opaque, !value);
|
SetStyle(ControlStyles.SupportsTransparentBackColor, value);
|
|
InvalidateBitmap();
|
Invalidate();
|
}
|
}
|
|
#endregion
|
|
#region " Private Properties "
|
|
private Size _ImageSize;
|
protected Size ImageSize => _ImageSize;
|
|
protected bool IsParentForm { get; private set; }
|
|
protected bool IsParentMdi
|
{
|
get
|
{
|
if (Parent == null)
|
{
|
return false;
|
}
|
|
return Parent.Parent != null;
|
}
|
}
|
|
private int _LockWidth;
|
protected int LockWidth
|
{
|
get => _LockWidth;
|
set
|
{
|
_LockWidth = value;
|
if (!(LockWidth == 0) && IsHandleCreated)
|
{
|
Width = LockWidth;
|
}
|
}
|
}
|
|
private int _LockHeight;
|
protected int LockHeight
|
{
|
get => _LockHeight;
|
set
|
{
|
_LockHeight = value;
|
if (!(LockHeight == 0) && IsHandleCreated)
|
{
|
Height = LockHeight;
|
}
|
}
|
}
|
|
private int _Header = 24;
|
protected int Header
|
{
|
get => _Header;
|
set
|
{
|
_Header = value;
|
|
if (!_ControlMode)
|
{
|
Frame = new(7, 7, Width - 14, value - 7);
|
Invalidate();
|
}
|
}
|
}
|
|
private bool _ControlMode;
|
protected bool ControlMode
|
{
|
get => _ControlMode;
|
set
|
{
|
_ControlMode = value;
|
|
Transparent = _Transparent;
|
if (_Transparent && _BackColor)
|
{
|
BackColor = Color.Transparent;
|
}
|
|
InvalidateBitmap();
|
Invalidate();
|
}
|
}
|
|
private bool _IsAnimated;
|
protected bool IsAnimated
|
{
|
get => _IsAnimated;
|
set
|
{
|
_IsAnimated = value;
|
InvalidateTimer();
|
}
|
}
|
|
#endregion
|
|
#region " Property Helpers "
|
|
protected Pen GetPen(string name)
|
{
|
return new(Items[name]);
|
}
|
protected Pen GetPen(string name, float width)
|
{
|
return new(Items[name], width);
|
}
|
|
protected SolidBrush GetBrush(string name)
|
{
|
return new SolidBrush(Items[name]);
|
}
|
|
protected Color GetColor(string name)
|
{
|
return Items[name];
|
}
|
|
protected void SetColor(string name, Color value)
|
{
|
if (Items.ContainsKey(name))
|
{
|
Items[name] = value;
|
}
|
else
|
{
|
Items.Add(name, value);
|
}
|
}
|
protected void SetColor(string name, byte r, byte g, byte b)
|
{
|
SetColor(name, Color.FromArgb(r, g, b));
|
}
|
protected void SetColor(string name, byte a, byte r, byte g, byte b)
|
{
|
SetColor(name, Color.FromArgb(a, r, g, b));
|
}
|
protected void SetColor(string name, byte a, Color value)
|
{
|
SetColor(name, Color.FromArgb(a, value));
|
}
|
|
private void InvalidateBitmap()
|
{
|
if (_Transparent && _ControlMode)
|
{
|
if (Width == 0 || Height == 0)
|
{
|
return;
|
}
|
|
B = new(Width, Height, PixelFormat.Format32bppPArgb);
|
G = Graphics.FromImage(B);
|
}
|
else
|
{
|
G = null;
|
B = null;
|
}
|
}
|
|
private void InvalidateCustimization()
|
{
|
MemoryStream M = new(Items.Count * 4);
|
|
foreach (BloomAir B in Colors)
|
{
|
M.Write(BitConverter.GetBytes(B.Value.ToArgb()), 0, 4);
|
}
|
|
M.Close();
|
_Customization = Convert.ToBase64String(M.ToArray());
|
}
|
|
private void InvalidateTimer()
|
{
|
if (DesignMode || !DoneCreation)
|
{
|
return;
|
}
|
|
if (_IsAnimated)
|
{
|
ThemeShareAir.AddAnimationCallback(DoAnimationAir);
|
}
|
else
|
{
|
ThemeShareAir.RemoveAnimationCallback(DoAnimationAir);
|
}
|
}
|
|
#endregion
|
|
#region " User Hooks "
|
|
protected abstract void ColorHook();
|
protected abstract void PaintHook();
|
|
protected virtual void OnCreation()
|
{
|
}
|
|
protected virtual void OnAnimation()
|
{
|
}
|
|
#endregion
|
|
#region " Offset "
|
|
private Rectangle OffsetReturnRectangle;
|
protected Rectangle Offset(Rectangle r, int amount)
|
{
|
OffsetReturnRectangle = new(r.X + amount, r.Y + amount, r.Width - (amount * 2), r.Height - (amount * 2));
|
return OffsetReturnRectangle;
|
}
|
|
private Size OffsetReturnSize;
|
protected Size Offset(Size s, int amount)
|
{
|
OffsetReturnSize = new(s.Width + amount, s.Height + amount);
|
return OffsetReturnSize;
|
}
|
|
private Point OffsetReturnPoint;
|
protected Point Offset(Point p, int amount)
|
{
|
OffsetReturnPoint = new(p.X + amount, p.Y + amount);
|
return OffsetReturnPoint;
|
}
|
|
#endregion
|
|
#region " Center "
|
|
private Point CenterReturn;
|
protected Point Center(Rectangle p, Rectangle c)
|
{
|
CenterReturn = new((p.Width / 2) - (c.Width / 2) + p.X + c.X, (p.Height / 2) - (c.Height / 2) + p.Y + c.Y);
|
return CenterReturn;
|
}
|
protected Point Center(Rectangle p, Size c)
|
{
|
CenterReturn = new((p.Width / 2) - (c.Width / 2) + p.X, (p.Height / 2) - (c.Height / 2) + p.Y);
|
return CenterReturn;
|
}
|
|
protected Point Center(Rectangle child)
|
{
|
return Center(Width, Height, child.Width, child.Height);
|
}
|
protected Point Center(Size child)
|
{
|
return Center(Width, Height, child.Width, child.Height);
|
}
|
protected Point Center(int childWidth, int childHeight)
|
{
|
return Center(Width, Height, childWidth, childHeight);
|
}
|
|
protected Point Center(Size p, Size c)
|
{
|
return Center(p.Width, p.Height, c.Width, c.Height);
|
}
|
|
protected Point Center(int pWidth, int pHeight, int cWidth, int cHeight)
|
{
|
CenterReturn = new((pWidth / 2) - (cWidth / 2), (pHeight / 2) - (cHeight / 2));
|
return CenterReturn;
|
}
|
|
#endregion
|
|
#region " Measure "
|
|
private readonly Bitmap MeasureBitmap;
|
|
private readonly Graphics MeasureGraphics;
|
protected Size Measure()
|
{
|
lock (MeasureGraphics)
|
{
|
return MeasureGraphics.MeasureString(Text, Font, Width).ToSize();
|
}
|
}
|
protected Size Measure(string text)
|
{
|
lock (MeasureGraphics)
|
{
|
return MeasureGraphics.MeasureString(text, Font, Width).ToSize();
|
}
|
}
|
|
#endregion
|
|
#region " DrawPixel "
|
|
private SolidBrush DrawPixelBrush;
|
protected void DrawPixel(Color c1, int x, int y)
|
{
|
if (_Transparent)
|
{
|
B.SetPixel(x, y, c1);
|
}
|
else
|
{
|
DrawPixelBrush = new(c1);
|
G.FillRectangle(DrawPixelBrush, x, y, 1, 1);
|
}
|
}
|
|
#endregion
|
|
#region " DrawCorners "
|
|
private SolidBrush DrawCornersBrush;
|
protected void DrawCorners(Color c1, int offset)
|
{
|
DrawCorners(c1, 0, 0, Width, Height, offset);
|
}
|
protected void DrawCorners(Color c1, Rectangle r1, int offset)
|
{
|
DrawCorners(c1, r1.X, r1.Y, r1.Width, r1.Height, offset);
|
}
|
protected void DrawCorners(Color c1, int x, int y, int width, int height, int offset)
|
{
|
DrawCorners(c1, x + offset, y + offset, width - (offset * 2), height - (offset * 2));
|
}
|
|
protected void DrawCorners(Color c1)
|
{
|
DrawCorners(c1, 0, 0, Width, Height);
|
}
|
protected void DrawCorners(Color c1, Rectangle r1)
|
{
|
DrawCorners(c1, r1.X, r1.Y, r1.Width, r1.Height);
|
}
|
protected void DrawCorners(Color c1, int x, int y, int width, int height)
|
{
|
if (_NoRounding)
|
{
|
return;
|
}
|
|
if (_Transparent)
|
{
|
B.SetPixel(x, y, c1);
|
B.SetPixel(x + (width - 1), y, c1);
|
B.SetPixel(x, y + (height - 1), c1);
|
B.SetPixel(x + (width - 1), y + (height - 1), c1);
|
}
|
else
|
{
|
DrawCornersBrush = new(c1);
|
G.FillRectangle(DrawCornersBrush, x, y, 1, 1);
|
G.FillRectangle(DrawCornersBrush, x + (width - 1), y, 1, 1);
|
G.FillRectangle(DrawCornersBrush, x, y + (height - 1), 1, 1);
|
G.FillRectangle(DrawCornersBrush, x + (width - 1), y + (height - 1), 1, 1);
|
}
|
}
|
|
#endregion
|
|
#region " DrawBorders "
|
|
protected void DrawBorders(Pen p1, int offset)
|
{
|
DrawBorders(p1, 0, 0, Width, Height, offset);
|
}
|
protected void DrawBorders(Pen p1, Rectangle r, int offset)
|
{
|
DrawBorders(p1, r.X, r.Y, r.Width, r.Height, offset);
|
}
|
protected void DrawBorders(Pen p1, int x, int y, int width, int height, int offset)
|
{
|
DrawBorders(p1, x + offset, y + offset, width - (offset * 2), height - (offset * 2));
|
}
|
|
protected void DrawBorders(Pen p1)
|
{
|
DrawBorders(p1, 0, 0, Width, Height);
|
}
|
protected void DrawBorders(Pen p1, Rectangle r)
|
{
|
DrawBorders(p1, r.X, r.Y, r.Width, r.Height);
|
}
|
protected void DrawBorders(Pen p1, int x, int y, int width, int height)
|
{
|
G.DrawRectangle(p1, x, y, width - 1, height - 1);
|
}
|
|
#endregion
|
|
#region " DrawText "
|
|
private Point DrawTextPoint;
|
|
private Size DrawTextSize;
|
protected void DrawText(Brush b1, HorizontalAlignment a, int x, int y)
|
{
|
DrawText(b1, Text, a, x, y);
|
}
|
protected void DrawText(Brush b1, string text, HorizontalAlignment a, int x, int y)
|
{
|
if (text.Length == 0)
|
{
|
return;
|
}
|
|
DrawTextSize = Measure(text);
|
DrawTextPoint = new((Width / 2) - (DrawTextSize.Width / 2), (Header / 2) - (DrawTextSize.Height / 2));
|
|
switch (a)
|
{
|
case HorizontalAlignment.Left:
|
G.DrawString(text, Font, b1, x, DrawTextPoint.Y + y);
|
break;
|
case HorizontalAlignment.Center:
|
G.DrawString(text, Font, b1, DrawTextPoint.X + x, DrawTextPoint.Y + y);
|
break;
|
case HorizontalAlignment.Right:
|
G.DrawString(text, Font, b1, Width - DrawTextSize.Width - x, DrawTextPoint.Y + y);
|
break;
|
}
|
}
|
|
protected void DrawText(Brush b1, Point p1)
|
{
|
if (Text.Length == 0)
|
{
|
return;
|
}
|
|
G.DrawString(Text, Font, b1, p1);
|
}
|
protected void DrawText(Brush b1, int x, int y)
|
{
|
if (Text.Length == 0)
|
{
|
return;
|
}
|
|
G.DrawString(Text, Font, b1, x, y);
|
}
|
|
#endregion
|
|
#region " DrawImage "
|
|
private Point DrawImagePoint;
|
protected void DrawImage(HorizontalAlignment a, int x, int y)
|
{
|
DrawImage(_Image, a, x, y);
|
}
|
protected void DrawImage(Image image, HorizontalAlignment a, int x, int y)
|
{
|
if (image == null)
|
{
|
return;
|
}
|
|
DrawImagePoint = new((Width / 2) - (image.Width / 2), (Header / 2) - (image.Height / 2));
|
|
switch (a)
|
{
|
case HorizontalAlignment.Left:
|
G.DrawImage(image, x, DrawImagePoint.Y + y, image.Width, image.Height);
|
break;
|
case HorizontalAlignment.Center:
|
G.DrawImage(image, DrawImagePoint.X + x, DrawImagePoint.Y + y, image.Width, image.Height);
|
break;
|
case HorizontalAlignment.Right:
|
G.DrawImage(image, Width - image.Width - x, DrawImagePoint.Y + y, image.Width, image.Height);
|
break;
|
}
|
}
|
|
protected void DrawImage(Point p1)
|
{
|
DrawImage(_Image, p1.X, p1.Y);
|
}
|
protected void DrawImage(int x, int y)
|
{
|
DrawImage(_Image, x, y);
|
}
|
|
protected void DrawImage(Image image, Point p1)
|
{
|
DrawImage(image, p1.X, p1.Y);
|
}
|
protected void DrawImage(Image image, int x, int y)
|
{
|
if (image == null)
|
{
|
return;
|
}
|
|
G.DrawImage(image, x, y, image.Width, image.Height);
|
}
|
|
#endregion
|
|
#region " DrawGradient "
|
|
private LinearGradientBrush DrawGradientBrush;
|
|
private Rectangle DrawGradientRectangle;
|
protected void DrawGradient(ColorBlend blend, int x, int y, int width, int height)
|
{
|
DrawGradientRectangle = new(x, y, width, height);
|
DrawGradient(blend, DrawGradientRectangle);
|
}
|
protected void DrawGradient(ColorBlend blend, int x, int y, int width, int height, float angle)
|
{
|
DrawGradientRectangle = new(x, y, width, height);
|
DrawGradient(blend, DrawGradientRectangle, angle);
|
}
|
|
protected void DrawGradient(ColorBlend blend, Rectangle r)
|
{
|
DrawGradientBrush = new(r, Color.Empty, Color.Empty, 90f)
|
{
|
InterpolationColors = blend
|
};
|
G.FillRectangle(DrawGradientBrush, r);
|
}
|
protected void DrawGradient(ColorBlend blend, Rectangle r, float angle)
|
{
|
DrawGradientBrush = new(r, Color.Empty, Color.Empty, angle)
|
{
|
InterpolationColors = blend
|
};
|
G.FillRectangle(DrawGradientBrush, r);
|
}
|
|
protected void DrawGradient(Color c1, Color c2, int x, int y, int width, int height)
|
{
|
DrawGradientRectangle = new(x, y, width, height);
|
DrawGradient(c1, c2, DrawGradientRectangle);
|
}
|
protected void DrawGradient(Color c1, Color c2, int x, int y, int width, int height, float angle)
|
{
|
DrawGradientRectangle = new(x, y, width, height);
|
DrawGradient(c1, c2, DrawGradientRectangle, angle);
|
}
|
|
protected void DrawGradient(Color c1, Color c2, Rectangle r)
|
{
|
DrawGradientBrush = new(r, c1, c2, 90f);
|
G.FillRectangle(DrawGradientBrush, r);
|
}
|
protected void DrawGradient(Color c1, Color c2, Rectangle r, float angle)
|
{
|
DrawGradientBrush = new(r, c1, c2, angle);
|
G.FillRectangle(DrawGradientBrush, r);
|
}
|
|
#endregion
|
|
#region " DrawRadial "
|
|
private readonly GraphicsPath DrawRadialPath;
|
private PathGradientBrush DrawRadialBrush1;
|
private LinearGradientBrush DrawRadialBrush2;
|
|
private Rectangle DrawRadialRectangle;
|
public void DrawRadial(ColorBlend blend, int x, int y, int width, int height)
|
{
|
DrawRadialRectangle = new(x, y, width, height);
|
DrawRadial(blend, DrawRadialRectangle, width / 2, height / 2);
|
}
|
public void DrawRadial(ColorBlend blend, int x, int y, int width, int height, Point center)
|
{
|
DrawRadialRectangle = new(x, y, width, height);
|
DrawRadial(blend, DrawRadialRectangle, center.X, center.Y);
|
}
|
public void DrawRadial(ColorBlend blend, int x, int y, int width, int height, int cx, int cy)
|
{
|
DrawRadialRectangle = new(x, y, width, height);
|
DrawRadial(blend, DrawRadialRectangle, cx, cy);
|
}
|
|
public void DrawRadial(ColorBlend blend, Rectangle r)
|
{
|
DrawRadial(blend, r, r.Width / 2, r.Height / 2);
|
}
|
public void DrawRadial(ColorBlend blend, Rectangle r, Point center)
|
{
|
DrawRadial(blend, r, center.X, center.Y);
|
}
|
public void DrawRadial(ColorBlend blend, Rectangle r, int cx, int cy)
|
{
|
DrawRadialPath.Reset();
|
DrawRadialPath.AddEllipse(r.X, r.Y, r.Width - 1, r.Height - 1);
|
|
DrawRadialBrush1 = new PathGradientBrush(DrawRadialPath)
|
{
|
CenterPoint = new(r.X + cx, r.Y + cy),
|
InterpolationColors = blend
|
};
|
|
if (G.SmoothingMode == SmoothingMode.AntiAlias)
|
{
|
G.FillEllipse(DrawRadialBrush1, r.X + 1, r.Y + 1, r.Width - 3, r.Height - 3);
|
}
|
else
|
{
|
G.FillEllipse(DrawRadialBrush1, r);
|
}
|
}
|
|
protected void DrawRadial(Color c1, Color c2, int x, int y, int width, int height)
|
{
|
DrawRadialRectangle = new(x, y, width, height);
|
DrawRadial(c1, c2, DrawGradientRectangle);
|
}
|
protected void DrawRadial(Color c1, Color c2, int x, int y, int width, int height, float angle)
|
{
|
DrawRadialRectangle = new(x, y, width, height);
|
DrawRadial(c1, c2, DrawGradientRectangle, angle);
|
}
|
|
protected void DrawRadial(Color c1, Color c2, Rectangle r)
|
{
|
DrawRadialBrush2 = new(r, c1, c2, 90f);
|
G.FillRectangle(DrawGradientBrush, r);
|
}
|
protected void DrawRadial(Color c1, Color c2, Rectangle r, float angle)
|
{
|
DrawRadialBrush2 = new(r, c1, c2, angle);
|
G.FillEllipse(DrawGradientBrush, r);
|
}
|
|
#endregion
|
|
#region " CreateRound "
|
|
private GraphicsPath CreateRoundPath;
|
|
private Rectangle CreateRoundRectangle;
|
public GraphicsPath CreateRound(int x, int y, int width, int height, int slope)
|
{
|
CreateRoundRectangle = new(x, y, width, height);
|
return CreateRound(CreateRoundRectangle, slope);
|
}
|
|
public GraphicsPath CreateRound(Rectangle r, int slope)
|
{
|
CreateRoundPath = new(FillMode.Winding);
|
CreateRoundPath.AddArc(r.X, r.Y, slope, slope, 180f, 90f);
|
CreateRoundPath.AddArc(r.Right - slope, r.Y, slope, slope, 270f, 90f);
|
CreateRoundPath.AddArc(r.Right - slope, r.Bottom - slope, slope, slope, 0f, 90f);
|
CreateRoundPath.AddArc(r.X, r.Bottom - slope, slope, slope, 90f, 90f);
|
CreateRoundPath.CloseFigure();
|
return CreateRoundPath;
|
}
|
|
#endregion
|
|
}
|
|
public abstract class AirControl : Control
|
{
|
#region " Initialization "
|
|
protected Graphics G;
|
|
protected Bitmap B;
|
|
public AirControl()
|
{
|
SetStyle((ControlStyles)139270, true);
|
|
_ImageSize = Size.Empty;
|
Font = new("Verdana", 8);
|
|
MeasureBitmap = new(1, 1);
|
MeasureGraphics = Graphics.FromImage(MeasureBitmap);
|
|
DrawRadialPath = new();
|
|
InvalidateCustimization();
|
//Remove?
|
}
|
|
protected sealed override void OnHandleCreated(EventArgs e)
|
{
|
InvalidateCustimization();
|
ColorHook();
|
|
if (!(_LockWidth == 0))
|
{
|
Width = _LockWidth;
|
}
|
|
if (!(_LockHeight == 0))
|
{
|
Height = _LockHeight;
|
}
|
|
Transparent = _Transparent;
|
if (_Transparent && _BackColor)
|
{
|
BackColor = Color.Transparent;
|
}
|
|
base.OnHandleCreated(e);
|
}
|
|
private bool DoneCreation;
|
protected sealed override void OnParentChanged(EventArgs e)
|
{
|
if (Parent != null)
|
{
|
OnCreation();
|
DoneCreation = true;
|
InvalidateTimer();
|
}
|
|
base.OnParentChanged(e);
|
}
|
|
#endregion
|
|
private void DoAnimationAir(bool i)
|
{
|
OnAnimation();
|
if (i)
|
{
|
Invalidate();
|
}
|
}
|
|
protected sealed override void OnPaint(PaintEventArgs e)
|
{
|
if (Width == 0 || Height == 0)
|
{
|
return;
|
}
|
|
if (_Transparent)
|
{
|
PaintHook();
|
e.Graphics.DrawImage(B, 0, 0);
|
}
|
else
|
{
|
G = e.Graphics;
|
PaintHook();
|
}
|
}
|
|
protected override void OnHandleDestroyed(EventArgs e)
|
{
|
ThemeShareAir.RemoveAnimationCallback(DoAnimationAir);
|
base.OnHandleDestroyed(e);
|
}
|
|
#region " Size Handling "
|
|
protected sealed override void OnSizeChanged(EventArgs e)
|
{
|
if (_Transparent)
|
{
|
InvalidateBitmap();
|
}
|
|
Invalidate();
|
base.OnSizeChanged(e);
|
}
|
|
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
|
{
|
if (!(_LockWidth == 0))
|
{
|
width = _LockWidth;
|
}
|
|
if (!(_LockHeight == 0))
|
{
|
height = _LockHeight;
|
}
|
|
base.SetBoundsCore(x, y, width, height, specified);
|
}
|
|
#endregion
|
|
#region " State Handling "
|
|
private bool InPosition;
|
protected override void OnMouseEnter(EventArgs e)
|
{
|
InPosition = true;
|
SetState(MouseStateAir.Over);
|
base.OnMouseEnter(e);
|
}
|
|
protected override void OnMouseUp(MouseEventArgs e)
|
{
|
if (InPosition)
|
{
|
SetState(MouseStateAir.Over);
|
}
|
|
base.OnMouseUp(e);
|
}
|
|
protected override void OnMouseDown(MouseEventArgs e)
|
{
|
if (e.Button == MouseButtons.Left)
|
{
|
SetState(MouseStateAir.Down);
|
}
|
|
base.OnMouseDown(e);
|
}
|
|
protected override void OnMouseLeave(EventArgs e)
|
{
|
InPosition = false;
|
SetState(MouseStateAir.None);
|
base.OnMouseLeave(e);
|
}
|
|
protected override void OnEnabledChanged(EventArgs e)
|
{
|
if (Enabled)
|
{
|
SetState(MouseStateAir.None);
|
}
|
else
|
{
|
SetState(MouseStateAir.Block);
|
}
|
|
base.OnEnabledChanged(e);
|
}
|
|
protected MouseStateAir State;
|
private void SetState(MouseStateAir current)
|
{
|
State = current;
|
Invalidate();
|
}
|
|
#endregion
|
|
#region " Base Properties "
|
|
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
public override Color ForeColor
|
{
|
get => Color.Empty;
|
set { }
|
}
|
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
public override Image BackgroundImage
|
{
|
get => null;
|
set { }
|
}
|
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
public override ImageLayout BackgroundImageLayout
|
{
|
get => ImageLayout.None;
|
set { }
|
}
|
|
public override string Text
|
{
|
get => base.Text;
|
set
|
{
|
base.Text = value;
|
Invalidate();
|
}
|
}
|
public override Font Font
|
{
|
get => base.Font;
|
set
|
{
|
base.Font = value;
|
Invalidate();
|
}
|
}
|
|
private bool _BackColor;
|
[Category("Misc")]
|
public override Color BackColor
|
{
|
get => base.BackColor;
|
set
|
{
|
if (!IsHandleCreated && value == Color.Transparent)
|
{
|
_BackColor = true;
|
return;
|
}
|
|
base.BackColor = value;
|
if (Parent != null)
|
{
|
ColorHook();
|
}
|
}
|
}
|
|
#endregion
|
|
#region " Public Properties "
|
|
private bool _NoRounding;
|
public bool NoRounding
|
{
|
get => _NoRounding;
|
set
|
{
|
_NoRounding = value;
|
Invalidate();
|
}
|
}
|
|
private Image _Image;
|
public Image Image
|
{
|
get => _Image;
|
set
|
{
|
if (value == null)
|
{
|
_ImageSize = Size.Empty;
|
}
|
else
|
{
|
_ImageSize = value.Size;
|
}
|
|
_Image = value;
|
Invalidate();
|
}
|
}
|
|
private bool _Transparent;
|
public bool Transparent
|
{
|
get => _Transparent;
|
set
|
{
|
_Transparent = value;
|
if (!IsHandleCreated)
|
{
|
return;
|
}
|
|
if (!value && !(BackColor.A == 255))
|
{
|
throw new Exception("Unable to change value to false while a transparent BackColor is in use.");
|
}
|
|
SetStyle(ControlStyles.Opaque, !value);
|
SetStyle(ControlStyles.SupportsTransparentBackColor, value);
|
|
if (value)
|
{
|
InvalidateBitmap();
|
}
|
else
|
{
|
B = null;
|
}
|
|
Invalidate();
|
}
|
}
|
|
private readonly Dictionary<string, Color> Items = new();
|
public BloomAir[] Colors
|
{
|
get
|
{
|
List<BloomAir> T = new();
|
Dictionary<string, Color>.Enumerator E = Items.GetEnumerator();
|
|
while (E.MoveNext())
|
{
|
T.Add(new BloomAir(E.Current.Key, E.Current.Value));
|
}
|
|
return T.ToArray();
|
}
|
set
|
{
|
foreach (BloomAir B in value)
|
{
|
if (Items.ContainsKey(B.Name))
|
{
|
Items[B.Name] = B.Value;
|
}
|
}
|
|
InvalidateCustimization();
|
ColorHook();
|
Invalidate();
|
}
|
}
|
|
private string _Customization;
|
public string Customization
|
{
|
get => _Customization;
|
set
|
{
|
if (value == _Customization)
|
{
|
return;
|
}
|
|
BloomAir[] Items = Colors;
|
|
try
|
{
|
byte[] Data = Convert.FromBase64String(value);
|
for (int I = 0; I <= Items.Length - 1; I++)
|
{
|
Items[I].Value = Color.FromArgb(BitConverter.ToInt32(Data, I * 4));
|
}
|
}
|
catch
|
{
|
return;
|
}
|
|
_Customization = value;
|
|
Colors = Items;
|
ColorHook();
|
Invalidate();
|
}
|
}
|
|
#endregion
|
|
#region " Private Properties "
|
|
private Size _ImageSize;
|
protected Size ImageSize => _ImageSize;
|
|
private int _LockWidth;
|
protected int LockWidth
|
{
|
get => _LockWidth;
|
set
|
{
|
_LockWidth = value;
|
if (!(LockWidth == 0) && IsHandleCreated)
|
{
|
Width = LockWidth;
|
}
|
}
|
}
|
|
private int _LockHeight;
|
protected int LockHeight
|
{
|
get => _LockHeight;
|
set
|
{
|
_LockHeight = value;
|
if (!(LockHeight == 0) && IsHandleCreated)
|
{
|
Height = LockHeight;
|
}
|
}
|
}
|
|
private bool _IsAnimated;
|
protected bool IsAnimated
|
{
|
get => _IsAnimated;
|
set
|
{
|
_IsAnimated = value;
|
InvalidateTimer();
|
}
|
}
|
|
#endregion
|
|
#region " Property Helpers "
|
|
protected Pen GetPen(string name)
|
{
|
return new(Items[name]);
|
}
|
protected Pen GetPen(string name, float width)
|
{
|
return new(Items[name], width);
|
}
|
|
protected SolidBrush GetBrush(string name)
|
{
|
return new SolidBrush(Items[name]);
|
}
|
|
protected Color GetColor(string name)
|
{
|
return Items[name];
|
}
|
|
protected void SetColor(string name, Color value)
|
{
|
if (Items.ContainsKey(name))
|
{
|
Items[name] = value;
|
}
|
else
|
{
|
Items.Add(name, value);
|
}
|
}
|
protected void SetColor(string name, byte r, byte g, byte b)
|
{
|
SetColor(name, Color.FromArgb(r, g, b));
|
}
|
protected void SetColor(string name, byte a, byte r, byte g, byte b)
|
{
|
SetColor(name, Color.FromArgb(a, r, g, b));
|
}
|
protected void SetColor(string name, byte a, Color value)
|
{
|
SetColor(name, Color.FromArgb(a, value));
|
}
|
|
private void InvalidateBitmap()
|
{
|
if (Width == 0 || Height == 0)
|
{
|
return;
|
}
|
|
B = new(Width, Height, PixelFormat.Format32bppPArgb);
|
G = Graphics.FromImage(B);
|
}
|
|
private void InvalidateCustimization()
|
{
|
MemoryStream M = new(Items.Count * 4);
|
|
foreach (BloomAir B in Colors)
|
{
|
M.Write(BitConverter.GetBytes(B.Value.ToArgb()), 0, 4);
|
}
|
|
M.Close();
|
_Customization = Convert.ToBase64String(M.ToArray());
|
}
|
|
private void InvalidateTimer()
|
{
|
if (DesignMode || !DoneCreation)
|
{
|
return;
|
}
|
|
if (_IsAnimated)
|
{
|
ThemeShareAir.AddAnimationCallback(DoAnimationAir);
|
}
|
else
|
{
|
ThemeShareAir.RemoveAnimationCallback(DoAnimationAir);
|
}
|
}
|
#endregion
|
|
#region " User Hooks "
|
|
protected abstract void ColorHook();
|
protected abstract void PaintHook();
|
|
protected virtual void OnCreation()
|
{
|
}
|
|
protected virtual void OnAnimation()
|
{
|
}
|
|
#endregion
|
|
#region " Offset "
|
|
private Rectangle OffsetReturnRectangle;
|
protected Rectangle Offset(Rectangle r, int amount)
|
{
|
OffsetReturnRectangle = new(r.X + amount, r.Y + amount, r.Width - (amount * 2), r.Height - (amount * 2));
|
return OffsetReturnRectangle;
|
}
|
|
private Size OffsetReturnSize;
|
protected Size Offset(Size s, int amount)
|
{
|
OffsetReturnSize = new(s.Width + amount, s.Height + amount);
|
return OffsetReturnSize;
|
}
|
|
private Point OffsetReturnPoint;
|
protected Point Offset(Point p, int amount)
|
{
|
OffsetReturnPoint = new(p.X + amount, p.Y + amount);
|
return OffsetReturnPoint;
|
}
|
|
#endregion
|
|
#region " Center "
|
|
private Point CenterReturn;
|
protected Point Center(Rectangle p, Rectangle c)
|
{
|
CenterReturn = new((p.Width / 2) - (c.Width / 2) + p.X + c.X, (p.Height / 2) - (c.Height / 2) + p.Y + c.Y);
|
return CenterReturn;
|
}
|
protected Point Center(Rectangle p, Size c)
|
{
|
CenterReturn = new((p.Width / 2) - (c.Width / 2) + p.X, (p.Height / 2) - (c.Height / 2) + p.Y);
|
return CenterReturn;
|
}
|
|
protected Point Center(Rectangle child)
|
{
|
return Center(Width, Height, child.Width, child.Height);
|
}
|
protected Point Center(Size child)
|
{
|
return Center(Width, Height, child.Width, child.Height);
|
}
|
protected Point Center(int childWidth, int childHeight)
|
{
|
return Center(Width, Height, childWidth, childHeight);
|
}
|
|
protected Point Center(Size p, Size c)
|
{
|
return Center(p.Width, p.Height, c.Width, c.Height);
|
}
|
|
protected Point Center(int pWidth, int pHeight, int cWidth, int cHeight)
|
{
|
CenterReturn = new((pWidth / 2) - (cWidth / 2), (pHeight / 2) - (cHeight / 2));
|
return CenterReturn;
|
}
|
|
#endregion
|
|
#region " Measure "
|
|
private readonly Bitmap MeasureBitmap;
|
//TODO: Potential issues during multi-threading.
|
private readonly Graphics MeasureGraphics;
|
|
protected Size Measure()
|
{
|
return MeasureGraphics.MeasureString(Text, Font, Width).ToSize();
|
}
|
protected Size Measure(string text)
|
{
|
return MeasureGraphics.MeasureString(text, Font, Width).ToSize();
|
}
|
|
#endregion
|
|
#region " DrawPixel "
|
|
private SolidBrush DrawPixelBrush;
|
protected void DrawPixel(Color c1, int x, int y)
|
{
|
if (_Transparent)
|
{
|
B.SetPixel(x, y, c1);
|
}
|
else
|
{
|
DrawPixelBrush = new(c1);
|
G.FillRectangle(DrawPixelBrush, x, y, 1, 1);
|
}
|
}
|
|
#endregion
|
|
#region " DrawCorners "
|
|
private SolidBrush DrawCornersBrush;
|
protected void DrawCorners(Color c1, int offset)
|
{
|
DrawCorners(c1, 0, 0, Width, Height, offset);
|
}
|
protected void DrawCorners(Color c1, Rectangle r1, int offset)
|
{
|
DrawCorners(c1, r1.X, r1.Y, r1.Width, r1.Height, offset);
|
}
|
protected void DrawCorners(Color c1, int x, int y, int width, int height, int offset)
|
{
|
DrawCorners(c1, x + offset, y + offset, width - (offset * 2), height - (offset * 2));
|
}
|
|
protected void DrawCorners(Color c1)
|
{
|
DrawCorners(c1, 0, 0, Width, Height);
|
}
|
protected void DrawCorners(Color c1, Rectangle r1)
|
{
|
DrawCorners(c1, r1.X, r1.Y, r1.Width, r1.Height);
|
}
|
protected void DrawCorners(Color c1, int x, int y, int width, int height)
|
{
|
if (_NoRounding)
|
{
|
return;
|
}
|
|
if (_Transparent)
|
{
|
B.SetPixel(x, y, c1);
|
B.SetPixel(x + (width - 1), y, c1);
|
B.SetPixel(x, y + (height - 1), c1);
|
B.SetPixel(x + (width - 1), y + (height - 1), c1);
|
}
|
else
|
{
|
DrawCornersBrush = new(c1);
|
G.FillRectangle(DrawCornersBrush, x, y, 1, 1);
|
G.FillRectangle(DrawCornersBrush, x + (width - 1), y, 1, 1);
|
G.FillRectangle(DrawCornersBrush, x, y + (height - 1), 1, 1);
|
G.FillRectangle(DrawCornersBrush, x + (width - 1), y + (height - 1), 1, 1);
|
}
|
}
|
|
#endregion
|
|
#region " DrawBorders "
|
|
protected void DrawBorders(Pen p1, int offset)
|
{
|
DrawBorders(p1, 0, 0, Width, Height, offset);
|
}
|
protected void DrawBorders(Pen p1, Rectangle r, int offset)
|
{
|
DrawBorders(p1, r.X, r.Y, r.Width, r.Height, offset);
|
}
|
protected void DrawBorders(Pen p1, int x, int y, int width, int height, int offset)
|
{
|
DrawBorders(p1, x + offset, y + offset, width - (offset * 2), height - (offset * 2));
|
}
|
|
protected void DrawBorders(Pen p1)
|
{
|
DrawBorders(p1, 0, 0, Width, Height);
|
}
|
protected void DrawBorders(Pen p1, Rectangle r)
|
{
|
DrawBorders(p1, r.X, r.Y, r.Width, r.Height);
|
}
|
protected void DrawBorders(Pen p1, int x, int y, int width, int height)
|
{
|
G.DrawRectangle(p1, x, y, width - 1, height - 1);
|
}
|
|
#endregion
|
|
#region " DrawText "
|
|
private Point DrawTextPoint;
|
|
private Size DrawTextSize;
|
protected void DrawText(Brush b1, HorizontalAlignment a, int x, int y)
|
{
|
DrawText(b1, Text, a, x, y);
|
}
|
protected void DrawText(Brush b1, string text, HorizontalAlignment a, int x, int y)
|
{
|
if (text.Length == 0)
|
{
|
return;
|
}
|
|
DrawTextSize = Measure(text);
|
DrawTextPoint = Center(DrawTextSize);
|
|
switch (a)
|
{
|
case HorizontalAlignment.Left:
|
G.DrawString(text, Font, b1, x, DrawTextPoint.Y + y);
|
break;
|
case HorizontalAlignment.Center:
|
G.DrawString(text, Font, b1, DrawTextPoint.X + x, DrawTextPoint.Y + y);
|
break;
|
case HorizontalAlignment.Right:
|
G.DrawString(text, Font, b1, Width - DrawTextSize.Width - x, DrawTextPoint.Y + y);
|
break;
|
}
|
}
|
|
protected void DrawText(Brush b1, Point p1)
|
{
|
if (Text.Length == 0)
|
{
|
return;
|
}
|
|
G.DrawString(Text, Font, b1, p1);
|
}
|
protected void DrawText(Brush b1, int x, int y)
|
{
|
if (Text.Length == 0)
|
{
|
return;
|
}
|
|
G.DrawString(Text, Font, b1, x, y);
|
}
|
|
#endregion
|
|
#region " DrawImage "
|
|
private Point DrawImagePoint;
|
protected void DrawImage(HorizontalAlignment a, int x, int y)
|
{
|
DrawImage(_Image, a, x, y);
|
}
|
protected void DrawImage(Image image, HorizontalAlignment a, int x, int y)
|
{
|
if (image == null)
|
{
|
return;
|
}
|
|
DrawImagePoint = Center(image.Size);
|
|
switch (a)
|
{
|
case HorizontalAlignment.Left:
|
G.DrawImage(image, x, DrawImagePoint.Y + y, image.Width, image.Height);
|
break;
|
case HorizontalAlignment.Center:
|
G.DrawImage(image, DrawImagePoint.X + x, DrawImagePoint.Y + y, image.Width, image.Height);
|
break;
|
case HorizontalAlignment.Right:
|
G.DrawImage(image, Width - image.Width - x, DrawImagePoint.Y + y, image.Width, image.Height);
|
break;
|
}
|
}
|
|
protected void DrawImage(Point p1)
|
{
|
DrawImage(_Image, p1.X, p1.Y);
|
}
|
protected void DrawImage(int x, int y)
|
{
|
DrawImage(_Image, x, y);
|
}
|
|
protected void DrawImage(Image image, Point p1)
|
{
|
DrawImage(image, p1.X, p1.Y);
|
}
|
protected void DrawImage(Image image, int x, int y)
|
{
|
if (image == null)
|
{
|
return;
|
}
|
|
G.DrawImage(image, x, y, image.Width, image.Height);
|
}
|
|
#endregion
|
|
#region " DrawGradient "
|
|
private LinearGradientBrush DrawGradientBrush;
|
|
private Rectangle DrawGradientRectangle;
|
protected void DrawGradient(ColorBlend blend, int x, int y, int width, int height)
|
{
|
DrawGradientRectangle = new(x, y, width, height);
|
DrawGradient(blend, DrawGradientRectangle);
|
}
|
protected void DrawGradient(ColorBlend blend, int x, int y, int width, int height, float angle)
|
{
|
DrawGradientRectangle = new(x, y, width, height);
|
DrawGradient(blend, DrawGradientRectangle, angle);
|
}
|
|
protected void DrawGradient(ColorBlend blend, Rectangle r)
|
{
|
DrawGradientBrush = new(r, Color.Empty, Color.Empty, 90f)
|
{
|
InterpolationColors = blend
|
};
|
G.FillRectangle(DrawGradientBrush, r);
|
}
|
protected void DrawGradient(ColorBlend blend, Rectangle r, float angle)
|
{
|
DrawGradientBrush = new(r, Color.Empty, Color.Empty, angle)
|
{
|
InterpolationColors = blend
|
};
|
G.FillRectangle(DrawGradientBrush, r);
|
}
|
|
protected void DrawGradient(Color c1, Color c2, int x, int y, int width, int height)
|
{
|
DrawGradientRectangle = new(x, y, width, height);
|
DrawGradient(c1, c2, DrawGradientRectangle);
|
}
|
protected void DrawGradient(Color c1, Color c2, int x, int y, int width, int height, float angle)
|
{
|
DrawGradientRectangle = new(x, y, width, height);
|
DrawGradient(c1, c2, DrawGradientRectangle, angle);
|
}
|
|
protected void DrawGradient(Color c1, Color c2, Rectangle r)
|
{
|
DrawGradientBrush = new(r, c1, c2, 90f);
|
G.FillRectangle(DrawGradientBrush, r);
|
}
|
protected void DrawGradient(Color c1, Color c2, Rectangle r, float angle)
|
{
|
DrawGradientBrush = new(r, c1, c2, angle);
|
G.FillRectangle(DrawGradientBrush, r);
|
}
|
|
#endregion
|
|
#region " DrawRadial "
|
|
private readonly GraphicsPath DrawRadialPath;
|
private PathGradientBrush DrawRadialBrush1;
|
private LinearGradientBrush DrawRadialBrush2;
|
|
private Rectangle DrawRadialRectangle;
|
public void DrawRadial(ColorBlend blend, int x, int y, int width, int height)
|
{
|
DrawRadialRectangle = new(x, y, width, height);
|
DrawRadial(blend, DrawRadialRectangle, width / 2, height / 2);
|
}
|
public void DrawRadial(ColorBlend blend, int x, int y, int width, int height, Point center)
|
{
|
DrawRadialRectangle = new(x, y, width, height);
|
DrawRadial(blend, DrawRadialRectangle, center.X, center.Y);
|
}
|
public void DrawRadial(ColorBlend blend, int x, int y, int width, int height, int cx, int cy)
|
{
|
DrawRadialRectangle = new(x, y, width, height);
|
DrawRadial(blend, DrawRadialRectangle, cx, cy);
|
}
|
|
public void DrawRadial(ColorBlend blend, Rectangle r)
|
{
|
DrawRadial(blend, r, r.Width / 2, r.Height / 2);
|
}
|
public void DrawRadial(ColorBlend blend, Rectangle r, Point center)
|
{
|
DrawRadial(blend, r, center.X, center.Y);
|
}
|
public void DrawRadial(ColorBlend blend, Rectangle r, int cx, int cy)
|
{
|
DrawRadialPath.Reset();
|
DrawRadialPath.AddEllipse(r.X, r.Y, r.Width - 1, r.Height - 1);
|
|
DrawRadialBrush1 = new PathGradientBrush(DrawRadialPath)
|
{
|
CenterPoint = new(r.X + cx, r.Y + cy),
|
InterpolationColors = blend
|
};
|
|
if (G.SmoothingMode == SmoothingMode.AntiAlias)
|
{
|
G.FillEllipse(DrawRadialBrush1, r.X + 1, r.Y + 1, r.Width - 3, r.Height - 3);
|
}
|
else
|
{
|
G.FillEllipse(DrawRadialBrush1, r);
|
}
|
}
|
|
protected void DrawRadial(Color c1, Color c2, int x, int y, int width, int height)
|
{
|
DrawRadialRectangle = new(x, y, width, height);
|
DrawRadial(c1, c2, DrawRadialRectangle);
|
}
|
protected void DrawRadial(Color c1, Color c2, int x, int y, int width, int height, float angle)
|
{
|
DrawRadialRectangle = new(x, y, width, height);
|
DrawRadial(c1, c2, DrawRadialRectangle, angle);
|
}
|
|
protected void DrawRadial(Color c1, Color c2, Rectangle r)
|
{
|
DrawRadialBrush2 = new(r, c1, c2, 90f);
|
G.FillEllipse(DrawRadialBrush2, r);
|
}
|
protected void DrawRadial(Color c1, Color c2, Rectangle r, float angle)
|
{
|
DrawRadialBrush2 = new(r, c1, c2, angle);
|
G.FillEllipse(DrawRadialBrush2, r);
|
}
|
|
#endregion
|
|
#region " CreateRound "
|
|
private GraphicsPath CreateRoundPath;
|
|
private Rectangle CreateRoundRectangle;
|
public GraphicsPath CreateRound(int x, int y, int width, int height, int slope)
|
{
|
CreateRoundRectangle = new(x, y, width, height);
|
return CreateRound(CreateRoundRectangle, slope);
|
}
|
|
public GraphicsPath CreateRound(Rectangle r, int slope)
|
{
|
CreateRoundPath = new(FillMode.Winding);
|
CreateRoundPath.AddArc(r.X, r.Y, slope, slope, 180f, 90f);
|
CreateRoundPath.AddArc(r.Right - slope, r.Y, slope, slope, 270f, 90f);
|
CreateRoundPath.AddArc(r.Right - slope, r.Bottom - slope, slope, slope, 0f, 90f);
|
CreateRoundPath.AddArc(r.X, r.Bottom - slope, slope, slope, 90f, 90f);
|
CreateRoundPath.CloseFigure();
|
return CreateRoundPath;
|
}
|
|
#endregion
|
|
}
|
|
public static class ThemeShareAir
|
{
|
#region " Animation "
|
|
private static int Frames;
|
private static bool Invalidate;
|
|
public static PrecisionTimerAir ThemeTimer = new();
|
//1000 / 50 = 20 FPS
|
private const int FPS = 50;
|
|
private const int Rate = 10;
|
|
public delegate void AnimationDelegate(bool invalidate);
|
private static readonly List<AnimationDelegate> Callbacks = new();
|
|
private static void HandleCallbacksAir(IntPtr state, bool reserve)
|
{
|
Invalidate = Frames >= FPS;
|
if (Invalidate)
|
{
|
Frames = 0;
|
}
|
|
lock (Callbacks)
|
{
|
for (int I = 0; I <= Callbacks.Count - 1; I++)
|
{
|
Callbacks[I].Invoke(Invalidate);
|
}
|
}
|
|
Frames += Rate;
|
}
|
|
private static void InvalidateThemeTimer()
|
{
|
if (Callbacks.Count == 0)
|
{
|
ThemeTimer.Delete();
|
}
|
else
|
{
|
ThemeTimer.Create(0, Rate, HandleCallbacksAir);
|
}
|
}
|
|
public static void AddAnimationCallback(AnimationDelegate callback)
|
{
|
lock (Callbacks)
|
{
|
if (Callbacks.Contains(callback))
|
{
|
return;
|
}
|
|
Callbacks.Add(callback);
|
InvalidateThemeTimer();
|
}
|
}
|
|
public static void RemoveAnimationCallback(AnimationDelegate callback)
|
{
|
lock (Callbacks)
|
{
|
if (!Callbacks.Contains(callback))
|
{
|
return;
|
}
|
|
Callbacks.Remove(callback);
|
InvalidateThemeTimer();
|
}
|
}
|
|
#endregion
|
}
|
|
public enum MouseStateAir : byte
|
{
|
None = 0,
|
Over = 1,
|
Down = 2,
|
Block = 3
|
}
|
|
public struct BloomAir
|
{
|
|
public string _Name;
|
public string Name => _Name;
|
|
public Color Value { get; set; }
|
|
public string ValueHex
|
{
|
get => string.Concat("#", Value.R.ToString("X2", null), Value.G.ToString("X2", null), Value.B.ToString("X2", null));
|
set
|
{
|
try
|
{
|
Value = ColorTranslator.FromHtml(value);
|
}
|
catch
|
{
|
return;
|
}
|
}
|
}
|
|
public BloomAir(string name, Color value)
|
{
|
_Name = name;
|
Value = value;
|
}
|
}
|
|
public class PrecisionTimerAir : IDisposable
|
{
|
public bool Enabled { get; private set; }
|
|
private IntPtr Handle;
|
|
private TimerDelegate TimerCallback;
|
[DllImport("kernel32.dll", EntryPoint = "CreateTimerQueueTimer")]
|
private static extern bool CreateTimerQueueTimer(ref IntPtr handle, IntPtr queue, TimerDelegate callback, IntPtr state, uint dueTime, uint period, uint flags);
|
|
[DllImport("kernel32.dll", EntryPoint = "DeleteTimerQueueTimer")]
|
private static extern bool DeleteTimerQueueTimer(IntPtr queue, IntPtr handle, IntPtr callback);
|
|
public delegate void TimerDelegate(IntPtr r1, bool r2);
|
|
public void Create(uint dueTime, uint period, TimerDelegate callback)
|
{
|
if (Enabled)
|
{
|
return;
|
}
|
|
TimerCallback = callback;
|
bool Success = CreateTimerQueueTimer(ref Handle, IntPtr.Zero, TimerCallback, IntPtr.Zero, dueTime, period, 0);
|
|
if (!Success)
|
{
|
ThrowNewException("CreateTimerQueueTimer");
|
}
|
|
Enabled = Success;
|
}
|
|
public void Delete()
|
{
|
if (!Enabled)
|
{
|
return;
|
}
|
|
bool Success = DeleteTimerQueueTimer(IntPtr.Zero, Handle, IntPtr.Zero);
|
|
if (!Success && !(Marshal.GetLastWin32Error() == 997))
|
{
|
ThrowNewException("DeleteTimerQueueTimer");
|
}
|
|
Enabled = !Success;
|
}
|
|
private static void ThrowNewException(string name)
|
{
|
throw new Exception(string.Format("{0} failed. Win32Error: {1}", name, Marshal.GetLastWin32Error()));
|
}
|
|
void IDisposable.Dispose()
|
{
|
GC.SuppressFinalize(this);
|
Delete();
|
}
|
}
|
|
#endregion
|
}
|