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

DarkFloatNumeric.cs

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