Загрузка данных


using System;
using System.Drawing;
using System.Globalization;
using System.Windows.Forms;

namespace SimpleCalculator
{
    internal static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new CalculatorForm());
        }
    }

    public class CalculatorForm : Form
    {
        private readonly TextBox txtDisplay;

        private double resultValue = 0;
        private string operationPerformed = "";
        private bool isOperationPerformed = false;

        private Button? glowingButton;
        private readonly Timer glowTimer;

        private readonly Color neonBaseColor =
            Color.FromArgb(0, 192, 255);

        private readonly Color buttonBackColor =
            Color.FromArgb(32, 32, 42);

        private readonly Color buttonForeColor =
            Color.FromArgb(200, 200, 220);

        public CalculatorForm()
        {
            Text = "Neon Calculator";
            Width = 310;
            Height = 460;

            FormBorderStyle = FormBorderStyle.FixedSingle;
            MaximizeBox = false;
            StartPosition = FormStartPosition.CenterScreen;
            BackColor = Color.FromArgb(18, 18, 24);

            KeyPreview = true;
            KeyPress += CalculatorForm_KeyPress;
            KeyDown += CalculatorForm_KeyDown;

            txtDisplay = new TextBox
            {
                Location = new Point(15, 15),
                Size = new Size(265, 45),
                Font = new Font("Consolas", 22, FontStyle.Bold),
                BackColor = Color.FromArgb(28, 28, 38),
                ForeColor = neonBaseColor,
                TextAlign = HorizontalAlignment.Right,
                BorderStyle = BorderStyle.FixedSingle,
                Text = "0"
            };

            Controls.Add(txtDisplay);

            glowTimer = new Timer
            {
                Interval = 350
            };

            glowTimer.Tick += GlowTimer_Tick;

            InitializeButtons();
        }

        private void InitializeButtons()
        {
            string[,] buttons =
            {
                { "C", "^", "/", "*" },
                { "7", "8", "9", "-" },
                { "4", "5", "6", "+" },
                { "1", "2", "3", "=" },
                { "0", ",", "±", "" }
            };

            int startX = 15;
            int startY = 80;
            int btnWidth = 62;
            int btnHeight = 55;
            int gap = 6;

            for (int row = 0; row < 5; row++)
            {
                for (int col = 0; col < 4; col++)
                {
                    string text = buttons[row, col];

                    if (string.IsNullOrEmpty(text))
                        continue;

                    Button btn = new Button
                    {
                        Text = text,
                        Font = new Font(
                            "Segoe UI",
                            14,
                            FontStyle.Bold
                        ),
                        Size = new Size(btnWidth, btnHeight),
                        Location = new Point(
                            startX + col * (btnWidth + gap),
                            startY + row * (btnHeight + gap)
                        ),
                        FlatStyle = FlatStyle.Flat,
                        BackColor = buttonBackColor,
                        ForeColor = buttonForeColor,
                        Cursor = Cursors.Hand
                    };

                    btn.FlatAppearance.BorderSize = 1;
                    btn.FlatAppearance.BorderColor =
                        Color.FromArgb(50, 50, 70);

                    if (text == "=")
                    {
                        btn.Height = btnHeight * 2 + gap;
                    }

                    if (text == "C")
                    {
                        btn.Click += BtnClear_Click;
                    }
                    else if (text == "=")
                    {
                        btn.Click += BtnEquals_Click;
                    }
                    else if (text == "±")
                    {
                        btn.Click += BtnSign_Click;
                    }
                    else if ("0123456789,".Contains(text))
                    {
                        btn.Click += Button_Click;
                    }
                    else
                    {
                        btn.Click += Operator_Click;
                    }

                    btn.Click += (s, e) =>
                    {
                        TriggerNeonGlow(btn);
                    };

                    Controls.Add(btn);
                }
            }
        }

        // Определяем цвет числа
        private Color GetNumberColor()
        {
            string text = txtDisplay.Text.Trim();

            if (double.TryParse(
                text,
                NumberStyles.Float,
                CultureInfo.CurrentCulture,
                out double value))
            {
                if (value < 0)
                    return Color.FromArgb(255, 35, 75);

                if (value > 0)
                    return Color.FromArgb(10, 255, 100);
            }

            return neonBaseColor;
        }

        // Обновляем цвет дисплея
        private void TriggerDisplayColorUpdate()
        {
            txtDisplay.ForeColor = GetNumberColor();
        }

        // Подсветка кнопки
        private void TriggerNeonGlow(Button button)
        {
            if (glowingButton != null)
                ResetButtonGlow(glowingButton);

            glowTimer.Stop();

            glowingButton = button;

            Color neonColor = GetNumberColor();

            // Подсветка кнопки выбранным неоновым цветом
            button.BackColor = Color.FromArgb(
                neonColor.R / 4,
                neonColor.G / 4,
                neonColor.B / 4
            );

            button.ForeColor = neonColor;
            button.FlatAppearance.BorderColor = neonColor;

            TriggerDisplayColorUpdate();

            glowTimer.Start();
        }

        private void ResetButtonGlow(Button button)
        {
            button.BackColor = buttonBackColor;
            button.ForeColor = buttonForeColor;

            button.FlatAppearance.BorderColor =
                Color.FromArgb(50, 50, 70);
        }

        private void GlowTimer_Tick(object? sender, EventArgs e)
        {
            glowTimer.Stop();

            if (glowingButton != null)
            {
                ResetButtonGlow(glowingButton);
                glowingButton = null;
            }
        }

        private void FindAndGlowButton(string keyText)
        {
            foreach (Control control in Controls)
            {
                if (control is Button btn &&
                    btn.Text == keyText)
                {
                    TriggerNeonGlow(btn);
                    return;
                }
            }
        }

        // Ввод цифр
        private void Button_Click(object? sender, EventArgs e)
        {
            if (sender is not Button button)
                return;

            string text = button.Text;

            if (isOperationPerformed)
            {
                txtDisplay.Text = "0";
                isOperationPerformed = false;
            }

            if (text == ",")
            {
                if (!txtDisplay.Text.Contains(","))
                {
                    txtDisplay.Text += ",";
                }
            }
            else
            {
                if (txtDisplay.Text == "0")
                    txtDisplay.Text = text;
                else
                    txtDisplay.Text += text;
            }

            TriggerDisplayColorUpdate();
        }

        // Изменение знака числа
        private void BtnSign_Click(object? sender, EventArgs e)
        {
            if (!double.TryParse(
                txtDisplay.Text,
                NumberStyles.Float,
                CultureInfo.CurrentCulture,
                out double value))
            {
                return;
            }

            txtDisplay.Text = (-value).ToString(
                CultureInfo.CurrentCulture
            );

            isOperationPerformed = false;

            TriggerDisplayColorUpdate();
        }

        // Операторы
        private void Operator_Click(object? sender, EventArgs e)
        {
            if (sender is Button button)
            {
                HandleOperator(button.Text);
            }
        }

        private void HandleOperator(string op)
        {
            if (!double.TryParse(
                txtDisplay.Text,
                NumberStyles.Float,
                CultureInfo.CurrentCulture,
                out double currentValue))
            {
                return;
            }

            if (!string.IsNullOrEmpty(operationPerformed) &&
                !isOperationPerformed)
            {
                CalculateResult(currentValue);

                if (!double.TryParse(
                    txtDisplay.Text,
                    NumberStyles.Float,
                    CultureInfo.CurrentCulture,
                    out currentValue))
                {
                    return;
                }
            }

            resultValue = currentValue;
            operationPerformed = op;
            isOperationPerformed = true;
        }

        // Очистка
        private void BtnClear_Click(object? sender, EventArgs e)
        {
            txtDisplay.Text = "0";

            resultValue = 0;
            operationPerformed = "";
            isOperationPerformed = false;

            TriggerDisplayColorUpdate();
        }

        // Вычисление
        private void BtnEquals_Click(object? sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(operationPerformed))
                return;

            if (!double.TryParse(
                txtDisplay.Text,
                NumberStyles.Float,
                CultureInfo.CurrentCulture,
                out double currentNumber))
            {
                return;
            }

            CalculateResult(currentNumber);

            operationPerformed = "";
            isOperationPerformed = true;

            TriggerDisplayColorUpdate();
        }

        private void CalculateResult(double currentNumber)
        {
            double result;

            switch (operationPerformed)
            {
                case "+":
                    result = resultValue + currentNumber;
                    break;

                case "-":
                    result = resultValue - currentNumber;
                    break;

                case "*":
                    result = resultValue * currentNumber;
                    break;

                case "/":
                    if (currentNumber == 0)
                    {
                        MessageBox.Show(
                            "На ноль делить нельзя!",
                            "Ошибка",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Error
                        );

                        txtDisplay.Text = "0";
                        resultValue = 0;
                        return;
                    }

                    result = resultValue / currentNumber;
                    break;

                case "^":
                    result = Math.Pow(
                        resultValue,
                        currentNumber
                    );
                    break;

                default:
                    result = currentNumber;
                    break;
            }

            if (double.IsNaN(result) ||
                double.IsInfinity(result))
            {
                MessageBox.Show(
                    "Результат невозможно вычислить.",
                    "Ошибка",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning
                );

                result = 0;
            }

            resultValue = result;

            txtDisplay.Text = result.ToString(
                "G",
                CultureInfo.CurrentCulture
            );

            TriggerDisplayColorUpdate();
        }

        // Управление клавиатурой
        private void CalculatorForm_KeyPress(
            object? sender,
            KeyPressEventArgs e)
        {
            if (char.IsDigit(e.KeyChar))
            {
                Button_Click(
                    FindButton(e.KeyChar.ToString()),
                    EventArgs.Empty
                );

                FindAndGlowButton(e.KeyChar.ToString());
                e.Handled = true;
            }
            else if (e.KeyChar == ',' || e.KeyChar == '.')
            {
                Button_Click(FindButton(","), EventArgs.Empty);
                FindAndGlowButton(",");
                e.Handled = true;
            }
            else if ("+-*/^".Contains(e.KeyChar))
            {
                HandleOperator(e.KeyChar.ToString());
                FindAndGlowButton(e.KeyChar.ToString());
                e.Handled = true;
            }
            else if (e.KeyChar == '=')
            {
                BtnEquals_Click(this, EventArgs.Empty);
                FindAndGlowButton("=");
                e.Handled = true;
            }
        }

        private Button? FindButton(string text)
        {
            foreach (Control control in Controls)
            {
                if (control is Button btn && btn.Text == text)
                    return btn;
            }

            return null;
        }

        private void CalculatorForm_KeyDown(
            object? sender,
            KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                BtnEquals_Click(this, EventArgs.Empty);
                FindAndGlowButton("=");

                e.Handled = true;
                e.SuppressKeyPress = true;
            }
            else if (e.KeyCode == Keys.Escape)
            {
                BtnClear_Click(this, EventArgs.Empty);
                FindAndGlowButton("C");

                e.Handled = true;
            }
            else if (e.KeyCode == Keys.Back)
            {
                if (txtDisplay.Text.Length > 1)
                {
                    txtDisplay.Text = txtDisplay.Text
                        .Substring(0, txtDisplay.Text.Length - 1);
                }
                else
                {
                    txtDisplay.Text = "0";
                }

                TriggerDisplayColorUpdate();

                e.Handled = true;
                e.SuppressKeyPress = true;
            }
        }

        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            glowTimer.Stop();
            glowTimer.Dispose();

            base.OnFormClosed(e);
        }
    }
}