windowcapture
исходный код / UI/Controls/DarkNumeric.cs

DarkNumeric.cs

113 строк · 5,505 байт · модуль UI
  1using System;
  2using System.Drawing;
  3using System.Drawing.Drawing2D;
  4using System.Windows.Forms;
  5using System.Collections.Generic;
  6using WindowCapture.Helpers;
  7
  8namespace WindowCapture.UI
  9{
 10    // Glass-style numeric control
 11    public class DarkNumeric : Control
 12    {
 13        private static readonly Color GE = Color.FromArgb(225, 232, 245);
 14
 15        private int _value, _min, _max;
 16        private bool hoverUp, hoverDown;
 17        private Timer repeatTimer;
 18        private int repeatDir;
 19
 20        public event EventHandler ValueChanged;
 21
 22        public int Value
 23        {
 24            get { return _value; }
 25            set { int v = Math.Max(_min, Math.Min(_max, value)); if (v != _value) { _value = v; Invalidate(); if (ValueChanged != null) ValueChanged(this, EventArgs.Empty); } }
 26        }
 27        public int Minimum { get { return _min; } set { _min = value; } }
 28        public int Maximum { get { return _max; } set { _max = value; } }
 29
 30        public DarkNumeric()
 31        {
 32            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.SupportsTransparentBackColor, true);
 33            BackColor = Color.Transparent;
 34            Size = new Size(80, 26); Font = new Font("Segoe UI", 11f, GraphicsUnit.Pixel);
 35            _min = 0; _max = 100; _value = 0;
 36            repeatTimer = new Timer(); repeatTimer.Interval = 100;
 37            repeatTimer.Tick += (s, e) => { ChangeValue(repeatDir); };
 38        }
 39
 40        protected override void OnPaint(PaintEventArgs e)
 41        {
 42            var g = e.Graphics;
 43            float glow = GlowHelper.ComputeGlow(this);
 44
 45            // Glass fill — brighter when cursor near
 46            int fillA = 12 + (int)(18 * glow);
 47            using (var brush = new SolidBrush(Color.FromArgb(fillA, GE)))
 48                g.FillRectangle(brush, 0, 0, Width, Height);
 49            // Glass border — glows with cursor
 50            int borderA = 40 + (int)(60 * glow);
 51            using (var pen = new Pen(Color.FromArgb(borderA, GE), 1f))
 52                g.DrawRectangle(pen, 0, 0, Width - 1, Height - 1);
 53
 54            // Value text — uses adaptive color for background visibility
 55            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
 56            Color tc = SettingsDialog.AdaptiveTextColor;
 57            int textA = 160 + (int)(65 * glow);
 58            using (var brush = new SolidBrush(Color.FromArgb(textA, tc)))
 59            {
 60                var sf = new StringFormat { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Center };
 61                g.DrawString(_value.ToString(), Font, brush, new Rectangle(7, 0, Width - 30, Height), sf);
 62            }
 63
 64            // Up/Down arrows with glass hover
 65            int btnW = 22, btnH = Height / 2;
 66            if (hoverUp) using (var brush = new SolidBrush(Color.FromArgb(25, tc))) g.FillRectangle(brush, Width - btnW, 0, btnW, btnH);
 67            if (hoverDown) using (var brush = new SolidBrush(Color.FromArgb(25, tc))) g.FillRectangle(brush, Width - btnW, btnH, btnW, btnH);
 68            // Separator line
 69            int sepA = 30 + (int)(30 * glow);
 70            using (var pen = new Pen(Color.FromArgb(sepA, tc), 1f)) g.DrawLine(pen, Width - btnW, 0, Width - btnW, Height);
 71
 72            DrawGlassArrow(g, new Rectangle(Width - btnW, 0, btnW, btnH), true, hoverUp, glow);
 73            DrawGlassArrow(g, new Rectangle(Width - btnW, btnH, btnW, btnH), false, hoverDown, glow);
 74        }
 75
 76        private void DrawGlassArrow(Graphics g, Rectangle r, bool up, bool hov, float glow)
 77        {
 78            Color tc = SettingsDialog.AdaptiveTextColor;
 79            int cx = r.X + r.Width / 2, cy = r.Y + r.Height / 2, sz = 3;
 80            Point[] pts = up
 81                ? new Point[] { new Point(cx - sz, cy + 1), new Point(cx + sz, cy + 1), new Point(cx, cy - 2) }
 82                : new Point[] { new Point(cx - sz, cy - 1), new Point(cx + sz, cy - 1), new Point(cx, cy + 2) };
 83            int arrowA = (int)((hov ? 180 : 80) + (40 * glow));
 84            if (arrowA > 255) arrowA = 255;
 85            using (var brush = new SolidBrush(Color.FromArgb(arrowA, tc)))
 86                g.FillPolygon(brush, pts);
 87        }
 88
 89        protected override void OnMouseMove(MouseEventArgs e)
 90        {
 91            int btnW = 22, btnH = Height / 2;
 92            bool u = e.X >= Width - btnW && e.Y < btnH, d = e.X >= Width - btnW && e.Y >= btnH;
 93            if (u != hoverUp || d != hoverDown) { hoverUp = u; hoverDown = d; Invalidate(); }
 94        }
 95        protected override void OnMouseLeave(EventArgs e) { hoverUp = hoverDown = false; Invalidate(); }
 96        protected override void OnMouseDown(MouseEventArgs e)
 97        {
 98            int btnW = 22, btnH = Height / 2;
 99            if (e.X >= Width - btnW) { int dir = e.Y < btnH ? 1 : -1; ChangeValue(dir); repeatDir = dir; repeatTimer.Start(); }
100        }
101        protected override void OnMouseUp(MouseEventArgs e) { repeatTimer.Stop(); }
102        protected override void OnMouseWheel(MouseEventArgs e) { ChangeValue(e.Delta > 0 ? 1 : -1); }
103
104        private void ChangeValue(int delta)
105        {
106            int v = _value + delta;
107            if (v >= _min && v <= _max) { _value = v; Invalidate(); if (ValueChanged != null) ValueChanged(this, EventArgs.Empty); }
108        }
109
110        protected override void Dispose(bool disposing)
111        { if (disposing && repeatTimer != null) { repeatTimer.Dispose(); repeatTimer = null; } base.Dispose(disposing); }
112    }
113}