using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ImpulseVision
{
public partial class EgoldsFormStyle : Component
{
#region -- Свойста --
public Form Form { get; set; }
private fStyle formStyle = fStyle.None;
public fStyle FormStyle
{
get => formStyle;
set
{
formStyle = value;
if (Site.DesignMode) return;
if (StyleUsed == false)
{
// Если стиль не был использован, то:
Sign();
}
else
{
// Если стиль был использован то:
SetStyle(formStyle);
}
}
}
public enum fStyle // Набор стилей
{
None,
UserStyle,
SimpleDark,
TelegramStyle
}
[Description("Указывает, может ли пользователь изменять размер окна")]
public bool AllowUserResize { get; set; }
[Description("Указывает, включен ли эффект свечения от курсора при наведении на значки меню окна")]
public bool EnableControlBoxMouseLight { get; set; }
///
/// Указывает, включен ли эффект свечения от значков меню окна
///
[Description("Указывает, включен ли эффект свечения от значков меню окна")]
public bool EnableControlBoxIconsLight { get; set; }
[Description("Ширина кнопок меню окна")]
public int ControlBoxButtonsWidth { get; set; } = 20;
[Description("Высота шапки (заголовка)")]
public int HeaderHeight { get; set; } = 38;
[Description("Цвет шапки (заголовка)")]
public Color HeaderColor { get; set; } = Color.DimGray;
[Description("Дополнительный цвет шапки (заголовка) используемый для создания градиента (При HeaderColorGradientEnabled = true)")]
public Color HeaderColorAdditional { get; set; } = Color.White;
[Description("Указывает, включен ли градинт цета шапки (заголовка)")]
public bool HeaderColorGradientEnable { get; set; } = false;
[Description("Определяет направление линейного градиента шапки")]
public LinearGradientMode HeaderColorGradientMode { get; set; } = LinearGradientMode.Horizontal;
[Description("Меню быстрого доступа, отображаемое при щелчке правой кнопкой мыши на иконке окна")]
public ContextMenuStrip ContextMenuForm { get; set; }
[Description("Шрифт текста шапки (заголовка)")]
public Font HeaderTextFont { get; set; } = new Font("Segoe UI", 9.75F, FontStyle.Regular);
[Description("Цвет текста шапки (заголовка)")]
public Color HeaderTextColor { get; set; } = Color.White;
public Image HeaderImage { get; set; }
[Description("Фоновый цвет формы")]
public Color BackColor { get; set; } = Color.White;
#endregion
#region -- Поля --
private List FormControls = new List();
private Panel MainContainer = null;
private Dictionary StylesDictionary; // Словарь вида: <Стиль из набора, Объект стиля с параметрами>
private StylesForForm CurrentStyle; // Актуальный стиль, класс с его параметрамы
private bool StyleUsed = false; // Применялся ли стиль(тема)
private Size IconSize = new Size(14, 14); // Размер икноки формы
private Rectangle rectIcon = new Rectangle(); // Структура иконки формы
private bool IconHovered = false; // Наведен ли курсор на иконку
private StringFormat SF = new StringFormat();
private bool MousePressed = false; // Кнопка мыши нажата
private Point clickPosition; // Начальная позиция курсора в момент клика
private Point moveStartPosition; // Начальная позиция формы в момент клика
private bool CanDragForm = false; // Указывает может ли форма перетаскивается
private MouseButtons LastClickedMouseButton; // Какая кнопка мыши была нажата последний раз
private Size ControlBoxIconSize = new Size(10, 10); // Размер иконок меню окна
private Rectangle rectBtnClose = new Rectangle(); // Структура кнопки меню окна Закрыть
private Rectangle rectBtnMax = new Rectangle(); // Структура кнопки меню окна Развернуть/Свернуть в окно
private Rectangle rectBtnMin = new Rectangle(); // Структура кнопки меню окна Свернуть
private bool btnCloseHovered = false; // Наведен ли курсор на кнопку Закрыть
private bool btnMaximizeHovered = false; // Наведен ли курсор на кнопку Развернуть/Свернуть в окно
private bool btnMinimizeHovered = false; // Наведен ли курсор на кнопку Свернуть
private Pen penBtnClose = new Pen(Color.White, 1.55F); // Кисть для кнопки Закрыть
private Pen penBtnMaximize = new Pen(Color.DarkGray, 1.55F); // Кисть для кнопки Развернуть/Свернуть в окно
private Pen penBtnMinimize = new Pen(Color.Gray, 1.55F); // Кисть для кнопки Свернуть
private Rectangle rectHeader = new Rectangle(); // Структура заголовка формы
private Rectangle rectBorder = new Rectangle(); // Структура обводки
private int ResizeBorderSize = 4; // Размер невидимой границы при наведении на которую меняется курсор, чтобы изменять размер формы
private int ResizeAngleBorderOffset = 15; // Смещение от углов, где мы трактуем угловую часть для изменения размера по углам
private bool IsResizing = false; // Режим изменения размера
private BorderHoverPositionEnum BorderHoverPosition = BorderHoverPositionEnum.None; // Куда наведен курсор в отношении обводки для изменения формы
enum BorderHoverPositionEnum
{
None, // Не наведен
Left, Top, Right, Bottom, // Стороны
TopLeft, TopRight, BottomLeft, BottomRight // Углы
}
private int ResizeStartRight = 0;
private int ResizeStartBottom = 0;
// Указывает, нужно ли восстановить позицию окна,
// которая была, перед разворачиванием на весь экран (Maximize), с помощью перетаскивания окна вверх экана
private bool FormNeedReposition = false;
#endregion
public EgoldsFormStyle()
{
InitializeComponent();
}
public EgoldsFormStyle(IContainer container)
{
DefineStyles();
container.Add(this);
InitializeComponent();
}
///
/// Определение стилей (тем)
///
private void DefineStyles()
{
StylesDictionary = new Dictionary();
// Стиль стандартной формы, без параметров, кроме HeaderHeight
StylesDictionary.Add(fStyle.None,
new StylesForForm()
{
HeaderHeight = 0
});
// Стиль пользователя, на основе параметров компонента, параметры устанавливаются в SaveUserStyleConfig()
StylesDictionary.Add(fStyle.UserStyle,
new StylesForForm()
{
FormBorderStyle = FormBorderStyle.None
});
// Стиль SimpleDark
StylesDictionary.Add(fStyle.SimpleDark,
new StylesForForm()
{
FormBorderStyle = FormBorderStyle.None,
BackColor = Color.White,
HeaderHeight = 38,
HeaderColor = FlatColors.WetAsphalt,
HeaderTextColor = Color.White,
HeaderTextFont = new Font("Segoe UI", 9.75F, FontStyle.Regular),
ControlBoxButtonsWidth = HeaderHeight,
ControlBoxIconsSize = new Size(10, 10),
UseSecondControlBoxIconsColorOnHover = false, // <-
ControlBoxEnabledIconsColor = Color.White
});
// Стиль TelegramStyle
StylesDictionary.Add(fStyle.TelegramStyle,
new StylesForForm()
{
FormBorderStyle = FormBorderStyle.None,
BackColor = Color.White,
HeaderHeight = 20,
HeaderColor = FlatColors.GrayLight2,
HeaderTextColor = Color.Gray,
HeaderTextFont = new Font("Segoe UI", 9F, FontStyle.Bold),
ControlBoxButtonsWidth = 24,
ControlBoxIconsSize = new Size(8, 8),
UseSecondControlBoxIconsColorOnHover = true,
ControlBoxEnabledIconsColor = Color.Gray,
ControlBoxOnHoverIconsColor = Color.White
});
}
///
/// Сохранение значения свойста FormBorderStyle стандартной формы в стиль "NoneStyle", выполняется только один раз
///
private void SaveNoneStyleConfig()
{
if (StylesDictionary.ContainsKey(fStyle.None) && StyleUsed == false)
{
StylesForForm NoneStyle = StylesDictionary[fStyle.None];
NoneStyle.FormBorderStyle = Form.FormBorderStyle;
NoneStyle.BackColor = Form.BackColor;
}
}
private void SaveUserStyleConfig()
{
if (StylesDictionary.ContainsKey(fStyle.UserStyle) && StyleUsed == false)
{
// Стиль пользователя, на основе параметров компонента
StylesForForm UserStyle = StylesDictionary[fStyle.UserStyle];
UserStyle.FormBorderStyle = FormBorderStyle.None;
UserStyle.HeaderHeight = HeaderHeight;
UserStyle.HeaderColor = HeaderColor;
UserStyle.BackColor = BackColor;
UserStyle.HeaderTextColor = HeaderTextColor;
UserStyle.HeaderTextFont = HeaderTextFont;
UserStyle.ControlBoxButtonsWidth = ControlBoxButtonsWidth;
UserStyle.ControlBoxIconsSize = ControlBoxIconSize;
}
}
///
/// Подписываем форме новое событие, для применения стилей
///
private void Sign()
{
if (Form != null)
{
// Используем событие HandleCreated, так как оно вызывается перед тем как форма загрузится
Form.HandleCreated += Form_HandleCreated;
// На случай если изначально форма имела стандартный стиль, тоесть не использовался данный компонент и форма уже загружена
if (Form.IsHandleCreated)
{
Apply();
Form.Refresh();
}
}
}
///
/// Первоначальная настройка формы
///
private void Apply()
{
SaveNoneStyleConfig();
SaveUserStyleConfig();
MigrateControls();
SetStyle(FormStyle);
StyleUsed = true;
SF.Alignment = StringAlignment.Near;
SF.LineAlignment = StringAlignment.Center;
Size minimumSize = new Size(100, 50);
if (Form.MinimumSize.Width < minimumSize.Width || Form.MinimumSize.Height < minimumSize.Height)
Form.MinimumSize = minimumSize;
SetDoubleBuffered(Form);
// Цепляем необходимые события к форме
Form.Paint += Form_Paint;
Form.MouseDown += Form_MouseDown;
Form.MouseUp += Form_MouseUp;
Form.MouseMove += Form_MouseMove;
Form.MouseLeave += Form_MouseLeave;
Form.SizeChanged += Form_SizeChanged;
Form.DoubleClick += Form_DoubleClick;
Form.Click += Form_Click;
Form.BackColorChanged += Form_BackColorChanged;
}
///
/// Изменение стиля
///
/// Стиль из набора fStyle
private void SetStyle(fStyle Style)
{
FormWindowState formWindowStateTEMP = Form.WindowState;
Form.WindowState = FormWindowState.Normal;
if (StyleUsed)
{
//OffsetControls(-HeaderHeight);
OffsetMainContrainer(-HeaderHeight);
Form.Height -= HeaderHeight;
}
CurrentStyle = StylesDictionary[Style];
HeaderHeight = CurrentStyle.HeaderHeight;
HeaderColor = CurrentStyle.HeaderColor;
BackColor = CurrentStyle.BackColor;
HeaderTextFont = CurrentStyle.HeaderTextFont;
HeaderTextColor = CurrentStyle.HeaderTextColor;
IconSize = CurrentStyle.IconSize;
ControlBoxIconSize = CurrentStyle.ControlBoxIconsSize;
ControlBoxButtonsWidth = CurrentStyle.ControlBoxButtonsWidth;
Form.BackColor = BackColor;
//OffsetControls(HeaderHeight);
OffsetMainContrainer(HeaderHeight);
Form.Height += HeaderHeight;
Form.Refresh();
Form.FormBorderStyle = CurrentStyle.FormBorderStyle;
Form.WindowState = formWindowStateTEMP;
}
///
/// Смещение контролов
///
///
private void OffsetControls(int offsett)
{
foreach (Control ctrl in Form.Controls)
{
ctrl.Location = new Point(ctrl.Location.X, ctrl.Location.Y + offsett);
ctrl.Refresh();
}
}
private void MigrateControls()
{
// Определение панели-контейнера
MainContainer = new Panel();
MainContainer.BackColor = Form.BackColor;
MainContainer.Location = new Point(1, HeaderHeight + 1);
ChangeMainContainerSize();
// Перенос контролов на отдельную панель
if (FormControls.Count == 0)
FormControls.AddRange(Form.Controls.OfType());
Form.Controls.Clear();
if (FormControls.Count > 0)
MainContainer.Controls.AddRange(FormControls.ToArray());
Form.Controls.Add(MainContainer);
}
private void OffsetMainContrainer(int offset)
{
MainContainer.Location = new Point(MainContainer.Location.X, MainContainer.Location.Y + offset);
MainContainer.Refresh();
}
private void ChangeMainContainerSize()
{
MainContainer.Size = new Size(Form.Width - 2, Form.Height - HeaderHeight - 2);
}
#region -- Form Events --
// В этом событии выполняется раньше чем в Load
private void Form_HandleCreated(object sender, EventArgs e)
{
Apply();
}
private void Form_Paint(object sender, PaintEventArgs e)
{
if (FormStyle != fStyle.None)
DrawStyle(e.Graphics);
}
private void Form_SizeChanged(object sender, EventArgs e)
{
Form.Refresh();
ChangeMainContainerSize();
}
private void Form_BackColorChanged(object sender, EventArgs e)
{
MainContainer.BackColor = Form.BackColor;
}
private void Form_MouseLeave(object sender, EventArgs e)
{
if (FormStyle == fStyle.None) return;
btnCloseHovered = false;
btnMaximizeHovered = false;
btnMinimizeHovered = false;
Form.Invalidate();
}
private void Form_MouseMove(object sender, MouseEventArgs e)
{
if (FormStyle == fStyle.None) return;
// Dragging
if (CanDragForm && e.Button == MouseButtons.Left)
{
if (Form.WindowState == FormWindowState.Maximized)
{
float maxWidth = Form.Width;
float cursosOnMaxPosition = e.X;
float coeff = cursosOnMaxPosition / (maxWidth / 100f) / 100f;
// Change WindowState if is Maximized
Form.WindowState = FormWindowState.Normal;
int XFormOffset = (int)(Form.Width * coeff);
Form.Location = new Point(Cursor.Position.X - XFormOffset, Cursor.Position.Y - HeaderHeight / 2);
moveStartPosition = Form.Location;
clickPosition = Cursor.Position;
}
else
{
// Moving
Size frmOffset = new Size(Point.Subtract(Cursor.Position, new Size(clickPosition)));
Form.Location = Point.Add(moveStartPosition, frmOffset);
}
}
// Hovering
else
{
// Close Button Hovering
if (rectBtnClose.Contains(e.Location))
{
if (btnCloseHovered == false)
{
btnCloseHovered = true;
if (EnableControlBoxMouseLight == false)
Form.Invalidate();
}
if (EnableControlBoxMouseLight == true)
Form.Invalidate();
}
else
{
if (btnCloseHovered == true)
{
btnCloseHovered = false;
Form.Invalidate();
}
}
// Maximize Button Hovering
if (rectBtnMax.Contains(e.Location))
{
if (btnMaximizeHovered == false)
{
btnMaximizeHovered = true;
if (EnableControlBoxMouseLight == false)
Form.Invalidate();
}
if (EnableControlBoxMouseLight == true)
Form.Invalidate();
}
else
{
if (btnMaximizeHovered)
{
btnMaximizeHovered = false;
Form.Invalidate();
}
}
// Minimize Button Hovering
if (rectBtnMin.Contains(e.Location))
{
if (btnMinimizeHovered == false)
{
btnMinimizeHovered = true;
if (EnableControlBoxMouseLight == false)
Form.Invalidate();
}
if (EnableControlBoxMouseLight == true)
Form.Invalidate();
}
else
{
if (btnMinimizeHovered)
{
btnMinimizeHovered = false;
Form.Invalidate();
}
}
// Icon Hovering
if (rectIcon.Contains(e.Location))
{
IconHovered = true;
}
else
{
IconHovered = false;
}
}
// On hover on border for resize
if (AllowUserResize && IsResizing == false && Form.WindowState == FormWindowState.Normal)
{
if (rectBorder.Top + ResizeBorderSize >= e.Location.Y)
{
// Левый верхний угол
if (e.Location.X <= ResizeAngleBorderOffset)
{
Form.Cursor = Cursors.SizeNWSE;
BorderHoverPosition = BorderHoverPositionEnum.TopLeft;
}
// Правый верхний угол
else if (e.Location.X >= rectBorder.Width - ResizeAngleBorderOffset)
{
Form.Cursor = Cursors.SizeNESW;
BorderHoverPosition = BorderHoverPositionEnum.TopRight;
}
else
{
Form.Cursor = Cursors.SizeNS;
BorderHoverPosition = BorderHoverPositionEnum.Top;
}
}
else if (rectBorder.Bottom - ResizeBorderSize <= e.Location.Y)
{
// Левый нижний угол
if (e.Location.X <= ResizeAngleBorderOffset)
{
Form.Cursor = Cursors.SizeNESW;
BorderHoverPosition = BorderHoverPositionEnum.BottomLeft;
}
// Правый нижний угол
else if (e.Location.X >= rectBorder.Width - ResizeAngleBorderOffset)
{
Form.Cursor = Cursors.SizeNWSE;
BorderHoverPosition = BorderHoverPositionEnum.BottomRight;
}
else
{
Form.Cursor = Cursors.SizeNS;
BorderHoverPosition = BorderHoverPositionEnum.Bottom;
}
}
else if (rectBorder.Left + ResizeBorderSize >= e.Location.X)
{
// Левый верхний угол
if (e.Location.Y <= ResizeAngleBorderOffset)
{
Form.Cursor = Cursors.SizeNWSE;
BorderHoverPosition = BorderHoverPositionEnum.TopLeft;
}
// Левый нижний угол
else if (e.Location.Y >= rectBorder.Height - ResizeAngleBorderOffset)
{
Form.Cursor = Cursors.SizeNESW;
BorderHoverPosition = BorderHoverPositionEnum.BottomLeft;
}
else
{
Form.Cursor = Cursors.SizeWE;
BorderHoverPosition = BorderHoverPositionEnum.Left;
}
}
else if (rectBorder.Right - ResizeBorderSize <= e.Location.X)
{
// Правый верхний угол
if (e.Location.Y <= ResizeAngleBorderOffset)
{
Form.Cursor = Cursors.SizeNESW;
BorderHoverPosition = BorderHoverPositionEnum.TopRight;
}
// Правый нижний угол
else if (e.Location.Y >= rectBorder.Height - ResizeAngleBorderOffset)
{
Form.Cursor = Cursors.SizeNWSE;
BorderHoverPosition = BorderHoverPositionEnum.BottomRight;
}
else
{
Form.Cursor = Cursors.SizeWE;
BorderHoverPosition = BorderHoverPositionEnum.Right;
}
}
else if (Form.Cursor != Cursors.Default)
{
Form.Cursor = Cursors.Default;
BorderHoverPosition = BorderHoverPositionEnum.None;
}
}
// Resize
else if (AllowUserResize && IsResizing && Form.WindowState == FormWindowState.Normal)
{
// Resize
switch (BorderHoverPosition)
{
// Стороны / Sides
case BorderHoverPositionEnum.Left:
Form.Location = new Point(Cursor.Position.X, Form.Location.Y);
Form.Width = Form.Width - (Form.Right - ResizeStartRight);
break;
case BorderHoverPositionEnum.Top:
Form.Location = new Point(Form.Location.X, Cursor.Position.Y);
Form.Height = Form.Height - (Form.Bottom - ResizeStartBottom);
break;
case BorderHoverPositionEnum.Right:
Form.Width = Cursor.Position.X - Form.Left;
break;
case BorderHoverPositionEnum.Bottom:
Form.Height = Cursor.Position.Y - Form.Top;
break;
// Углы / Angles
case BorderHoverPositionEnum.TopLeft:
Form.Location = new Point(Form.Location.X, Cursor.Position.Y);
Form.Height = Form.Height - (Form.Bottom - ResizeStartBottom);
Form.Location = new Point(Cursor.Position.X, Form.Location.Y);
Form.Width = Form.Width - (Form.Right - ResizeStartRight);
break;
case BorderHoverPositionEnum.TopRight:
Form.Location = new Point(Form.Location.X, Cursor.Position.Y);
Form.Height = Form.Height - (Form.Bottom - ResizeStartBottom);
Form.Width = Cursor.Position.X - Form.Left;
break;
case BorderHoverPositionEnum.BottomLeft:
Form.Height = Cursor.Position.Y - Form.Top;
Form.Location = new Point(Cursor.Position.X, Form.Location.Y);
Form.Width = Form.Width - (Form.Right - ResizeStartRight);
break;
case BorderHoverPositionEnum.BottomRight:
Form.Height = Cursor.Position.Y - Form.Top;
Form.Width = Cursor.Position.X - Form.Left;
break;
}
}
}
private void Form_MouseUp(object sender, MouseEventArgs e)
{
if (Form.IsHandleCreated == false) return;
MousePressed = false;
CanDragForm = false;
IsResizing = false;
if (AllowUserResize && BorderHoverPosition != BorderHoverPositionEnum.None)
return;
// Если окно поднять вверх -> разворачиваем на весь экран
if (Cursor.Position.Y == Screen.FromHandle(Form.Handle).WorkingArea.Y
&& Form.WindowState == FormWindowState.Normal)
{
Form.WindowState = FormWindowState.Maximized;
FormNeedReposition = true;
}
// Огранечение по Y
if (Form.Location.Y < Screen.FromHandle(Form.Handle).WorkingArea.Y)
{
Form.Location = new Point(Form.Location.X, Screen.FromHandle(Form.Handle).WorkingArea.Y);
}
// Нажатия на кнопки управления окном
if (e.Button == MouseButtons.Left && Form.ControlBox == true)
{
// Close Button Click
if (rectBtnClose.Contains(e.Location))
Form.Close();
// Max Button Click
if (rectBtnMax.Contains(e.Location) && Form.MaximizeBox == true)
{
if (Form.WindowState == FormWindowState.Maximized)
{
Form.WindowState = FormWindowState.Normal;
if (FormNeedReposition)
{
FormNeedReposition = false;
Form.Location = moveStartPosition;
}
}
else if (Form.WindowState == FormWindowState.Normal)
{
Form.WindowState = FormWindowState.Maximized;
}
}
// Min Button Click
if (rectBtnMin.Contains(e.Location) && Form.MinimizeBox == true)
Form.WindowState = FormWindowState.Minimized;
}
// Контекстное меню при нажатии на иконку
if (e.Button == MouseButtons.Right && IconHovered)
{
if (ContextMenuForm != null)
{
ContextMenuForm.Show(Cursor.Position);
}
}
}
private void Form_MouseDown(object sender, MouseEventArgs e)
{
if (FormStyle == fStyle.None) return;
MousePressed = true;
if (AllowUserResize && BorderHoverPosition != BorderHoverPositionEnum.None)
{
if (e.Button == MouseButtons.Left)
{
IsResizing = true;
ResizeStartRight = Form.Right;
ResizeStartBottom = Form.Bottom;
return;
}
}
if (e.Location.Y <= HeaderHeight
&& !rectBtnClose.Contains(e.Location)
&& !rectBtnMax.Contains(e.Location)
&& !rectBtnMin.Contains(e.Location))
{
CanDragForm = true;
clickPosition = Cursor.Position;
moveStartPosition = Form.Location;
}
LastClickedMouseButton = e.Button;
}
private void Form_DoubleClick(object sender, EventArgs e)
{
if (FormStyle == fStyle.None) return;
if (BorderHoverPosition != BorderHoverPositionEnum.None)
return;
if (MousePressed && LastClickedMouseButton == MouseButtons.Left && rectHeader.Contains(Form.PointToClient(Cursor.Position)))
{
if (Form.WindowState == FormWindowState.Maximized)
{
Form.WindowState = FormWindowState.Normal;
}
else if (Form.WindowState == FormWindowState.Normal)
{
Form.WindowState = FormWindowState.Maximized;
}
}
}
private void Form_Click(object sender, EventArgs e)
{
Form.Focus();
}
#endregion
///
/// Рисование стиля
///
///
private void DrawStyle(Graphics graph)
{
graph.SmoothingMode = SmoothingMode.HighQuality;
graph.InterpolationMode = InterpolationMode.HighQualityBicubic;
if (HeaderHeight == 0) return;
#region - Structures Defining -
// Header Structure
rectHeader = new Rectangle(0, 0, Form.Width - 1, HeaderHeight);
// Border Structure
rectBorder = new Rectangle(0, 0, Form.Width - 1, Form.Height - 1);
// Icon Structure
rectIcon = new Rectangle(
rectHeader.Height / 2 - IconSize.Width / 2,
rectHeader.Height / 2 - IconSize.Height / 2,
IconSize.Width, IconSize.Height
);
// Title Structure
Rectangle rectTitleText = new Rectangle(Form.ShowIcon ? rectIcon.Right + 5 : rectIcon.Left, rectHeader.Y, rectHeader.Width, rectHeader.Height);
// Title Image Structure
Rectangle rectHeaderImage = new Rectangle();
if (HeaderImage != null)
{
int imageHeight = (int)(HeaderHeight * 0.9f); // Высота картинки = 90% от высоты шапки
int imageWidth = HeaderImage.Width / (HeaderImage.Height / imageHeight); // Получаем ширину с сохранением пропорций
rectHeaderImage = new Rectangle(rectIcon.Left, HeaderHeight / 2 - imageHeight / 2, imageWidth, imageHeight);
}
// Close Button Structure
rectBtnClose = new Rectangle(rectHeader.Width - ControlBoxButtonsWidth, rectHeader.Y, ControlBoxButtonsWidth, rectHeader.Height);
// Crosshair Structure
Rectangle rectCrosshair = new Rectangle(
rectBtnClose.X + rectBtnClose.Width / 2 - ControlBoxIconSize.Width / 2,
rectBtnClose.Height / 2 - ControlBoxIconSize.Height / 2,
ControlBoxIconSize.Width, ControlBoxIconSize.Height);
// Maximize Button Structure
rectBtnMax = new Rectangle(rectBtnClose.X - ControlBoxButtonsWidth, rectHeader.Y, ControlBoxButtonsWidth, rectHeader.Height);
// Maximize Icon Structure
Rectangle rectMaxButtonIcon = new Rectangle(
rectBtnMax.X + rectBtnMax.Width / 2 - ControlBoxIconSize.Width / 2,
rectBtnMax.Height / 2 - ControlBoxIconSize.Height / 2,
ControlBoxIconSize.Width, ControlBoxIconSize.Height);
// Second Maximize Icon Structure [in Maximized state]
Rectangle rectMaxButtonIconSecond = rectMaxButtonIcon;
if (Form.WindowState == FormWindowState.Maximized)
{
//Inflate - изменяет размер и одновременно положение (В данном случае -1 по ширине и +2 по X, -1 по высоте и +2 по Y)
rectMaxButtonIconSecond.Inflate(-1, -1);
rectMaxButtonIconSecond.Offset(1, -1);
rectMaxButtonIcon.Inflate(-1, -1);
rectMaxButtonIcon.Offset(-1, 1);
}
// Minimize Button Structure
rectBtnMin = new Rectangle(rectBtnMax.X - ControlBoxButtonsWidth, rectHeader.Y, ControlBoxButtonsWidth, rectHeader.Height);
Point point1BtnMin = new Point(
rectBtnMin.X + rectBtnMin.Width / 2 - ControlBoxIconSize.Width / 2,
rectBtnMin.Height / 2 + ControlBoxIconSize.Height / 2
);
Point point2BtnMin = new Point(
rectBtnMin.X + rectBtnMin.Width / 2 + ControlBoxIconSize.Width / 2,
rectBtnMin.Height / 2 + ControlBoxIconSize.Height / 2
);
#endregion
#region - Drawing -
Brush headerBrush = new SolidBrush(HeaderColor);
if (HeaderColorGradientEnable)
{
if (rectHeader.Width > 0 && rectHeader.Height > 0)
headerBrush = new LinearGradientBrush(rectHeader, HeaderColor, HeaderColorAdditional, HeaderColorGradientMode);
}
// Шапка / Header
graph.DrawRectangle(new Pen(headerBrush), rectHeader);
graph.FillRectangle(headerBrush, rectHeader);
if (HeaderImage != null)
{
// Картинка, вместо заголовка и иконки
graph.DrawImage(HeaderImage, rectHeaderImage);
}
else
{
// Текст заголовка / Title
graph.DrawString(Form.Text, HeaderTextFont, new SolidBrush(HeaderTextColor), rectTitleText, SF);
// Иконка / Icon
if (Form.ShowIcon)
{
graph.DrawImage(Form.Icon.ToBitmap(), rectIcon);
}
}
if (Form.ControlBox == true)
{
#region - Icon Color Changing -
if (CurrentStyle.UseSecondControlBoxIconsColorOnHover)
{
penBtnClose.Color = btnCloseHovered ? CurrentStyle.ControlBoxOnHoverIconsColor : CurrentStyle.ControlBoxEnabledIconsColor;
penBtnMaximize.Color = btnMaximizeHovered ? CurrentStyle.ControlBoxOnHoverIconsColor : CurrentStyle.ControlBoxEnabledIconsColor;
penBtnMinimize.Color = btnMinimizeHovered ? CurrentStyle.ControlBoxOnHoverIconsColor : CurrentStyle.ControlBoxEnabledIconsColor;
}
else
{
penBtnClose.Color = penBtnMaximize.Color = penBtnMinimize.Color = CurrentStyle.ControlBoxEnabledIconsColor;
}
if (Form.MaximizeBox == false)
penBtnMaximize.Color = CurrentStyle.ControlBoxDisabledIconsColor;
if (Form.MinimizeBox == false)
penBtnMinimize.Color = CurrentStyle.ControlBoxDisabledIconsColor;
#endregion
// Кнопка Х
#region - Button X -
graph.DrawRectangle(new Pen(btnCloseHovered ? FlatColors.Red2 : Color.Transparent), rectBtnClose);
graph.FillRectangle(new SolidBrush(btnCloseHovered ? FlatColors.Red2 : Color.Transparent), rectBtnClose);
DrawCrosshair(graph, rectCrosshair, penBtnClose);
#endregion
// Кнопка [MAX]
#region - Button Maximize -
graph.DrawRectangle(new Pen(btnMaximizeHovered && Form.MaximizeBox ? Color.FromArgb(100, Color.Gray) : Color.Transparent), rectBtnMax);
graph.FillRectangle(new SolidBrush(btnMaximizeHovered && Form.MaximizeBox ? Color.FromArgb(100, Color.Gray) : Color.Transparent), rectBtnMax);
if (EnableControlBoxIconsLight)
{
if (Form.WindowState == FormWindowState.Maximized)
{
Drawer.DrawBlurredRectangle(graph, Color.White, rectMaxButtonIconSecond, 8, 20);
}
Drawer.DrawBlurredRectangle(graph, Color.White, rectMaxButtonIcon, 8, 20);
}
// Draw icon
if (Form.WindowState == FormWindowState.Maximized)
{
graph.DrawRectangle(penBtnMaximize, rectMaxButtonIconSecond);
//graph.FillRectangle(new SolidBrush(HeaderColor), rectMaxButtonIcon);
graph.FillRectangle(headerBrush, rectMaxButtonIcon);
}
graph.DrawRectangle(penBtnMaximize, rectMaxButtonIcon);
#endregion
// Кнопка [ _ ]
#region - Button Minimize -
graph.DrawRectangle(new Pen(btnMinimizeHovered && Form.MinimizeBox ? Color.FromArgb(100, Color.Gray) : Color.Transparent), rectBtnMin);
graph.FillRectangle(new SolidBrush(btnMinimizeHovered && Form.MinimizeBox ? Color.FromArgb(100, Color.Gray) : Color.Transparent), rectBtnMin);
// Draw icon
if (EnableControlBoxIconsLight)
{
Drawer.DrawBlurredLine(graph, Color.White, point1BtnMin, point2BtnMin, 8, 20);
}
graph.DrawLine(penBtnMinimize, point1BtnMin, point2BtnMin);
#endregion
// Свечение от курсора
#region - Mouse Light on ControlBox -
if (EnableControlBoxMouseLight && (btnCloseHovered || btnMaximizeHovered || btnMinimizeHovered))
{
Point cursorPoint1 = Form.PointToClient(Cursor.Position);
Point cursorPoint2 = new Point(cursorPoint1.X, cursorPoint1.Y + 1);
Drawer.DrawBlurredLine(graph, Color.White, cursorPoint1, cursorPoint2, 7, 70);
}
#endregion
}
// Обводка / Border
graph.DrawRectangle(new Pen(Color.Gray), rectBorder);
#endregion
}
///
/// Рисование крестика
///
///
///
///
private void DrawCrosshair(Graphics graph, Rectangle rect, Pen pen)
{
if (EnableControlBoxIconsLight)
{
Drawer.DrawBlurredLine(
graph,
Color.White,
new Point(rect.X, rect.Y),
new Point(rect.X + rect.Width, rect.Y + rect.Height),
8,
20);
Drawer.DrawBlurredLine(graph,
Color.White,
new Point(rect.X + rect.Width, rect.Y),
new Point(rect.X, rect.Y + rect.Height),
8,
20);
}
graph.DrawLine(
pen,
rect.X,
rect.Y,
rect.X + rect.Width,
rect.Y + rect.Height);
graph.DrawLine(
pen,
rect.X + rect.Width,
rect.Y,
rect.X,
rect.Y + rect.Height);
}
///
/// Включение DoubleBuffered, для предотвращения мерцания
///
///
public static void SetDoubleBuffered(Control c)
{
if (SystemInformation.TerminalServerSession)
return;
System.Reflection.PropertyInfo pDoubleBuffered =
typeof(Control).GetProperty(
"DoubleBuffered",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
pDoubleBuffered.SetValue(c, true, null);
}
}
}