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

DarkFontSizeNumeric.cs

179 строк · 6,580 байт · модуль 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    // Font size control with geometric progression after 16pt
 11    public class DarkFontSizeNumeric : Control
 12    {
 13        private static readonly Color GE = Color.FromArgb(225, 232, 245);
 14
 15        // Preset sizes: 8-16 linear, then geometric up to 300
 16        private static readonly int[] FontSizes = { 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 24, 28, 32, 36, 42, 48, 56, 64, 72, 84, 96, 110, 128, 150, 175, 200, 230, 265, 300 };
 17
 18        private int _sizeIndex;
 19        private bool hoverUp, hoverDown;
 20        private Timer repeatTimer;
 21        private int repeatDir;
 22
 23        public event EventHandler ValueChanged;
 24
 25        public int Value
 26        {
 27            get { return FontSizes[_sizeIndex]; }
 28            set
 29            {
 30                int newIdx = FindClosestIndex(value);
 31                if (newIdx != _sizeIndex)
 32                {
 33                    _sizeIndex = newIdx;
 34                    Invalidate();
 35                    if (ValueChanged != null) ValueChanged(this, EventArgs.Empty);
 36                }
 37            }
 38        }
 39
 40        private int FindClosestIndex(int size)
 41        {
 42            for (int i = 0; i < FontSizes.Length; i++)
 43            {
 44                if (FontSizes[i] >= size) return i;
 45            }
 46            return FontSizes.Length - 1;
 47        }
 48
 49        public DarkFontSizeNumeric()
 50        {
 51            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.SupportsTransparentBackColor, true);
 52            BackColor = Color.Transparent;
 53            Size = new Size(70, 26);
 54            Font = new Font("Segoe UI", 11f, GraphicsUnit.Pixel);
 55            _sizeIndex = 4; // default 12
 56
 57            repeatTimer = new Timer();
 58            repeatTimer.Interval = 150;
 59            repeatTimer.Tick += (s, e) => { ChangeValue(repeatDir); };
 60        }
 61
 62        protected override void OnPaint(PaintEventArgs e)
 63        {
 64            var g = e.Graphics;
 65            float glow = GlowHelper.ComputeGlow(this);
 66            int fillA = 12 + (int)(18 * glow);
 67            using (var brush = new SolidBrush(Color.FromArgb(fillA, GE)))
 68                g.FillRectangle(brush, 0, 0, Width, Height);
 69            int borderA = 40 + (int)(60 * glow);
 70            using (var pen = new Pen(Color.FromArgb(borderA, GE), 1f))
 71                g.DrawRectangle(pen, 0, 0, Width - 1, Height - 1);
 72
 73            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
 74            Color tc = SettingsDialog.AdaptiveTextColor;
 75            int textA = 160 + (int)(65 * glow);
 76            using (var brush = new SolidBrush(Color.FromArgb(textA, tc)))
 77            {
 78                var sf = new StringFormat { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Center };
 79                g.DrawString(Value.ToString(), Font, brush, new Rectangle(7, 0, Width - 30, Height), sf);
 80            }
 81
 82            int btnW = 22, btnH = Height / 2;
 83            if (hoverUp) using (var brush = new SolidBrush(Color.FromArgb(25, tc))) g.FillRectangle(brush, Width - btnW, 0, btnW, btnH);
 84            if (hoverDown) using (var brush = new SolidBrush(Color.FromArgb(25, tc))) g.FillRectangle(brush, Width - btnW, btnH, btnW, btnH);
 85            int sepA = 30 + (int)(30 * glow);
 86            using (var pen = new Pen(Color.FromArgb(sepA, tc), 1f)) g.DrawLine(pen, Width - btnW, 0, Width - btnW, Height);
 87
 88            DrawGlassArrow(g, new Rectangle(Width - btnW, 0, btnW, btnH), true, hoverUp, glow);
 89            DrawGlassArrow(g, new Rectangle(Width - btnW, btnH, btnW, btnH), false, hoverDown, glow);
 90        }
 91
 92        private void DrawGlassArrow(Graphics g, Rectangle r, bool up, bool hov, float glow)
 93        {
 94            Color tc = SettingsDialog.AdaptiveTextColor;
 95            int cx = r.X + r.Width / 2, cy = r.Y + r.Height / 2, sz = 3;
 96            Point[] pts = up
 97                ? new Point[] { new Point(cx - sz, cy + 1), new Point(cx + sz, cy + 1), new Point(cx, cy - 2) }
 98                : new Point[] { new Point(cx - sz, cy - 1), new Point(cx + sz, cy - 1), new Point(cx, cy + 2) };
 99            int arrowA = (int)((hov ? 180 : 80) + (40 * glow));
100            if (arrowA > 255) arrowA = 255;
101            using (var brush = new SolidBrush(Color.FromArgb(arrowA, tc)))
102                g.FillPolygon(brush, pts);
103        }
104
105        protected override void OnMouseMove(MouseEventArgs e)
106        {
107            int btnW = 20;
108            int btnH = Height / 2;
109            bool newHoverUp = e.X >= Width - btnW && e.Y < btnH;
110            bool newHoverDown = e.X >= Width - btnW && e.Y >= btnH;
111
112            if (newHoverUp != hoverUp || newHoverDown != hoverDown)
113            {
114                hoverUp = newHoverUp;
115                hoverDown = newHoverDown;
116                Invalidate();
117            }
118        }
119
120        protected override void OnMouseLeave(EventArgs e)
121        {
122            hoverUp = hoverDown = false;
123            Invalidate();
124        }
125
126        protected override void OnMouseDown(MouseEventArgs e)
127        {
128            int btnW = 20;
129            int btnH = Height / 2;
130
131            if (e.X >= Width - btnW)
132            {
133                if (e.Y < btnH)
134                {
135                    ChangeValue(1);
136                    repeatDir = 1;
137                    repeatTimer.Start();
138                }
139                else
140                {
141                    ChangeValue(-1);
142                    repeatDir = -1;
143                    repeatTimer.Start();
144                }
145            }
146        }
147
148        protected override void OnMouseUp(MouseEventArgs e)
149        {
150            repeatTimer.Stop();
151        }
152
153        protected override void OnMouseWheel(MouseEventArgs e)
154        {
155            ChangeValue(e.Delta > 0 ? 1 : -1);
156        }
157
158        private void ChangeValue(int delta)
159        {
160            int newIdx = _sizeIndex + delta;
161            if (newIdx >= 0 && newIdx < FontSizes.Length)
162            {
163                _sizeIndex = newIdx;
164                Invalidate();
165                if (ValueChanged != null) ValueChanged(this, EventArgs.Empty);
166            }
167        }
168
169        protected override void Dispose(bool disposing)
170        {
171            if (disposing && repeatTimer != null)
172            {
173                repeatTimer.Dispose();
174                repeatTimer = null;
175            }
176            base.Dispose(disposing);
177        }
178    }
179}