LevelOS-Core/Dashboards/Cadastros/FuncionariosCadastroPanel.cs
2026-04-17 21:09:19 -03:00

948 lines
35 KiB
C#

using BLL;
using CustomMessageBox;
using DAL;
using MLL;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
using AForge.Video;
using AForge.Video.DirectShow;
namespace UI
{
public class FuncionariosCadastroPanel : UserControl
{
private int idBanco = 0;
private string _cx = DadosDaConexao.ObterConexao();
private readonly Color AccentBlue = Color.FromArgb(37, 99, 235);
private readonly Color TextDark = Color.FromArgb(30, 41, 59);
private readonly Color BorderColor = Color.FromArgb(226, 232, 240);
private Panel pnlToolbar = null!;
private Panel mainScroll = null!;
private Panel content = null!;
// Identificação
private RoundTextBox txtId = null!, txtCodigo = null!, txtNome = null!;
private RoundTextBox txtCPF = null!, txtCI = null!, txtCTPS = null!;
private RoundTextBox txtCNH = null!, txtCatCNH = null!;
private RoundTextBox txtECivil = null!, txtRegime = null!;
// Filiação
private RoundTextBox txtPai = null!, txtMae = null!;
// Endereço
private RoundTextBox txtcep=null!, txtEndereco = null!,txtEndNumero=null!, txtBairro = null!, txtCidade = null!, txtUF = null!;
// Dados Bancários
private RoundTextBox txtBanco = null!, txtAgencia = null!, txtConta = null!;
private RoundComboBox cbBanco = null!;
// Contato
private RoundTextBox txtTelefone = null!;
// Acesso
private RoundTextBox txtPass = null!;
private CheckBox chkMasterUser = null!, chkVendedor = null!, chkTecnico = null!;
private CheckBox chkDemitido = null!, chkContador = null!, chkOutros = null!;
// Outros
private RoundTextBox txtFPath = null!, txtObserv = null!;
// Datas
private RoundTextBox txtDataAdm = null!, txtDataDem = null!, txtAniver = null!;
// ── CARREGAR FUNCIONÁRIO ──────────────────────────────────────────────
private void CarregarFuncionario(int id)
{
//var bll = new BLLFuncionarios(_cx);
//var f = bll.CarregarPorId(id);
//if (f == null)
//{
// NT_MessageBox.Show("Funcionário não encontrado.",
// "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
// return;
//}
//PreencherCampos(f);
}
private void PreencherCampos(ModeloFuncionarios f)
{
txtId.Text = f.ID_FUNCIONARIO.ToString();
txtCodigo.Text = f.CODIGO;
txtNome.Text = f.NOME;
txtPai.Text = f.PAI;
txtMae.Text = f.MAE;
txtCPF.Text = f.CPF;
txtCI.Text = f.CI;
txtCTPS.Text = f.CTPS;
txtCNH.Text = f.CNH;
txtCatCNH.Text = f.CAT_CNH;
txtECivil.Text = f.ECIVIL;
txtRegime.Text = f.REGIME;
txtEndereco.Text = f.ENDERECO;
txtBairro.Text = f.BAIRRO;
txtCidade.Text = f.CIDADE;
txtUF.Text = f.UF;
txtBanco.Text = f.BANCO;
txtAgencia.Text = f.AGENCIA;
txtConta.Text = f.CONTA;
txtTelefone.Text = f.TELEFONE;
txtPass.Text = f.PASS;
txtFPath.Text = f.FPATH;
txtObserv.Text = f.OBSERV;
//txtDataAdm.Text = f.DATA_ADM;
//txtDataDem.Text = f.DATA_DEM;
//txtAniver.Text = f.ANIVER;
//chkMasterUser.Checked = f.MASTERUSER == "S";
//chkVendedor.Checked = f.VENDEDOR == "S";
//chkTecnico.Checked = f.TECNICO == "S";
//chkDemitido.Checked = f.DEMITIDO == "S";
//chkContador.Checked = f.FTECNICO == "S";
//chkOutros.Checked = f.FVENDEDOR == "S";
}
private Control[] TodosOsControles() => new Control[]{
txtCodigo, txtNome,
txtCPF, txtCI, txtCTPS, txtCNH, txtCatCNH,
txtECivil, txtRegime,
txtPai, txtMae,
txtcep, txtEndereco, txtEndNumero, txtBairro, txtCidade, txtUF,
// 👇 ComboBox entra aqui
cbBanco,
txtAgencia, txtConta,
txtTelefone,
txtPass,
txtFPath, txtObserv,
txtDataAdm, txtDataDem, txtAniver
};//todos os controles
private void SetCamposAtulizado(bool enabled)
{
foreach (var ctrl in TodosOsControles())
{
ctrl.Enabled = enabled;
// 🎨 Se for TextBox
if (ctrl is RoundTextBox txt)
{
txt.BackColor = enabled
? Color.White
: Color.FromArgb(241, 245, 249);
}
// 🎨 Se for ComboBox
else if (ctrl is RoundComboBox cmb)
{
cmb.BackColor = enabled
? Color.White
: Color.FromArgb(241, 245, 249);
}
}
foreach (var chk in TodosOsChecks())
chk.Enabled = enabled;
}//SetCampos
private void CarregarComboBoxAtualizada()
{
BLLBancos bLLBancos = new BLLBancos(_cx);
var tabela = bLLBancos.LocalizarTodos();
// 🔥 cria coluna personalizada
tabela.Columns.Add("EXIBICAO", typeof(string), "NUMERO + ' - ' + NOME");
cbBanco.DataSource = tabela;
cbBanco.DisplayMember = "EXIBICAO"; // 👈 aqui
cbBanco.ValueMember = "ID_BANCOS";
if (cbBanco.SelectedValue != null)
this.idBanco = Convert.ToInt32(cbBanco.SelectedValue);
}//CarregarComboBoxAtualizada
private DateTime? ConverterData(string texto)
{
if (string.IsNullOrWhiteSpace(texto))
return null;
if (DateTime.TryParse(texto, out DateTime data))
return data;
return null;
}//ConverterData
public FuncionariosCadastroPanel()
{
Dock = DockStyle.Fill;
BackColor = Color.White;
DoubleBuffered = true;
InitializeLayout();
this.CarregarComboBoxAtualizada();
}
private void InitializeLayout()
{
this.Controls.Clear();
// ── TOOLBAR ───────────────────────────────────────────────────────
pnlToolbar = new Panel
{
Dock = DockStyle.Top,
Height = 55,
BackColor = Color.FromArgb(248, 250, 252),
BorderStyle = BorderStyle.None
};
var flowButtons = new FlowLayoutPanel
{
Dock = DockStyle.Fill,
Padding = new Padding(12, 10, 0, 0),
BackColor = Color.Transparent
};
var btnNovo = CreateToolbarButton("Novo", Color.FromArgb(34, 197, 94));
var btnAlterar = CreateToolbarButton("Alterar", Color.FromArgb(245, 158, 11));
var btnExcluir = CreateToolbarButton("Excluir", Color.FromArgb(239, 68, 68));
var btnLocalizar = CreateToolbarButton("Localizar", AccentBlue);
var btnSalvar = CreateToolbarButton("Salvar", AccentBlue);
var btnGerarFicha = CreateToolbarButton("Gerar Ficha", Color.FromArgb(255,0,0));
var btnCancelar = CreateToolbarButton("Cancelar", Color.FromArgb(148, 163, 184));
btnNovo.Click += (s, e) => BtnNovo_Click();
btnAlterar.Click += (s, e) => BtnAlterar_Click();
btnExcluir.Click += (s, e) => BtnExcluir_Click();
btnLocalizar.Click += (s, e) => BtnLocalizar_Click();
btnSalvar.Click += (s, e) => BtnSalvar_Click();
btnCancelar.Click += (s, e) => BtnCancelar_Click();
btnGerarFicha.Click += (s, e) => BtnFichaFuncionario_Click();
flowButtons.Controls.AddRange(new Control[]
{ btnNovo, btnAlterar, btnExcluir, btnLocalizar, btnSalvar,btnGerarFicha,btnCancelar });
pnlToolbar.Controls.Add(flowButtons);
this.Controls.Add(pnlToolbar);
// ── SCROLL + CONTENT ──────────────────────────────────────────────
mainScroll = new Panel
{
Dock = DockStyle.Fill,
AutoScroll = true,
BackColor = Color.White
};
this.Controls.Add(mainScroll);
mainScroll.BringToFront();
content = new Panel
{
Width = 1100,
Height = 900,
Location = new Point(0, 0),
BackColor = Color.White
};
mainScroll.Controls.Add(content);
const int rowH = 52;
const int secGap = 10;
const int secH = 28;
const int inputH = 28;
int y = 10;
// ── 1. IDENTIFICAÇÃO DO FUNCIONÁRIO ───────────────────────────────
content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO DO FUNCIONÁRIO", y));
y += secH + 4;
txtId = AddInput(content, "ID", 20, y, 60, inputH, readOnly: true);
txtCodigo = AddInput(content, "Código", 90, y, 100, inputH, readOnly: true);
txtNome = AddInput(content, "Nome", 200, y, 450, inputH);
y += rowH;
txtCPF = AddInput(content, "CPF", 20, y, 160, inputH);
DocumentoHelper.Registrar(txtCPF);
txtCI = AddInput(content, "RG / CI", 190, y, 160, inputH);
txtCTPS = AddInput(content, "CTPS", 360, y, 140, inputH);
txtCNH = AddInput(content, "CNH", 510, y, 160, inputH);
txtCatCNH = AddInput(content, "Cat. CNH", 680, y, 90, inputH);
y += rowH;
txtECivil = AddInput(content, "Estado Civil", 20, y, 160, inputH);
txtRegime = AddInput(content, "Regime", 190, y, 160, inputH);
// ── 2. FILIAÇÃO ───────────────────────────────────────────────────
y += rowH + secGap;
content.Controls.Add(CreateSectionHeader("FILIAÇÃO", y));
y += secH + 4;
txtPai = AddInput(content, "Nome do Pai", 20, y, 400, inputH);
txtMae = AddInput(content, "Nome da Mãe", 430, y, 400, inputH);
// ── 3. ENDEREÇO ─────────────────────────────────────────────
y += rowH + secGap;
content.Controls.Add(CreateSectionHeader("ENDEREÇO", y));
y += secH + 4;
// LINHA ÚNICA
txtcep = AddInput(content, "CEP", 20, y, 80, inputH);
txtcep.Leave += (s, e) =>
{
string cep = txtcep.Text.Trim().Replace("-", "");
if (cep.Length != 8) return;
if (TLL.VerifyCep.verificaCEP(cep))
{
txtEndereco.Text = TLL.VerifyCep.endereco;
txtBairro.Text = TLL.VerifyCep.bairro;
txtCidade.Text = TLL.VerifyCep.cidade;
txtUF.Text = TLL.VerifyCep.estado;
// Formata o CEP com hífen
txtcep.Text = $"{cep[..5]}-{cep[5..]}";
}
else
{
NT_MessageBox.Show("CEP não encontrado.", "CEP",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
};//cep
txtEndereco = AddInput(content, "Logradouro", 110, y, 260, inputH);
txtEndNumero = AddInput(content, "Nº", 380, y, 70, inputH);
txtBairro = AddInput(content, "Bairro", 460, y, 150, inputH);
txtCidade = AddInput(content, "Cidade", 620, y, 150, inputH);
txtUF = AddInput(content, "UF", 780, y, 60, inputH);
// ── 4. DADOS BANCÁRIOS ────────────────────────────────────────────
y += rowH + secGap;
content.Controls.Add(CreateSectionHeader("DADOS BANCÁRIOS", y));
y += secH + 4;
//txtBanco = AddInput(content, "Banco", 20, y, 280, inputH);
cbBanco = AddComboBox(content, "Banco", 20, y, 200, inputH);
txtAgencia = AddInput(content, "Agência", 310, y, 160, inputH);
txtConta = AddInput(content, "Conta", 480, y, 160, inputH);
// ── 5. CONTATO ────────────────────────────────────────────────────
y += rowH + secGap;
content.Controls.Add(CreateSectionHeader("CONTATO", y));
y += secH + 4;
txtTelefone = AddInput(content, "Telefone", 20, y, 200, inputH);
// ── 6. ACESSO AO SISTEMA ──────────────────────────────────────────
y += rowH + secGap;
content.Controls.Add(CreateSectionHeader("ACESSO AO SISTEMA", y));
y += secH + 4;
txtPass = AddInput(content, "Senha", 20, y, 200, inputH);
txtPass.PasswordChar = '*';
y += rowH;
chkMasterUser = CreateCheckBox("Master User", 20, y);
chkVendedor = CreateCheckBox("Vendedor", 160, y);
chkTecnico = CreateCheckBox("Técnico", 290, y);
chkOutros = CreateCheckBox("Outros", 420, y);
chkContador = CreateCheckBox("Contador", 560, y);
chkDemitido = CreateCheckBox("Demitido", 690, y);
content.Controls.AddRange(new Control[]
{ chkMasterUser, chkVendedor, chkTecnico, chkOutros, chkContador, chkDemitido });
// ── 7. OUTROS ─────────────────────────────────────────────────────
y += 35 + secGap;
content.Controls.Add(CreateSectionHeader("OUTROS", y));
y += secH + 4;
// Label da foto
var lblFoto = new Label
{
Text = "Caminho da Foto (FPATH)",
Location = new Point(20, y),
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
ForeColor = TextDark,
AutoSize = true
};
content.Controls.Add(lblFoto);
// Campo de texto da foto (menor para dar espaço ao botão lupa)
txtFPath = new RoundTextBox
{
Location = new Point(20, y + 16),
Size = new Size(560, inputH),
Radius = 4,
BorderColor = BorderColor,
FocusColor = AccentBlue,
BackColor = Color.White
};
content.Controls.Add(txtFPath);
// Botão lupa 🔍
var btnFoto = new Button
{
Text = "🔍",
Location = new Point(588, y + 16),
Size = new Size(36, inputH),
FlatStyle = FlatStyle.Flat,
BackColor = Color.FromArgb(37, 99, 235),
ForeColor = Color.White,
Font = new Font("Segoe UI", 11f),
Cursor = Cursors.Hand,
TabStop = false
};
btnFoto.FlatAppearance.BorderSize = 0;
btnFoto.Click += (s, e) => BtnFoto_Click();
content.Controls.Add(btnFoto);
y += rowH;
txtObserv = AddInput(content, "Observações", 20, y, 920, inputH);
txtObserv.Multiline = true;
txtObserv.Height = 60;
// ── 8. DATAS ──────────────────────────────────────────────────────
y += 70 + secGap;
content.Controls.Add(CreateSectionHeader("DATAS", y));
y += secH + 4;
txtDataAdm = AddInput(content, "Data de Admissão", 20, y, 175, inputH);
txtDataDem = AddInput(content, "Data de Demissão", 205, y, 175, inputH);
txtAniver = AddInput(content, "Aniversário", 390, y, 175, inputH);
y += rowH;
content.Height = y + 10;
//SetCampos(false);
SetCamposAtulizado(false);
}
// ── FOTO: LUPA ────────────────────────────────────────────────────────
private void BtnFoto_Click()
{
using var dlg = new FotoOrigemDialog();
if (dlg.ShowDialog() != DialogResult.OK) return;
string? caminhoSalvo = dlg.UsarWebcam
? CapturarDaWebcam()
: SelecionarDoComputador();
if (!string.IsNullOrEmpty(caminhoSalvo))
txtFPath.Text = caminhoSalvo;
}
private string? SelecionarDoComputador()
{
using var ofd = new OpenFileDialog
{
Title = "Selecionar Foto do Funcionário",
Filter = "Imagens|*.jpg;*.jpeg;*.png;*.bmp|Todos os arquivos|*.*"
};
if (ofd.ShowDialog() != DialogResult.OK) return null;
return SalvarFoto(ofd.FileName);
}
private string? CapturarDaWebcam()
{
using var webcamForm = new WebcamCaptureForm();
if (webcamForm.ShowDialog() != DialogResult.OK) return null;
if (webcamForm.ImagemCapturada == null) return null;
string temp = Path.Combine(Path.GetTempPath(), $"webcam_{Guid.NewGuid()}.jpg");
webcamForm.ImagemCapturada.Save(temp, ImageFormat.Jpeg);
return SalvarFoto(temp);
}
private string SalvarFoto(string origem)
{
const string pasta = @"C:\Levelcode\LevelOS\Uploads\Images\Funcionarios";
Directory.CreateDirectory(pasta);
// Nome: NomeFuncionario_yyyyMMdd_HHmmss.jpg
string nomeBase = string.IsNullOrWhiteSpace(txtNome.Text)
? "Funcionario"
: txtNome.Text.Trim().Replace(" ", "_");
string nomeArq = $"{nomeBase}_{DateTime.Now:yyyyMMdd_HHmmss}.jpg";
string destino = Path.Combine(pasta, nomeArq);
File.Copy(origem, destino, overwrite: true);
return destino;
}
// ── CAMPOS ────────────────────────────────────────────────────────────
private RoundTextBox[] TodosOsCampos() => new[]
{
txtCodigo, txtNome,
txtCPF, txtCI, txtCTPS, txtCNH, txtCatCNH,
txtECivil, txtRegime,
txtPai, txtMae,
txtcep,txtEndereco,txtEndNumero, txtBairro, txtCidade, txtUF,
/*txtBanco,*/ txtAgencia, txtConta,
txtTelefone,
txtPass,
txtFPath, txtObserv,
txtDataAdm, txtDataDem, txtAniver
};
private CheckBox[] TodosOsChecks() => new[]
{
chkMasterUser, chkVendedor, chkTecnico,
chkDemitido, chkContador, chkOutros
};
private void SetCampos(bool enabled)
{
foreach (var campo in TodosOsCampos())
{
campo.Enabled = enabled;
campo.BackColor = enabled ? Color.White : Color.FromArgb(241, 245, 249);
}
foreach (var chk in TodosOsChecks())
chk.Enabled = enabled;
}
// ── EVENTOS ───────────────────────────────────────────────────────────
private void BtnNovo_Click()
{
foreach (var campo in TodosOsCampos())
campo.Text = string.Empty;
foreach (var chk in TodosOsChecks())
chk.Checked = false;
//SetCampos(true);
SetCamposAtulizado(true);
}
private void BtnAlterar_Click()
{
if (string.IsNullOrWhiteSpace(txtId.Text))
{
NT_MessageBox.Show(
"Nenhum registro selecionado para alterar.",
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
//SetCampos(true);
SetCamposAtulizado(true);
txtId.Enabled = false;
txtId.BackColor = Color.FromArgb(241, 245, 249);
}
private void BtnExcluir_Click()
{
}
private void BtnLocalizar_Click()
{
// Abre tela/diálogo de busca e preenche os campos
}
private void BtnSalvar_Click()
{
var bll = new BLLFuncionarios(_cx);
if (string.IsNullOrWhiteSpace(txtNome.Text) ||
string.IsNullOrWhiteSpace(txtCPF.Text))
{
NT_MessageBox.Show("Preencha ao menos Nome e CPF.",
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
bool isNew = string.IsNullOrWhiteSpace(txtId.Text);
var funcionario = new ModeloFuncionarios
{
ID_FUNCIONARIO = isNew ? 0 : int.Parse(txtId.Text),
CODIGO = txtCodigo.Text,
NOME = txtNome.Text,
PAI = txtPai.Text,
MAE = txtMae.Text,
CPF = txtCPF.Text,
CI = txtCI.Text,
CTPS = txtCTPS.Text,
CNH = txtCNH.Text,
CAT_CNH = txtCatCNH.Text,
ECIVIL = txtECivil.Text,
REGIME = txtRegime.Text,
CEP = txtcep.Text,
ENDERECO = txtEndereco.Text,
ENDNUMERO = txtEndNumero.Text,
BAIRRO = txtBairro.Text,
CIDADE = txtCidade.Text,
UF = txtUF.Text,
// 🔥 BANCO vindo do ComboBox
BANCO = cbBanco.SelectedValue?.ToString(),
AGENCIA = txtAgencia.Text,
CONTA = txtConta.Text,
TELEFONE = txtTelefone.Text,
PASS = txtPass.Text,
// 🔥 BOOL correto
MASTERUSER = chkMasterUser.Checked,
VENDEDOR = chkVendedor.Checked,
TECNICO = chkTecnico.Checked,
DEMITIDO = chkDemitido.Checked,
FTECNICO = chkContador.Checked ? "1" : null,
FVENDEDOR = chkOutros.Checked ? "1" : null,
FPATH = txtFPath.Text,
OBSERV = txtObserv.Text,
// 🔥 DATAS
DATA_ADM = ConverterData(txtDataAdm.Text),
DATA_DEM = ConverterData(txtDataDem.Text),
ANIVER = ConverterData(txtAniver.Text)
};
bool sucesso = isNew
? bll.Inserir(funcionario)
: bll.Alterar(funcionario);
if (!sucesso)
{
NT_MessageBox.Show("Erro ao salvar funcionário.",
"Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
SetCampos(false);
NT_MessageBox.Show("Funcionário salvo com sucesso!", "Sucesso",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void BtnFichaFuncionario_Click()
{
var bll = new BLLFuncionarios(_cx);
var funcionario = bll.CarregarPorCodigo("100");
if (funcionario == null)
{
MessageBox.Show("Funcionário não encontrado.");
return;
}
var resultado = TLL.FichaFuncionarioPDF.GerarEAbrir(funcionario);
if (!resultado.Sucesso)
MessageBox.Show(resultado.Mensagem, "Erro",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
private void BtnCancelar_Click()
{
foreach (var campo in TodosOsCampos())
campo.Text = string.Empty;
foreach (var chk in TodosOsChecks())
chk.Checked = false;
//SetCampos(false);
SetCamposAtulizado(false);
//this.cbBanco.Enabled = false;
}
// ── HELPERS ───────────────────────────────────────────────────────────
private Panel CreateSectionHeader(string title, int y)
{
var pnl = new Panel { Location = new Point(20, y), Width = 1000, Height = 26 };
var lbl = new Label
{
Text = title,
Font = new Font("Segoe UI", 8.5f, FontStyle.Bold),
ForeColor = AccentBlue,
AutoSize = true,
Location = new Point(0, 0)
};
var line = new Panel
{
BackColor = BorderColor,
Height = 1,
Width = 980,
Location = new Point(0, 20)
};
pnl.Controls.Add(lbl);
pnl.Controls.Add(line);
return pnl;
}
private RoundTextBox AddInput(Control parent, string label,
int x, int y, int width, int height,
bool readOnly = false)
{
var lbl = new Label
{
Text = label,
Location = new Point(x, y),
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
ForeColor = readOnly ? Color.Gray : TextDark,
AutoSize = true
};
var txt = new RoundTextBox
{
Location = new Point(x, y + 16),
Size = new Size(width, height),
Radius = 4,
BorderColor = readOnly ? Color.FromArgb(203, 213, 225) : BorderColor,
FocusColor = AccentBlue,
ReadOnly = readOnly,
BackColor = readOnly ? Color.FromArgb(241, 245, 249) : Color.White
};
parent.Controls.Add(lbl);
parent.Controls.Add(txt);
return txt;
}
private RoundComboBox AddComboBox(Control parent, string label,
int x, int y, int width, int height)
{
var lbl = new Label
{
Text = label,
Location = new Point(x, y),
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
ForeColor = TextDark,
AutoSize = true
};
var cb = new RoundComboBox
{
Location = new Point(x, y + 16),
Size = new Size(width, height),
Radius = 4,
BorderColor = BorderColor,
FocusColor = AccentBlue,
BackColor = Color.White
};
parent.Controls.Add(lbl);
parent.Controls.Add(cb);
return cb;
}
private CheckBox CreateCheckBox(string text, int x, int y) => new CheckBox
{
Text = text,
Location = new Point(x, y),
Font = new Font("Segoe UI", 8.5f, FontStyle.Bold),
ForeColor = TextDark,
AutoSize = true
};
private RoundButton CreateToolbarButton(string text, Color color) => new RoundButton
{
Text = text,
Size = new Size(95, 32),
BackColor = color,
ForeColor = Color.White,
Font = new Font("Segoe UI Semibold", 8.5f),
Margin = new Padding(0, 0, 6, 0),
Cursor = Cursors.Hand
};
}
// ══════════════════════════════════════════════════════════════════════════
// DIALOG: Escolher origem da foto (Computador ou Webcam)
// ══════════════════════════════════════════════════════════════════════════
public class FotoOrigemDialog : Form
{
public bool UsarWebcam { get; private set; }
public FotoOrigemDialog()
{
Text = "Selecionar Foto";
Size = new Size(340, 160);
StartPosition = FormStartPosition.CenterParent;
FormBorderStyle = FormBorderStyle.FixedDialog;
MaximizeBox = false;
MinimizeBox = false;
BackColor = Color.White;
var lbl = new Label
{
Text = "Como deseja adicionar a foto?",
Font = new Font("Segoe UI", 9.5f),
Location = new Point(20, 18),
AutoSize = true
};
var btnComputador = new Button
{
Text = "📁 Do Computador",
Location = new Point(20, 55),
Size = new Size(140, 38),
FlatStyle = FlatStyle.Flat,
BackColor = Color.FromArgb(37, 99, 235),
ForeColor = Color.White,
Font = new Font("Segoe UI", 9f),
Cursor = Cursors.Hand
};
btnComputador.FlatAppearance.BorderSize = 0;
btnComputador.Click += (s, e) =>
{
UsarWebcam = false;
DialogResult = DialogResult.OK;
Close();
};
var btnWebcam = new Button
{
Text = "📷 Webcam",
Location = new Point(172, 55),
Size = new Size(140, 38),
FlatStyle = FlatStyle.Flat,
BackColor = Color.FromArgb(16, 185, 129),
ForeColor = Color.White,
Font = new Font("Segoe UI", 9f),
Cursor = Cursors.Hand
};
btnWebcam.FlatAppearance.BorderSize = 0;
btnWebcam.Click += (s, e) =>
{
UsarWebcam = true;
DialogResult = DialogResult.OK;
Close();
};
Controls.AddRange(new Control[] { lbl, btnComputador, btnWebcam });
}
}
// ══════════════════════════════════════════════════════════════════════════
// FORM: Captura pela Webcam usando AForge
// ══════════════════════════════════════════════════════════════════════════
public class WebcamCaptureForm : Form
{
public Bitmap? ImagemCapturada { get; private set; }
private PictureBox picPreview = null!;
private VideoCaptureDevice? _camera;
private Bitmap? _frameAtual;
public WebcamCaptureForm()
{
Text = "Capturar Foto pela Webcam";
Size = new Size(680, 560);
StartPosition = FormStartPosition.CenterParent;
FormBorderStyle = FormBorderStyle.FixedDialog;
MaximizeBox = false;
BackColor = Color.FromArgb(15, 23, 42);
picPreview = new PictureBox
{
Location = new Point(20, 20),
Size = new Size(628, 440),
SizeMode = PictureBoxSizeMode.Zoom,
BackColor = Color.Black
};
Controls.Add(picPreview);
var btnCapturar = new Button
{
Text = "📷 Capturar",
Location = new Point(20, 475),
Size = new Size(200, 38),
FlatStyle = FlatStyle.Flat,
BackColor = Color.FromArgb(37, 99, 235),
ForeColor = Color.White,
Font = new Font("Segoe UI", 9.5f),
Cursor = Cursors.Hand
};
btnCapturar.FlatAppearance.BorderSize = 0;
btnCapturar.Click += BtnCapturar_Click;
Controls.Add(btnCapturar);
var btnCancelar = new Button
{
Text = "Cancelar",
Location = new Point(234, 475),
Size = new Size(120, 38),
FlatStyle = FlatStyle.Flat,
BackColor = Color.FromArgb(100, 116, 139),
ForeColor = Color.White,
Font = new Font("Segoe UI", 9.5f),
Cursor = Cursors.Hand
};
btnCancelar.FlatAppearance.BorderSize = 0;
btnCancelar.Click += (s, e) => { PararCamera(); DialogResult = DialogResult.Cancel; Close(); };
Controls.Add(btnCancelar);
FormClosing += (s, e) => PararCamera();
IniciarCamera();
}
private void IniciarCamera()
{
var cameras = new FilterInfoCollection(FilterCategory.VideoInputDevice);
if (cameras.Count == 0)
{
MessageBox.Show("Nenhuma webcam encontrada.", "Webcam",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
DialogResult = DialogResult.Cancel;
Close();
return;
}
_camera = new VideoCaptureDevice(cameras[0].MonikerString);
_camera.NewFrame += Camera_NewFrame;
_camera.Start();
}
private void Camera_NewFrame(object sender, NewFrameEventArgs e)
{
_frameAtual?.Dispose();
_frameAtual = (Bitmap)e.Frame.Clone();
picPreview.Invoke((MethodInvoker)(() =>
{
picPreview.Image?.Dispose();
picPreview.Image = (Bitmap)_frameAtual.Clone();
}));
}
private void BtnCapturar_Click(object? sender, EventArgs e)
{
if (_frameAtual == null)
{
MessageBox.Show("Aguarde a câmera inicializar.", "Atenção",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
ImagemCapturada = (Bitmap)_frameAtual.Clone();
PararCamera();
DialogResult = DialogResult.OK;
Close();
}
private void PararCamera()
{
if (_camera != null && _camera.IsRunning)
{
_camera.SignalToStop();
_camera.WaitForStop();
}
}
}
}