243 lines
8.6 KiB
C#
243 lines
8.6 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Windows.Forms;
|
|
|
|
namespace CPM
|
|
{
|
|
/// <summary>
|
|
/// ComboBox customizado do sistema LevelOS.
|
|
/// Segue o mesmo padrão visual do LV_TEXTBOX1.
|
|
/// </summary>
|
|
public class LV_COMBOBOX : UserControl
|
|
{
|
|
// ── CAMPOS INTERNOS ───────────────────────────────────────────────────
|
|
private ComboBox _combo;
|
|
private bool _isFocused = false;
|
|
|
|
// ── PROPRIEDADES VISUAIS ──────────────────────────────────────────────
|
|
private Color _borderColor = Color.FromArgb(226, 232, 240);
|
|
private Color _borderFocusColor = Color.FromArgb(37, 99, 235);
|
|
private Color _arrowColor = Color.FromArgb(100, 116, 139);
|
|
private int _borderRadius = 6;
|
|
private int _borderSize = 1;
|
|
|
|
public Color BorderColor
|
|
{
|
|
get => _borderColor;
|
|
set { _borderColor = value; Invalidate(); }
|
|
}
|
|
|
|
public Color BorderFocusColor
|
|
{
|
|
get => _borderFocusColor;
|
|
set { _borderFocusColor = value; Invalidate(); }
|
|
}
|
|
|
|
public Color ArrowColor
|
|
{
|
|
get => _arrowColor;
|
|
set { _arrowColor = value; Invalidate(); }
|
|
}
|
|
|
|
public int BorderRadius
|
|
{
|
|
get => _borderRadius;
|
|
set { _borderRadius = value; Invalidate(); }
|
|
}
|
|
|
|
public int BorderSize
|
|
{
|
|
get => _borderSize;
|
|
set { _borderSize = value; Invalidate(); }
|
|
}
|
|
|
|
// ── PROPRIEDADES DO COMBOBOX ──────────────────────────────────────────
|
|
public ComboBoxStyle DropDownStyle
|
|
{
|
|
get => _combo.DropDownStyle;
|
|
set => _combo.DropDownStyle = value;
|
|
}
|
|
|
|
public System.Windows.Forms.ComboBox.ObjectCollection Items => _combo.Items;
|
|
|
|
public object? SelectedItem
|
|
{
|
|
get => _combo.SelectedItem;
|
|
set => _combo.SelectedItem = value;
|
|
}
|
|
|
|
public int SelectedIndex
|
|
{
|
|
get => _combo.SelectedIndex;
|
|
set => _combo.SelectedIndex = value;
|
|
}
|
|
|
|
public string Text
|
|
{
|
|
get => _combo.Text;
|
|
set => _combo.Text = value;
|
|
}
|
|
|
|
public override Font Font
|
|
{
|
|
get => base.Font;
|
|
set
|
|
{
|
|
base.Font = value;
|
|
_combo.Font = value;
|
|
AjustarAltura();
|
|
}
|
|
}
|
|
|
|
public new bool Enabled
|
|
{
|
|
get => base.Enabled;
|
|
set
|
|
{
|
|
base.Enabled = value;
|
|
_combo.Enabled = value;
|
|
BackColor = value ? Color.White : Color.FromArgb(241, 245, 249);
|
|
Invalidate();
|
|
}
|
|
}
|
|
|
|
// ── EVENTOS REPASSADOS ────────────────────────────────────────────────
|
|
public event EventHandler? SelectedIndexChanged
|
|
{
|
|
add => _combo.SelectedIndexChanged += value;
|
|
remove => _combo.SelectedIndexChanged -= value;
|
|
}
|
|
|
|
public new event EventHandler? TextChanged
|
|
{
|
|
add => _combo.TextChanged += value;
|
|
remove => _combo.TextChanged -= value;
|
|
}
|
|
|
|
// ── CONSTRUTOR ────────────────────────────────────────────────────────
|
|
public LV_COMBOBOX()
|
|
{
|
|
_combo = new ComboBox
|
|
{
|
|
DropDownStyle = ComboBoxStyle.DropDownList,
|
|
FlatStyle = FlatStyle.Flat,
|
|
Font = new Font("Segoe UI", 9f),
|
|
BackColor = Color.White,
|
|
ForeColor = Color.FromArgb(30, 41, 59),
|
|
Dock = DockStyle.None,
|
|
IntegralHeight = false
|
|
};
|
|
|
|
// Configura o controle pai
|
|
Padding = new Padding(8, 0, 30, 0); // espaço para seta customizada
|
|
BackColor = Color.White;
|
|
ForeColor = Color.FromArgb(30, 41, 59);
|
|
Font = new Font("Segoe UI", 9f);
|
|
Size = new Size(200, 36);
|
|
DoubleBuffered = true;
|
|
|
|
Controls.Add(_combo);
|
|
AjustarAltura();
|
|
|
|
// Eventos de foco
|
|
_combo.GotFocus += (s, e) => { _isFocused = true; Invalidate(); };
|
|
_combo.LostFocus += (s, e) => { _isFocused = false; Invalidate(); };
|
|
|
|
// Propaga clique na área do controle para o combo
|
|
this.Click += (s, e) => _combo.Focus();
|
|
|
|
_combo.DropDown += (s, e) => Invalidate();
|
|
_combo.DropDownClosed += (s, e) => Invalidate();
|
|
}
|
|
|
|
// ── AJUSTE DE ALTURA ──────────────────────────────────────────────────
|
|
private void AjustarAltura()
|
|
{
|
|
int altura = _combo.PreferredHeight;
|
|
this.Height = altura + 10;
|
|
_combo.Width = this.Width - 38; // reserva espaço para seta
|
|
_combo.Left = 8;
|
|
_combo.Top = (this.Height - _combo.Height) / 2;
|
|
}
|
|
|
|
// ── RESIZE ────────────────────────────────────────────────────────────
|
|
protected override void OnResize(EventArgs e)
|
|
{
|
|
base.OnResize(e);
|
|
_combo.Width = this.Width - 38;
|
|
_combo.Left = 8;
|
|
_combo.Top = (this.Height - _combo.Height) / 2;
|
|
Invalidate();
|
|
}
|
|
|
|
// ── PAINT ─────────────────────────────────────────────────────────────
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
base.OnPaint(e);
|
|
|
|
var g = e.Graphics;
|
|
g.SmoothingMode = SmoothingMode.AntiAlias;
|
|
|
|
var cor = _isFocused ? _borderFocusColor : _borderColor;
|
|
var rect = new Rectangle(0, 0, Width - 1, Height - 1);
|
|
var bgRect = new Rectangle(1, 1, Width - 2, Height - 2);
|
|
|
|
// Fundo
|
|
using var bgBrush = new SolidBrush(Enabled ? BackColor : Color.FromArgb(241, 245, 249));
|
|
g.FillRoundedRectangle(bgBrush, bgRect, _borderRadius);
|
|
|
|
// Borda
|
|
using var pen = new Pen(cor, _borderSize);
|
|
g.DrawRoundedRectangle(pen, rect, _borderRadius);
|
|
|
|
// Seta customizada
|
|
DesenharSeta(g);
|
|
}
|
|
|
|
private void DesenharSeta(Graphics g)
|
|
{
|
|
int arrowX = Width - 22;
|
|
int arrowY = Height / 2;
|
|
|
|
using var brush = new SolidBrush(_isFocused ? _borderFocusColor : _arrowColor);
|
|
var pontos = new Point[]
|
|
{
|
|
new Point(arrowX - 5, arrowY - 3),
|
|
new Point(arrowX + 5, arrowY - 3),
|
|
new Point(arrowX, arrowY + 4)
|
|
};
|
|
g.FillPolygon(brush, pontos);
|
|
}
|
|
}
|
|
|
|
// ── EXTENSÕES DE GRAPHICS PARA ROUNDED RECT ───────────────────────────────
|
|
internal static class GraphicsExtensions
|
|
{
|
|
public static void FillRoundedRectangle(this Graphics g, Brush brush, Rectangle rect, int radius)
|
|
{
|
|
using var path = GetRoundedPath(rect, radius);
|
|
g.FillPath(brush, path);
|
|
}
|
|
|
|
public static void DrawRoundedRectangle(this Graphics g, Pen pen, Rectangle rect, int radius)
|
|
{
|
|
using var path = GetRoundedPath(rect, radius);
|
|
g.DrawPath(pen, path);
|
|
}
|
|
|
|
private static GraphicsPath GetRoundedPath(Rectangle rect, int radius)
|
|
{
|
|
int r = Math.Min(radius, Math.Min(rect.Width, rect.Height) / 2);
|
|
var d = r * 2;
|
|
var path = new GraphicsPath();
|
|
path.AddArc(rect.X, rect.Y, d, d, 180, 90);
|
|
path.AddArc(rect.Right - d, rect.Y, d, d, 270, 90);
|
|
path.AddArc(rect.Right - d, rect.Bottom - d, d, d, 0, 90);
|
|
path.AddArc(rect.X, rect.Bottom - d, d, d, 90, 90);
|
|
path.CloseFigure();
|
|
return path;
|
|
}
|
|
}
|
|
}
|