diff --git a/CLL/AppFileSystem.cs b/CLL/AppFileSystem.cs new file mode 100644 index 0000000..75300e3 --- /dev/null +++ b/CLL/AppFileSystem.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CLL +{ + public static class AppFileSystem + { + //Private + private readonly static string appFileIconSystem = Path.Combine(AppFolderSystem.appDataFolderConfig, "icone.ico"); + private readonly static string appFileDBSystem = Path.Combine(AppFolderSystem.appDataFolderConfig, "Database.cfg"); + private readonly static string appFileFTPSystem = Path.Combine(AppFolderSystem.appDataFolderConfig, "Ftp-client.cfg"); + private readonly static string appFileTelegramSystem = Path.Combine(AppFolderSystem.appDataFolderConfig, "Telegram-Client.cfg"); + private readonly static string appFileSMTPSystem = Path.Combine(AppFolderSystem.appDataFolderConfig, "Smtp-Client.cfg"); + private readonly static string appFileConfigEmpresa = Path.Combine(AppFolderSystem.appDataFolderConfig, "Empresa-Client.cfg"); + + + + //Public + public static string AppFileIconSystem => appFileIconSystem; + public static string AppFileDBSystem => appFileDBSystem; + + public static string AppFileFTPSystem => appFileFTPSystem; + + public static string AppFileTelegramSystem => appFileTelegramSystem; + + public static string AppFileSMTPSystem => appFileSMTPSystem; + + public static string AppFileConfigEmpresa => appFileConfigEmpresa; + } +} diff --git a/CLL/AppFolderSystem.cs b/CLL/AppFolderSystem.cs new file mode 100644 index 0000000..c98d8f3 --- /dev/null +++ b/CLL/AppFolderSystem.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +namespace CLL +{ + public static class AppFolderSystem + { + // ROOT + public static readonly string appDataFolderRoot = @"C:\LevelCode"; + + // SISTEMA + public static readonly string appDataFolderSystem = Path.Combine(appDataFolderRoot, "LevelOS"); + public static readonly string appDataFolderConfig = Path.Combine(appDataFolderSystem, "Config"); + + // USUÁRIO + public static readonly string appDataFolderUser = Path.Combine(appDataFolderSystem, "UserData"); + public static readonly string appDataFolderUserTemp = Path.Combine(appDataFolderUser, "Temp"); + public static readonly string appDataFolderUserCache = Path.Combine(appDataFolderUser, "Cache"); + + // LOGS + public static readonly string appDataFolderLogs = Path.Combine(appDataFolderSystem, "Logs"); + public static readonly string appDataFolderLogsError = Path.Combine(appDataFolderLogs, "Error"); + public static readonly string appDataFolderLogsAccess = Path.Combine(appDataFolderLogs, "Access"); + + // BACKUP + public static readonly string appDataFolderBackup = Path.Combine(appDataFolderSystem, "Backup"); + public static readonly string appDataFolderBackupDatabase = Path.Combine(appDataFolderBackup, "Database"); + public static readonly string appDataFolderBackupFiles = Path.Combine(appDataFolderBackup, "Files"); + + // RELATÓRIOS + public static readonly string appDataFolderReports = Path.Combine(appDataFolderSystem, "Reports"); + public static readonly string appDataFolderReportsPDF = Path.Combine(appDataFolderReports, "PDF"); + public static readonly string appDataFolderReportsTemp = Path.Combine(appDataFolderReports, "Temp"); + + // UPLOADS + public static readonly string appDataFolderUploads = Path.Combine(appDataFolderSystem, "Uploads"); + public static readonly string appDataFolderUploadsImages = Path.Combine(appDataFolderUploads, "Images"); + public static readonly string appDataFolderUploadsDocuments = Path.Combine(appDataFolderUploads, "Documents"); + + // CONTRATOS / OS + public static readonly string appDataFolderContracts = Path.Combine(appDataFolderSystem, "Contracts"); + public static readonly string appDataFolderOS = Path.Combine(appDataFolderSystem, "OrdemServico"); + + // EXPORTAÇÕES + public static readonly string appDataFolderExport = Path.Combine(appDataFolderSystem, "Export"); + public static readonly string appDataFolderImport = Path.Combine(appDataFolderSystem, "Import"); + public static readonly string appDataFolderExportXML = Path.Combine(appDataFolderSystem, "Xml"); + + public static void CriarEstruturaPastas() + { + var pastas = new[] + { + // ROOT + appDataFolderRoot, + + // SISTEMA + appDataFolderSystem, + appDataFolderConfig, + + // USUÁRIO + appDataFolderUser, + appDataFolderUserTemp, + appDataFolderUserCache, + + // LOGS + appDataFolderLogs, + appDataFolderLogsError, + appDataFolderLogsAccess, + + // BACKUP + appDataFolderBackup, + appDataFolderBackupDatabase, + appDataFolderBackupFiles, + + // RELATÓRIOS + appDataFolderReports, + appDataFolderReportsPDF, + appDataFolderReportsTemp, + + // UPLOADS + appDataFolderUploads, + appDataFolderUploadsImages, + appDataFolderUploadsDocuments, + + // CONTRATOS / OS + appDataFolderContracts, + appDataFolderOS, + + // EXPORTAÇÃO + appDataFolderExport, + appDataFolderImport, + appDataFolderExportXML + }; + + foreach (var pasta in pastas) + { + if (!Directory.Exists(pasta)) + { + Directory.CreateDirectory(pasta); + } + } + }//Criando estruturaDePastas + } + +} diff --git a/CLL/AppInfoSystem.cs b/CLL/AppInfoSystem.cs new file mode 100644 index 0000000..7b08937 --- /dev/null +++ b/CLL/AppInfoSystem.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace CLL +{ + public static class AppInfoSystem + { + private readonly static string appKeyMasterCrip = "LevelCode@2026#" + GerarChaveMaquina(); + + public static string AppKeyMasterCrip => appKeyMasterCrip; + + private static string GerarChaveMaquina() + { + string baseInfo = Environment.MachineName + Environment.UserName; + + var hash = SHA256.HashData(Encoding.UTF8.GetBytes(baseInfo)); + + return Convert.ToBase64String(hash); + }//Cria uma chave unica baseada em cada maquina + } +} diff --git a/CLL/Class1.cs b/CLL/Class1.cs deleted file mode 100644 index 21093c8..0000000 --- a/CLL/Class1.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace CLL -{ - public class Class1 - { - - } -} diff --git a/Components/Buttons/LV-BUTTON.cs b/Components/Buttons/LV-BUTTON.cs new file mode 100644 index 0000000..ba67d8e --- /dev/null +++ b/Components/Buttons/LV-BUTTON.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using System.Windows.Forms; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel; + +namespace CPM +{ + public class LV_BUTTON : Button + { + //Fields + private int borderSize = 0; + private int borderRadius = 0; + private Color borderColor = Color.PaleVioletRed; + private Color hoverColor = Color.LightBlue; + private Color clickColor = Color.DarkBlue; + + [Category("Levelcode")] + public Color HoverColor + { + get { return hoverColor; } + set { hoverColor = value; } + } + + [Category("Levelcode")] + public Color ClickColor + { + get { return clickColor; } + set { clickColor = value; } + } + //Properties + [Category("Levelcode")] + public int BorderSize + { + get { return borderSize; } + set + { + borderSize = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public int BorderRadius + { + get { return borderRadius; } + set + { + borderRadius = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public Color BorderColor + { + get { return borderColor; } + set + { + borderColor = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public Color BackgroundColor + { + get { return this.BackColor; } + set { this.BackColor = value; } + } + + [Category("Levelcode")] + public Color TextColor + { + get { return this.ForeColor; } + set { this.ForeColor = value; } + } + + //Constructor + public LV_BUTTON() + { + this.FlatStyle = FlatStyle.Flat; + this.FlatAppearance.BorderSize = 0; + this.Size = new Size(150, 40); + this.BackColor = Color.MediumSlateBlue; + this.ForeColor = Color.White; + this.Resize += new EventHandler(Button_Resize); + this.MouseEnter += (s, e) => this.BackColor = hoverColor; + this.MouseLeave += (s, e) => this.BackColor = BackgroundColor; + this.MouseDown += (s, e) => this.BackColor = clickColor; + this.MouseUp += (s, e) => this.BackColor = hoverColor; + } + + //Methods + private GraphicsPath GetFigurePath(Rectangle rect, int radius) + { + GraphicsPath path = new GraphicsPath(); + float curveSize = radius * 2F; + + path.StartFigure(); + path.AddArc(rect.X, rect.Y, curveSize, curveSize, 180, 90); + path.AddArc(rect.Right - curveSize, rect.Y, curveSize, curveSize, 270, 90); + path.AddArc(rect.Right - curveSize, rect.Bottom - curveSize, curveSize, curveSize, 0, 90); + path.AddArc(rect.X, rect.Bottom - curveSize, curveSize, curveSize, 90, 90); + path.CloseFigure(); + return path; + } + + protected override void OnPaint(PaintEventArgs pevent) + { + base.OnPaint(pevent); + + + Rectangle rectSurface = this.ClientRectangle; + Rectangle rectBorder = Rectangle.Inflate(rectSurface, -borderSize, -borderSize); + int smoothSize = 2; + if (borderSize > 0) + smoothSize = borderSize; + + if (borderRadius > 2) //Rounded button + { + using (GraphicsPath pathSurface = GetFigurePath(rectSurface, borderRadius)) + using (GraphicsPath pathBorder = GetFigurePath(rectBorder, borderRadius - borderSize)) + using (Pen penSurface = new Pen(this.Parent.BackColor, smoothSize)) + using (Pen penBorder = new Pen(borderColor, borderSize)) + { + pevent.Graphics.SmoothingMode = SmoothingMode.AntiAlias; + //Button surface + this.Region = new Region(pathSurface); + //Draw surface border for HD result + pevent.Graphics.DrawPath(penSurface, pathSurface); + + //Button border + if (borderSize >= 1) + //Draw control border + pevent.Graphics.DrawPath(penBorder, pathBorder); + } + } + else //Normal button + { + pevent.Graphics.SmoothingMode = SmoothingMode.None; + //Button surface + this.Region = new Region(rectSurface); + //Button border + if (borderSize >= 1) + { + using (Pen penBorder = new Pen(borderColor, borderSize)) + { + penBorder.Alignment = PenAlignment.Inset; + pevent.Graphics.DrawRectangle(penBorder, 0, 0, this.Width - 1, this.Height - 1); + } + } + } + } + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + this.Parent.BackColorChanged += new EventHandler(Container_BackColorChanged); + } + + private void Container_BackColorChanged(object sender, EventArgs e) + { + this.Invalidate(); + } + private void Button_Resize(object sender, EventArgs e) + { + if (borderRadius > this.Height) + borderRadius = this.Height; + } + } + +} diff --git a/Components/Class1.cs b/Components/Class1.cs deleted file mode 100644 index 1b9054d..0000000 --- a/Components/Class1.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Components -{ - public class Class1 - { - - } -} diff --git a/Components/ComboBox/LV-COMBOBOXCUSTOM.cs b/Components/ComboBox/LV-COMBOBOXCUSTOM.cs new file mode 100644 index 0000000..7e51de1 --- /dev/null +++ b/Components/ComboBox/LV-COMBOBOXCUSTOM.cs @@ -0,0 +1,347 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Design; +using System.Windows.Forms; + +namespace CPM +{ + [ToolboxItem(true)] + public class LV_COMBOBOXCUSTOM : UserControl + { + // Fields + private Color backColor = Color.WhiteSmoke; + private Color iconColor = Color.MediumSlateBlue; + private Color listBackColor = Color.FromArgb(230, 228, 245); + private Color listTextColor = Color.DimGray; + private Color borderColor = Color.MediumSlateBlue; + private int borderSize = 1; + + // Components + private ComboBox cmbList; + private Label lblText; + private Button btnIcon; + + // Events + public event EventHandler OnSelectedIndexChanged; + + public LV_COMBOBOXCUSTOM() + { + cmbList = new ComboBox(); + lblText = new Label(); + btnIcon = new Button(); + + this.SuspendLayout(); + + // ComboBox + cmbList.BackColor = listBackColor; + cmbList.Font = new Font(this.Font.Name, 10F); + cmbList.ForeColor = listTextColor; + cmbList.SelectedIndexChanged += ComboBox_SelectedIndexChanged; + cmbList.TextChanged += ComboBox_TextChanged; + + // Button (icon) + btnIcon.Dock = DockStyle.Right; + btnIcon.FlatStyle = FlatStyle.Flat; + btnIcon.FlatAppearance.BorderSize = 0; + btnIcon.BackColor = backColor; + btnIcon.Size = new Size(30, 30); + btnIcon.Cursor = Cursors.Hand; + btnIcon.Click += Icon_Click; + btnIcon.Paint += Icon_Paint; + + // Label (text) + lblText.Dock = DockStyle.Fill; + lblText.AutoSize = false; + lblText.BackColor = backColor; + lblText.TextAlign = ContentAlignment.MiddleLeft; + lblText.Padding = new Padding(8, 0, 0, 0); + lblText.Font = new Font(this.Font.Name, 10F); + lblText.Click += Surface_Click; + lblText.MouseEnter += Surface_MouseEnter; + lblText.MouseLeave += Surface_MouseLeave; + + // Add controls + this.Controls.Add(lblText); + this.Controls.Add(btnIcon); + this.Controls.Add(cmbList); + + // UserControl properties + this.MinimumSize = new Size(200, 30); + this.Size = new Size(200, 30); + this.ForeColor = Color.DimGray; + this.Padding = new Padding(borderSize); + base.BackColor = borderColor; + + this.ResumeLayout(); + AdjustComboBoxDimensions(); + } + // Properties + [Category("Levelcode")] + public new Color BackColor + { + get => backColor; + set + { + backColor = value; + lblText.BackColor = backColor; + btnIcon.BackColor = backColor; + } + } + + [Category("Levelcode")] + public Color IconColor + { + get => iconColor; + set + { + iconColor = value; + btnIcon.Invalidate(); + } + } + + [Category("Levelcode")] + public Color ListBackColor + { + get => listBackColor; + set + { + listBackColor = value; + cmbList.BackColor = listBackColor; + } + } + + [Category("Levelcode")] + public Color ListTextColor + { + get => listTextColor; + set + { + listTextColor = value; + cmbList.ForeColor = listTextColor; + } + } + + [Category("Levelcode")] + public Color BorderColor + { + get => borderColor; + set + { + borderColor = value; + base.BackColor = borderColor; + } + } + + [Category("Levelcode")] + public int BorderSize + { + get => borderSize; + set + { + borderSize = value; + this.Padding = new Padding(borderSize); + AdjustComboBoxDimensions(); + } + } + + [Category("Levelcode")] + public override Color ForeColor + { + get => base.ForeColor; + set + { + base.ForeColor = value; + lblText.ForeColor = value; + } + } + + [Category("Levelcode")] + public override Font Font + { + get => base.Font; + set + { + base.Font = value; + lblText.Font = value; + cmbList.Font = value; + } + } + + [Category("Levelcode")] + public string Texts + { + get => lblText.Text; + set => lblText.Text = value; + } + + [Category("Levelcode")] + public ComboBoxStyle DropDownStyle + { + get => cmbList.DropDownStyle; + set + { + if (value != ComboBoxStyle.Simple) + cmbList.DropDownStyle = value; + } + } + + [Category("Levelcode - Data")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + [Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + [Localizable(true)] + public ComboBox.ObjectCollection Items => cmbList.Items; + + [Category("Levelcode - Data")] + [AttributeProvider(typeof(IListSource))] + [DefaultValue(null)] + public object DataSource + { + get => cmbList.DataSource; + set => cmbList.DataSource = value; + } + + [Category("Levelcode - Data")] + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + [Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + [EditorBrowsable(EditorBrowsableState.Always)] + [Localizable(true)] + public AutoCompleteStringCollection AutoCompleteCustomSource + { + get => cmbList.AutoCompleteCustomSource; + set => cmbList.AutoCompleteCustomSource = value; + } + + [Category("Levelcode - Data")] + [Browsable(true)] + [DefaultValue(AutoCompleteSource.None)] + [EditorBrowsable(EditorBrowsableState.Always)] + public AutoCompleteSource AutoCompleteSource + { + get => cmbList.AutoCompleteSource; + set => cmbList.AutoCompleteSource = value; + } + + [Category("Levelcode - Data")] + [Browsable(true)] + [DefaultValue(AutoCompleteMode.None)] + [EditorBrowsable(EditorBrowsableState.Always)] + public AutoCompleteMode AutoCompleteMode + { + get => cmbList.AutoCompleteMode; + set => cmbList.AutoCompleteMode = value; + } + + [Category("Levelcode - Data")] + [Bindable(true)] + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object SelectedItem + { + get => cmbList.SelectedItem; + set => cmbList.SelectedItem = value; + } + + [Category("Levelcode - Data")] + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int SelectedIndex + { + get => cmbList.SelectedIndex; + set => cmbList.SelectedIndex = value; + } + + [Category("Levelcode - Data")] + [DefaultValue("")] + [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + [TypeConverter("System.Windows.Forms.Design.DataMemberFieldConverter, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] + public string DisplayMember + { + get => cmbList.DisplayMember; + set => cmbList.DisplayMember = value; + } + + [Category("Levelcode - Data")] + [DefaultValue("")] + [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + public string ValueMember + { + get => cmbList.ValueMember; + set => cmbList.ValueMember = value; + } + + [Category("Levelcode - Data")] + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object SelectedValue + { + get => cmbList.SelectedValue; + set => cmbList.SelectedValue = value; + } + + // Private methods + private void AdjustComboBoxDimensions() + { + cmbList.Width = Math.Max(lblText.Width, 0); + cmbList.Location = new Point( + this.Padding.Left, + lblText.Bottom - cmbList.Height + ); + } + + // Events + private void ComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + lblText.Text = cmbList.Text; + OnSelectedIndexChanged?.Invoke(this, e); + } + + private void ComboBox_TextChanged(object sender, EventArgs e) + { + lblText.Text = cmbList.Text; + } + + private void Icon_Paint(object sender, PaintEventArgs e) + { + int iconWidth = 14; + int iconHeight = 6; + var rectIcon = new Rectangle((btnIcon.Width - iconWidth) / 2, (btnIcon.Height - iconHeight) / 2, iconWidth, iconHeight); + Graphics graph = e.Graphics; + + using (GraphicsPath path = new GraphicsPath()) + using (Pen pen = new Pen(iconColor, 2)) + { + graph.SmoothingMode = SmoothingMode.AntiAlias; + path.AddLine(rectIcon.X, rectIcon.Y, rectIcon.X + (iconWidth / 2), rectIcon.Bottom); + path.AddLine(rectIcon.X + (iconWidth / 2), rectIcon.Bottom, rectIcon.Right, rectIcon.Y); + graph.DrawPath(pen, path); + } + } + + private void Icon_Click(object sender, EventArgs e) + { + cmbList.Select(); + cmbList.DroppedDown = true; + } + + private void Surface_Click(object sender, EventArgs e) + { + this.OnClick(e); + cmbList.Select(); + if (cmbList.DropDownStyle == ComboBoxStyle.DropDownList) + cmbList.DroppedDown = true; + } + + private void Surface_MouseEnter(object sender, EventArgs e) => this.OnMouseEnter(e); + private void Surface_MouseLeave(object sender, EventArgs e) => this.OnMouseLeave(e); + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + AdjustComboBoxDimensions(); + } + } + +} diff --git a/Components/Components.csproj b/Components/Components.csproj index fa71b7a..fe8c6e3 100644 --- a/Components/Components.csproj +++ b/Components/Components.csproj @@ -1,9 +1,16 @@ - + - - net8.0 - enable - enable - + + WinExe + net8.0-windows + true + - + + + + + + + + \ No newline at end of file diff --git a/Components/Components.csproj.user b/Components/Components.csproj.user new file mode 100644 index 0000000..9bc126e --- /dev/null +++ b/Components/Components.csproj.user @@ -0,0 +1,50 @@ + + + + + + Component + + + UserControl + + + Component + + + Component + + + UserControl + + + Component + + + Component + + + UserControl + + + Component + + + Component + + + Form + + + UserControl + + + Component + + + + + Designer + + + \ No newline at end of file diff --git a/Components/Datetimepicker/LV-DATETIMEPICKER.cs b/Components/Datetimepicker/LV-DATETIMEPICKER.cs new file mode 100644 index 0000000..5279481 --- /dev/null +++ b/Components/Datetimepicker/LV-DATETIMEPICKER.cs @@ -0,0 +1,164 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Reflection; +using System.Windows.Forms; +using System.ComponentModel; + +namespace CPM.Datetimepicker +{ + [ToolboxItem(true)] + public class LV_DATETIMEPICKER : DateTimePicker + { + // Aparência + private Color skinColor = Color.MediumSlateBlue; + private Color textColor = Color.White; + private Color borderColor = Color.PaleVioletRed; + private int borderSize = 0; + + // Auxiliares + private bool droppedDown = false; + private Image calendarIcon; + private RectangleF iconButtonArea; + private const int calendarIconWidth = 34; + private const int arrowIconWidth = 17; + + public LV_DATETIMEPICKER() + { + SetStyle(ControlStyles.UserPaint, true); + MinimumSize = new Size(0, 35); + Font = new Font(Font.Name, 9.5F); + + calendarIcon = + LoadEmbeddedImage("Imagens.calendarWhite.png") + ?? SystemIcons.Information.ToBitmap(); + } + + // 🔹 Propriedades públicas + public Color SkinColor + { + get => skinColor; + set + { + skinColor = value; + + // Troca automática de ícone conforme o fundo + calendarIcon = + skinColor.GetBrightness() >= 0.6F + ? LoadEmbeddedImage("Imagens.calendarDark.png") + : LoadEmbeddedImage("Imagens.calendarWhite.png") + ?? SystemIcons.Information.ToBitmap(); + + Invalidate(); + } + } + + public Color TextColor + { + get => textColor; + set { textColor = value; Invalidate(); } + } + + public Color BorderColor + { + get => borderColor; + set { borderColor = value; Invalidate(); } + } + + public int BorderSize + { + get => borderSize; + set { borderSize = value; Invalidate(); } + } + + // 🔹 Eventos + protected override void OnDropDown(EventArgs e) + { + base.OnDropDown(e); + droppedDown = true; + Invalidate(); + } + + protected override void OnCloseUp(EventArgs e) + { + base.OnCloseUp(e); + droppedDown = false; + Invalidate(); + } + + protected override void OnKeyPress(KeyPressEventArgs e) + { + base.OnKeyPress(e); + e.Handled = true; + } + + protected override void OnPaint(PaintEventArgs e) + { + Graphics g = e.Graphics; + g.SmoothingMode = SmoothingMode.AntiAlias; + + using var penBorder = new Pen(borderColor, borderSize) { Alignment = PenAlignment.Inset }; + using var skinBrush = new SolidBrush(skinColor); + using var textBrush = new SolidBrush(textColor); + using var openBrush = new SolidBrush(Color.FromArgb(50, 64, 64, 64)); + using var format = new StringFormat { LineAlignment = StringAlignment.Center }; + + RectangleF client = new RectangleF(0, 0, Width - 0.5F, Height - 0.5F); + RectangleF iconArea = new RectangleF(client.Width - calendarIconWidth, 0, calendarIconWidth, client.Height); + + // Fundo + g.FillRectangle(skinBrush, client); + + // Texto + g.DrawString(" " + Text, Font, textBrush, client, format); + + // Ícone + if (calendarIcon != null) + { + g.DrawImage(calendarIcon, + Width - calendarIcon.Width - 9, + (Height - calendarIcon.Height) / 2); + } + + // Destaque quando aberto + if (droppedDown) + g.FillRectangle(openBrush, iconArea); + + // Borda + if (borderSize > 0) + g.DrawRectangle(penBorder, client.X, client.Y, client.Width, client.Height); + } + + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + + int iconWidth = GetIconButtonWidth(); + iconButtonArea = new RectangleF(Width - iconWidth, 0, iconWidth, Height); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + Cursor = iconButtonArea.Contains(e.Location) ? Cursors.Hand : Cursors.Default; + } + + // 🔹 Métodos privados + private int GetIconButtonWidth() + { + int textWidth = TextRenderer.MeasureText(Text, Font).Width; + return textWidth <= Width - (calendarIconWidth + 20) + ? calendarIconWidth + : arrowIconWidth; + } + + private Image LoadEmbeddedImage(string relativePath) + { + var asm = Assembly.GetExecutingAssembly(); + var resourceName = $"{asm.GetName().Name}.{relativePath}"; + + using var stream = asm.GetManifestResourceStream(resourceName); + return stream != null ? Image.FromStream(stream) : null; + } + } +} diff --git a/Components/DropdownMenu/LV-DROPDOWNMENU.cs b/Components/DropdownMenu/LV-DROPDOWNMENU.cs new file mode 100644 index 0000000..19e5f59 --- /dev/null +++ b/Components/DropdownMenu/LV-DROPDOWNMENU.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CPM.DropdownMenu +{ + public class LV_DROPDOWNMENU : ContextMenuStrip + { + //Fields + private bool isMainMenu; + private int menuItemHeight = 25; + private Color menuItemTextColor = Color.Empty;//No color, The default color is set in the MenuRenderer class + private Color primaryColor = Color.Empty;//No color, The default color is set in the MenuRenderer class + private Bitmap menuItemHeaderSize; + + public LV_DROPDOWNMENU(IContainer container) + : base(container) + { + + } + //Properties + //Optionally, hide the properties in the toolbox to avoid the problem of displaying and/or + //saving control property changes in the designer at design time in Visual Studio. + //If the problem I mention does not occur you can expose the properties and manipulate them from the toolbox. + [Browsable(false)] + public bool IsMainMenu + { + get { return isMainMenu; } + set { isMainMenu = value; } + } + [Browsable(false)] + public int MenuItemHeight + { + get { return menuItemHeight; } + set { menuItemHeight = value; } + } + [Browsable(false)] + public Color MenuItemTextColor + { + get { return menuItemTextColor; } + set { menuItemTextColor = value; } + } + [Browsable(false)] + public Color PrimaryColor + { + get { return primaryColor; } + set { primaryColor = value; } + } + //Private methods + private void LoadMenuItemHeight() + { + if (isMainMenu) + menuItemHeaderSize = new Bitmap(25, 45); + else menuItemHeaderSize = new Bitmap(20, menuItemHeight); + foreach (ToolStripMenuItem menuItemL1 in this.Items) + { + menuItemL1.ImageScaling = ToolStripItemImageScaling.None; + if (menuItemL1.Image == null) menuItemL1.Image = menuItemHeaderSize; + foreach (ToolStripMenuItem menuItemL2 in menuItemL1.DropDownItems) + { + menuItemL2.ImageScaling = ToolStripItemImageScaling.None; + if (menuItemL2.Image == null) menuItemL2.Image = menuItemHeaderSize; + foreach (ToolStripMenuItem menuItemL3 in menuItemL2.DropDownItems) + { + menuItemL3.ImageScaling = ToolStripItemImageScaling.None; + if (menuItemL3.Image == null) menuItemL3.Image = menuItemHeaderSize; + foreach (ToolStripMenuItem menuItemL4 in menuItemL3.DropDownItems) + { + menuItemL4.ImageScaling = ToolStripItemImageScaling.None; + if (menuItemL4.Image == null) menuItemL4.Image = menuItemHeaderSize; + ///Level 5++ + } + } + } + } + } + //Overrides + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + if (this.DesignMode == false) + { + this.Renderer = new LV_MENURENDERER(isMainMenu, primaryColor, menuItemTextColor); + LoadMenuItemHeight(); + } + } + + } +} diff --git a/Components/DropdownMenu/LV-MENUCOLORTABLE.cs b/Components/DropdownMenu/LV-MENUCOLORTABLE.cs new file mode 100644 index 0000000..3690b00 --- /dev/null +++ b/Components/DropdownMenu/LV-MENUCOLORTABLE.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CPM.DropdownMenu +{ + public class LV_MENUCOLORTABLE : ProfessionalColorTable + { + //Fields + private Color backColor; + private Color leftColumnColor; + private Color borderColor; + private Color menuItemBorderColor; + private Color menuItemSelectedColor; + + public LV_MENUCOLORTABLE(bool isMainMenu, Color primaryColor) + { + if (isMainMenu) + { + backColor = Color.MediumPurple; + leftColumnColor = Color.Transparent; + borderColor = Color.FromArgb(32, 33, 51); + menuItemBorderColor = primaryColor; + menuItemSelectedColor = primaryColor; + } + else + { + backColor = Color.White; + leftColumnColor = Color.LightGray; + borderColor = Color.LightGray; + menuItemBorderColor = primaryColor; + menuItemSelectedColor = primaryColor; + } + } + //Overrides + public override Color ToolStripDropDownBackground { get { return backColor; } } + public override Color MenuBorder { get { return borderColor; } } + public override Color MenuItemBorder { get { return menuItemBorderColor; } } + public override Color MenuItemSelected { get { return menuItemSelectedColor; } } + public override Color ImageMarginGradientBegin { get { return leftColumnColor; } } + public override Color ImageMarginGradientMiddle { get { return leftColumnColor; } } + public override Color ImageMarginGradientEnd { get { return leftColumnColor; } } + + } +} diff --git a/Components/DropdownMenu/LV-MENURENDERER.cs b/Components/DropdownMenu/LV-MENURENDERER.cs new file mode 100644 index 0000000..b5b8cec --- /dev/null +++ b/Components/DropdownMenu/LV-MENURENDERER.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CPM.DropdownMenu +{ + public class LV_MENURENDERER : ToolStripProfessionalRenderer + { + //Fields + private Color primaryColor; + private Color textColor; + private int arrowThickness; + //Constructor + public LV_MENURENDERER(bool isMainMenu, Color primaryColor, Color textColor) + : base(new LV_MENUCOLORTABLE(isMainMenu, primaryColor)) + { + this.primaryColor = primaryColor; + if (isMainMenu) + { + arrowThickness = 3; + if (textColor == Color.Empty) //Set Default Color + this.textColor = Color.Gainsboro; + else//Set custom text color + this.textColor = textColor; + } + else + { + arrowThickness = 2; + if (textColor == Color.Empty) //Set Default Color + this.textColor = Color.DimGray; + else//Set custom text color + this.textColor = textColor; + } + } + //Overrides + protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) + { + base.OnRenderItemText(e); + e.Item.ForeColor = e.Item.Selected ? Color.White : textColor; + } + protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e) + { + //Fields + var graph = e.Graphics; + var arrowSize = new Size(5, 12); + var arrowColor = e.Item.Selected ? Color.White : primaryColor; + var rect = new Rectangle(e.ArrowRectangle.Location.X, (e.ArrowRectangle.Height - arrowSize.Height) / 2, + arrowSize.Width, arrowSize.Height); + using (GraphicsPath path = new GraphicsPath()) + using (Pen pen = new Pen(arrowColor, arrowThickness)) + { + //Drawing + graph.SmoothingMode = SmoothingMode.AntiAlias; + path.AddLine(rect.Left, rect.Top, rect.Right, rect.Top + rect.Height / 2); + path.AddLine(rect.Right, rect.Top + rect.Height / 2, rect.Left, rect.Top + rect.Height); + graph.DrawPath(pen, path); + } + }//end onrender + } + +} diff --git a/Components/Imagens/calendarDark.png b/Components/Imagens/calendarDark.png new file mode 100644 index 0000000..c93a061 Binary files /dev/null and b/Components/Imagens/calendarDark.png differ diff --git a/Components/Imagens/calendarWhite.png b/Components/Imagens/calendarWhite.png new file mode 100644 index 0000000..668b051 Binary files /dev/null and b/Components/Imagens/calendarWhite.png differ diff --git a/Components/Imagens/chat.png b/Components/Imagens/chat.png new file mode 100644 index 0000000..060339f Binary files /dev/null and b/Components/Imagens/chat.png differ diff --git a/Components/Imagens/error.png b/Components/Imagens/error.png new file mode 100644 index 0000000..e06bd2c Binary files /dev/null and b/Components/Imagens/error.png differ diff --git a/Components/Imagens/exclamation.png b/Components/Imagens/exclamation.png new file mode 100644 index 0000000..04edd8e Binary files /dev/null and b/Components/Imagens/exclamation.png differ diff --git a/Components/Imagens/information.png b/Components/Imagens/information.png new file mode 100644 index 0000000..321e192 Binary files /dev/null and b/Components/Imagens/information.png differ diff --git a/Components/Imagens/question.png b/Components/Imagens/question.png new file mode 100644 index 0000000..f2b0a76 Binary files /dev/null and b/Components/Imagens/question.png differ diff --git a/Components/MasktedTextbox/LV-MaskTextboxCustom.cs b/Components/MasktedTextbox/LV-MaskTextboxCustom.cs new file mode 100644 index 0000000..9cdf5eb --- /dev/null +++ b/Components/MasktedTextbox/LV-MaskTextboxCustom.cs @@ -0,0 +1,322 @@ +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 ControllsCustom.NT_MASKTEXTBOX +{ + public partial class LV_MASKTEDTEXTBOX : UserControl + { + private Color borderColor = Color.MediumSlateBlue; + private Color borderFocusColor = Color.HotPink; + private int borderSize = 2; + private bool underlinedStyle = false; + private bool isFocused = false; + private int borderRadius = 0; + private Color placeholderColor = Color.DarkGray; + private string placeholderText = ""; + private bool isPlaceholder = false; + public LV_MASKTEDTEXTBOX() + { + InitializeComponent(); + SetPlaceholder(); + } + [Category("levelcode")] + public Color BorderColor + { + get { return borderColor; } + set + { + borderColor = value; + this.Invalidate(); + } + } + + [Category("levelcode")] + public Color BorderFocusColor + { + get { return borderFocusColor; } + set { borderFocusColor = value; } + } + + [Category("levelcode")] + public int BorderSize + { + get { return borderSize; } + set + { + if (value >= 1) + { + borderSize = value; + this.Invalidate(); + } + } + } + + [Category("levelcode")] + public bool UnderlinedStyle + { + get { return underlinedStyle; } + set + { + underlinedStyle = value; + this.Invalidate(); + } + } + + [Category("levelcode")] + public override Color BackColor + { + get { return base.BackColor; } + set + { + base.BackColor = value; + maskedTextBox1.BackColor = value; + } + } + + [Category("levelcode")] + public override Color ForeColor + { + get { return base.ForeColor; } + set + { + base.ForeColor = value; + maskedTextBox1.ForeColor = value; + } + } + + [Category("levelcode")] + public override Font Font + { + get { return base.Font; } + set + { + base.Font = value; + maskedTextBox1.Font = value; + if (this.DesignMode) + UpdateControlHeight(); + } + } + + [Category("levelcode")] + public string Texts + { + get + { + if (isPlaceholder) return ""; + else return maskedTextBox1.Text; + } + set + { + maskedTextBox1.Text = value; + SetPlaceholder(); + } + } + + [Category("levelcode")] + public int BorderRadius + { + get { return borderRadius; } + set + { + if (value >= 0) + { + borderRadius = value; + this.Invalidate();//Redraw control + } + } + } + + [Category("levelcode")] + public Color PlaceholderColor + { + get { return placeholderColor; } + set + { + placeholderColor = value; + if (isPlaceholder) + maskedTextBox1.ForeColor = value; + } + } + + [Category("levelcode")] + public string PlaceholderText + { + get { return placeholderText; } + set + { + placeholderText = value; + maskedTextBox1.Text = ""; + SetPlaceholder(); + } + } + [Category("levelcode")] + public string Mask + { + get { return maskedTextBox1.Mask; } + set { maskedTextBox1.Mask = value; } + } + + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + if (this.DesignMode) + UpdateControlHeight(); + } + + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + UpdateControlHeight(); + } + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + Graphics graph = e.Graphics; + + if (borderRadius > 1)//Rounded MaskedTextBox + { + var rectBorderSmooth = this.ClientRectangle; + var rectBorder = Rectangle.Inflate(rectBorderSmooth, -borderSize, -borderSize); + int smoothSize = borderSize > 0 ? borderSize : 1; + + using (GraphicsPath pathBorderSmooth = GetFigurePath(rectBorderSmooth, borderRadius)) + using (GraphicsPath pathBorder = GetFigurePath(rectBorder, borderRadius - borderSize)) + using (Pen penBorderSmooth = new Pen(this.Parent.BackColor, smoothSize)) + using (Pen penBorder = new Pen(borderColor, borderSize)) + { + this.Region = new Region(pathBorderSmooth);//Set the rounded region of UserControl + if (borderRadius > 15) SetMaskedTextBoxRoundedRegion();//Set the rounded region of MaskedTextBox component + graph.SmoothingMode = SmoothingMode.AntiAlias; + penBorder.Alignment = PenAlignment.Center; + if (isFocused) penBorder.Color = borderFocusColor; + + if (underlinedStyle) //Line Style + { + graph.DrawPath(penBorderSmooth, pathBorderSmooth); + graph.SmoothingMode = SmoothingMode.None; + graph.DrawLine(penBorder, 0, this.Height - 1, this.Width, this.Height - 1); + } + else //Normal Style + { + graph.DrawPath(penBorderSmooth, pathBorderSmooth); + graph.DrawPath(penBorder, pathBorder); + } + } + } + else //Square/Normal MaskedTextBox + { + using (Pen penBorder = new Pen(borderColor, borderSize)) + { + this.Region = new Region(this.ClientRectangle); + penBorder.Alignment = PenAlignment.Inset; + if (isFocused) penBorder.Color = borderFocusColor; + + if (underlinedStyle) //Line Style + graph.DrawLine(penBorder, 0, this.Height - 1, this.Width, this.Height - 1); + else //Normal Style + graph.DrawRectangle(penBorder, 0, 0, this.Width - 0.5F, this.Height - 0.5F); + } + } + } + + private void SetPlaceholder() + { + if (string.IsNullOrWhiteSpace(maskedTextBox1.Text) && placeholderText != "") + { + isPlaceholder = true; + maskedTextBox1.Text = placeholderText; + maskedTextBox1.ForeColor = placeholderColor; + } + } + + private void RemovePlaceholder() + { + if (isPlaceholder && placeholderText != "") + { + isPlaceholder = false; + maskedTextBox1.Text = ""; + maskedTextBox1.ForeColor = this.ForeColor; + } + } + + private GraphicsPath GetFigurePath(Rectangle rect, int radius) + { + GraphicsPath path = new GraphicsPath(); + float curveSize = radius * 2F; + + path.StartFigure(); + path.AddArc(rect.X, rect.Y, curveSize, curveSize, 180, 90); + path.AddArc(rect.Right - curveSize, rect.Y, curveSize, curveSize, 270, 90); + path.AddArc(rect.Right - curveSize, rect.Bottom - curveSize, curveSize, curveSize, 0, 90); + path.AddArc(rect.X, rect.Bottom - curveSize, curveSize, curveSize, 90, 90); + path.CloseFigure(); + return path; + } + + private void SetMaskedTextBoxRoundedRegion() + { + GraphicsPath pathTxt; + if (maskedTextBox1.Multiline) + { + pathTxt = GetFigurePath(maskedTextBox1.ClientRectangle, borderRadius - borderSize); + maskedTextBox1.Region = new Region(pathTxt); + } + else + { + pathTxt = GetFigurePath(maskedTextBox1.ClientRectangle, borderSize * 2); + maskedTextBox1.Region = new Region(pathTxt); + } + pathTxt.Dispose(); + } + + private void UpdateControlHeight() + { + if (!maskedTextBox1.Multiline) + { + int txtHeight = TextRenderer.MeasureText("Text", this.Font).Height + 1; + maskedTextBox1.Multiline = true; + maskedTextBox1.MinimumSize = new Size(0, txtHeight); + maskedTextBox1.Multiline = false; + + this.Height = maskedTextBox1.Height + this.Padding.Top + this.Padding.Bottom; + } + } + + private void maskedTextBox1_Enter(object sender, EventArgs e) + { + isFocused = true; + this.Invalidate(); + RemovePlaceholder(); + } + + private void maskedTextBox1_Leave(object sender, EventArgs e) + { + isFocused = false; + this.Invalidate(); + SetPlaceholder(); + } + + private void maskedTextBox1_TextChanged(object sender, EventArgs e) + { + if (isPlaceholder) + { + maskedTextBox1.ForeColor = placeholderColor; + } + else + { + maskedTextBox1.ForeColor = this.ForeColor; + } + } + + } +} diff --git a/Components/MasktedTextbox/NT-MASKTEDTEXTBOX.Designer.cs b/Components/MasktedTextbox/NT-MASKTEDTEXTBOX.Designer.cs new file mode 100644 index 0000000..a0cdc6d --- /dev/null +++ b/Components/MasktedTextbox/NT-MASKTEDTEXTBOX.Designer.cs @@ -0,0 +1,62 @@ +namespace ControllsCustom.NT_MASKTEXTBOX +{ + partial class LV_MASKTEDTEXTBOX + { + /// + /// Variável de designer necessária. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Limpar os recursos que estão sendo usados. + /// + /// true se for necessário descartar os recursos gerenciados; caso contrário, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Código gerado pelo Designer de Componentes + + /// + /// Método necessário para suporte ao Designer - não modifique + /// o conteúdo deste método com o editor de código. + /// + private void InitializeComponent() + { + this.maskedTextBox1 = new System.Windows.Forms.MaskedTextBox(); + this.SuspendLayout(); + // + // maskedTextBox1 + // + this.maskedTextBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.maskedTextBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.maskedTextBox1.Location = new System.Drawing.Point(7, 7); + this.maskedTextBox1.Name = "maskedTextBox1"; + this.maskedTextBox1.Size = new System.Drawing.Size(236, 13); + this.maskedTextBox1.TabIndex = 0; + // + // NT_MASKTEDTEXTBOX + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.White; + this.Controls.Add(this.maskedTextBox1); + this.Margin = new System.Windows.Forms.Padding(4); + this.Name = "NT_MASKTEDTEXTBOX"; + this.Padding = new System.Windows.Forms.Padding(7); + this.Size = new System.Drawing.Size(250, 30); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.MaskedTextBox maskedTextBox1; + } +} diff --git a/Components/MasktedTextbox/NT-MASKTEDTEXTBOX.resx b/Components/MasktedTextbox/NT-MASKTEDTEXTBOX.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Components/MasktedTextbox/NT-MASKTEDTEXTBOX.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Components/Monthcalendar/LV-MonthCalendar.cs b/Components/Monthcalendar/LV-MonthCalendar.cs new file mode 100644 index 0000000..f9a48a7 --- /dev/null +++ b/Components/Monthcalendar/LV-MonthCalendar.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CPM.Monthcalendar +{ + public class LV_MonthCalendar : MonthCalendar + { + // Fields for appearance + private Color titleBackColor = Color.MediumSlateBlue; + private Color titleForeColor = Color.White; + private Color dayForeColor = Color.Black; + private Color borderColor = Color.PaleVioletRed; + private int borderSize = 2; + + // Properties + public Color TitleBackColor + { + get { return titleBackColor; } + set { titleBackColor = value; this.Invalidate(); } + } + + public Color TitleForeColor + { + get { return titleForeColor; } + set { titleForeColor = value; this.Invalidate(); } + } + + public Color DayForeColor + { + get { return dayForeColor; } + set { dayForeColor = value; this.Invalidate(); } + } + + public Color BorderColor + { + get { return borderColor; } + set { borderColor = value; this.Invalidate(); } + } + + public int BorderSize + { + get { return borderSize; } + set { borderSize = value; this.Invalidate(); } + } + + public LV_MonthCalendar() + { + // Customizations on creation + this.TitleBackColor = titleBackColor; + this.TitleForeColor = titleForeColor; + this.ForeColor = dayForeColor; + this.Font = new Font("Arial", 10F, FontStyle.Regular); + } + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + // Drawing custom border + using (Pen borderPen = new Pen(borderColor, borderSize)) + { + e.Graphics.DrawRectangle(borderPen, this.ClientRectangle.X, this.ClientRectangle.Y, + this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1); + } + } + + // Example method to adjust title colors dynamically + protected override void OnDateChanged(DateRangeEventArgs e) + { + base.OnDateChanged(e); + this.TitleBackColor = Color.FromArgb(100, 150, 200); // Dynamic title color change + } + } +} diff --git a/Components/PictureBar/LV-CIRCULARBARPICTUREBOX.cs b/Components/PictureBar/LV-CIRCULARBARPICTUREBOX.cs new file mode 100644 index 0000000..3f5e00d --- /dev/null +++ b/Components/PictureBar/LV-CIRCULARBARPICTUREBOX.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CPM.PictureBar +{ + public class LV_CIRCULARBARPICTUREBOX : PictureBox + { + private int borderSize = 2; + private Color borderColor = Color.RoyalBlue; + private Color borderColor2 = Color.HotPink; + private DashStyle borderLineStyle = DashStyle.Solid; + private DashCap borderCapStyle = DashCap.Flat; + private float gradientAngle = 50F; + + public LV_CIRCULARBARPICTUREBOX() + { + this.Size = new Size(100, 100); + this.SizeMode = PictureBoxSizeMode.StretchImage; + } + //Properties + [Category("Levelcode")] + public int BorderSize + { + get { return borderSize; } + set + { + borderSize = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public Color BorderColor + { + get { return borderColor; } + set + { + borderColor = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public Color BorderColor2 + { + get { return borderColor2; } + set + { + borderColor2 = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public DashStyle BorderLineStyle + { + get { return borderLineStyle; } + set + { + borderLineStyle = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public DashCap BorderCapStyle + { + get { return borderCapStyle; } + set + { + borderCapStyle = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public float GradientAngle + { + get { return gradientAngle; } + set + { + gradientAngle = value; + this.Invalidate(); + } + } + + //Overridden methods + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + this.Size = new Size(this.Width, this.Width); + } + + protected override void OnPaint(PaintEventArgs pe) + { + base.OnPaint(pe); + //Fields + var graph = pe.Graphics; + var rectContourSmooth = Rectangle.Inflate(this.ClientRectangle, -1, -1); + var rectBorder = Rectangle.Inflate(rectContourSmooth, -borderSize, -borderSize); + var smoothSize = borderSize > 0 ? borderSize * 3 : 1; + using (var borderGColor = new LinearGradientBrush(rectBorder, borderColor, borderColor2, gradientAngle)) + using (var pathRegion = new GraphicsPath()) + using (var penSmooth = new Pen(this.Parent.BackColor, smoothSize)) + using (var penBorder = new Pen(borderGColor, borderSize)) + { + graph.SmoothingMode = SmoothingMode.AntiAlias; + penBorder.DashStyle = borderLineStyle; + penBorder.DashCap = borderCapStyle; + pathRegion.AddEllipse(rectContourSmooth); + //Set rounded region + this.Region = new Region(pathRegion); + + //Drawing + graph.DrawEllipse(penSmooth, rectContourSmooth);//Draw contour smoothing + if (borderSize > 0) //Draw border + graph.DrawEllipse(penBorder, rectBorder); + } + } + } +} diff --git a/Components/Program.cs b/Components/Program.cs new file mode 100644 index 0000000..165ef71 --- /dev/null +++ b/Components/Program.cs @@ -0,0 +1,16 @@ +using System; +using System.Windows.Forms; +using static System.Windows.Forms.DataFormats; + +namespace CPM.Test +{ + internal static class Program + { + [STAThread] + static void Main() + { + + Application.Run(new FrmTestComponents()); // ou seu form principal + } + } +} \ No newline at end of file diff --git a/Components/ProgressBar/LV-CIRCULEPROGRESSBAR.cs b/Components/ProgressBar/LV-CIRCULEPROGRESSBAR.cs new file mode 100644 index 0000000..43b35b1 --- /dev/null +++ b/Components/ProgressBar/LV-CIRCULEPROGRESSBAR.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CPM.ProgressBar +{ + public class LV_CIRCULEPROGRESSBAR : UserControl + { + private int _valor = 0; + private int _maximo = 100; + private int _larguraBorda = 10; + private Color _corProgresso = Color.FromArgb(0, 120, 215); + private Color _corFundo = Color.LightGray; + private Font _fonteTexto = new Font("Segoe UI", 10, FontStyle.Bold); + private bool _mostrarPorcentagem = true; + + [Category("Comportamento")] + public int Valor + { + get => _valor; + set + { + _valor = Math.Min(_maximo, Math.Max(0, value)); + Invalidate(); + } + } + + [Category("Comportamento")] + public int Maximo + { + get => _maximo; + set + { + _maximo = value <= 0 ? 1 : value; + Invalidate(); + } + } + + [Category("Aparência")] + public int LarguraBorda + { + get => _larguraBorda; + set + { + _larguraBorda = Math.Max(1, value); + Invalidate(); + } + } + + [Category("Aparência")] + public Color CorProgresso + { + get => _corProgresso; + set + { + _corProgresso = value; + Invalidate(); + } + } + + [Category("Aparência")] + public Color CorFundo + { + get => _corFundo; + set + { + _corFundo = value; + Invalidate(); + } + } + + [Category("Aparência")] + public Font FonteTexto + { + get => _fonteTexto; + set + { + _fonteTexto = value; + Invalidate(); + } + } + + [Category("Aparência")] + public bool MostrarPorcentagem + { + get => _mostrarPorcentagem; + set + { + _mostrarPorcentagem = value; + Invalidate(); + } + } + + public LV_CIRCULEPROGRESSBAR() + { + DoubleBuffered = true; + ResizeRedraw = true; + Size = new Size(150, 150); + } + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; + + Rectangle rect = new Rectangle(_larguraBorda, _larguraBorda, + Width - _larguraBorda * 2, Height - _larguraBorda * 2); + + using (Pen fundoPen = new Pen(_corFundo, _larguraBorda)) + using (Pen progressoPen = new Pen(_corProgresso, _larguraBorda)) + { + progressoPen.StartCap = LineCap.Round; + progressoPen.EndCap = LineCap.Round; + + // Fundo + e.Graphics.DrawArc(fundoPen, rect, -90, 360); + + // Progresso + float angulo = 360f * _valor / _maximo; + e.Graphics.DrawArc(progressoPen, rect, -90, angulo); + } + + if (_mostrarPorcentagem) + { + string texto = $"{(int)((double)_valor / _maximo * 100)}%"; + SizeF tamanhoTexto = e.Graphics.MeasureString(texto, _fonteTexto); + e.Graphics.DrawString(texto, _fonteTexto, new SolidBrush(Color.White), + (Width - tamanhoTexto.Width) / 2, (Height - tamanhoTexto.Height) / 2); + } + } + } +} diff --git a/Components/ProgressBar/LV-PROGRESSBARCUSTOM.cs b/Components/ProgressBar/LV-PROGRESSBARCUSTOM.cs new file mode 100644 index 0000000..6a4a0f5 --- /dev/null +++ b/Components/ProgressBar/LV-PROGRESSBARCUSTOM.cs @@ -0,0 +1,272 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel; + +namespace CPM.ProgressBar +{ + public class LV_PROGRESSBARCUSTON : System.Windows.Forms.ProgressBar + { + public enum TextPosition + { + Left, + Right, + Center, + Sliding, + None + } + + //Fields + //-> Appearance + private Color channelColor = Color.LightSteelBlue; + private Color sliderColor = Color.RoyalBlue; + private Color foreBackColor = Color.RoyalBlue; + private int channelHeight = 6; + private int sliderHeight = 6; + private TextPosition showValue = TextPosition.Right; + private string symbolBefore = ""; + private string symbolAfter = ""; + private bool showMaximun = false; + + //-> Others + private bool paintedBack = false; + private bool stopPainting = false; + + public LV_PROGRESSBARCUSTON() + { + this.SetStyle(ControlStyles.UserPaint, true); + this.ForeColor = Color.White; + } + //Propertiesfff + [Category("Levelcode")] + public Color ChannelColor + { + get { return channelColor; } + set + { + channelColor = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public Color SliderColor + { + get { return sliderColor; } + set + { + sliderColor = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public Color ForeBackColor + { + get { return foreBackColor; } + set + { + foreBackColor = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public int ChannelHeight + { + get { return channelHeight; } + set + { + channelHeight = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public int SliderHeight + { + get { return sliderHeight; } + set + { + sliderHeight = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public TextPosition ShowValue + { + get { return showValue; } + set + { + showValue = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public string SymbolBefore + { + get { return symbolBefore; } + set + { + symbolBefore = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public string SymbolAfter + { + get { return symbolAfter; } + set + { + symbolAfter = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public bool ShowMaximun + { + get { return showMaximun; } + set + { + showMaximun = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + [Browsable(true)] + [EditorBrowsable(EditorBrowsableState.Always)] + public override Font Font + { + get { return base.Font; } + set + { + base.Font = value; + } + } + + [Category("Levelcode")] + public override Color ForeColor + { + get { return base.ForeColor; } + set + { + base.ForeColor = value; + } + } + + //-> Paint the background & channel + protected override void OnPaintBackground(PaintEventArgs pevent) + { + if (stopPainting == false) + { + if (paintedBack == false) + { + //Fields + Graphics graph = pevent.Graphics; + Rectangle rectChannel = new Rectangle(0, 0, this.Width, ChannelHeight); + using (var brushChannel = new SolidBrush(channelColor)) + { + if (channelHeight >= sliderHeight) + rectChannel.Y = this.Height - channelHeight; + else rectChannel.Y = this.Height - ((channelHeight + sliderHeight) / 2); + + //Painting + graph.Clear(this.Parent.BackColor);//Surface + graph.FillRectangle(brushChannel, rectChannel);//Channel + + //Stop painting the back & Channel + if (this.DesignMode == false) + paintedBack = true; + } + } + //Reset painting the back & channel + if (this.Value == this.Maximum || this.Value == this.Minimum) + paintedBack = false; + } + } + //-> Paint slider + protected override void OnPaint(PaintEventArgs e) + { + if (stopPainting == false) + { + //Fields + Graphics graph = e.Graphics; + double scaleFactor = (((double)this.Value - this.Minimum) / ((double)this.Maximum - this.Minimum)); + int sliderWidth = (int)(this.Width * scaleFactor); + Rectangle rectSlider = new Rectangle(0, 0, sliderWidth, sliderHeight); + using (var brushSlider = new SolidBrush(sliderColor)) + { + if (sliderHeight >= channelHeight) + rectSlider.Y = this.Height - sliderHeight; + else rectSlider.Y = this.Height - ((sliderHeight + channelHeight) / 2); + + //Painting + if (sliderWidth > 1) //Slider + graph.FillRectangle(brushSlider, rectSlider); + if (showValue != TextPosition.None) //Text + DrawValueText(graph, sliderWidth, rectSlider); + } + } + if (this.Value == this.Maximum) stopPainting = true;//Stop painting + else stopPainting = false; //Keep painting + } + + //-> Paint value text + private void DrawValueText(Graphics graph, int sliderWidth, Rectangle rectSlider) + { + //Fields + string text = symbolBefore + this.Value.ToString() + symbolAfter; + if (showMaximun) text = text + "/" + symbolBefore + this.Maximum.ToString() + symbolAfter; + var textSize = TextRenderer.MeasureText(text, this.Font); + var rectText = new Rectangle(0, 0, textSize.Width, textSize.Height + 2); + using (var brushText = new SolidBrush(this.ForeColor)) + using (var brushTextBack = new SolidBrush(foreBackColor)) + using (var textFormat = new StringFormat()) + { + switch (showValue) + { + case TextPosition.Left: + rectText.X = 0; + textFormat.Alignment = StringAlignment.Near; + break; + + case TextPosition.Right: + rectText.X = this.Width - textSize.Width; + textFormat.Alignment = StringAlignment.Far; + break; + + case TextPosition.Center: + rectText.X = (this.Width - textSize.Width) / 2; + textFormat.Alignment = StringAlignment.Center; + break; + + case TextPosition.Sliding: + rectText.X = sliderWidth - textSize.Width; + textFormat.Alignment = StringAlignment.Center; + //Clean previous text surface + using (var brushClear = new SolidBrush(this.Parent.BackColor)) + { + var rect = rectSlider; + rect.Y = rectText.Y; + rect.Height = rectText.Height; + graph.FillRectangle(brushClear, rect); + } + break; + } + //Painting + graph.FillRectangle(brushTextBack, rectText); + graph.DrawString(text, this.Font, brushText, rectText, textFormat); + } + } + } +} diff --git a/Components/Properties/Resources.Designer.cs b/Components/Properties/Resources.Designer.cs new file mode 100644 index 0000000..7bd31d2 --- /dev/null +++ b/Components/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// O código foi gerado por uma ferramenta. +// Versão de Tempo de Execução:4.0.30319.42000 +// +// As alterações ao arquivo poderão causar comportamento incorreto e serão perdidas se +// o código for gerado novamente. +// +//------------------------------------------------------------------------------ + +namespace CPM.Properties { + using System; + + + /// + /// Uma classe de recurso de tipo de alta segurança, para pesquisar cadeias de caracteres localizadas etc. + /// + // Essa classe foi gerada automaticamente pela classe StronglyTypedResourceBuilder + // através de uma ferramenta como ResGen ou Visual Studio. + // Para adicionar ou remover um associado, edite o arquivo .ResX e execute ResGen novamente + // com a opção /str, ou recrie o projeto do VS. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Retorna a instância de ResourceManager armazenada em cache usada por essa classe. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CPM.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Substitui a propriedade CurrentUICulture do thread atual para todas as + /// pesquisas de recursos que usam essa classe de recurso de tipo de alta segurança. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Components/Properties/Resources.resx b/Components/Properties/Resources.resx new file mode 100644 index 0000000..4fdb1b6 --- /dev/null +++ b/Components/Properties/Resources.resx @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Components/Radiobutton/LV-RADIOBUTTON.cs b/Components/Radiobutton/LV-RADIOBUTTON.cs new file mode 100644 index 0000000..5822865 --- /dev/null +++ b/Components/Radiobutton/LV-RADIOBUTTON.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace CPM.Radiobutton +{ + public class LV_RADIOBUTTON : RadioButton + { + //propriedades privadas + private Color checkedColor = Color.MediumSlateBlue; + private Color unCheckedColor = Color.Gray; + + //propriedades publicas + public Color CheckedColor { get => checkedColor; set => checkedColor = value; } + public Color UnCheckedColor { get => unCheckedColor; set => unCheckedColor = value; } + + public LV_RADIOBUTTON() + { + this.MinimumSize = new Size(0, 21); + //Add a padding of 10 to the left to have a considerable distance between the text and the RadioButton. + this.Padding = new Padding(10, 0, 0, 0); + } + protected override void OnPaint(PaintEventArgs pevent) + { + //Fields + Graphics graphics = pevent.Graphics; + graphics.SmoothingMode = SmoothingMode.AntiAlias; + float rbBorderSize = 18F; + float rbCheckSize = 12F; + RectangleF rectRbBorder = new RectangleF() + { + X = 0.5F, + Y = (this.Height - rbBorderSize) / 2, //Center + Width = rbBorderSize, + Height = rbBorderSize + }; + RectangleF rectRbCheck = new RectangleF() + { + X = rectRbBorder.X + ((rectRbBorder.Width - rbCheckSize) / 2), //Center + Y = (this.Height - rbCheckSize) / 2, //Center + Width = rbCheckSize, + Height = rbCheckSize + }; + + //Drawing + using (Pen penBorder = new Pen(checkedColor, 1.6F)) + using (SolidBrush brushRbCheck = new SolidBrush(checkedColor)) + using (SolidBrush brushText = new SolidBrush(this.ForeColor)) + { + //Draw surface + graphics.Clear(this.BackColor); + //Draw Radio Button + if (this.Checked) + { + graphics.DrawEllipse(penBorder, rectRbBorder);//Circle border + graphics.FillEllipse(brushRbCheck, rectRbCheck); //Circle Radio Check + } + else + { + penBorder.Color = unCheckedColor; + graphics.DrawEllipse(penBorder, rectRbBorder); //Circle border + } + //Draw text + graphics.DrawString(this.Text, this.Font, brushText, + rbBorderSize + 8, (this.Height - TextRenderer.MeasureText(this.Text, this.Font).Height) / 2);//Y=Center + } + } + + //X-> Obsolete code, this was replaced by the Padding property in the constructor + //(this.Padding = new Padding(10,0,0,0);) + //protected override void OnResize(EventArgs e) + //{ + // base.OnResize(e); + // this.Width = TextRenderer.MeasureText(this.Text, this.Font).Width + 30; + //} + }//end OnPaint + +} diff --git a/Components/Test/FrmTestComponents.Designer.cs b/Components/Test/FrmTestComponents.Designer.cs new file mode 100644 index 0000000..938b78b --- /dev/null +++ b/Components/Test/FrmTestComponents.Designer.cs @@ -0,0 +1,45 @@ +namespace CPM.Test +{ + partial class FrmTestComponents + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + SuspendLayout(); + // + // FrmTestComponents + // + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(739, 605); + Name = "FrmTestComponents"; + Text = "FrmTestComponents"; + ResumeLayout(false); + } + + #endregion + } +} \ No newline at end of file diff --git a/Components/Test/FrmTestComponents.cs b/Components/Test/FrmTestComponents.cs new file mode 100644 index 0000000..0b5aa5c --- /dev/null +++ b/Components/Test/FrmTestComponents.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CPM.Test +{ + public partial class FrmTestComponents : Form + { + public FrmTestComponents() + { + InitializeComponent(); + } + } +} diff --git a/Components/Test/FrmTestComponents.resx b/Components/Test/FrmTestComponents.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/Components/Test/FrmTestComponents.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Components/Textbox/LV-TEXTBOX1.cs b/Components/Textbox/LV-TEXTBOX1.cs new file mode 100644 index 0000000..d60a488 --- /dev/null +++ b/Components/Textbox/LV-TEXTBOX1.cs @@ -0,0 +1,210 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using static System.Net.Mime.MediaTypeNames; +using Image = System.Drawing.Image; + +namespace CPM +{ + public partial class LV_TEXTBOX1 : UserControl + { + private Color borderColor = Color.Gray; + private Color borderFocusColor = Color.DodgerBlue; + private int borderSize = 2; + private bool isFocused = false; + private bool underlineStyle = false; + + public event EventHandler IconClick; + + public LV_TEXTBOX1() + { + InitializeComponent(); + Redraw(); + } + + // Propriedades + public override string Text + { + get { return txt.Text; } + set { txt.Text = value; } + } + public bool ReadOnly + { + get { return txt.ReadOnly; } + set { txt.ReadOnly = value; } + } + public Color BorderColor + { + get { return borderColor; } + set { borderColor = value; Invalidate(); } + } + + public Color BorderFocusColor + { + get { return borderFocusColor; } + set { borderFocusColor = value; Invalidate(); } + } + + public int BorderSize + { + get { return borderSize; } + set { borderSize = value; Invalidate(); } + } + // No seu LvlTextbox + [Browsable(true)] + [Category("Behavior")] + public int SelectionStart + { + get { return txt.SelectionStart; } + set { txt.SelectionStart = value; } + } + + [Browsable(true)] + [Category("Behavior")] + public int MaxLength + { + get { return txt.MaxLength; } + set { txt.MaxLength = value; } + } + [Browsable(true)] + [Category("Behavior")] + public bool Multiline + { + get { return txt.Multiline; } + set { txt.Multiline = value; } + } + + public bool UnderlineStyle + { + get { return underlineStyle; } + set { underlineStyle = value; Invalidate(); } + } + + public Image Icon + { + get { return picIcon.Image; } + set + { + picIcon.Image = value; + picIcon.Visible = (value != null); + Redraw(); + } + } + + public enum IconAlignEnum { Left, Right } + + private IconAlignEnum iconAlign = IconAlignEnum.Left; + + public IconAlignEnum IconAlign + { + get { return iconAlign; } + set { iconAlign = value; Redraw(); } + } + + // Renderização da borda + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + + Color color = isFocused ? borderFocusColor : borderColor; + + using (Pen pen = new Pen(color, borderSize)) + { + pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset; + + if (underlineStyle) + { + e.Graphics.DrawLine(pen, 0, Height - 1, Width, Height - 1); + } + else + { + e.Graphics.DrawRectangle(pen, 0, 0, Width - 1, Height - 1); + } + } + } + + // Atualizar layout + public void Redraw() + { + int offset = 0; + + if (picIcon.Visible) + { + offset = picIcon.Width + 8; + + if (iconAlign == IconAlignEnum.Left) + { + picIcon.Left = 5; + txt.Left = offset; + txt.Width = Width - offset - 5; + } + else + { + picIcon.Left = Width - picIcon.Width - 5; + txt.Left = 5; + txt.Width = Width - offset - 5; + } + } + else + { + txt.Left = 5; + txt.Width = Width - 10; + } + + Invalidate(); + } + + // Eventos internos + private void txt_Enter(object sender, EventArgs e) + { + isFocused = true; + Invalidate(); + } + + private void txt_Leave(object sender, EventArgs e) + { + isFocused = false; + Invalidate(); + } + private char _passwordChar = '\0'; + public char PasswordChar + { + get { return _passwordChar; } + set + { + _passwordChar = value; + txt.PasswordChar = value; + txt.UseSystemPasswordChar = (value != '\0'); + } + } + + public bool UseSystemPasswordChar + { + get { return txt.UseSystemPasswordChar; } + set { txt.UseSystemPasswordChar = value; } + } + + + private void txt_KeyPress(object sender, KeyPressEventArgs e) + { + OnKeyPress(e); + } + + private void txt_TextChanged(object sender, EventArgs e) + { + OnTextChanged(e); + } + + private void picIcon_Click(object sender, EventArgs e) + { + if (IconClick != null) + IconClick(this, e); + } + + private void LvlTextbox_Resize(object sender, EventArgs e) + { + Redraw(); + } + } +} diff --git a/Components/Textbox/LV-TEXTBOX1.resx b/Components/Textbox/LV-TEXTBOX1.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Components/Textbox/LV-TEXTBOX1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Components/Textbox/LV_TEXTBOX1.Designer.cs b/Components/Textbox/LV_TEXTBOX1.Designer.cs new file mode 100644 index 0000000..c155ebd --- /dev/null +++ b/Components/Textbox/LV_TEXTBOX1.Designer.cs @@ -0,0 +1,60 @@ +namespace CPM +{ + partial class LV_TEXTBOX1 + { + private System.ComponentModel.IContainer components = null; + private System.Windows.Forms.TextBox txt; + private System.Windows.Forms.PictureBox picIcon; + + protected override void Dispose(bool disposing) + { + if (disposing && components != null) + components.Dispose(); + + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.txt = new System.Windows.Forms.TextBox(); + this.picIcon = new System.Windows.Forms.PictureBox(); + + ((System.ComponentModel.ISupportInitialize)(this.picIcon)).BeginInit(); + this.SuspendLayout(); + + // txt + this.txt.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.txt.Location = new System.Drawing.Point(5, 5); + this.txt.Name = "txt"; + this.txt.Size = new System.Drawing.Size(150, 16); + this.txt.TabIndex = 0; + this.txt.Enter += new System.EventHandler(this.txt_Enter); + this.txt.Leave += new System.EventHandler(this.txt_Leave); + this.txt.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.txt_KeyPress); + this.txt.TextChanged += new System.EventHandler(this.txt_TextChanged); + + // picIcon + this.picIcon.Location = new System.Drawing.Point(5, 5); + this.picIcon.Name = "picIcon"; + this.picIcon.Size = new System.Drawing.Size(20, 20); + this.picIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.picIcon.TabStop = false; + this.picIcon.Visible = false; + this.picIcon.Click += new System.EventHandler(this.picIcon_Click); + + // LvlTextbox + this.BackColor = System.Drawing.Color.White; + this.Controls.Add(this.picIcon); + this.Controls.Add(this.txt); + this.Name = "LvlTextbox"; + this.Size = new System.Drawing.Size(200, 30); + this.Resize += new System.EventHandler(this.LvlTextbox_Resize); + + ((System.ComponentModel.ISupportInitialize)(this.picIcon)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + this.txt.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.txt_KeyPress); + } + } +} diff --git a/Components/ToggleButton/LV-TOGGLEBUTTON.cs b/Components/ToggleButton/LV-TOGGLEBUTTON.cs new file mode 100644 index 0000000..87edf83 --- /dev/null +++ b/Components/ToggleButton/LV-TOGGLEBUTTON.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Drawing.Drawing2D; +using System.ComponentModel; +using System.Drawing; + +namespace CPM.ToggleButton +{ + public class LV_TOGGLEBUTTON : CheckBox + { + //Fields + private Color onBackColor = Color.MediumSlateBlue; + private Color onToggleColor = Color.WhiteSmoke; + private Color offBackColor = Color.Gray; + private Color offToggleColor = Color.Gainsboro; + private bool solidStyle = true; + + //Properties + [Category("Levelcode")] + public Color OnBackColor + { + get + { + return onBackColor; + } + + set + { + onBackColor = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public Color OnToggleColor + { + get + { + return onToggleColor; + } + + set + { + onToggleColor = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public Color OffBackColor + { + get + { + return offBackColor; + } + + set + { + offBackColor = value; + this.Invalidate(); + } + } + + [Category("Levelcode")] + public Color OffToggleColor + { + get + { + return offToggleColor; + } + + set + { + offToggleColor = value; + this.Invalidate(); + } + } + + [Browsable(false)] + public override string Text + { + get + { + return base.Text; + } + + set + { + + } + } + + [Category("Levelcode")] + [DefaultValue(true)] + public bool SolidStyle + { + get + { + return solidStyle; + } + + set + { + solidStyle = value; + this.Invalidate(); + } + } + + public LV_TOGGLEBUTTON() + { + this.MinimumSize = new Size(45, 22); + } + + //Methods + private GraphicsPath GetFigurePath() + { + int arcSize = this.Height - 1; + Rectangle leftArc = new Rectangle(0, 0, arcSize, arcSize); + Rectangle rightArc = new Rectangle(this.Width - arcSize - 2, 0, arcSize, arcSize); + + GraphicsPath path = new GraphicsPath(); + path.StartFigure(); + path.AddArc(leftArc, 90, 180); + path.AddArc(rightArc, 270, 180); + path.CloseFigure(); + + return path; + } + + protected override void OnPaint(PaintEventArgs pevent) + { + int toggleSize = this.Height - 5; + pevent.Graphics.SmoothingMode = SmoothingMode.AntiAlias; + pevent.Graphics.Clear(this.Parent.BackColor); + + if (this.Checked) //ON + { + //Draw the control surface + if (solidStyle) + pevent.Graphics.FillPath(new SolidBrush(onBackColor), GetFigurePath()); + else pevent.Graphics.DrawPath(new Pen(onBackColor, 2), GetFigurePath()); + //Draw the toggle + pevent.Graphics.FillEllipse(new SolidBrush(onToggleColor), + new Rectangle(this.Width - this.Height + 1, 2, toggleSize, toggleSize)); + } + else //OFF + { + //Draw the control surface + if (solidStyle) + pevent.Graphics.FillPath(new SolidBrush(offBackColor), GetFigurePath()); + else pevent.Graphics.DrawPath(new Pen(offBackColor, 2), GetFigurePath()); + //Draw the toggle + pevent.Graphics.FillEllipse(new SolidBrush(offToggleColor), + new Rectangle(2, 2, toggleSize, toggleSize)); + } + } + } +} diff --git a/LevelOS/Cadastros/AgendaCadastroPanel.cs b/LevelOS/Cadastros/AgendaCadastroPanel.cs new file mode 100644 index 0000000..4d43308 --- /dev/null +++ b/LevelOS/Cadastros/AgendaCadastroPanel.cs @@ -0,0 +1,803 @@ +using BLL; +using CPM; +//using CustomMessageBox; +using DAL; +using MLL; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Windows.Forms; + +namespace LevelOS +{ + public class AgendaCadastroPanel : UserControl + { + string _cx = DadosDaConexao.ObterConexao(); + + // ── CORES ───────────────────────────────────────────────────────────── + 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 readonly Color GreenColor = Color.FromArgb(34, 197, 94); + private readonly Color AmberColor = Color.FromArgb(245, 158, 11); + private readonly Color RedColor = Color.FromArgb(239, 68, 68); + private readonly Color MutedGray = Color.FromArgb(148, 163, 184); + private readonly Color SurfaceColor = Color.FromArgb(248, 250, 252); + private readonly Color DisabledBack = Color.FromArgb(241, 245, 249); + + // ── LAYOUT ──────────────────────────────────────────────────────────── + private Panel pnlToolbar = null!; + private Panel pnlLeft = null!; + private Panel pnlRight = null!; + private Panel pnlEventList = null!; + private Panel pnlSplit = null!; + private Panel pnlDias = null!; + + // ── TOOLBAR ─────────────────────────────────────────────────────────── + private LV_BUTTON btnNovo = null!; + private LV_BUTTON btnAlterar = null!; + private LV_BUTTON btnExcluir = null!; + private LV_BUTTON btnLocalizar = null!; + private LV_BUTTON btnSalvar = null!; + private LV_BUTTON btnCancelar = null!; + + // ── CAMPOS DO FORMULÁRIO ────────────────────────────────────────────── + private LV_TEXTBOX1 txtId = null!; + private LV_TEXTBOX1 txtCodigo = null!; + private LV_TEXTBOX1 txtCompromisso = null!; + private LV_TEXTBOX1 txtData = null!; + private LV_TEXTBOX1 txtDia = null!; + private LV_TEXTBOX1 txtHora = null!; + private LV_TEXTBOX1 txtFunc = null!; + private LV_TEXTBOX1 txtAvisar = null!; + private LV_TEXTBOX1 txtOsVinc = null!; + private CheckBox chkRealizado = null!; + + // ── INFO (readonly) ─────────────────────────────────────────────────── + private LV_TEXTBOX1 txtCriadoEm = null!; + private LV_TEXTBOX1 txtAtualizadoEm = null!; + + // ── CALENDÁRIO ──────────────────────────────────────────────────────── + private Label lblMesAno = null!; + private Button btnPrev = null!; + private Button btnNext = null!; + + // ── ESTADO ──────────────────────────────────────────────────────────── + private DateTime _currentMonth = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1); + private DateTime? _selectedDate = null; + private List _eventos = new(); + private int _nextId = 1; + + // ── CONSTRUTOR ──────────────────────────────────────────────────────── + public AgendaCadastroPanel() + { + Dock = DockStyle.Fill; + BackColor = Color.White; + DoubleBuffered = true; + + InitializeLayout(); + SetCampos(false); + CarregarDadosDoBanco(); + RenderCalendario(); + RenderListaEventos(); + } + + // ══════════════════════════════════════════════════════════════════════ + // LAYOUT + // ══════════════════════════════════════════════════════════════════════ + private void InitializeLayout() + { + Controls.Clear(); + + // ── TOOLBAR ─────────────────────────────────────────────────────── + pnlToolbar = new Panel + { + Dock = DockStyle.Top, + Height = 55, + BackColor = SurfaceColor + }; + + var flow = new FlowLayoutPanel + { + Dock = DockStyle.Fill, + Padding = new Padding(12, 10, 0, 0), + BackColor = Color.Transparent + }; + + btnNovo = CreateToolbarButton("Novo", GreenColor); + btnAlterar = CreateToolbarButton("Alterar", AmberColor); + btnExcluir = CreateToolbarButton("Excluir", RedColor); + btnLocalizar = CreateToolbarButton("Localizar", AccentBlue); + btnSalvar = CreateToolbarButton("Salvar", AccentBlue); + btnCancelar = CreateToolbarButton("Cancelar", MutedGray); + + btnNovo.Click += (_, _) => BtnNovo_Click(); + btnAlterar.Click += (_, _) => BtnAlterar_Click(); + btnExcluir.Click += (_, _) => BtnExcluir_Click(); + btnLocalizar.Click += (_, _) => BtnLocalizar_Click(); + btnSalvar.Click += (_, _) => BtnSalvar_Click(); + btnCancelar.Click += (_, _) => BtnCancelar_Click(); + + flow.Controls.AddRange(new Control[] + { btnNovo, btnAlterar, btnExcluir, btnLocalizar, btnSalvar, btnCancelar }); + + pnlToolbar.Controls.Add(flow); + Controls.Add(pnlToolbar); + + // ── SPLIT ───────────────────────────────────────────────────────── + pnlSplit = new Panel { Dock = DockStyle.Fill, BackColor = Color.White }; + Controls.Add(pnlSplit); + pnlSplit.BringToFront(); + + // RIGHT ─ calendário + lista + pnlRight = new Panel + { + Dock = DockStyle.Right, + Width = 340, + BackColor = Color.White, + Padding = new Padding(10, 10, 10, 10) + }; + pnlSplit.Controls.Add(pnlRight); + BuildCalendario(); + + // Divider + pnlSplit.Controls.Add(new Panel + { + Dock = DockStyle.Right, + Width = 1, + BackColor = BorderColor + }); + + // LEFT ─ formulário + pnlLeft = new Panel + { + Dock = DockStyle.Fill, + AutoScroll = true, + BackColor = Color.White + }; + pnlSplit.Controls.Add(pnlLeft); + BuildFormulario(); + } + + // ── FORMULÁRIO ──────────────────────────────────────────────────────── + private void BuildFormulario() + { + var content = new Panel { Width = 800, BackColor = Color.White }; + pnlLeft.Controls.Add(content); + + const int rowH = 52; + const int secH = 28; + const int secGap = 10; + const int inputH = 28; + int y = 10; + + // IDENTIFICAÇÃO + content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO", y)); + y += secH + 4; + + txtId = AddInput(content, "ID", 20, y, 60, inputH, readOnly: true); + txtCodigo = AddInput(content, "Código", 90, y, 120, inputH); + txtCompromisso = AddInput(content, "Compromisso", 220, y, 520, inputH); + y += rowH; + + // DATA E HORA + y += secGap; + content.Controls.Add(CreateSectionHeader("DATA E HORA", y)); + y += secH + 4; + + txtData = AddInput(content, "Data", 20, y, 130, inputH, readOnly: true); + txtDia = AddInput(content, "Dia", 160, y, 150, inputH, readOnly: true); + txtHora = AddInput(content, "Hora", 320, y, 100, inputH); + y += rowH; + + // RESPONSÁVEL E AVISO + y += secGap; + content.Controls.Add(CreateSectionHeader("RESPONSÁVEL E AVISO", y)); + y += secH + 4; + + txtFunc = AddInput(content, "Funcionário", 20, y, 280, inputH); + txtAvisar = AddInput(content, "Avisar", 310, y, 180, inputH); + txtOsVinc = AddInput(content, "OS Vinculada", 500, y, 140, inputH); + y += rowH; + + // SITUAÇÃO + y += secGap; + content.Controls.Add(CreateSectionHeader("SITUAÇÃO", y)); + y += secH + 4; + + chkRealizado = new CheckBox + { + Text = "Realizado", + Location = new Point(20, y + 4), + Font = new Font("Segoe UI", 8.5f, FontStyle.Bold), + ForeColor = TextDark, + AutoSize = true + }; + content.Controls.Add(chkRealizado); + y += rowH; + + // INFORMAÇÕES DO REGISTRO + y += secGap; + content.Controls.Add(CreateSectionHeader("INFORMAÇÕES DO REGISTRO", y)); + y += secH + 4; + + txtCriadoEm = AddInput(content, "Criado Em", 20, y, 175, inputH, readOnly: true); + txtAtualizadoEm = AddInput(content, "Atualizado Em", 205, y, 175, inputH, readOnly: true); + y += rowH; + + content.Height = y + 10; + } + + // ── CALENDÁRIO ──────────────────────────────────────────────────────── + private void BuildCalendario() + { + // 1º Fill — lista de eventos + pnlEventList = new Panel + { + Dock = DockStyle.Fill, + AutoScroll = true, + BackColor = Color.White, + Padding = new Padding(0, 4, 0, 0) + }; + pnlRight.Controls.Add(pnlEventList); + + // 2º Top — grid dos dias + pnlDias = new Panel + { + Dock = DockStyle.Top, + Height = 215, + BackColor = Color.White + }; + pnlRight.Controls.Add(pnlDias); + + // 3º Top — cabeçalho mês/ano + var pnlCalHeader = new Panel + { + Dock = DockStyle.Top, + Height = 38, + BackColor = Color.White + }; + + btnPrev = new Button + { + Text = "‹", + Size = new Size(28, 26), + Location = new Point(0, 6), + FlatStyle = FlatStyle.Flat, + Font = new Font("Segoe UI", 13f), + ForeColor = AccentBlue, + BackColor = Color.White, + Cursor = Cursors.Hand + }; + btnPrev.FlatAppearance.BorderColor = BorderColor; + btnPrev.Click += (_, _) => + { + _currentMonth = _currentMonth.AddMonths(-1); + RenderCalendario(); + RenderListaEventos(); + }; + + btnNext = new Button + { + Text = "›", + Size = new Size(28, 26), + Location = new Point(290, 6), + FlatStyle = FlatStyle.Flat, + Font = new Font("Segoe UI", 13f), + ForeColor = AccentBlue, + BackColor = Color.White, + Cursor = Cursors.Hand + }; + btnNext.FlatAppearance.BorderColor = BorderColor; + btnNext.Click += (_, _) => + { + _currentMonth = _currentMonth.AddMonths(1); + RenderCalendario(); + RenderListaEventos(); + }; + + lblMesAno = new Label + { + AutoSize = false, + TextAlign = ContentAlignment.MiddleCenter, + Font = new Font("Segoe UI", 10f, FontStyle.Bold), + ForeColor = TextDark, + Size = new Size(256, 26), + Location = new Point(32, 6) + }; + + pnlCalHeader.Controls.AddRange(new Control[] { btnPrev, lblMesAno, btnNext }); + pnlRight.Controls.Add(pnlCalHeader); + } + + // ══════════════════════════════════════════════════════════════════════ + // RENDER CALENDÁRIO + // ══════════════════════════════════════════════════════════════════════ + private void RenderCalendario() + { + pnlDias.Controls.Clear(); + + lblMesAno.Text = _currentMonth.ToString("MMMM yyyy", + new System.Globalization.CultureInfo("pt-BR")).ToUpper(); + + string[] dowLabels = { "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb" }; + int cellW = 44; + int cellH = 26; + int startX = 2; + + for (int i = 0; i < 7; i++) + { + pnlDias.Controls.Add(new Label + { + Text = dowLabels[i], + Size = new Size(cellW, 18), + Location = new Point(startX + i * cellW, 0), + TextAlign = ContentAlignment.MiddleCenter, + Font = new Font("Segoe UI", 7.5f, FontStyle.Bold), + ForeColor = MutedGray + }); + } + + int firstDow = (int)new DateTime(_currentMonth.Year, _currentMonth.Month, 1).DayOfWeek; + int daysInMonth = DateTime.DaysInMonth(_currentMonth.Year, _currentMonth.Month); + var datesWithEvts = GetDatesWithEvents(); + DateTime today = DateTime.Today; + int col = firstDow, row = 0; + + for (int d = 1; d <= daysInMonth; d++) + { + var date = new DateTime(_currentMonth.Year, _currentMonth.Month, d); + bool isToday = date == today; + bool isSelected = _selectedDate.HasValue && date == _selectedDate.Value; + bool hasEvent = datesWithEvts.Contains(date.Date); + + var btn = new Button + { + Text = hasEvent ? $"{d} •" : d.ToString(), + Size = new Size(cellW - 2, cellH), + Location = new Point(startX + col * cellW, 22 + row * (cellH + 2)), + FlatStyle = FlatStyle.Flat, + Font = new Font("Segoe UI", 8f, + isToday || isSelected ? FontStyle.Bold : FontStyle.Regular), + Cursor = Cursors.Hand, + Tag = date + }; + + if (isSelected) + { + btn.BackColor = AccentBlue; + btn.ForeColor = Color.White; + btn.FlatAppearance.BorderColor = AccentBlue; + } + else if (isToday) + { + btn.BackColor = Color.White; + btn.ForeColor = AccentBlue; + btn.FlatAppearance.BorderColor = AccentBlue; + } + else + { + btn.BackColor = Color.White; + btn.ForeColor = TextDark; + btn.FlatAppearance.BorderColor = BorderColor; + } + + btn.Click += (s, _) => + { + if (s is Button b && b.Tag is DateTime dt) + { + _selectedDate = dt; + if (txtData.Enabled) + { + txtData.Text = dt.ToString("dd/MM/yyyy"); + txtDia.Text = new System.Globalization.CultureInfo("pt-BR") + .DateTimeFormat.GetDayName(dt.DayOfWeek); + } + RenderCalendario(); + RenderListaEventos(); + } + }; + + pnlDias.Controls.Add(btn); + + col++; + if (col == 7) { col = 0; row++; } + } + } + + // ══════════════════════════════════════════════════════════════════════ + // RENDER LISTA DE EVENTOS + // ══════════════════════════════════════════════════════════════════════ + private void RenderListaEventos() + { + pnlEventList.Controls.Clear(); + + var filtrados = _selectedDate.HasValue + ? _eventos.Where(e => ParseData(e.DDATA).Date == _selectedDate.Value.Date).ToList() + : _eventos.Where(e => ParseData(e.DDATA).Month == _currentMonth.Month + && ParseData(e.DDATA).Year == _currentMonth.Year).ToList(); + + filtrados = filtrados.OrderBy(e => e.HORA).ToList(); + + int listW = pnlEventList.ClientSize.Width > 0 + ? pnlEventList.ClientSize.Width + : pnlRight.Width - pnlRight.Padding.Horizontal - 20; + + int y = 0; + + string titulo = _selectedDate.HasValue + ? $"COMPROMISSOS — {_selectedDate.Value:dd/MM/yyyy}" + : $"COMPROMISSOS — {_currentMonth.ToString("MMMM/yyyy", new System.Globalization.CultureInfo("pt-BR")).ToUpper()}"; + + pnlEventList.Controls.Add(new Label + { + Text = titulo, + AutoSize = false, + Width = listW, + Height = 18, + Location = new Point(0, y), + Font = new Font("Segoe UI", 7.5f, FontStyle.Bold), + ForeColor = MutedGray + }); + y += 6; + + pnlEventList.Controls.Add(new Panel + { + Location = new Point(0, y + 14), + Size = new Size(listW, 1), + BackColor = BorderColor + }); + y += 22; + + if (!filtrados.Any()) + { + pnlEventList.Controls.Add(new Label + { + Text = "Nenhum compromisso encontrado.", + Location = new Point(0, y + 8), + AutoSize = true, + Font = new Font("Segoe UI", 8.5f), + ForeColor = MutedGray + }); + return; + } + + foreach (var ev in filtrados) + { + bool realizado = ev.REALIZADO?.ToUpper() == "S"; + + var card = new Panel + { + Location = new Point(0, y), + Width = listW, + Height = 72, + BackColor = Color.White, + BorderStyle = BorderStyle.None, + Cursor = Cursors.Hand, + Tag = ev + }; + + card.Controls.Add(new Panel + { + Location = new Point(0, 0), + Size = new Size(3, 72), + BackColor = realizado ? GreenColor : AmberColor + }); + + card.Controls.Add(new Label + { + Text = $"{ev.HORA} — {ev.DDATA}", + Location = new Point(10, 5), + AutoSize = true, + Font = new Font("Segoe UI", 7.5f, FontStyle.Bold), + ForeColor = AccentBlue + }); + card.Controls.Add(new Label + { + Text = ev.COMPROMISSO, + Location = new Point(10, 21), + AutoSize = true, + Font = new Font("Segoe UI", 8.5f, FontStyle.Bold), + ForeColor = TextDark + }); + card.Controls.Add(new Label + { + Text = string.IsNullOrWhiteSpace(ev.FUNC) ? "—" : ev.FUNC, + Location = new Point(10, 39), + AutoSize = true, + Font = new Font("Segoe UI", 8f), + ForeColor = MutedGray + }); + card.Controls.Add(new Label + { + Text = realizado ? "✔ Realizado" : "⏳ Pendente", + Location = new Point(10, 55), + AutoSize = true, + Font = new Font("Segoe UI", 7.5f, FontStyle.Bold), + ForeColor = realizado + ? Color.FromArgb(22, 101, 52) + : Color.FromArgb(146, 64, 14) + }); + + card.Paint += (_, pe) => + { + using var pen = new Pen(BorderColor); + pe.Graphics.DrawRectangle(pen, 0, 0, card.Width - 1, card.Height - 1); + }; + + var evLocal = ev; + EventHandler clickHandler = (_, _) => CarregarEvento(evLocal); + card.Click += clickHandler; + foreach (Control child in card.Controls) + child.Click += clickHandler; + + pnlEventList.Controls.Add(card); + y += 78; + } + } + + // ══════════════════════════════════════════════════════════════════════ + // EVENTOS DOS BOTÕES + // ══════════════════════════════════════════════════════════════════════ + private void BtnNovo_Click() + { + LimparCampos(); + SetCampos(true); + txtCriadoEm.Text = DateTime.Now.ToString("dd/MM/yyyy"); + } + + private void BtnAlterar_Click() + { + if (string.IsNullOrWhiteSpace(txtId.Text)) + { + MessageBox.Show("Nenhum registro selecionado para alterar.", + "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; + } + SetCampos(true); + } + + private void BtnExcluir_Click() + { + //BLLAgenda _agendaBLL = new BLLAgenda(_cx); + + //if (string.IsNullOrWhiteSpace(txtId.Text)) + //{ + // NT_MessageBox.Show("Nenhum registro selecionado para excluir.", + // "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning); + // return; + //} + + //var confirm = NT_MessageBox.Show("Confirma a exclusão deste registro?", + // "Confirmar Exclusão", MessageBoxButtons.YesNo, MessageBoxIcon.Question); + + //if (confirm == DialogResult.Yes) + //{ + // int id = int.Parse(txtId.Text); + // bool sucesso = _agendaBLL.Excluir(id); + + // if (!sucesso) + // { + // NT_MessageBox.Show("Erro ao excluir o registro.", + // "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error); + // return; + // } + + // _eventos.Clear(); + // _eventos.AddRange(_agendaBLL.Listar()); + + // LimparCampos(); + // SetCampos(false); + // RenderCalendario(); + // RenderListaEventos(); + + // NT_MessageBox.Show("Registro excluído com sucesso!", + // "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); + //} + } + + private void BtnLocalizar_Click() + { + //FormHelper.Show("Agenda de Compromissos"); + } + + private void BtnSalvar_Click() + { + // BLLAgenda _agendaBLL = new BLLAgenda(_cx); + + // if (string.IsNullOrWhiteSpace(txtData.Text) || + // string.IsNullOrWhiteSpace(txtCompromisso.Text)) + // { + // MessageBox.Show("Preencha ao menos Data e Compromisso.", + // "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning); + // return; + // } + + // bool isNew = string.IsNullOrWhiteSpace(txtId.Text); + + // var agenda = new MLL.ModeloAgenda( + // iD_AGENDA: isNew ? 0 : int.Parse(txtId.Text), + // cODIGO: txtCodigo.Text, + // cOMPROMISSO: txtCompromisso.Text, + // dDATA: txtData.Text, + // aVISAR: txtAvisar.Text, + // fUNC: txtFunc.Text, + // dIA: txtDia.Text, + // hORA: txtHora.Text, + // rEALIZADO: chkRealizado.Checked ? "S" : "N", + // oS_VINC: txtOsVinc.Text + // ); + + // bool sucesso = isNew ? _agendaBLL.Inserir(agenda) : _agendaBLL.Alterar(agenda); + + // if (!sucesso) + // { + // MessageBox.Show("Erro ao salvar no banco de dados.", + // "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error); + // return; + // } + + // _eventos = _agendaBLL.Listar(); + + // txtAtualizadoEm.Text = DateTime.Now.ToString("dd/MM/yyyy"); + // SetCampos(false); + // RenderCalendario(); + // RenderListaEventos(); + + // MessageBox.Show("Registro salvo com sucesso!", "Sucesso", + // MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void BtnCancelar_Click() + { + LimparCampos(); + SetCampos(false); + } + + // ══════════════════════════════════════════════════════════════════════ + // HELPERS + // ══════════════════════════════════════════════════════════════════════ + private void SetCampos(bool enabled) + { + var campos = new[] { txtCodigo, txtCompromisso, txtHora, txtFunc, txtAvisar, txtOsVinc }; + foreach (var c in campos) + { + c.Enabled = enabled; + c.BackColor = enabled ? Color.White : DisabledBack; + } + chkRealizado.Enabled = enabled; + txtData.BackColor = enabled ? Color.FromArgb(239, 246, 255) : DisabledBack; + } + + private void LimparCampos() + { + txtId.Text = txtCodigo.Text = txtCompromisso.Text = string.Empty; + txtData.Text = txtDia.Text = txtHora.Text = string.Empty; + txtFunc.Text = txtAvisar.Text = txtOsVinc.Text = string.Empty; + txtCriadoEm.Text = txtAtualizadoEm.Text = string.Empty; + chkRealizado.Checked = false; + _selectedDate = null; + } + + private void CarregarEvento(MLL.ModeloAgenda ev) + { + txtId.Text = ev.ID_AGENDA.ToString(); + txtCodigo.Text = ev.CODIGO; + txtCompromisso.Text = ev.COMPROMISSO; + txtData.Text = ev.DDATA; + txtDia.Text = ev.DIA; + txtHora.Text = ev.HORA; + txtFunc.Text = ev.FUNC; + txtAvisar.Text = ev.AVISAR; + txtOsVinc.Text = ev.OS_VINC; + txtCriadoEm.Text = ev.DDATA; + txtAtualizadoEm.Text = DateTime.Now.ToString("dd/MM/yyyy"); + chkRealizado.Checked = ev.REALIZADO?.ToUpper() == "S"; + + var dt = ParseData(ev.DDATA); + if (dt != DateTime.MinValue) + { + _selectedDate = dt; + _currentMonth = new DateTime(dt.Year, dt.Month, 1); + } + + SetCampos(false); + RenderCalendario(); + RenderListaEventos(); + } + + private HashSet GetDatesWithEvents() + { + var set = new HashSet(); + foreach (var ev in _eventos) + { + var dt = ParseData(ev.DDATA); + if (dt != DateTime.MinValue) set.Add(dt.Date); + } + return set; + } + + private static DateTime ParseData(string? value) + { + if (string.IsNullOrWhiteSpace(value)) return DateTime.MinValue; + if (DateTime.TryParseExact(value, "dd/MM/yyyy", + System.Globalization.CultureInfo.InvariantCulture, + System.Globalization.DateTimeStyles.None, out var dt)) + return dt; + if (DateTime.TryParse(value, out dt)) return dt; + return DateTime.MinValue; + } + + private void CarregarDadosDoBanco() + { + //BLLAgenda _agendaBLL = new BLLAgenda(_cx); + //_eventos.Clear(); + //_eventos.AddRange(_agendaBLL.Listar()); + } + + private static string DiaSemana(DateTime d) => + new System.Globalization.CultureInfo("pt-BR").DateTimeFormat.GetDayName(d.DayOfWeek); + + // ── UI HELPERS ──────────────────────────────────────────────────────── + private Panel CreateSectionHeader(string title, int y) + { + var pnl = new Panel { Location = new Point(20, y), Width = 760, Height = 26 }; + pnl.Controls.Add(new Label + { + Text = title, + Font = new Font("Segoe UI", 8.5f, FontStyle.Bold), + ForeColor = AccentBlue, + AutoSize = true, + Location = new Point(0, 0) + }); + pnl.Controls.Add(new Panel + { + BackColor = BorderColor, + Height = 1, + Width = 740, + Location = new Point(0, 20) + }); + return pnl; + } + + private LV_TEXTBOX1 AddInput(Control parent, string label, + int x, int y, int width, int height, + bool readOnly = false) + { + parent.Controls.Add(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 LV_TEXTBOX1 + { + Location = new Point(x, y + 16), + Size = new Size(width, height), + BorderColor = readOnly ? Color.FromArgb(203, 213, 225) : BorderColor, + BorderFocusColor = AccentBlue, + ReadOnly = readOnly, + BackColor = readOnly ? DisabledBack : Color.White + }; + + parent.Controls.Add(txt); + return txt; + } + + private LV_BUTTON CreateToolbarButton(string text, Color color) => new LV_BUTTON + { + 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, + BorderRadius = 6 + }; + } +} \ No newline at end of file diff --git a/LevelOS/Cadastros/Empresacadastropanel.cs b/LevelOS/Cadastros/Empresacadastropanel.cs new file mode 100644 index 0000000..f9e3240 --- /dev/null +++ b/LevelOS/Cadastros/Empresacadastropanel.cs @@ -0,0 +1,526 @@ +using BLL; +using CPM; +using CPM.ToggleButton; +using DAL; +using MLL; +using System.Drawing; +using System.Windows.Forms; + +namespace LevelOS.Cadastros +{ + public class EmpresaCadastroPanel : UserControl + { + 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 LV_TEXTBOX1 txtId = null!, txtNome = null!, txtCNPJ = null!; + private LV_TEXTBOX1 txtTipoEmpresa = null!, txtRegimeTributario = null!, txtCNAE = null!; + + // Endereço + private LV_TEXTBOX1 txtCep = null!, txtEndereco = null!, txtNumero = null!, txtComplemento = null!; + private LV_TEXTBOX1 txtBairro = null!, txtCidade = null!, txtUF = null!, txtPais = null!; + + // Contatos + private LV_TEXTBOX1 txtTelefone1 = null!, txtTelefone2 = null!, txtCelular = null!, txtWhatsapp = null!; + private LV_TEXTBOX1 txtEmail = null!, txtSite = null!; + + // Fiscal + private LV_TEXTBOX1 txtInscricaoEstadual = null!, txtInscricaoMunicipal = null!; + + // Contador + private LV_TEXTBOX1 txtCNPJCPF_Contador = null!, txtNome_Contador = null!; + + // Outros + private LV_TEXTBOX1 txtTextoParaRecibo = null!; + private CheckBox chkAtivo = null!; + + // Info (readonly) + private LV_TEXTBOX1 txtCriadoEm = null!, txtAtualizadoEm = null!; + + // Carregar dados da empresa atual, se houver no banco de dados + private void CarregarEmpresaAtiva() + { + //var bll = new BLLEmpresa(_cx); + //var empresa = bll.CarregarEmpresaAtiva(); + + //if (empresa == null) + //{ + // MessageBox.Show("Nenhuma empresa ativa encontrada.", + // "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning); + // return; + //} + + //// Preenche todos os campos do formulário + //txtId.Text = empresa.Id.ToString(); + //txtNome.Text = empresa.Nome; + //txtCNPJ.Text = empresa.CNPJ; + //txtTipoEmpresa.Text = empresa.TipoEmpresa; + //txtRegimeTributario.Text = empresa.RegimeTributario; + //txtCNAE.Text = empresa.CNAE; + //txtInscricaoEstadual.Text = empresa.InscricaoEstadual; + //txtInscricaoMunicipal.Text = empresa.InscricaoMunicipal; + //txtCep.Text = empresa.Cep; + //txtEndereco.Text = empresa.Endereco; + //txtNumero.Text = empresa.Numero.ToString(); + //txtComplemento.Text = empresa.Complemento; + //txtBairro.Text = empresa.Bairro; + //txtCidade.Text = empresa.Cidade; + //txtUF.Text = empresa.UF; + //txtPais.Text = empresa.Pais; + //txtTelefone1.Text = empresa.Telefone1; + //txtTelefone2.Text = empresa.Telefone2; + //txtCelular.Text = empresa.Celular; + //txtWhatsapp.Text = empresa.Whatsapp; + //txtEmail.Text = empresa.Email; + //txtSite.Text = empresa.Site; + //txtCNPJCPF_Contador.Text = empresa.CNPJCPF_Contador; + //txtNome_Contador.Text = empresa.Nome_Contador; + //txtTextoParaRecibo.Text = empresa.TextoParaRecibo; + //chkAtivo.Checked = empresa.Ativo; + //txtCriadoEm.Text = empresa.CriadoEm.ToString("dd/MM/yyyy"); + //txtAtualizadoEm.Text = empresa.AtualizadoEm.ToString("dd/MM/yyyy"); + } + private LV_TOGGLEBUTTON CreateToggle(string text, int x, int y) => new LV_TOGGLEBUTTON + { + Location = new Point(x, y), + Cursor = Cursors.Hand + }; + + public EmpresaCadastroPanel() + { + Dock = DockStyle.Fill; + BackColor = Color.White; + DoubleBuffered = true; + InitializeLayout(); + CarregarEmpresaAtiva(); + } + + 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 btnCancelar = CreateToolbarButton("Cancelar", Color.FromArgb(148, 163, 184)); + var btnCriarCert = CreateToolbarButton("Certificado", Color.FromArgb(148, 160, 184)); + var btnGerarFichaPDF = CreateToolbarButton("Ficha Tecnica", Color.FromArgb(255, 0, 0)); + + 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(); + btnCriarCert.Click += (s, e) => BtnGerarCertificado_Click(); + btnGerarFichaPDF.Click += (s, e) => BtnFicha_Click(); + + flowButtons.Controls.AddRange(new Control[] + { btnNovo, btnAlterar, btnExcluir, btnLocalizar, btnSalvar, btnCancelar, btnCriarCert, btnGerarFichaPDF }); + 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 DA EMPRESA ─────────────────────────────────── + content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO DA EMPRESA", y)); + y += secH + 4; + + txtId = AddInput(content, "ID", 20, y, 60, inputH, readOnly: true); + txtNome = AddInput(content, "Nome / Razão Social", 90, y, 450, inputH); + txtCNPJ = AddInput(content, "CNPJ", 550, y, 180, inputH); + DocumentoHelper.Registrar(txtCNPJ); + txtTipoEmpresa = AddInput(content, "Tipo Empresa", 740, y, 200, inputH); + y += rowH; + + txtRegimeTributario = AddInput(content, "Regime Tributário", 20, y, 200, inputH); + txtCNAE = AddInput(content, "CNAE", 230, y, 150, inputH); + txtInscricaoEstadual = AddInput(content, "Inscrição Estadual", 390, y, 200, inputH); + txtInscricaoMunicipal = AddInput(content, "Inscrição Municipal", 600, y, 200, inputH); + + // ── 2. ENDEREÇO COMPLETO ────────────────────────────────────────── + y += rowH + secGap; + content.Controls.Add(CreateSectionHeader("ENDEREÇO COMPLETO", y)); + y += secH + 4; + + txtCep = AddInput(content, "CEP", 20, y, 95, 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; + // txtPais.Text = "Brasil"; + // txtCep.Text = $"{cep[..5]}-{cep[5..]}"; + // } + // else + // { + // NT_MessageBox.Show("CEP não encontrado.", "CEP", + // MessageBoxButtons.OK, MessageBoxIcon.Warning); + // } + //}; + + txtEndereco = AddInput(content, "Logradouro", 125, y, 370, inputH); + txtNumero = AddInput(content, "Nº", 505, y, 60, inputH); + txtComplemento = AddInput(content, "Complemento", 575, y, 175, inputH); + txtBairro = AddInput(content, "Bairro", 760, y, 180, inputH); + y += rowH; + + txtCidade = AddInput(content, "Cidade", 20, y, 280, inputH); + txtUF = AddInput(content, "UF", 310, y, 55, inputH); + txtPais = AddInput(content, "País", 375, y, 150, inputH); + + // ── 3. CONTATOS E COMUNICAÇÃO ───────────────────────────────────── + y += rowH + secGap; + content.Controls.Add(CreateSectionHeader("CONTATOS E COMUNICAÇÃO", y)); + y += secH + 4; + + txtTelefone1 = AddInput(content, "Telefone 1", 20, y, 155, inputH); + txtTelefone2 = AddInput(content, "Telefone 2", 185, y, 155, inputH); + txtCelular = AddInput(content, "Celular", 350, y, 155, inputH); + txtWhatsapp = AddInput(content, "WhatsApp", 515, y, 155, inputH); + y += rowH; + + txtEmail = AddInput(content, "E-mail", 20, y, 350, inputH); + txtSite = AddInput(content, "Site", 380, y, 290, inputH); + + // ── 4. DADOS DO CONTADOR ────────────────────────────────────────── + y += rowH + secGap; + content.Controls.Add(CreateSectionHeader("DADOS DO CONTADOR", y)); + y += secH + 4; + + txtCNPJCPF_Contador = AddInput(content, "CPF/CNPJ do Contador", 20, y, 200, inputH); + DocumentoHelper.Registrar(txtCNPJCPF_Contador); + txtNome_Contador = AddInput(content, "Nome do Contador", 230, y, 400, inputH); + + // ── 5. OUTROS ───────────────────────────────────────────────────── + y += rowH + secGap; + content.Controls.Add(CreateSectionHeader("OUTROS", y)); + y += secH + 4; + + txtTextoParaRecibo = AddInput(content, "Texto para Recibo", 20, y, 920, inputH); + y += rowH; + //txtTextoParaRecibo.Multiline = true; + + chkAtivo = CreateCheckBox("Ativo", 20, y); + content.Controls.Add(chkAtivo); + + // ── 6. INFORMAÇÕES DO REGISTRO ──────────────────────────────────── + y += 35 + secGap; + content.Controls.Add(CreateSectionHeader("INFORMAÇÕES DO REGISTRO", y)); + y += secH + 4; + + txtCriadoEm = AddInput(content, "Criado Em", 20, y, 175, inputH, readOnly: true); + txtAtualizadoEm = AddInput(content, "Atualizado Em", 205, y, 175, inputH, readOnly: true); + y += rowH; + + content.Height = y + 10; + + SetCampos(false); + } + + // ── CAMPOS ──────────────────────────────────────────────────────────── + + private LV_TEXTBOX1[] TodosOsCampos() => new[] + { + txtNome, txtCNPJ, txtTipoEmpresa, txtRegimeTributario, txtCNAE, + txtInscricaoEstadual, txtInscricaoMunicipal, + txtCep, txtEndereco, txtNumero, txtComplemento, + txtBairro, txtCidade, txtUF, txtPais, + txtTelefone1, txtTelefone2, txtCelular, txtWhatsapp, + txtEmail, txtSite, + txtCNPJCPF_Contador, txtNome_Contador, + txtTextoParaRecibo + }; + + private void SetCampos(bool enabled) + { + foreach (var campo in TodosOsCampos()) + { + campo.Enabled = enabled; + campo.BackColor = enabled ? Color.White : Color.FromArgb(241, 245, 249); + } + chkAtivo.Enabled = enabled; + } + + // ── EVENTOS ─────────────────────────────────────────────────────────── + + private void BtnNovo_Click() + { + foreach (var campo in TodosOsCampos()) + campo.Text = string.Empty; + + chkAtivo.Checked = true; + SetCampos(true); + } + + private void BtnAlterar_Click() + { + if (string.IsNullOrWhiteSpace(txtId.Text)) + { + MessageBox.Show( + "Nenhum registro selecionado para alterar.", + "Atenção", + MessageBoxButtons.OK, + MessageBoxIcon.Warning); + return; + } + + SetCampos(true); + txtId.Enabled = false; + txtId.BackColor = Color.FromArgb(241, 245, 249); + } + + private void BtnFicha_Click() + { + //var bll = new BLLEmpresa(_cx); + //var empresa = bll.CarregarEmpresaAtiva(); + + //if (empresa == null) + //{ + // MessageBox.Show("Nenhuma empresa ativa encontrada."); + // return; + //} + + //var resultado = TLL.FichaEmpresaPDF.GerarEAbrir(empresa); + + //if (!resultado.Sucesso) + // MessageBox.Show(resultado.Mensagem, "Erro", + // MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + private void BtnExcluir_Click() + { + // Solicita confirmação e exclui o registro atual + } + + private void BtnLocalizar_Click() + { + // Abre tela/diálogo de busca e preenche os campos + } + + private void BtnGerarCertificado_Click() + { + //ModeloEmpresa empresa = new ModeloEmpresa(); + //var resultado = TLL.CertificadoHelper.Gerar(empresa, "Nike12122020*##"); + + //if (resultado.Sucesso) + // NT_MessageBox.Show( + // $"Certificado gerado!\nVálido até: {resultado.ValidoAte:dd/MM/yyyy}\n" + + // $"Thumbprint: {resultado.Thumbprint}", + // "Certificado", MessageBoxButtons.OK, MessageBoxIcon.Information); + //else + // NT_MessageBox.Show(resultado.Mensagem, "Erro", + // MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + private void BtnVerificarCert_Click() + { + //ModeloEmpresa empresa = new ModeloEmpresa(); + //var status = TLL.CertificadoHelper.VerificarStatus(empresa.CNPJ, "Nike12122020*##"); + + //if (!status.Valido) + // NT_MessageBox.Show("Certificado expirado! Gere um novo.", + // "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + + private void BtnSalvar_Click() + { + // BLLEmpresa _empresaBLL = new BLLEmpresa(_cx); + + // if (string.IsNullOrWhiteSpace(txtNome.Text) || + // string.IsNullOrWhiteSpace(txtCNPJ.Text) || + // string.IsNullOrWhiteSpace(txtEmail.Text)) + // { + // NT_MessageBox.Show("Preencha ao menos Nome, CNPJ e Email.", + // "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning); + // return; + // } + + // bool isNew = string.IsNullOrWhiteSpace(txtId.Text); + + // var empresa = new MLL.ModeloEmpresa( + // id: isNew ? 0 : int.Parse(txtId.Text), + // nome: txtNome.Text, + // cNPJ: txtCNPJ.Text, + // tipoEmpresa: txtTipoEmpresa.Text, + // regimeTributario: txtRegimeTributario.Text, + // cNAE: txtCNAE.Text, + // cep: txtCep.Text, + // endereco: txtEndereco.Text, + // numero: string.IsNullOrWhiteSpace(txtNumero.Text) ? 0 : int.Parse(txtNumero.Text), + // complemento: txtComplemento.Text, + // bairro: txtBairro.Text, + // cidade: txtCidade.Text, + // uF: txtUF.Text, + // pais: txtPais.Text, + // telefone1: txtTelefone1.Text, + // telefone2: txtTelefone2.Text, + // celular: txtCelular.Text, + // whatsapp: txtWhatsapp.Text, + // email: txtEmail.Text, + // site: txtSite.Text, + // inscricaoEstadual: txtInscricaoEstadual.Text, + // inscricaoMunicipal: txtInscricaoMunicipal.Text, + // cNPJCPF_Contador: txtCNPJCPF_Contador.Text, + // nome_Contador: txtNome_Contador.Text, + // textoParaRecibo: txtTextoParaRecibo.Text, + // ativo: chkAtivo.Checked, + // criadoEm: DateTime.Now, + // atualizadoEm: DateTime.Now + // ); + + // bool sucesso = isNew ? _empresaBLL.Inserir(empresa) : _empresaBLL.Alterar(empresa); + + // if (!sucesso) + // { + // NT_MessageBox.Show("Erro ao salvar empresa.", + // "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error); + // return; + // } + + // txtAtualizadoEm.Text = DateTime.Now.ToString("dd/MM/yyyy"); + // SetCampos(false); + + // NT_MessageBox.Show("Empresa salva com sucesso!", "Sucesso", + // MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void BtnCancelar_Click() + { + foreach (var campo in TodosOsCampos()) + campo.Text = string.Empty; + + chkAtivo.Checked = false; + SetCampos(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 LV_TEXTBOX1 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 LV_TEXTBOX1 + { + Location = new Point(x, y + 16), + Size = new Size(width, height), + BorderColor = readOnly ? Color.FromArgb(203, 213, 225) : BorderColor, + BorderFocusColor = AccentBlue, + ReadOnly = readOnly, + BackColor = readOnly ? Color.FromArgb(241, 245, 249) : Color.White + }; + parent.Controls.Add(lbl); + parent.Controls.Add(txt); + return txt; + } + + 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 Button CreateToolbarButton(string text, Color color) => new Button + { + 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, + FlatStyle = FlatStyle.Flat, + FlatAppearance = { BorderSize = 0 } + }; + } +} \ No newline at end of file diff --git a/LevelOS/Cadastros/Empresacadastropanel.resx b/LevelOS/Cadastros/Empresacadastropanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/LevelOS/Cadastros/Empresacadastropanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/LevelOS/Dashboards/Base/FrmBase.Designer.cs b/LevelOS/Dashboards/Base/FrmBase.Designer.cs index c249143..d202bf5 100644 --- a/LevelOS/Dashboards/Base/FrmBase.Designer.cs +++ b/LevelOS/Dashboards/Base/FrmBase.Designer.cs @@ -28,18 +28,67 @@ /// private void InitializeComponent() { + lvlDashHome = new CPM.LV_BUTTON(); + lV_button1 = new CPM.LV_BUTTON(); SuspendLayout(); // + // lvlDashHome + // + lvlDashHome.BackColor = Color.MediumSlateBlue; + lvlDashHome.BackgroundColor = Color.MediumSlateBlue; + lvlDashHome.BorderColor = Color.PaleVioletRed; + lvlDashHome.BorderRadius = 0; + lvlDashHome.BorderSize = 0; + lvlDashHome.ClickColor = Color.DarkBlue; + lvlDashHome.FlatAppearance.BorderSize = 0; + lvlDashHome.FlatStyle = FlatStyle.Flat; + lvlDashHome.ForeColor = Color.White; + lvlDashHome.HoverColor = Color.LightBlue; + lvlDashHome.Location = new Point(1023, 12); + lvlDashHome.Name = "lvlDashHome"; + lvlDashHome.Size = new Size(150, 40); + lvlDashHome.TabIndex = 0; + lvlDashHome.Text = "Dashboard home"; + lvlDashHome.TextColor = Color.White; + lvlDashHome.UseVisualStyleBackColor = false; + lvlDashHome.Click += lvlDashHome_Click; + // + // lV_button1 + // + lV_button1.BackColor = Color.MediumSlateBlue; + lV_button1.BackgroundColor = Color.MediumSlateBlue; + lV_button1.BorderColor = Color.PaleVioletRed; + lV_button1.BorderRadius = 0; + lV_button1.BorderSize = 0; + lV_button1.ClickColor = Color.DarkBlue; + lV_button1.FlatAppearance.BorderSize = 0; + lV_button1.FlatStyle = FlatStyle.Flat; + lV_button1.ForeColor = Color.White; + lV_button1.HoverColor = Color.LightBlue; + lV_button1.Location = new Point(1023, 58); + lV_button1.Name = "lV_button1"; + lV_button1.Size = new Size(150, 40); + lV_button1.TabIndex = 1; + lV_button1.Text = "MensageBox"; + lV_button1.TextColor = Color.White; + lV_button1.UseVisualStyleBackColor = false; + lV_button1.Click += lV_button1_Click; + // // Form1 // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(1185, 628); + Controls.Add(lV_button1); + Controls.Add(lvlDashHome); Name = "Form1"; Text = "Form1"; ResumeLayout(false); } #endregion + + private CPM.LV_BUTTON lvlDashHome; + private CPM.LV_BUTTON lV_button1; } } diff --git a/LevelOS/Dashboards/Base/FrmBase.cs b/LevelOS/Dashboards/Base/FrmBase.cs index 10e2fb3..9e5e1d5 100644 --- a/LevelOS/Dashboards/Base/FrmBase.cs +++ b/LevelOS/Dashboards/Base/FrmBase.cs @@ -1,3 +1,8 @@ + +using LevelOS.Cadastros; +using ControllsCustom; +using CustomMessageBox; + namespace LevelOS { public partial class Form1 : Form @@ -6,5 +11,16 @@ namespace LevelOS { InitializeComponent(); } + + private void lvlDashHome_Click(object sender, EventArgs e) + { + MainForm main = new MainForm(); + main.ShowDialog(); + } + + private void lV_button1_Click(object sender, EventArgs e) + { + NT_MessageBox.Show("Em desenvolvimento", "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Information); + } } } diff --git a/LevelOS/Dashboards/Home/DashboardPanel.cs b/LevelOS/Dashboards/Home/DashboardPanel.cs new file mode 100644 index 0000000..0be0544 --- /dev/null +++ b/LevelOS/Dashboards/Home/DashboardPanel.cs @@ -0,0 +1,368 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using System.Globalization; +namespace LevelOS +{ + // ═══════════════════════════════════════════════════════════════════════ + // DashboardPanel — painel principal com KPI cards + tabela de OS + // ═══════════════════════════════════════════════════════════════════════ + public class DashboardPanel : UserControl + { + // ── Paleta ───────────────────────────────────────────────────────── + private static readonly Color Surface = Color.FromArgb(255, 255, 255); + private static readonly Color Surface2 = Color.FromArgb(248, 250, 252); + private static readonly Color Border = Color.FromArgb(226, 232, 240); + private static readonly Color TextPri = Color.FromArgb(15, 23, 42); + private static readonly Color TextSec = Color.FromArgb(71, 85, 105); + private static readonly Color TextMuted = Color.FromArgb(148, 163, 184); + + private static readonly Color Blue = Color.FromArgb(37, 99, 235); + private static readonly Color BlueLight = Color.FromArgb(219, 234, 254); + private static readonly Color Green = Color.FromArgb(22, 163, 74); + private static readonly Color GreenL = Color.FromArgb(220, 252, 231); + private static readonly Color Amber = Color.FromArgb(217, 119, 6); + private static readonly Color AmberL = Color.FromArgb(254, 243, 199); + private static readonly Color Red = Color.FromArgb(220, 38, 38); + private static readonly Color RedL = Color.FromArgb(254, 226, 226); + private static readonly Color Orange = Color.FromArgb(234, 88, 12); + private static readonly Color OrangeL = Color.FromArgb(255, 237, 213); + + // ── Dados de OS ──────────────────────────────────────────────────── + private readonly List _ordens = new() + { + new OsRow("#0001", "João Silva", "Notebook Dell", OsStatus.EmAndamento, "07/04"), + new OsRow("#0002", "Maria Souza", "PC Gamer", OsStatus.Concluida, "07/04"), + new OsRow("#0003", "Carlos Mota", "Impressora HP", OsStatus.Aguardando, "08/04"), + new OsRow("#0004", "Ana Lima", "iPhone 14", OsStatus.EmAndamento, "08/04"), + new OsRow("#0005", "Pedro Rocha", "Monitor LG", OsStatus.Pendente, "09/04"), + }; + + // ── KPI cards ────────────────────────────────────────────────────── + // CORRIGIDO: instanciação posicional explícita (sem parâmetros nomeados) + private readonly KpiCard[] _kpis; + + // ── Layout ───────────────────────────────────────────────────────── + private const int Pad = 24; + private const int KpiH = 110; + private const int KpiGap = 14; + private const int CardRad = 10; + private const int TopbarH = 56; + private const int RowH = 38; + + private readonly Font _fLabel; + private readonly Font _fValue; + private readonly Font _fDelta; + private readonly Font _fHead; + private readonly Font _fCell; + private readonly Font _fColHead; + private readonly Font _fMono; + private readonly Font _fBtn; + private readonly Font _fTopTitle; + private readonly Font _fTopSub; + + private Rectangle _btnNovaOS; + private int _hoverRow = -1; + + public DashboardPanel() + { + // CORRIGIDO: inicialização dos campos Font no construtor + // (evita o aviso "campo não anulável precisa conter valor não nulo") + _fLabel = new Font("Segoe UI", 8.5f); + _fValue = new Font("Segoe UI Semibold", 18f); + _fDelta = new Font("Segoe UI", 9f); + _fHead = new Font("Segoe UI Semibold", 10.5f); + _fCell = new Font("Segoe UI", 10f); + _fColHead = new Font("Segoe UI", 8f); + _fMono = new Font("Consolas", 9.5f); + _fBtn = new Font("Segoe UI Semibold", 10f); + _fTopTitle = new Font("Segoe UI Semibold", 13f); + _fTopSub = new Font("Segoe UI", 9f); + + // CORRIGIDO: KpiCard instanciado com construtor posicional explícito + _kpis = new[] + { + new KpiCard("OS Abertas", "12", "↑ 4 essa semana", true, BlueLight, Blue), + new KpiCard("OS Concluídas", "45", "↑ 12% vs mês", true, GreenL, Green), + new KpiCard("Faturamento", "22.5k", "↑ R$ 2.100", true, AmberL, Amber), + new KpiCard("Pendências", "3", "↓ aguardando", false, RedL, Red), + }; + + BackColor = Surface2; + DoubleBuffered = true; + SetStyle(ControlStyles.AllPaintingInWmPaint | + ControlStyles.OptimizedDoubleBuffer | + ControlStyles.ResizeRedraw, true); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _fLabel.Dispose(); _fValue.Dispose(); _fDelta.Dispose(); + _fHead.Dispose(); _fCell.Dispose(); _fColHead.Dispose(); + _fMono.Dispose(); _fBtn.Dispose(); _fTopTitle.Dispose(); + _fTopSub.Dispose(); + } + base.Dispose(disposing); + } + + // ── Paint ────────────────────────────────────────────────────────── + protected override void OnPaint(PaintEventArgs e) + { + var g = e.Graphics; + g.SmoothingMode = SmoothingMode.AntiAlias; + g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; + + DrawTopbar(g); + int y = TopbarH + Pad; + DrawKpiRow(g, y); + y += KpiH + 20; + DrawOsCard(g, y); + } + + // ── Topbar ───────────────────────────────────────────────────────── + private void DrawTopbar(Graphics g) + { + g.FillRectangle(new SolidBrush(Surface), 0, 0, Width, TopbarH); + g.DrawLine(new Pen(Border, 1), 0, TopbarH, Width, TopbarH); + + g.DrawString("Home", _fTopTitle, new SolidBrush(TextPri), Pad, 12); + //g.DrawString("Quinta, 09 de abril de 2026", _fTopSub, + g.DrawString( + DateTime.Now.ToString("dd 'de' MMMM 'de' yyyy", new CultureInfo("pt-BR")), _fTopSub, + new SolidBrush(TextMuted), Pad, 32); + + int bw = 110, bh = 32; + int bx = Width - Pad - bw; + int by = (TopbarH - bh) / 2; + _btnNovaOS = new Rectangle(bx, by, bw, bh); + FillRoundRect(g, new SolidBrush(Blue), _btnNovaOS, 6); + + var sf = new StringFormat + { + Alignment = StringAlignment.Center, + LineAlignment = StringAlignment.Center + }; + g.DrawString("+ Nova OS", _fBtn, new SolidBrush(Color.White), _btnNovaOS, sf); + } + + // ── KPI Row ──────────────────────────────────────────────────────── + private void DrawKpiRow(Graphics g, int y) + { + int totalGap = KpiGap * (_kpis.Length - 1); + int kpiW = (Width - Pad * 2 - totalGap) / _kpis.Length; + + for (int i = 0; i < _kpis.Length; i++) + { + int x = Pad + i * (kpiW + KpiGap); + DrawKpiCard(g, _kpis[i], new Rectangle(x, y, kpiW, KpiH)); + } + } + + private void DrawKpiCard(Graphics g, KpiCard kpi, Rectangle r) + { + FillRoundRect(g, new SolidBrush(Surface), r, CardRad); + DrawRoundBorder(g, r, CardRad, Border); + + int dotSize = 36; + var dotRect = new Rectangle(r.Right - 16 - dotSize, r.Y + 16, dotSize, dotSize); + FillRoundRect(g, new SolidBrush(kpi.DotBg), dotRect, 8); + + g.DrawString(kpi.Label, _fLabel, new SolidBrush(TextMuted), r.X + 16, r.Y + 18); + g.DrawString(kpi.Value, _fValue, new SolidBrush(TextPri), r.X + 14, r.Y + 36); + + var deltaColor = kpi.DeltaUp ? Green : Red; + g.DrawString(kpi.Delta, _fDelta, new SolidBrush(deltaColor), r.X + 16, r.Y + 76); + } + + // ── OS Card ──────────────────────────────────────────────────────── + private void DrawOsCard(Graphics g, int y) + { + string[] cols = { "OS", "Cliente", "Equipamento", "Status", "Data" }; + float[] colW = { 0.08f, 0.22f, 0.28f, 0.22f, 0.10f }; + + int cardH = 28 + RowH + RowH * _ordens.Count + 16; + var card = new Rectangle(Pad, y, Width - Pad * 2, cardH); + + FillRoundRect(g, new SolidBrush(Surface), card, CardRad); + DrawRoundBorder(g, card, CardRad, Border); + + g.DrawString("Ordens de Serviço Recentes", _fHead, + new SolidBrush(TextPri), card.X + 18, card.Y + 16); + + int tableY = card.Y + 44; + g.DrawLine(new Pen(Border, 0.5f), card.X, tableY, card.Right, tableY); + + int cx = card.X; + for (int c = 0; c < cols.Length; c++) + { + int cw = (int)(card.Width * colW[c]); + var sf = new StringFormat { LineAlignment = StringAlignment.Center }; + g.DrawString(cols[c].ToUpperInvariant(), _fColHead, + new SolidBrush(TextMuted), cx + 10, tableY + 2, sf); + cx += cw; + } + + for (int i = 0; i < _ordens.Count; i++) + { + int ry = tableY + RowH + i * RowH; + var row = _ordens[i]; + + if (i == _hoverRow) + g.FillRectangle(new SolidBrush(Surface2), + card.X + 1, ry, card.Width - 2, RowH); + + g.DrawLine(new Pen(Border, 0.5f), card.X, ry, card.Right, ry); + + cx = card.X; + int[] cws = GetColWidths(card.Width, colW); + + g.DrawString(row.OS, _fMono, + new SolidBrush(TextMuted), cx + 10, ry + (RowH - 14) / 2); + cx += cws[0]; + + g.DrawString(row.Cliente, _fCell, + new SolidBrush(TextPri), cx + 8, ry + (RowH - 14) / 2); + cx += cws[1]; + + g.DrawString(row.Equipamento, _fCell, + new SolidBrush(TextSec), cx + 8, ry + (RowH - 14) / 2); + cx += cws[2]; + + DrawBadge(g, row.Status, cx + 8, ry + (RowH - 20) / 2); + cx += cws[3]; + + g.DrawString(row.Data, _fCell, + new SolidBrush(TextMuted), cx + 8, ry + (RowH - 14) / 2); + } + } + + private static int[] GetColWidths(int total, float[] ratios) + { + var ws = new int[ratios.Length]; + for (int i = 0; i < ratios.Length; i++) + ws[i] = (int)(total * ratios[i]); + return ws; + } + + private void DrawBadge(Graphics g, OsStatus status, int x, int y) + { + var (label, bg, fg) = status switch + { + OsStatus.Concluida => ("Concluída", GreenL, Color.FromArgb(22, 101, 52)), + OsStatus.EmAndamento => ("Em andamento", AmberL, Color.FromArgb(146, 64, 14)), + OsStatus.Aguardando => ("Aguardando", BlueLight, Color.FromArgb(30, 64, 175)), + OsStatus.Pendente => ("Pendente", RedL, Color.FromArgb(153, 27, 27)), + _ => ("—", Border, TextMuted) + }; + + var sz = g.MeasureString(label, _fDelta); + int bw = (int)sz.Width + 16; + int bh = 20; + var badge = new Rectangle(x, y, bw, bh); + FillRoundRect(g, new SolidBrush(bg), badge, 10); + + var sf = new StringFormat + { + Alignment = StringAlignment.Center, + LineAlignment = StringAlignment.Center + }; + g.DrawString(label, _fDelta, new SolidBrush(fg), badge, sf); + } + + // ── Mouse ────────────────────────────────────────────────────────── + protected override void OnMouseMove(MouseEventArgs e) + { + int row = HitTestRow(e.Y); + if (row != _hoverRow) { _hoverRow = row; Invalidate(); } + Cursor = _btnNovaOS.Contains(e.Location) ? Cursors.Hand : Cursors.Default; + } + + protected override void OnMouseLeave(EventArgs e) + { + _hoverRow = -1; + Invalidate(); + } + + private int HitTestRow(int mouseY) + { + int tableY = TopbarH + Pad + KpiH + 20 + 44 + RowH; + for (int i = 0; i < _ordens.Count; i++) + { + int ry = tableY + i * RowH; + if (mouseY >= ry && mouseY < ry + RowH) return i; + } + return -1; + } + + // ── GDI Helpers ──────────────────────────────────────────────────── + private static void FillRoundRect(Graphics g, Brush brush, Rectangle r, int radius) + { + using var path = RoundRectPath(r, radius); + g.FillPath(brush, path); + } + + private static void DrawRoundBorder(Graphics g, Rectangle r, int radius, Color color) + { + using var path = RoundRectPath(r, radius); + g.DrawPath(new Pen(color, 0.5f), path); + } + + private static GraphicsPath RoundRectPath(Rectangle r, int radius) + { + var path = new GraphicsPath(); + path.AddArc(r.X, r.Y, radius * 2, radius * 2, 180, 90); + path.AddArc(r.Right - radius * 2, r.Y, radius * 2, radius * 2, 270, 90); + path.AddArc(r.Right - radius * 2, r.Bottom - radius * 2, radius * 2, radius * 2, 0, 90); + path.AddArc(r.X, r.Bottom - radius * 2, radius * 2, radius * 2, 90, 90); + path.CloseFigure(); + return path; + } + + // ── Modelos ──────────────────────────────────────────────────────── + // CORRIGIDO: usando classes simples em vez de records posicionais + // para compatibilidade com qualquer versão do compilador .NET 6+. + private class OsRow + { + public string OS { get; } + public string Cliente { get; } + public string Equipamento { get; } + public OsStatus Status { get; } + public string Data { get; } + + public OsRow(string os, string cliente, string equipamento, OsStatus status, string data) + { + OS = os; + Cliente = cliente; + Equipamento = equipamento; + Status = status; + Data = data; + } + } + + private class KpiCard + { + public string Label { get; } + public string Value { get; } + public string Delta { get; } + public bool DeltaUp { get; } + public Color DotBg { get; } + public Color DotFg { get; } + + public KpiCard(string label, string value, string delta, bool deltaUp, Color dotBg, Color dotFg) + { + Label = label; + Value = value; + Delta = delta; + DeltaUp = deltaUp; + DotBg = dotBg; + DotFg = dotFg; + } + } + + private enum OsStatus { Concluida, EmAndamento, Aguardando, Pendente } + } +} diff --git a/LevelOS/Dashboards/Home/DashboardPanel.resx b/LevelOS/Dashboards/Home/DashboardPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/LevelOS/Dashboards/Home/DashboardPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/LevelOS/Dashboards/Home/MainForm.cs b/LevelOS/Dashboards/Home/MainForm.cs new file mode 100644 index 0000000..9d9d5ba --- /dev/null +++ b/LevelOS/Dashboards/Home/MainForm.cs @@ -0,0 +1,150 @@ +//using CCH; +//using CustomMessageBox; +using DAL; +using System; +using System.Drawing; +using System.Windows.Forms; +//using TLL; +namespace LevelOS.Cadastros +{ + public class MainForm : Form + { + private readonly SidebarControl _sidebar; + private readonly DashboardPanel _dashboard; + + //private readonly ClienteCadastroPanel _pClientes; + private readonly EmpresaCadastroPanel _pEmpresa; + //private readonly EmpresaConfiguracoesPanel _pEmpresaConfig; + private readonly AgendaCadastroPanel _pAgendaCadastro; + //private readonly AgendaConsultaPanel _pAgendaConsulta; + //private readonly FuncionariosCadastroPanel _pfuncionariosCadastro ; + private readonly Panel _pOrdens; + private readonly Panel _pProdutos; + private readonly Panel _pEstoque; + private readonly Panel _pFinanceiro; + + public MainForm() + { + Text = "LevelOS — Sistema ERP"; + this.WindowState = FormWindowState.Maximized; + this.MinimumSize = new Size(1100, 750); + this.BackColor = Color.FromArgb(248, 250, 252); + + _sidebar = new SidebarControl { Dock = DockStyle.Left }; + _sidebar.NavItemClicked += OnNavItemClicked; + + _dashboard = new DashboardPanel { Dock = DockStyle.Fill }; + + //_pClientes = new ClienteCadastroPanel { Dock = DockStyle.Fill, Visible = false }; + _pEmpresa = new EmpresaCadastroPanel { Dock = DockStyle.Fill, Visible = false }; + //_pEmpresaConfig = new EmpresaConfiguracoesPanel { Dock = DockStyle.Fill, Visible = false }; + _pAgendaCadastro = new AgendaCadastroPanel { Dock = DockStyle.Fill, Visible = false }; + //_pAgendaConsulta = new AgendaConsultaPanel { Dock = DockStyle.Fill, Visible = false }; + //_pfuncionariosCadastro = new FuncionariosCadastroPanel { Dock = DockStyle.Fill, Visible = false }; + _pOrdens = PlaceholderPanel("Ordens de Serviço", Color.FromArgb(22, 163, 74)); + _pProdutos = PlaceholderPanel("Catálogo de Produtos", Color.FromArgb(217, 119, 6)); + _pEstoque = PlaceholderPanel("Controle de Estoque", Color.FromArgb(234, 88, 12)); + _pFinanceiro = PlaceholderPanel("Fluxo Financeiro", Color.FromArgb(124, 58, 237)); + + var mainContainer = new Panel { Dock = DockStyle.Fill }; + mainContainer.Controls.Add(_pFinanceiro); + mainContainer.Controls.Add(_pAgendaCadastro); + //mainContainer.Controls.Add(_pAgendaConsulta); + mainContainer.Controls.Add(_pEstoque); + mainContainer.Controls.Add(_pProdutos); + mainContainer.Controls.Add(_pOrdens); + mainContainer.Controls.Add(_pEmpresa); + //mainContainer.Controls.Add(_pEmpresaConfig); + //mainContainer.Controls.Add(_pClientes); + mainContainer.Controls.Add(_dashboard); + //mainContainer.Controls.Add(_pfuncionariosCadastro); + + Controls.Add(mainContainer); + Controls.Add(_sidebar); + + ShowPanel(_dashboard); + + } + + private void OnNavItemClicked(object? sender, int index) + { + /* Índices: + 0 = Dashboard + 2 = Ordens de Serviço + 4 = Produtos + 5 = Estoque + 9 = Financeiro + 99 = Submenu → Clientes + 98 = Submenu → Empresa + */ + switch (index) + { + case 0: ShowPanel(_dashboard); break; + case 2: ShowPanel(_pOrdens); break; + case 4: ShowPanel(_pProdutos); break; + case 5: ShowPanel(_pEstoque); break; + case 9: ShowPanel(_pFinanceiro); break; + case 27: ShowPanel(_pEmpresa); break; + case 30: ShowPanel(_pAgendaCadastro); break; + + //case 99: ShowPanel(_pClientes); break; + //case 103: ShowPanel(_pfuncionariosCadastro); break; + //case 106: ShowPanel(_pEmpresa); break; + + + //case 202: ShowPanel(_pEmpresaConfig); break; + // + //case 301: ShowPanel(_pAgendaConsulta); break; + + + } + } + + private void ShowPanel(Control panelToShow) + { + _dashboard.Visible = (panelToShow == _dashboard); + //_pClientes.Visible = (panelToShow == _pClientes); + _pEmpresa.Visible = (panelToShow == _pEmpresa); + //_pEmpresaConfig.Visible = (panelToShow == _pEmpresaConfig); + _pOrdens.Visible = (panelToShow == _pOrdens); + _pProdutos.Visible = (panelToShow == _pProdutos); + _pEstoque.Visible = (panelToShow == _pEstoque); + _pFinanceiro.Visible = (panelToShow == _pFinanceiro); + _pAgendaCadastro.Visible = (panelToShow == _pAgendaCadastro); + //_pAgendaConsulta.Visible = (panelToShow == _pAgendaConsulta); + //_pfuncionariosCadastro.Visible = (panelToShow == _pfuncionariosCadastro); + + if (panelToShow.Visible) + { + panelToShow.BringToFront(); + panelToShow.Focus(); + } + } + + private static Panel PlaceholderPanel(string titulo, Color cor) + { + var p = new Panel { Dock = DockStyle.Fill, Visible = false }; + p.Paint += (s, e) => + { + var g = e.Graphics; + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + var r = p.ClientRectangle; + g.Clear(Color.FromArgb(248, 250, 252)); + + var circle = new Rectangle(r.Width / 2 - 40, r.Height / 2 - 80, 80, 80); + g.FillEllipse(new SolidBrush(Color.FromArgb(20, cor)), circle); + + using var f1 = new Font("Segoe UI Semibold", 16f); + using var f2 = new Font("Segoe UI", 10f); + var sf = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }; + + g.DrawString(titulo, f1, new SolidBrush(Color.FromArgb(30, 41, 59)), + new RectangleF(0, r.Height / 2f - 10, r.Width, 40), sf); + + g.DrawString("Este módulo está sendo integrado ao LevelOS", f2, new SolidBrush(Color.FromArgb(148, 163, 184)), + new RectangleF(0, r.Height / 2f + 25, r.Width, 30), sf); + }; + return p; + } + } +} \ No newline at end of file diff --git a/LevelOS/Dashboards/Home/MainForm.resx b/LevelOS/Dashboards/Home/MainForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/LevelOS/Dashboards/Home/MainForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/LevelOS/Dashboards/Home/SidebarControl.cs b/LevelOS/Dashboards/Home/SidebarControl.cs new file mode 100644 index 0000000..db91326 --- /dev/null +++ b/LevelOS/Dashboards/Home/SidebarControl.cs @@ -0,0 +1,421 @@ +using DAL; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace LevelOS.Cadastros +{ + public class SidebarControl : UserControl + { + //Recebendo a conexao + string _cx = DadosDaConexao.ObterConexao(); + + // ── Cores do Tema LevelOS ────────────────────────────────────────── + private static readonly Color NavyDark = Color.FromArgb(15, 30, 60); + private static readonly Color NavyMid = Color.FromArgb(26, 45, 80); + private static readonly Color AccentBlue = Color.FromArgb(37, 99, 235); + private static readonly Color TextLight = Color.FromArgb(255, 255, 255); + private static readonly Color TextMuted = Color.FromArgb(148, 163, 184); + private static readonly Color Divider = Color.FromArgb(40, 255, 255, 255); + + // ── Estado e Escalonamento (DPI) ─────────────────────────────────── + private float _scale = 1.0f; + private int _activeIndex = 0; + private int _hoverIndex = -1; + + // Propriedades Scaled (Ajustam-se ao monitor) + private int ScaledWidth => (int)(220 * _scale); + private int ScaledLogoH => (int)(55 * _scale); + private int ScaledSectionH => (int)(32 * _scale); + private int ScaledItemH => (int)(40 * _scale); + private int ScaledItemPadX => (int)(12 * _scale); + private int ScaledFooterH => (int)(50 * _scale); + private int ScaledIconSize => (int)(16 * _scale); + + // ── Submenus ─────────────────────────────────────────────────────── + private ContextMenuStrip _subMenuBanco, _subMenuConfiguracao, + _subMenuAjuda, _subMenuOrdemServico, _subMenuFinanceiro,_subMenuCadastro, _subMenuAgenda; + + public string UserName = "Levelcode", UserFunction = "Administrador"; + public event EventHandler? NavItemClicked; + + private readonly List _items = new() + { + new NavItem("Dashboard", SvgIcon.Grid, "Principal", null), + new NavItem("Cadastro", SvgIcon.UserPlus, null, "3"), + new NavItem("Ordens de Serviço", SvgIcon.FileText, null, "12"), + new NavItem("Agenda", SvgIcon.Calendar, null, null), + new NavItem("Produtos", SvgIcon.Package, "Gestão", null), + new NavItem("Estoque", SvgIcon.Inventory, null, null), + //new NavItem("Serviços", SvgIcon.Briefcase, null, null), + //new NavItem("Transportadoras", SvgIcon.Truck, null, null), + new NavItem("Financeiro", SvgIcon.DollarSign, null, null), + new NavItem("Banco de Dados", SvgIcon.Database, "Sistema", null), + new NavItem("Configurações", SvgIcon.Settings, null, null), + new NavItem("Suporte Técnico", SvgIcon.Support, "Ajuda", null), + }; + + public void backupFull(string conexao) + { + //var backupService = new DALLBackupService(conexao); + //var resultadoFull = backupService.ExecutarBackupFull(); + + //if (resultadoFull.Sucesso) + // NT_MessageBox.Show($"✅ Backup FULL concluído em {resultadoFull.Duracao.TotalSeconds:F1}s","Backup do banco de dados",MessageBoxButtons.OK, MessageBoxIcon.Information); + //else + // NT_MessageBox.Show($"❌ Erro no Backup FULL: {resultadoFull.Erro}","Erro ao tentar executar backup do sistema.",MessageBoxButtons.OK,MessageBoxIcon.Error); + }//Criar backup full + + public void backupDifrencial(string conexao) + { + //var backupService = new DALLBackupService(conexao); + //var resultadoDiff = backupService.ExecutarBackupDiferencial(); + + //if (resultadoDiff.Sucesso) + // NT_MessageBox.Show($"✅ Backup DIFERENCIAL concluído em {resultadoDiff.Duracao.TotalSeconds:F1}s","Backup diferencial concluido", MessageBoxButtons.OK, MessageBoxIcon.Information); + //else + // NT_MessageBox.Show($"❌ Erro no Backup DIFERENCIAL: {resultadoDiff.Erro}","Erro ao tentar executar backup diferencial no sistema", MessageBoxButtons.OK, MessageBoxIcon.Error); + }//Criar backup diferencial + + + + public SidebarControl() + { + BackColor = NavyDark; + DoubleBuffered = true; + this.SetStyle(ControlStyles.ResizeRedraw, true); + } + + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + using (Graphics g = this.CreateGraphics()) { _scale = g.DpiX / 96f; } + this.Width = ScaledWidth; + SetupSubMenus(); + } + + private void SetupSubMenus() + { + //Submenu Cadastro + _subMenuCadastro = CreateStyledMenu(); + _subMenuCadastro.Items.Add("👤 Clientes", null, (s, e) => {NavItemClicked?.Invoke(this, 20);}); + _subMenuCadastro.Items.Add("💻 Equipamentos", null, (s, e) => { NavItemClicked?.Invoke(this, 21); }); + _subMenuCadastro.Items.Add("📜 Contratos", null, (s, e) => { NavItemClicked?.Invoke(this, 22); }); + _subMenuCadastro.Items.Add("🏭 Fornecedores", null, (s, e) => { NavItemClicked?.Invoke(this, 23); }); + _subMenuCadastro.Items.Add("👔 Funcionários", null, (s, e) => { NavItemClicked?.Invoke(this, 24); }); + _subMenuCadastro.Items.Add("🚚 Transportadoras", null, (s, e) => { NavItemClicked?.Invoke(this, 25); }); + _subMenuCadastro.Items.Add("🛠️ Serviços", null, (s, e) => { NavItemClicked?.Invoke(this, 26); }); + _subMenuCadastro.Items.Add("🏢 Empresa", null, (s, e) => { NavItemClicked?.Invoke(this, 27); }); + _subMenuCadastro.Items.Add("🔑 Usuários do Sistema", null, (s, e) => { NavItemClicked?.Invoke(this, 28); }); + + _subMenuBanco = CreateStyledMenu(); + _subMenuBanco.Items.Add("⚙️ Configuração Database", null, (s, e) => showForms
()); // Substitua pelo seu Form + _subMenuBanco.Items.Add("💾 Backup de Dados (FULL)", null, (s, e) => backupFull(this._cx)); + _subMenuBanco.Items.Add("⚡ Backup de Dados (DIFF)", null, (s, e) => backupDifrencial(this._cx)); + _subMenuBanco.Items.Add("🔄 Restaurar Banco"); + + + //submenu Configurações + _subMenuConfiguracao = CreateStyledMenu(); + _subMenuConfiguracao.Items.Add("🖼️ Personalização de OS"); + _subMenuConfiguracao.Items.Add("🖥️ Personalização de Sistema"); + _subMenuConfiguracao.Items.Add(" Configuração Empresa", null, (s, e) => { NavItemClicked?.Invoke(this, 202); }); + _subMenuConfiguracao.Items.Add(new ToolStripSeparator()); + _subMenuConfiguracao.Items.Add("📂 FTP-Cliente"); // Pasta para arquivos + _subMenuConfiguracao.Items.Add("💬 Telegram-Cliente"); // Balão de conversa + _subMenuConfiguracao.Items.Add("📩 SMTP-Cliente"); // Envelope de saída + _subMenuConfiguracao.Items.Add(new ToolStripSeparator()); + // Automação + _subMenuConfiguracao.Items.Add("⏰ Backups Automáticos"); // Relógio para agendamento + _subMenuConfiguracao.Items.Add("☁️ Backup em Nuvem"); + + _subMenuAjuda = CreateStyledMenu(); + _subMenuAjuda.Items.Add("💬 Atendimento Online"); + _subMenuAjuda.Items.Add("📖 Manual do Sistema"); + + _subMenuOrdemServico = CreateStyledMenu(); + + _subMenuOrdemServico.Items.Add("✚ Abrir nova O.S", null, (s, e) => { /* Lógica */ }); + _subMenuOrdemServico.Items.Add("✎ Alterar O.S", null, (s, e) => { /* Lógica */ }); + _subMenuOrdemServico.Items.Add("🔒 Encerrar O.S", null, (s, e) => { /* Lógica */ }); + _subMenuOrdemServico.Items.Add("🔍 Localizar O.S", null, (s, e) => { /* Lógica */ }); + _subMenuOrdemServico.Items.Add("📋 Orçamento de O.S", null, (s, e) => { /* Lógica */ }); + _subMenuOrdemServico.Items.Add("📜 Histórico de O.S", null, (s, e) => { /* Lógica */ }); + _subMenuOrdemServico.Items.Add("📊 Relatório de O.S", null, (s, e) => { /* Lógica */ }); + _subMenuOrdemServico.Items.Add("🖨 Imprimir", null, (s, e) => { /* Lógica */ }); + _subMenuOrdemServico.Items.Add("⚠️ Chamado Técnico", null, (s, e) => { /* Lógica */ }); + _subMenuOrdemServico.Items.Add("🌐 OS WEB", null, (s, e) => { /* Lógica */ }); + _subMenuOrdemServico.Items.Add("🔓 Reabrir OS", null, (s, e) => { /* Lógica */ }); + + _subMenuFinanceiro = CreateStyledMenu(); + + _subMenuFinanceiro.Items.Add("💳 Contas", null, (s, e) => { /* Lógica */ }); + _subMenuFinanceiro.Items.Add("📈 Contas a receber", null, (s, e) => { /* Lógica */ }); + _subMenuFinanceiro.Items.Add("📉 Contas a pagar", null, (s, e) => { /* Lógica */ }); + _subMenuFinanceiro.Items.Add(new ToolStripSeparator()); // Linha divisória + _subMenuFinanceiro.Items.Add("🛒 Compras", null, (s, e) => { /* Lógica */ }); + _subMenuFinanceiro.Items.Add("💰 Vendas", null, (s, e) => { /* Lógica */ }); + _subMenuFinanceiro.Items.Add("🧾 Notas Fiscais", null, (s, e) => { /* Lógica */ }); + _subMenuFinanceiro.Items.Add(new ToolStripSeparator()); // Linha divisória + _subMenuFinanceiro.Items.Add("📂 Arquivo Contador", null, (s, e) => { /* Lógica */ }); + _subMenuFinanceiro.Items.Add("🏦 Dados Bancários", null, (s, e) => { /* Lógica */ }); + _subMenuFinanceiro.Items.Add("🕒 Histórico Financeiro", null, (s, e) => { /* Lógica */ }); + + + // private ContextMenuStrip _subMenuAgenda; + _subMenuAgenda = CreateStyledMenu(); + //_subMenuAgenda.Items.Add("➕ Novo compromisso", null, (s, e) => {showForms();}); + _subMenuAgenda.Items.Add("➕ Novo compromisso", null, (s, e) => { NavItemClicked?.Invoke(this, 30); }); + _subMenuAgenda.Items.Add("🔍 Consultar compromissos", null, (s, e) => { NavItemClicked?.Invoke(this, 31); }); + _subMenuAgenda.Items.Add("✏️ Alterar compromisso", null, (s, e) => { /* Lógica de edição */ }); + _subMenuAgenda.Items.Add("🖨️ Imprimir", null, (s, e) => { /* Lógica de relatório */ }); + } + + private ContextMenuStrip CreateStyledMenu() + { + return new ContextMenuStrip + { + BackColor = NavyMid, + ForeColor = TextLight, + ShowImageMargin = false, + Font = new Font("Segoe UI", 10f * _scale), + Renderer = new ToolStripProfessionalRenderer(new SubMenuColorTable()) + }; + } + + private void showForms() where T : Form, new() + { + using (T form = new T()) + { + form.StartPosition = FormStartPosition.CenterScreen; + form.ShowDialog(); + } + } + //Abrir agenda + // AgendaForm.cs + public class AgendaForm : Form + { + //public AgendaForm() + //{ + // Text = "Agenda de Compromissos"; + // Size = new Size(1150, 780); + // StartPosition = FormStartPosition.CenterScreen; + // BackColor = Color.White; + + // var panel = new AgendaCadastroPanel(); + // Controls.Add(panel); + //} + }//abrir agenda de compromissos + + protected override void OnPaint(PaintEventArgs e) + { + var g = e.Graphics; + g.SmoothingMode = SmoothingMode.AntiAlias; + g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; + + DrawLogo(g); + DrawNavItems(g, ScaledLogoH + (int)(8 * _scale)); + DrawFooter(g); + } + + private void DrawNavItems(Graphics g, int startY) + { + int y = startY; + using var fSection = new Font("Segoe UI", 8f * _scale, FontStyle.Bold); + using var fItem = new Font("Segoe UI", 10f * _scale); + using var fItemSel = new Font("Segoe UI Semibold", 10f * _scale); + + for (int i = 0; i < _items.Count; i++) + { + var item = _items[i]; + if (item.Section != null) + { + y += (int)(10 * _scale); + g.DrawString(item.Section.ToUpper(), fSection, new SolidBrush(Color.FromArgb(120, TextMuted)), ScaledItemPadX + (int)(8 * _scale), y); + y += ScaledSectionH; + } + + bool isActive = (i == _activeIndex); + bool isHover = (i == _hoverIndex && !isActive); + var itemRect = new Rectangle(ScaledItemPadX, y, Width - ScaledItemPadX * 2, ScaledItemH); + + if (isActive) FillRoundRect(g, new SolidBrush(AccentBlue), itemRect, (int)(6 * _scale)); + else if (isHover) FillRoundRect(g, new SolidBrush(Color.FromArgb(20, 255, 255, 255)), itemRect, (int)(6 * _scale)); + + var color = isActive ? TextLight : Color.FromArgb(200, TextLight); + DrawIcon(g, item.Icon, ScaledItemPadX + (int)(10 * _scale), y + (ScaledItemH - ScaledIconSize) / 2, ScaledIconSize, color); + g.DrawString(item.Label, isActive ? fItemSel : fItem, new SolidBrush(color), ScaledItemPadX + (int)(36 * _scale), y + (ScaledItemH - (int)(16 * _scale)) / 2); + + if (HasSubMenu(item.Label)) + g.DrawString("›", fItem, new SolidBrush(Color.FromArgb(100, TextLight)), Width - (int)(30 * _scale), y + (ScaledItemH - (int)(18 * _scale)) / 2); + + y += ScaledItemH + (int)(2 * _scale); + } + } + + // Adicione "Cadastro" na verificação + private bool HasSubMenu(string label) => + label == "Cadastro" || // <-- Adicionado aqui + label == "Banco de Dados" || + label == "Financeiro" || + label == "Ordens de Serviço" || + label == "Configurações" || + label == "Suporte Técnico" || + label == "Agenda" + ; + + protected override void OnMouseClick(MouseEventArgs e) + { + int hit = HitTest(e.Y); + if (hit >= 0) + { + _activeIndex = hit; Invalidate(); + string label = _items[hit].Label; + Point menuPos = new Point(Width + 2, e.Y - (int)(15 * _scale)); + + if (label == "Banco de Dados") _subMenuBanco.Show(this, menuPos); + else if (label == "Financeiro") _subMenuFinanceiro.Show(this, menuPos); + else if(label == "Agenda") _subMenuAgenda.Show(this, menuPos); + else if (label == "Ordens de Serviço") _subMenuOrdemServico.Show(this, menuPos); + else if (label == "Configurações") _subMenuConfiguracao.Show(this, menuPos); + else if (label == "Suporte Técnico") _subMenuAjuda.Show(this, menuPos); + else if (label == "Cadastro") _subMenuCadastro.Show(this, menuPos); + else NavItemClicked?.Invoke(this, hit); + } + } + + private int HitTest(int mouseY) + { + int y = ScaledLogoH + (int)(8 * _scale); + for (int i = 0; i < _items.Count; i++) + { + if (_items[i].Section != null) y += (int)(10 * _scale) + ScaledSectionH; + if (mouseY >= y && mouseY < y + ScaledItemH) return i; + y += ScaledItemH + (int)(2 * _scale); + } + return -1; + } + + protected override void OnMouseMove(MouseEventArgs e) { int hit = HitTest(e.Y); if (hit != _hoverIndex) { _hoverIndex = hit; Invalidate(); } } + protected override void OnMouseLeave(EventArgs e) { _hoverIndex = -1; Invalidate(); } + + private void DrawLogo(Graphics g) + { + var iconRect = new Rectangle((int)(16 * _scale), (int)(18 * _scale), (int)(34 * _scale), (int)(34 * _scale)); + FillRoundRect(g, new SolidBrush(AccentBlue), iconRect, (int)(8 * _scale)); + using var fIcon = new Font("Segoe UI", 14f * _scale, FontStyle.Bold); + DrawCenteredString(g, "S", fIcon, TextLight, iconRect); + g.DrawString("LevelOS", new Font("Segoe UI Semibold", 13f * _scale), new SolidBrush(TextLight), 58 * _scale, 20 * _scale); + g.DrawString("SISTEMA ERP", new Font("Segoe UI", 8f * _scale), new SolidBrush(TextMuted), 59 * _scale, 38 * _scale); + g.DrawLine(new Pen(Divider), 0, ScaledLogoH, Width, ScaledLogoH); + } + + private void DrawFooter(Graphics g) + { + int fy = Height - ScaledFooterH; + g.DrawLine(new Pen(Divider), 0, fy, Width, fy); + var avRect = new Rectangle((int)(16 * _scale), fy + (int)(14 * _scale), (int)(32 * _scale), (int)(32 * _scale)); + g.FillEllipse(new SolidBrush(AccentBlue), avRect); + DrawCenteredString(g, "AD", new Font("Segoe UI Semibold", 10f * _scale), TextLight, avRect); + g.DrawString(UserName, new Font("Segoe UI Semibold", 11f * _scale), new SolidBrush(TextLight), 56 * _scale, fy + (14 * _scale)); + g.DrawString(UserFunction, new Font("Segoe UI", 9f * _scale), new SolidBrush(TextMuted), 57 * _scale, fy + (30 * _scale)); + } + + // ── MOTOR DE ÍCONES COMPLETO (GDI+) ──────────────────────────────── + private void DrawIcon(Graphics g, SvgIcon icon, int x, int y, int size, Color color) + { + using var p = new Pen(color, 1.6f * _scale) { StartCap = LineCap.Round, EndCap = LineCap.Round, LineJoin = LineJoin.Round }; + float s = size / 24f; + g.TranslateTransform(x, y); g.ScaleTransform(s, s); + + switch (icon) + { + case SvgIcon.Grid: + g.DrawRectangle(p, 3, 3, 7, 7); g.DrawRectangle(p, 14, 3, 7, 7); g.DrawRectangle(p, 3, 14, 7, 7); g.DrawRectangle(p, 14, 14, 7, 7); break; + case SvgIcon.Users: + g.DrawEllipse(p, 5, 3, 8, 8); g.DrawArc(p, 2, 13, 14, 8, 180, 180); g.DrawArc(p, 15, 8, 6, 6, 270, 180); break; + case SvgIcon.FileText: + g.DrawLines(p, new PointF[] { new(6, 2), new(6, 22), new(18, 22), new(18, 8), new(14, 2), new(6, 2) }); g.DrawLine(p, 14, 2, 14, 8); g.DrawLine(p, 14, 8, 18, 8); break; + case SvgIcon.Package: + g.DrawLines(p, new PointF[] { new(12, 2), new(2, 7), new(12, 12), new(22, 7), new(12, 2) }); g.DrawLine(p, 2, 7, 2, 17); g.DrawLine(p, 22, 7, 22, 17); g.DrawLine(p, 12, 12, 12, 22); break; + case SvgIcon.DollarSign: + g.DrawLine(p, 12, 2, 12, 22); g.DrawArc(p, 7, 5, 10, 7, 110, 250); g.DrawArc(p, 7, 12, 10, 7, 270, 250); break; + case SvgIcon.Database: + g.DrawEllipse(p, 4, 3, 16, 6); g.DrawLine(p, 4, 6, 4, 18); g.DrawLine(p, 20, 6, 20, 18); g.DrawArc(p, 4, 15, 16, 6, 0, 180); break; + case SvgIcon.Calendar: + g.DrawRectangle(p, 3, 4, 18, 17); g.DrawLine(p, 3, 9, 21, 9); g.DrawLine(p, 8, 2, 8, 6); g.DrawLine(p, 16, 2, 16, 6); break; + case SvgIcon.Truck: + g.DrawRectangle(p, 1, 5, 13, 11); g.DrawLines(p, new PointF[] { new(14, 16), new(14, 8), new(19, 8), new(23, 12), new(23, 16) }); + g.DrawEllipse(p, 3, 15, 4, 4); g.DrawEllipse(p, 17, 15, 4, 4); break; + case SvgIcon.Factory: + g.DrawRectangle(p, 2, 10, 20, 11); g.DrawLines(p, new PointF[] { new(2, 10), new(2, 5), new(8, 10), new(8, 5), new(14, 10) }); break; + case SvgIcon.Briefcase: + g.DrawRectangle(p, 3, 7, 18, 13); g.DrawArc(p, 9, 3, 6, 8, 180, 180); break; + case SvgIcon.Support: + g.DrawArc(p, 4, 4, 16, 16, 180, 180); g.DrawRectangle(p, 3, 13, 3, 5); g.DrawRectangle(p, 18, 13, 3, 5); break; + case SvgIcon.Inventory: + g.DrawRectangle(p, 3, 3, 18, 8); g.DrawRectangle(p, 3, 13, 18, 8); break; + case SvgIcon.Settings: + g.DrawEllipse(p, 9, 9, 6, 6); + for (int a = 0; a < 360; a += 45) + { + float r = a * (float)Math.PI / 180f; + g.DrawLine(p, 12 + (float)Math.Cos(r) * 8, 12 + (float)Math.Sin(r) * 8, 12 + (float)Math.Cos(r) * 11, 12 + (float)Math.Sin(r) * 11); + } + break; + case SvgIcon.User: g.DrawEllipse(p, 8, 2, 8, 8); g.DrawArc(p, 3, 14, 18, 8, 180, 180); break; + case SvgIcon.UserCheck: g.DrawEllipse(p, 8, 3, 8, 8); g.DrawArc(p, 3, 14, 18, 8, 180, 180); g.DrawRectangle(p, 10, 15, 4, 3); break; + case SvgIcon.UserPlus: + // Desenha o corpo do usuário (círculo e arco) + g.DrawEllipse(p, 4, 4, 8, 8); // Cabeça + g.DrawArc(p, 1, 14, 14, 8, 180, 180); // Ombros + + // Desenha o sinal de "+" ao lado + // Vertical + g.DrawLine(p, 19, 7, 19, 15); + // Horizontal + g.DrawLine(p, 15, 11, 23, 11); + break; + + + } + g.ResetTransform(); + } + + // ── Helpers ── + private static void FillRoundRect(Graphics g, Brush b, Rectangle r, int rad) { using var path = RoundRectPath(r, rad); g.FillPath(b, path); } + private static GraphicsPath RoundRectPath(Rectangle r, int rad) + { + var path = new GraphicsPath(); int d = Math.Max(rad * 2, 1); + path.AddArc(r.X, r.Y, d, d, 180, 90); path.AddArc(r.Right - d, r.Y, d, d, 270, 90); + path.AddArc(r.Right - d, r.Bottom - d, d, d, 0, 90); path.AddArc(r.X, r.Bottom - d, d, d, 90, 90); + path.CloseFigure(); return path; + } + private static void DrawCenteredString(Graphics g, string t, Font f, Color c, Rectangle r) + { + var sf = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }; + g.DrawString(t, f, new SolidBrush(c), r, sf); + } + + private class NavItem + { + public string Label { get; } + public SvgIcon Icon { get; } + public string? Section { get; } + public string? Badge { get; } + public NavItem(string l, SvgIcon i, string? s, string? b) { Label = l; Icon = i; Section = s; Badge = b; } + } + private class SubMenuColorTable : ProfessionalColorTable + { + public override Color ToolStripDropDownBackground => NavyMid; + public override Color MenuItemSelected => AccentBlue; + public override Color MenuItemBorder => Color.Transparent; + public override Color MenuItemSelectedGradientBegin => AccentBlue; + public override Color MenuItemSelectedGradientEnd => AccentBlue; + } + } + + public enum SvgIcon { Grid, Users, FileText, Package, DollarSign, User, Settings, Database, Truck, Factory, UserCheck, Briefcase, Support, Inventory, Wallet, ShoppingCart, ShoppingBag, Calendar , UserPlus} +} \ No newline at end of file diff --git a/LevelOS/Dashboards/Home/SidebarControl.resx b/LevelOS/Dashboards/Home/SidebarControl.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/LevelOS/Dashboards/Home/SidebarControl.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/LevelOS/Documentohelper.cs b/LevelOS/Documentohelper.cs new file mode 100644 index 0000000..21c97c6 --- /dev/null +++ b/LevelOS/Documentohelper.cs @@ -0,0 +1,69 @@ +using CPM; +using System.Linq; +using System.Windows.Forms; + +namespace LevelOS +{ + /// + /// Formata CPF ou CNPJ automaticamente enquanto o usuário digita. + /// Uso: DocumentoHelper.Registrar(txtDocumento); + /// + public static class DocumentoHelper + { + public static void Registrar(LV_TEXTBOX1 txt) + { + bool formatando = false; + + txt.TextChanged += (_, _) => + { + // Evita loop: TextChanged → altera Text → TextChanged → ... + if (formatando) return; + formatando = true; + + try + { + // 1. Extrai só os dígitos + string digits = new string(txt.Text.Where(char.IsDigit).ToArray()); + + // 2. Limita ao tamanho máximo do CNPJ + if (digits.Length > 14) digits = digits[..14]; + + // 3. Formata conforme o tamanho + string formatado = digits.Length <= 11 + ? FormatarCPF(digits) + : FormatarCNPJ(digits); + + // 4. Só atualiza se realmente mudou + if (txt.Text != formatado) + { + txt.Text = formatado; + txt.SelectionStart = formatado.Length; // cursor no final + } + } + finally + { + formatando = false; + } + }; + } + + // CPF: 000.000.000-00 + private static string FormatarCPF(string d) => d.Length switch + { + <= 3 => d, + <= 6 => $"{d[..3]}.{d[3..]}", + <= 9 => $"{d[..3]}.{d[3..6]}.{d[6..]}", + _ => $"{d[..3]}.{d[3..6]}.{d[6..9]}-{d[9..]}" + }; + + // CNPJ: 00.000.000/0000-00 + private static string FormatarCNPJ(string d) => d.Length switch + { + <= 2 => d, + <= 5 => $"{d[..2]}.{d[2..]}", + <= 8 => $"{d[..2]}.{d[2..5]}.{d[5..]}", + <= 12 => $"{d[..2]}.{d[2..5]}.{d[5..8]}/{d[8..]}", + _ => $"{d[..2]}.{d[2..5]}.{d[5..8]}/{d[8..12]}-{d[12..]}" + }; + } +} \ No newline at end of file diff --git a/LevelOS/LevelOS.csproj b/LevelOS/LevelOS.csproj index 18bf373..7a89480 100644 --- a/LevelOS/LevelOS.csproj +++ b/LevelOS/LevelOS.csproj @@ -9,13 +9,14 @@ - + + diff --git a/LevelOS/LevelOS.csproj.user b/LevelOS/LevelOS.csproj.user index 9afaf4c..32e8d73 100644 --- a/LevelOS/LevelOS.csproj.user +++ b/LevelOS/LevelOS.csproj.user @@ -1,8 +1,26 @@  + + UserControl + + + UserControl + Form + + UserControl + + + Form + + + UserControl + + + UserControl + \ No newline at end of file diff --git a/LevelOS/LevelOS.slnx b/LevelOS/LevelOS.slnx index 77fd8fb..8326c0b 100644 --- a/LevelOS/LevelOS.slnx +++ b/LevelOS/LevelOS.slnx @@ -5,6 +5,9 @@ + + + diff --git a/LevelOS/ModeloPanel/Formulariomodelo.cs b/LevelOS/ModeloPanel/Formulariomodelo.cs new file mode 100644 index 0000000..7a1d784 --- /dev/null +++ b/LevelOS/ModeloPanel/Formulariomodelo.cs @@ -0,0 +1,254 @@ +using CPM; +using DAL; +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace LevelOS +{ + /// + /// Modelo base para todos os formulários do sistema. + /// Herde esta classe e implemente os membros abstratos. + /// + public abstract class FormularioModelo : UserControl + { + // ── CONEXÃO ─────────────────────────────────────────────────────────── + protected string _cx = DadosDaConexao.ObterConexao(); + + // ── CORES DO SISTEMA ────────────────────────────────────────────────── + protected readonly Color AccentBlue = Color.FromArgb(37, 99, 235); + protected readonly Color TextDark = Color.FromArgb(30, 41, 59); + protected readonly Color BorderColor = Color.FromArgb(226, 232, 240); + protected readonly Color BgLight = Color.FromArgb(248, 250, 252); + protected readonly Color ReadOnlyBg = Color.FromArgb(241, 245, 249); + protected readonly Color ReadOnlyBorder = Color.FromArgb(203, 213, 225); + + // ── PAINÉIS ESTRUTURAIS ─────────────────────────────────────────────── + protected Panel pnlToolbar = null!; + protected Panel pnlTitulo = null!; + protected Panel mainScroll = null!; + protected Panel content = null!; + + // ── BOTÕES DA TOOLBAR ───────────────────────────────────────────────── + protected Button btnNovo = null!; + protected Button btnAlterar = null!; + protected Button btnExcluir = null!; + protected Button btnLocalizar = null!; + protected Button btnSalvar = null!; + protected Button btnCancelar = null!; + + // ── TÍTULO ──────────────────────────────────────────────────────────── + private Label lblTitulo = null!; + + /// Título exibido no cabeçalho do formulário. + public string Titulo + { + get => lblTitulo.Text; + set => lblTitulo.Text = value; + } + + // ── CONSTRUTOR ──────────────────────────────────────────────────────── + protected FormularioModelo() + { + Dock = DockStyle.Fill; + BackColor = Color.White; + DoubleBuffered = true; + + BuildToolbar(); + BuildTitulo(); + BuildScrollArea(); + + // Liga os eventos abstratos + btnNovo.Click += (s, e) => OnNovo(); + btnAlterar.Click += (s, e) => OnAlterar(); + btnExcluir.Click += (s, e) => OnExcluir(); + btnLocalizar.Click += (s, e) => OnLocalizar(); + btnSalvar.Click += (s, e) => OnSalvar(); + btnCancelar.Click += (s, e) => OnCancelar(); + } + + // ── CONSTRUÇÃO DA INTERFACE ─────────────────────────────────────────── + + private void BuildToolbar() + { + pnlToolbar = new Panel + { + Dock = DockStyle.Top, + Height = 55, + BackColor = Color.FromArgb(248, 250, 252) + }; + + var flow = new FlowLayoutPanel + { + Dock = DockStyle.Fill, + Padding = new Padding(12, 10, 0, 0), + BackColor = Color.Transparent + }; + + btnNovo = CreateToolbarButton("Novo", Color.FromArgb(34, 197, 94)); + btnAlterar = CreateToolbarButton("Alterar", Color.FromArgb(245, 158, 11)); + btnExcluir = CreateToolbarButton("Excluir", Color.FromArgb(239, 68, 68)); + btnLocalizar = CreateToolbarButton("Localizar", AccentBlue); + btnSalvar = CreateToolbarButton("Salvar", AccentBlue); + btnCancelar = CreateToolbarButton("Cancelar", Color.FromArgb(148, 163, 184)); + + flow.Controls.AddRange(new Control[] + { btnNovo, btnAlterar, btnExcluir, btnLocalizar, btnSalvar, btnCancelar }); + + pnlToolbar.Controls.Add(flow); + this.Controls.Add(pnlToolbar); + } + + private void BuildTitulo() + { + pnlTitulo = new Panel + { + Dock = DockStyle.Top, + Height = 42, + BackColor = Color.White + }; + + // Linha separadora no topo do título + var linha = new Panel + { + Dock = DockStyle.Top, + Height = 1, + BackColor = BorderColor + }; + + lblTitulo = new Label + { + Dock = DockStyle.Fill, + Text = "Título do Formulário", + Font = new Font("Segoe UI", 13f, FontStyle.Bold), + ForeColor = AccentBlue, + TextAlign = ContentAlignment.MiddleLeft, + Padding = new Padding(16, 0, 0, 0) + }; + + pnlTitulo.Controls.Add(lblTitulo); + pnlTitulo.Controls.Add(linha); + this.Controls.Add(pnlTitulo); + } + + private void BuildScrollArea() + { + mainScroll = new Panel + { + Dock = DockStyle.Fill, + AutoScroll = true, + BackColor = Color.White + }; + + content = new Panel + { + Width = 1100, + Height = 900, + Location = new Point(0, 0), + BackColor = Color.White + }; + + mainScroll.Controls.Add(content); + this.Controls.Add(mainScroll); + mainScroll.BringToFront(); + } + + // ── HELPERS DISPONÍVEIS PARA AS SUBCLASSES ──────────────────────────── + + /// Cria um cabeçalho de seção com linha separadora. + protected 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; + } + + /// Cria um campo LV_TEXTBOX1 com label acima. + protected LV_TEXTBOX1 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 LV_TEXTBOX1 + { + Location = new Point(x, y + 16), + Size = new Size(width, height), + BorderColor = readOnly ? ReadOnlyBorder : BorderColor, + BorderFocusColor = AccentBlue, + ReadOnly = readOnly, + BackColor = readOnly ? ReadOnlyBg : Color.White + }; + + parent.Controls.Add(lbl); + parent.Controls.Add(txt); + return txt; + } + + /// Cria um CheckBox padrão do sistema. + protected 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 + }; + + /// Cria um botão extra para a toolbar (ex: Ficha PDF, Certificado). + protected Button CreateToolbarButton(string text, Color color) => new Button + { + 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, + FlatStyle = FlatStyle.Flat, + FlatAppearance = { BorderSize = 0 } + }; + + /// Adiciona um botão extra na toolbar (após os padrões). + protected void AddToolbarButton(Button btn) + { + var flow = pnlToolbar.Controls[0] as FlowLayoutPanel; + flow?.Controls.Add(btn); + } + + // ── EVENTOS ABSTRATOS (cada formulário implementa o seu) ────────────── + + protected abstract void OnNovo(); + protected abstract void OnAlterar(); + protected abstract void OnExcluir(); + protected abstract void OnLocalizar(); + protected abstract void OnSalvar(); + protected abstract void OnCancelar(); + } +} \ No newline at end of file