1using System; 2using System.Collections.Generic; 3using System.Drawing; 4using System.Drawing.Drawing2D; 5using System.Drawing.Imaging; 6using System.Drawing.Text; 7using System.IO; 8using System.Linq; 9using System.Runtime.InteropServices; 10using System.Windows.Forms; 11using WindowCapture.App; 12using WindowCapture.Detection; 13using WindowCapture.Effects; 14using WindowCapture.Helpers; 15using WindowCapture.Integration; 16using WindowCapture.Models; 17using WindowCapture.Native; 18 19namespace WindowCapture.UI 20{ 21 public partial class EditorForm 22 { 23 // Static noise texture for Acrylic-like grain effect 24 private static Bitmap noiseTexture; 25 private static readonly object noiseLock = new object(); 26 27 private static Bitmap GetNoiseTexture() 28 { 29 if (noiseTexture != null) return noiseTexture; 30 lock (noiseLock) 31 { 32 if (noiseTexture != null) return noiseTexture; 33 // Generate 128x128 tileable noise (subtle grain like Acrylic) 34 const int sz = 128; 35 var bmp = new Bitmap(sz, sz, PixelFormat.Format32bppArgb); 36 var rng = new Random(42); // deterministic for consistent look 37 var bits = bmp.LockBits(new Rectangle(0, 0, sz, sz), 38 ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); 39 unsafe 40 { 41 byte* ptr = (byte*)bits.Scan0; 42 for (int i = 0; i < sz * sz; i++) 43 { 44 // Monochrome noise, very subtle alpha (4-12) 45 byte v = (byte)(rng.Next(180, 255)); 46 int a = rng.Next(4, 14); 47 ptr[0] = v; ptr[1] = v; ptr[2] = v; ptr[3] = (byte)a; 48 ptr += 4; 49 } 50 } 51 bmp.UnlockBits(bits); 52 noiseTexture = bmp; 53 return noiseTexture; 54 } 55 } 56 57 private void ScrollContainer_Paint(object sender, PaintEventArgs e) 58 { 59 var g = e.Graphics; 60 int r = Settings.CornerRadius; 61 int w = scrollContainer.Width; 62 int h = scrollContainer.Height; 63 64 Color tintColor = Settings.BlurTintColor; 65 int tintAlpha = Settings.BlurTintAlpha; 66 67 // DWM handles blur + tint via GradientColor. Here we only add noise + handle corners. 68 69 if (isWin10RoundedCorners && r > 0) 70 { 71 // Win10: opaque tint in corners (hides DWM blur outside rounded rect) 72 g.CompositingMode = CompositingMode.SourceCopy; 73 using (var brush = new SolidBrush(Color.FromArgb(255, tintColor.R, tintColor.G, tintColor.B))) 74 g.FillRectangle(brush, 0, 0, w, h); 75 76 // Transparent inside rounded rect (lets DWM tinted blur show through) 77 g.SmoothingMode = SmoothingMode.AntiAlias; 78 using (var path = CreateRoundRectPath(0, 0, w, h, r)) 79 using (var brush = new SolidBrush(Color.FromArgb(0, 0, 0, 0))) 80 g.FillPath(brush, path); 81 82 g.CompositingMode = CompositingMode.SourceOver; 83 84 // Anti-aliased edge 85 using (var path = CreateRoundRectPath(0, 0, w - 1, h - 1, r)) 86 using (var pen = new Pen(Color.FromArgb(180, tintColor.R, tintColor.G, tintColor.B), 1.5f)) 87 g.DrawPath(pen, path); 88 } 89 // No else needed — DWM handles the tint for flat windows 90 91 // Acrylic-style noise grain 92 var noise = GetNoiseTexture(); 93 using (var tb = new TextureBrush(noise, WrapMode.Tile)) 94 g.FillRectangle(tb, 0, 0, w, h); 95 96 g.SmoothingMode = SmoothingMode.AntiAlias; 97 98 // Window border 99 if (Settings.ShowWindowBorder) 100 { 101 int br = Math.Min(255, tintColor.R + 40); 102 int bg2 = Math.Min(255, tintColor.G + 40); 103 int bb = Math.Min(255, tintColor.B + 40); 104 var borderColor = Color.FromArgb(100, br, bg2, bb); 105 106 if (r > 0) 107 { 108 using (var path = CreateRoundRectPath(0, 0, w - 1, h - 1, r)) 109 using (var pen = new Pen(borderColor, 1f)) 110 g.DrawPath(pen, path); 111 } 112 else 113 { 114 using (var pen = new Pen(borderColor, 1f)) 115 g.DrawRectangle(pen, 0, 0, w - 1, h - 1); 116 } 117 } 118 } 119 120 private void DrawGearIcon(Graphics g, int x, int y, int size, bool hovered) 121 { 122 var center = new PointF(x + size / 2f, y + size / 2f); 123 float outerR = size / 2f - 1; 124 float innerR = size / 5f; 125 int teeth = 8; 126 127 var points = new List<PointF>(); 128 for (int i = 0; i < teeth * 2; i++) 129 { 130 float angle = (float)(i * Math.PI / teeth); 131 float r = (i % 2 == 0) ? outerR : outerR * 0.65f; 132 points.Add(new PointF(center.X + (float)Math.Cos(angle) * r, center.Y + (float)Math.Sin(angle) * r)); 133 } 134 135 using (var path = new GraphicsPath()) 136 { 137 path.AddPolygon(points.ToArray()); 138 path.AddEllipse(center.X - innerR, center.Y - innerR, innerR * 2, innerR * 2); 139 140 Color fill = hovered ? Color.FromArgb(220, 220, 220) : Color.FromArgb(140, 140, 140); 141 using (var brush = new SolidBrush(fill)) 142 g.FillPath(brush, path); 143 } 144 } 145 } 146}