1using System; 2using System.Drawing; 3using System.Drawing.Drawing2D; 4using System.Reflection; 5using System.Windows.Forms; 6using System.Collections.Generic; 7using WindowCapture.Helpers; 8using WindowCapture.Models; 9using WindowCapture.Native; 10 11namespace WindowCapture.UI 12{ 13 public class SettingsDialog : Form 14 { 15 // Glass theme colors 16 private static readonly Color GlassBg = Color.FromArgb(18, 20, 24); 17 private static readonly Color DarkBg = Color.FromArgb(18, 20, 24); 18 private static readonly Color DarkPanel = Color.FromArgb(22, 24, 28); 19 private static readonly Color DarkControl = Color.FromArgb(32, 34, 40); 20 private static readonly Color DarkBorder = Color.FromArgb(55, 60, 72); 21 private static readonly Color GlassEdge = Color.FromArgb(225, 232, 245); 22 private static readonly Color TextColor = Color.FromArgb(210, 218, 235); 23 private static readonly Color DimText = Color.FromArgb(100, 110, 130); 24 private static readonly Color AccentColor = Color.FromArgb(70, 130, 200); 25 26 // Get all installed system fonts 27 private static List<string> GetSystemFonts() 28 { 29 var fonts = new List<string>(); 30 foreach (var family in System.Drawing.FontFamily.Families) 31 { 32 fonts.Add(family.Name); 33 } 34 return fonts; 35 } 36 37 // Custom tab system 38 private Panel tabPanel; 39 private Panel contentPanel; 40 private int selectedTab = 0; 41 private string[] tabNames = { "General", "Effects", "Video", "Keys", "Text" }; 42 private Panel[] tabPages; 43 44 // General settings controls 45 private DarkNumeric nudHighlightAlpha; 46 private Button btnHighlightColor; 47 private Button btnHighlightBorderColor; 48 private DarkNumeric nudBorderWidth; 49 private CheckBox chkShowBorder; 50 private CheckBox chkDimAround; 51 private DarkNumeric nudMarkerSize; 52 private Button btnMarkerColor; 53 private Button btnArrowColor; 54 private CheckBox chkAutoFit; 55 private DarkNumeric nudDefaultWidth; 56 private DarkNumeric nudDefaultHeight; 57 58 // Window appearance controls 59 private DarkNumeric nudBlurTintAlpha; 60 private Button btnBlurTintColor; 61 // Blur mode removed — always BlurBehind with noise grain 62 private DarkNumeric nudCornerRadius; 63 private DarkNumeric nudNoiseIntensity; 64 private CheckBox chkWindowBorder; 65 66 // Effects settings controls 67 private DarkFloatNumeric nudBlurRadius; 68 private DarkNumeric nudMotionBlurDistance; 69 private DarkNumeric nudDimAlpha; 70 private DarkNumeric nudFeatherWidth; 71 private CheckBox chkEnableFadeBlur; 72 private DarkNumeric nudFadeBlurWidth; 73 74 // Text settings controls 75 private DarkComboBox cmbTextFont; 76 private DarkNumeric nudTextFontSize; 77 private Button btnTextColor; 78 private Button btnTextShadowColor; 79 private DarkNumeric nudShadowOffset; 80 81 // Video recording controls 82 private DarkNumeric nudVideoFps; 83 private DarkNumeric nudVideoJpegQuality; 84 private CheckBox chkRecordSystemAudio; 85 private CheckBox chkRecordMicrophone; 86 87 // Key bindings controls 88 private Panel keysListPanel; 89 private DarkComboBox cmbActivationKey; 90 91 // Text processing controls 92 private CheckBox chkAutoLangSwitch; 93 private CheckBox chkAutoT9; 94 private DarkNumeric nudT9Sensitivity; 95 private CheckBox chkT9ShowTooltip; 96 97 // Form dragging 98 private bool formDragging; 99 private Point formDragStart; 100 101 // Glass shimmer — cursor-proximity glow on all elements 102 private Timer shimmerTimer; 103 private List<Label> shimmerLabels = new List<Label>(); 104 private List<Control> glowControls = new List<Control>(); 105 private Point lastShimmerCursorPos = new Point(-9999, -9999); 106 private const float ShimmerRadius = 150f; 107 private const float ShimmerFullRadius = 30f; 108 109 // Background-adaptive colors 110 private Bitmap bgCapture; 111 private Color adaptiveDim = DimText; 112 private Color adaptiveGlow = GlassEdge; 113 114 private bool closing; 115 116 // Saved original blur settings for cancel/restore 117 private int origBlurTintAlpha; 118 private Color origBlurTintColor; 119 private int origCornerRadius; 120 private bool origShowBorder; 121 private int origNoiseIntensity; 122 123 // Panels we need to invalidate for glow 124 private Panel titleBarRef; 125 private Panel buttonPanelRef; 126 127 // Enable double buffering on any control (prevents flicker on DWM-blurred windows) 128 private static void EnableDoubleBuffer(Control c) 129 { 130 typeof(Control).InvokeMember("DoubleBuffered", 131 BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic, 132 null, c, new object[] { true }); 133 } 134 135 public SettingsDialog() 136 { 137 // Save original blur settings for cancel/restore 138 origBlurTintAlpha = Settings.BlurTintAlpha; 139 origBlurTintColor = Settings.BlurTintColor; 140 origCornerRadius = Settings.CornerRadius; 141 origShowBorder = Settings.ShowWindowBorder; 142 origNoiseIntensity = Settings.NoiseIntensity; 143 144 InitializeComponents(); 145 LoadSettings(); 146 } 147 148 private void InitializeComponents() 149 { 150 Text = "Settings"; 151 Size = new Size(520, 560); 152 FormBorderStyle = FormBorderStyle.None; 153 MaximizeBox = false; 154 MinimizeBox = false; 155 StartPosition = FormStartPosition.CenterScreen; 156 BackColor = GlassBg; 157 DoubleBuffered = true; 158 159 // Shimmer timer — tracks cursor for glass label glow 160 shimmerTimer = new Timer(); 161 shimmerTimer.Interval = 40; 162 shimmerTimer.Tick += ShimmerTimer_Tick; 163 shimmerTimer.Start(); 164 165 // Capture background before showing, then enable DWM blur 166 Shown += delegate { EnableDialogBlur(); }; 167 // Capture background BEFORE form is shown for adaptive text colors 168 CaptureBackground(); 169 170 // Custom title bar — glass style (double-buffered to prevent flicker) 171 Panel titleBar = new Panel(); 172 titleBar.Dock = DockStyle.Top; 173 titleBar.Height = 36; 174 titleBar.BackColor = Color.Transparent; 175 EnableDoubleBuffer(titleBar); 176 titleBar.MouseDown += (s, e) => { if (e.Button == MouseButtons.Left) { formDragging = true; formDragStart = e.Location; } }; 177 titleBar.MouseMove += (s, e) => { if (formDragging) Location = new Point(Location.X + e.X - formDragStart.X, Location.Y + e.Y - formDragStart.Y); }; 178 titleBar.MouseUp += (s, e) => { formDragging = false; }; 179 titleBar.Paint += TitleBar_Paint; 180 titleBarRef = titleBar; 181 182 // Close button — glass style 183 Button btnClose = CreateButton("\u2715", titleBar.Width - 40, 5, 32, 26); 184 btnClose.Anchor = AnchorStyles.Top | AnchorStyles.Right; 185 btnClose.BackColor = Color.FromArgb(1, 0, 0, 0); 186 btnClose.FlatAppearance.MouseOverBackColor = Color.FromArgb(60, 220, 80, 80); 187 btnClose.Click += (s, e) => { if (closing) return; closing = true; RestoreBlurSettings(); DialogResult = DialogResult.Cancel; Close(); }; 188 titleBar.Controls.Add(btnClose); 189 190 // Custom tab panel (left side) — glass style, double-buffered 191 tabPanel = new Panel(); 192 tabPanel.Location = new Point(0, 36); 193 tabPanel.Size = new Size(105, Height - 36 - 52); 194 tabPanel.BackColor = Color.Transparent; 195 EnableDoubleBuffer(tabPanel); 196 tabPanel.Paint += TabPanel_Paint; 197 tabPanel.MouseClick += TabPanel_MouseClick; 198 199 // Content panel (right side) — transparent, double-buffered 200 contentPanel = new Panel(); 201 contentPanel.Location = new Point(105, 36); 202 contentPanel.Size = new Size(Width - 105, Height - 36 - 52); 203 contentPanel.BackColor = Color.Transparent; 204 EnableDoubleBuffer(contentPanel); 205 206 // Create tab pages 207 tabPages = new Panel[5]; 208 209 tabPages[0] = CreateGeneralPage(); 210 tabPages[1] = CreateEffectsPage(); 211 tabPages[2] = CreateVideoPage(); 212 tabPages[3] = CreateKeysPage(); 213 tabPages[4] = CreateTextPage(); 214 215 foreach (var page in tabPages) 216 { 217 page.Visible = false; 218 contentPanel.Controls.Add(page); 219 } 220 tabPages[0].Visible = true; 221 222 // Buttons panel — glass style, double-buffered 223 Panel buttonPanel = new Panel(); 224 buttonPanel.Dock = DockStyle.Bottom; 225 buttonPanel.Height = 52; 226 buttonPanel.BackColor = Color.Transparent; 227 EnableDoubleBuffer(buttonPanel); 228 buttonPanel.Paint += ButtonPanel_Paint; 229 buttonPanelRef = buttonPanel; 230 231 Button btnSave = CreateButton("Save", 310, 11, 90, 30); 232 btnSave.BackColor = Color.FromArgb(50, AccentColor); 233 btnSave.FlatAppearance.MouseOverBackColor = Color.FromArgb(90, AccentColor); 234 btnSave.Click += delegate { if (closing) return; closing = true; SaveSettings(); DialogResult = DialogResult.OK; Close(); }; 235 236 Button btnCancel = CreateButton("Cancel", 410, 11, 90, 30); 237 btnCancel.Click += delegate { if (closing) return; closing = true; RestoreBlurSettings(); DialogResult = DialogResult.Cancel; Close(); }; 238 239 Button btnReset = CreateButton("Reset", 10, 11, 90, 30); 240 btnReset.Click += delegate { ResetToDefaults(); }; 241 242 buttonPanel.Controls.Add(btnSave); 243 buttonPanel.Controls.Add(btnCancel); 244 buttonPanel.Controls.Add(btnReset); 245 246 Controls.Add(contentPanel); 247 Controls.Add(tabPanel); 248 Controls.Add(buttonPanel); 249 Controls.Add(titleBar); 250 } 251 252 private void EnableDialogBlur() 253 { 254 BlurHelper.Apply(Handle); 255 } 256 257 private void CaptureBackground() 258 { 259 try 260 { 261 // Capture screen area where dialog will appear (before it's visible) 262 var screen = Screen.PrimaryScreen.WorkingArea; 263 int dx = (screen.Width - Width) / 2 + screen.X; 264 int dy = (screen.Height - Height) / 2 + screen.Y; 265 bgCapture = new Bitmap(Width, Height); 266 using (var g = Graphics.FromImage(bgCapture)) 267 g.CopyFromScreen(dx, dy, 0, 0, new Size(Width, Height)); 268 } 269 catch { bgCapture = null; } 270 271 // Compute adaptive colors from actual Settings tint + captured background 272 ComputeAdaptiveColors(); 273 } 274 275 private void ComputeAdaptiveColors() 276 { 277 // Use real settings tint values 278 float ta = Settings.BlurTintAlpha / 255f; 279 float tintR = Settings.BlurTintColor.R; 280 float tintG = Settings.BlurTintColor.G; 281 float tintB = Settings.BlurTintColor.B; 282 283 // Sample background if available, otherwise assume mid-gray 284 float bgR = 128f, bgG = 128f, bgB = 128f; 285 if (bgCapture != null) 286 { 287 try 288 { 289 long totalR = 0, totalG = 0, totalB = 0; int samples = 0; 290 for (int y = 0; y < bgCapture.Height; y += 20) 291 for (int x = 0; x < bgCapture.Width; x += 20) 292 { 293 Color px = bgCapture.GetPixel(x, y); 294 totalR += px.R; totalG += px.G; totalB += px.B; samples++; 295 } 296 if (samples > 0) 297 { 298 bgR = totalR / (float)samples; 299 bgG = totalG / (float)samples; 300 bgB = totalB / (float)samples; 301 } 302 } 303 catch { } 304 } 305 306 // Effective perceived color = tint blended over background 307 float er = ta * tintR + (1 - ta) * bgR; 308 float eg = ta * tintG + (1 - ta) * bgG; 309 float eb = ta * tintB + (1 - ta) * bgB; 310 float brightness = (er * 0.299f + eg * 0.587f + eb * 0.114f) / 255f; 311 312 if (brightness > 0.45f) 313 { 314 // Light background → dark text and glow 315 adaptiveDim = Color.FromArgb(50, 50, 60); 316 adaptiveGlow = Color.FromArgb(10, 12, 20); 317 AdaptiveTextColor = Color.FromArgb(10, 12, 20); 318 AdaptiveDimColor = Color.FromArgb(50, 50, 60); 319 } 320 else 321 { 322 // Dark background → light text and glow (default) 323 adaptiveDim = DimText; 324 adaptiveGlow = GlassEdge; 325 AdaptiveTextColor = GlassEdge; 326 AdaptiveDimColor = DimText; 327 } 328 } 329 330 // Adaptive colors accessible by child controls 331 internal static Color AdaptiveTextColor = GlassEdge; 332 internal static Color AdaptiveDimColor = DimText; 333 334 internal static float ComputeGlow(Control ctrl) 335 { 336 return GlowHelper.ComputeGlow(ctrl); 337 } 338 339 private void ShimmerTimer_Tick(object sender, EventArgs e) 340 { 341 if (!Visible) return; 342 Point screenPt = Cursor.Position; 343 // Skip if cursor hasn't moved — eliminates flickering 344 if (screenPt == lastShimmerCursorPos) return; 345 lastShimmerCursorPos = screenPt; 346 347 // Update label text colors based on cursor proximity 348 foreach (var lbl in shimmerLabels) 349 { 350 if (lbl.IsDisposed || !lbl.Visible || lbl.Parent == null) continue; 351 try 352 { 353 Point lblScreen = lbl.Parent.PointToScreen(new Point(lbl.Left + lbl.Width / 2, lbl.Top + lbl.Height / 2)); 354 float dx = screenPt.X - lblScreen.X; 355 float dy = screenPt.Y - lblScreen.Y; 356 float dist = (float)Math.Sqrt(dx * dx + dy * dy); 357 358 float glow = 0f; 359 if (dist < ShimmerFullRadius) glow = 1f; 360 else if (dist < ShimmerRadius) 361 { 362 float t = (dist - ShimmerFullRadius) / (ShimmerRadius - ShimmerFullRadius); 363 glow = 1f - t * t; 364 } 365 366 // Adaptive base and glow target 367 int cr = adaptiveDim.R + (int)((adaptiveGlow.R - adaptiveDim.R) * glow); 368 int cg = adaptiveDim.G + (int)((adaptiveGlow.G - adaptiveDim.G) * glow); 369 int cb = adaptiveDim.B + (int)((adaptiveGlow.B - adaptiveDim.B) * glow); 370 Color newColor = Color.FromArgb(cr, cg, cb); 371 372 if (lbl.ForeColor.ToArgb() != newColor.ToArgb()) 373 lbl.ForeColor = newColor; 374 } 375 catch { } 376 } 377 378 // Invalidate all glow-aware controls (borders, edges) 379 foreach (var ctrl in glowControls) 380 { 381 if (!ctrl.IsDisposed && ctrl.Visible) ctrl.Invalidate(); 382 } 383 384 // Invalidate panels with custom painting 385 if (tabPanel != null) tabPanel.Invalidate(); 386 if (titleBarRef != null) titleBarRef.Invalidate(); 387 if (buttonPanelRef != null) buttonPanelRef.Invalidate(); 388 Invalidate(); // dialog outer border 389 } 390 391 protected override void OnPaintBackground(PaintEventArgs e) 392 { 393 // Let DWM blur show through — paint mostly transparent 394 e.Graphics.Clear(Color.FromArgb(0, 0, 0, 0)); 395 } 396 397 protected override void OnPaint(PaintEventArgs e) 398 { 399 base.OnPaint(e); 400 // Glass outer border with cursor glow 401 Point sp = Cursor.Position; 402 Point cp; 403 try { cp = PointToClient(sp); } catch { cp = new Point(-999, -999); } 404 // Compute glow based on distance to nearest edge 405 float edgeDist = Math.Min(Math.Min(cp.X, Width - cp.X), Math.Min(cp.Y, Height - cp.Y)); 406 float edgeGlow = 0f; 407 if (edgeDist < 0) edgeDist = 0; 408 if (edgeDist < 80) edgeGlow = 1f - edgeDist / 80f; 409 int borderA = 40 + (int)(60 * edgeGlow); 410 using (var pen = new Pen(Color.FromArgb(borderA, AdaptiveTextColor), 1.0f)) 411 e.Graphics.DrawRectangle(pen, 0, 0, Width - 1, Height - 1); 412 } 413 414 private void TitleBar_Paint(object sender, PaintEventArgs e) 415 { 416 var p = (Panel)sender; 417 var g = e.Graphics; 418 // Glow on title bar bottom edge 419 Point sp = Cursor.Position; 420 Point lp; 421 try { lp = p.PointToClient(sp); } catch { lp = new Point(-999, -999); } 422 float dist = Math.Abs(lp.Y - p.Height); 423 float glow = dist < 60 ? 1f - dist / 60f : 0f; 424 int edgeA = 40 + (int)(60 * glow); 425 using (var pen = new Pen(Color.FromArgb(edgeA, AdaptiveTextColor), 1.0f)) 426 g.DrawLine(pen, 0, p.Height - 1, p.Width, p.Height - 1); 427 428 // Title text with shimmer 429 float textGlow = 0f; 430 float textDist = (float)Math.Sqrt((lp.X - 50) * (lp.X - 50) + (lp.Y - 18) * (lp.Y - 18)); 431 if (textDist < ShimmerFullRadius) textGlow = 1f; 432 else if (textDist < ShimmerRadius) { float t = (textDist - ShimmerFullRadius) / (ShimmerRadius - ShimmerFullRadius); textGlow = 1f - t * t; } 433 int tr = adaptiveDim.R + (int)((adaptiveGlow.R - adaptiveDim.R) * textGlow); 434 int tg = adaptiveDim.G + (int)((adaptiveGlow.G - adaptiveDim.G) * textGlow); 435 int tb = adaptiveDim.B + (int)((adaptiveGlow.B - adaptiveDim.B) * textGlow); 436 using (var brush = new SolidBrush(Color.FromArgb(tr, tg, tb))) 437 using (var font = new Font("Segoe UI", 11f, FontStyle.Regular, GraphicsUnit.Pixel)) 438 { 439 g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; 440 g.DrawString("Settings", font, brush, 14, 11); 441 } 442 } 443 444 private void TabPanel_Paint(object sender, PaintEventArgs e) 445 { 446 var g = e.Graphics; 447 int w = tabPanel.Width; 448 int h = tabPanel.Height; 449 450 // Get cursor position relative to tab panel for shimmer 451 Point screenPt = Cursor.Position; 452 Point localPt; 453 try { localPt = tabPanel.PointToClient(screenPt); } 454 catch { localPt = new Point(-999, -999); } 455 456 // Glass right edge (separator) with glow 457 float sepDist = Math.Abs(localPt.X - w); 458 float sepGlow = sepDist < 60 ? 1f - sepDist / 60f : 0f; 459 int sepA = 35 + (int)(50 * sepGlow); 460 using (var pen = new Pen(Color.FromArgb(sepA, AdaptiveTextColor), 1.0f)) 461 g.DrawLine(pen, w - 1, 0, w - 1, h); 462 463 int tabHeight = 36; 464 int y = 16; 465 466 for (int i = 0; i < tabNames.Length; i++) 467 { 468 bool sel = (i == selectedTab); 469 470 if (sel) 471 { 472 // Selected tab — subtle glass fill + left accent edge 473 using (var brush = new SolidBrush(Color.FromArgb(20, AdaptiveTextColor))) 474 g.FillRectangle(brush, 0, y, w - 1, tabHeight); 475 using (var pen = new Pen(Color.FromArgb(160, AdaptiveTextColor), 2f)) 476 g.DrawLine(pen, 1, y + 4, 1, y + tabHeight - 4); 477 } 478 479 // Compute shimmer glow for this tab label 480 float tabCenterX = w / 2f; 481 float tabCenterY = y + tabHeight / 2f; 482 float dx = localPt.X - tabCenterX; 483 float dy = localPt.Y - tabCenterY; 484 float dist = (float)Math.Sqrt(dx * dx + dy * dy); 485 float glow = 0f; 486 if (dist < ShimmerFullRadius) glow = 1f; 487 else if (dist < ShimmerRadius) 488 { 489 float t = (dist - ShimmerFullRadius) / (ShimmerRadius - ShimmerFullRadius); 490 glow = 1f - t * t; 491 } 492 493 Color baseC = sel ? adaptiveGlow : adaptiveDim; 494 int cr = baseC.R + (int)((adaptiveGlow.R - baseC.R) * glow); 495 int cg = baseC.G + (int)((adaptiveGlow.G - baseC.G) * glow); 496 int cb = baseC.B + (int)((adaptiveGlow.B - baseC.B) * glow); 497 Color tabColor = Color.FromArgb(cr, cg, cb); 498 499 using (var brush = new SolidBrush(tabColor)) 500 using (var font = new Font("Segoe UI", 11f, GraphicsUnit.Pixel)) 501 { 502 g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; 503 var sf = new StringFormat { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Center }; 504 g.DrawString(tabNames[i], font, brush, new Rectangle(16, y, w - 16, tabHeight), sf); 505 } 506 507 y += tabHeight; 508 } 509 } 510 511 private void ButtonPanel_Paint(object sender, PaintEventArgs e) 512 { 513 var p = (Panel)sender; 514 Point lp; 515 try { lp = p.PointToClient(Cursor.Position); } catch { lp = new Point(-999, -999); } 516 float dist = Math.Abs(lp.Y); 517 float glow = dist < 60 ? 1f - dist / 60f : 0f; 518 int edgeA = 40 + (int)(60 * glow); 519 using (var pen = new Pen(Color.FromArgb(edgeA, AdaptiveTextColor), 1.0f)) 520 e.Graphics.DrawLine(pen, 0, 0, p.Width, 0); 521 } 522 523 private void TabPanel_MouseClick(object sender, MouseEventArgs e) 524 { 525 int tabHeight = 36; 526 int y = 16; // must match TabPanel_Paint's starting offset (was 20 → 4px hit-test misalignment) 527 528 for (int i = 0; i < tabNames.Length; i++) 529 { 530 if (e.Y >= y && e.Y < y + tabHeight) 531 { 532 if (selectedTab != i) 533 { 534 tabPages[selectedTab].Visible = false; 535 selectedTab = i; 536 tabPages[selectedTab].Visible = true; 537 tabPanel.Invalidate(); 538 } 539 break; 540 } 541 y += tabHeight; 542 } 543 } 544 545 private Panel CreateGeneralPage() 546 { 547 var page = new GlassScrollPanel(); 548 page.Dock = DockStyle.Fill; 549 var inner = page.Content; 550 551 int y = 15; 552 int labelX = 15; 553 int controlX = 170; 554 555 AddLabel(inner, "Highlight Alpha:", labelX, y); 556 nudHighlightAlpha = AddNumeric(inner, controlX, y, 0, 255, Settings.HighlightAlpha); 557 y += 32; 558 559 AddLabel(inner, "Highlight Color:", labelX, y); 560 btnHighlightColor = AddColorButton(inner, controlX, y, Settings.HighlightColor); 561 y += 32; 562 563 AddLabel(inner, "Show Border:", labelX, y); 564 chkShowBorder = AddCheckBox(inner, controlX, y, Settings.ShowHighlightBorder); 565 y += 32; 566 567 AddLabel(inner, "Dim Around Selection:", labelX, y); 568 chkDimAround = AddCheckBox(inner, controlX, y, Settings.DimAroundSelection); 569 y += 32; 570 571 AddLabel(inner, "Border Color:", labelX, y); 572 btnHighlightBorderColor = AddColorButton(inner, controlX, y, Settings.HighlightBorderColor); 573 y += 32; 574 575 AddLabel(inner, "Border Width:", labelX, y); 576 nudBorderWidth = AddNumeric(inner, controlX, y, 1, 10, (int)Settings.HighlightBorderWidth); 577 y += 40; 578 579 AddLabel(inner, "Marker Size:", labelX, y); 580 nudMarkerSize = AddNumeric(inner, controlX, y, 16, 64, Settings.MarkerSize); 581 y += 32; 582 583 AddLabel(inner, "Marker Color:", labelX, y); 584 btnMarkerColor = AddColorButton(inner, controlX, y, Settings.MarkerColor); 585 y += 32; 586 587 AddLabel(inner, "Arrow Color:", labelX, y); 588 btnArrowColor = AddColorButton(inner, controlX, y, Settings.ArrowColor); 589 y += 40; 590 591 AddLabel(inner, "Auto-fit Window:", labelX, y); 592 chkAutoFit = AddCheckBox(inner, controlX, y, Settings.AutoFitToWindow); 593 y += 32; 594 595 AddLabel(inner, "Default Width:", labelX, y); 596 nudDefaultWidth = AddNumeric(inner, controlX, y, 400, 3840, Settings.DefaultWindowWidth); 597 y += 32; 598 599 AddLabel(inner, "Default Height:", labelX, y); 600 nudDefaultHeight = AddNumeric(inner, controlX, y, 300, 2160, Settings.DefaultWindowHeight); 601 y += 40; 602 603 // Window Appearance section — glass divider 604 AddSectionHeader(inner, "WINDOW APPEARANCE", labelX, y); 605 y += 28; 606 607 AddLabel(inner, "Tint Opacity:", labelX, y); 608 nudBlurTintAlpha = AddNumeric(inner, controlX, y, 0, 255, Settings.BlurTintAlpha); 609 nudBlurTintAlpha.ValueChanged += delegate { ApplyBlurPreview(); }; 610 y += 32; 611 612 AddLabel(inner, "Blur Tint Color:", labelX, y); 613 btnBlurTintColor = AddColorButton(inner, controlX, y, Settings.BlurTintColor); 614 btnBlurTintColor.BackColorChanged += delegate { ApplyBlurPreview(); }; 615 y += 32; 616 617 y += 0; // Blur mode removed — always BlurBehind with noise grain overlay 618 619 AddLabel(inner, "Corner Radius:", labelX, y); 620 nudCornerRadius = AddNumeric(inner, controlX, y, 0, 24, Settings.CornerRadius); 621 nudCornerRadius.ValueChanged += delegate { ApplyBlurPreview(); }; 622 y += 32; 623 624 AddLabel(inner, "Window Border:", labelX, y); 625 chkWindowBorder = AddCheckBox(inner, controlX, y, Settings.ShowWindowBorder); 626 chkWindowBorder.CheckedChanged += delegate { ApplyBlurPreview(); }; 627 y += 32; 628 629 AddLabel(inner, "Noise Grain:", labelX, y); 630 nudNoiseIntensity = AddNumeric(inner, controlX, y, 0, 30, Settings.NoiseIntensity); 631 nudNoiseIntensity.ValueChanged += delegate { ApplyBlurPreview(); }; 632 633 page.SetupScroll(); 634 page.HookChildWheelEvents(inner); 635 return page; 636 } 637 638 private Panel CreateEffectsPage() 639 { 640 var page = new GlassScrollPanel(); 641 page.Dock = DockStyle.Fill; 642 var inner = page.Content; 643 644 int y = 15; 645 int labelX = 15; 646 int controlX = 170; 647 648 AddLabel(inner, "Blur Radius:", labelX, y); 649 nudBlurRadius = AddFloatNumeric(inner, controlX, y, 0.1f, 10f, 0.1f, Settings.BlurRadius); 650 y += 32; 651 652 AddLabel(inner, "Motion Blur:", labelX, y); 653 nudMotionBlurDistance = AddNumeric(inner, controlX, y, 1, 50, Settings.MotionBlurDistance); 654 y += 32; 655 656 AddLabel(inner, "Dim Alpha:", labelX, y); 657 nudDimAlpha = AddNumeric(inner, controlX, y, 0, 255, Settings.DimAlpha); 658 y += 32; 659 660 AddLabel(inner, "Feather Width:", labelX, y); 661 nudFeatherWidth = AddNumeric(inner, controlX, y, 0, 50, Settings.FeatherWidth); 662 y += 40; 663 664 AddLabel(inner, "Fade Blur:", labelX, y); 665 chkEnableFadeBlur = AddCheckBox(inner, controlX, y, Settings.EnableFadeBlur); 666 y += 32; 667 668 AddLabel(inner, "Fade Width:", labelX, y); 669 nudFadeBlurWidth = AddNumeric(inner, controlX, y, 5, 100, Settings.FadeBlurWidth); 670 y += 50; 671 672 AddSectionHeader(inner, "TEXT BLOCK", labelX, y); 673 y += 28; 674 675 AddLabel(inner, "Font:", labelX, y); 676 cmbTextFont = new DarkComboBox(); 677 cmbTextFont.Location = new Point(controlX, y); 678 cmbTextFont.Size = new Size(160, 26); 679 var systemFonts = GetSystemFonts(); 680 foreach (string font in systemFonts) 681 cmbTextFont.Items.Add(font); 682 int fontIdx = systemFonts.IndexOf(Settings.TextBlockFont); 683 if (fontIdx >= 0) 684 cmbTextFont.SelectedIndex = fontIdx; 685 else if (cmbTextFont.Items.Count > 0) 686 cmbTextFont.SelectedIndex = 0; 687 inner.Controls.Add(cmbTextFont); 688 glowControls.Add(cmbTextFont); 689 y += 32; 690 691 AddLabel(inner, "Font Size:", labelX, y); 692 nudTextFontSize = AddNumeric(inner, controlX, y, 8, 300, (int)Settings.TextBlockFontSize); 693 y += 32; 694 695 AddLabel(inner, "Text Color:", labelX, y); 696 btnTextColor = AddColorButton(inner, controlX, y, Settings.TextBlockColor); 697 y += 32; 698 699 AddLabel(inner, "Shadow Color:", labelX, y); 700 btnTextShadowColor = AddColorButton(inner, controlX, y, Settings.TextBlockShadowColor); 701 y += 32; 702 703 AddLabel(inner, "Shadow Offset:", labelX, y); 704 nudShadowOffset = AddNumeric(inner, controlX, y, 0, 50, Settings.TextBlockShadowOffset); 705 706 page.SetupScroll(); 707 page.HookChildWheelEvents(inner); 708 return page; 709 } 710 711 private Panel CreateVideoPage() 712 { 713 var page = new GlassScrollPanel(); 714 page.Dock = DockStyle.Fill; 715 var inner = page.Content; 716 717 int y = 15; 718 int labelX = 15; 719 int controlX = 170; 720 721 AddSectionHeader(inner, "RECORDING", labelX, y); 722 y += 30; 723 724 AddLabel(inner, "FPS:", labelX, y); 725 nudVideoFps = AddNumeric(inner, controlX, y, 1, 120, Settings.VideoFps); 726 y += 32; 727 728 AddLabel(inner, "JPEG Quality:", labelX, y); 729 nudVideoJpegQuality = AddNumeric(inner, controlX, y, 10, 100, Settings.VideoJpegQuality); 730 y += 38; 731 732 AddSectionHeader(inner, "AUDIO", labelX, y); 733 y += 30; 734 735 AddLabel(inner, "System Audio:", labelX, y); 736 chkRecordSystemAudio = AddCheckBox(inner, controlX, y, Settings.RecordSystemAudio); 737 y += 32; 738 739 AddLabel(inner, "Microphone:", labelX, y); 740 chkRecordMicrophone = AddCheckBox(inner, controlX, y, Settings.RecordMicrophone); 741 y += 38; 742 743 // Info label 744 var infoLabel = new Label(); 745 infoLabel.Text = "Format: MJPEG AVI with PCM audio\nSystem Audio: captures desktop sound\nMicrophone: captures mic input\nBoth can be enabled simultaneously"; 746 infoLabel.ForeColor = Color.FromArgb(140, AdaptiveTextColor); 747 infoLabel.BackColor = Color.Transparent; 748 infoLabel.Font = new Font("Segoe UI", 8.5f); 749 infoLabel.Location = new Point(labelX, y + 5); 750 infoLabel.Size = new Size(280, 70); 751 inner.Controls.Add(infoLabel); 752 shimmerLabels.Add(infoLabel); 753 754 page.SetupScroll(); 755 page.HookChildWheelEvents(inner); 756 return page; 757 } 758 759 private Panel CreateKeysPage() 760 { 761 Panel page = new Panel(); 762 page.Dock = DockStyle.Fill; 763 page.BackColor = Color.Transparent; 764 765 int y = 15; 766 767 // Activation key setting 768 Label lblActivation = new Label(); 769 lblActivation.Text = "Activation (+ Win):"; 770 lblActivation.Location = new Point(15, y + 4); 771 lblActivation.AutoSize = true; 772 lblActivation.ForeColor = AdaptiveDimColor; 773 lblActivation.BackColor = Color.Transparent; 774 lblActivation.Font = new Font("Segoe UI", 11f, GraphicsUnit.Pixel); 775 page.Controls.Add(lblActivation); 776 shimmerLabels.Add(lblActivation); 777 778 cmbActivationKey = new DarkComboBox(); 779 cmbActivationKey.Location = new Point(170, y); 780 cmbActivationKey.Size = new Size(200, 26); 781 cmbActivationKey.AddItem("Alt"); 782 cmbActivationKey.AddItem("Ctrl"); 783 cmbActivationKey.AddItem("Shift"); 784 cmbActivationKey.AddItem("F1"); 785 cmbActivationKey.AddItem("F2"); 786 cmbActivationKey.AddItem("F3"); 787 cmbActivationKey.AddItem("F4"); 788 cmbActivationKey.AddItem("F5"); 789 cmbActivationKey.AddItem("F6"); 790 cmbActivationKey.AddItem("F7"); 791 cmbActivationKey.AddItem("F8"); 792 cmbActivationKey.AddItem("F9"); 793 cmbActivationKey.AddItem("F10"); 794 cmbActivationKey.AddItem("F11"); 795 cmbActivationKey.AddItem("F12"); 796 // Set current value 797 int activationIdx = cmbActivationKey.FindItem(Settings.ActivationKeyName); 798 if (activationIdx >= 0) cmbActivationKey.SelectedIndex = activationIdx; 799 page.Controls.Add(cmbActivationKey); 800 glowControls.Add(cmbActivationKey); 801 802 y += 45; 803 804 keysListPanel = new Panel(); 805 keysListPanel.Location = new Point(10, y); 806 keysListPanel.Size = new Size(390, 330); 807 keysListPanel.BackColor = Color.FromArgb(10, AdaptiveTextColor); 808 809 int listY = 10; 810 AddKeyRow(keysListPanel, "Capture Screen", KeyBindings.CaptureKey, 0, ref listY); 811 AddKeyRow(keysListPanel, "Copy and Close", KeyBindings.CopyAndClose, 1, ref listY); 812 AddKeyRow(keysListPanel, "Undo (Ctrl+)", KeyBindings.Undo, 2, ref listY); 813 AddKeyRow(keysListPanel, "Cancel", KeyBindings.Cancel, 3, ref listY); 814 815 Label lblInfo = new Label(); 816 lblInfo.Text = "Click on key to change binding"; 817 lblInfo.Location = new Point(10, y + 340); 818 lblInfo.AutoSize = true; 819 lblInfo.ForeColor = AdaptiveDimColor; 820 lblInfo.BackColor = Color.Transparent; 821 lblInfo.Font = new Font("Segoe UI", 10f, GraphicsUnit.Pixel); 822 page.Controls.Add(lblInfo); 823 shimmerLabels.Add(lblInfo); 824 825 page.Controls.Add(keysListPanel); 826 return page; 827 } 828 829 private Panel CreateTextPage() 830 { 831 Panel page = new Panel(); 832 page.Dock = DockStyle.Fill; 833 page.BackColor = Color.Transparent; 834 835 int y = 15; 836 837 // Section: Auto Language Switch 838 Label lblLangSection = new Label(); 839 lblLangSection.Text = "LANGUAGE"; 840 lblLangSection.Location = new Point(15, y); 841 lblLangSection.AutoSize = true; 842 lblLangSection.ForeColor = AccentColor; 843 lblLangSection.BackColor = Color.Transparent; 844 lblLangSection.Font = new Font("Segoe UI Semibold", 10f, GraphicsUnit.Pixel); 845 page.Controls.Add(lblLangSection); 846 shimmerLabels.Add(lblLangSection); 847 y += 22; 848 849 chkAutoLangSwitch = new CheckBox(); 850 chkAutoLangSwitch.Text = "Auto EN ↔ RU switch"; 851 chkAutoLangSwitch.Location = new Point(15, y); 852 chkAutoLangSwitch.Size = new Size(360, 24); 853 chkAutoLangSwitch.Checked = Settings.AutoLangSwitch; 854 chkAutoLangSwitch.ForeColor = AdaptiveDimColor; 855 chkAutoLangSwitch.BackColor = Color.Transparent; 856 chkAutoLangSwitch.Font = new Font("Segoe UI", 11f, GraphicsUnit.Pixel); 857 chkAutoLangSwitch.FlatStyle = FlatStyle.Flat; 858 page.Controls.Add(chkAutoLangSwitch); 859 glowControls.Add(chkAutoLangSwitch); 860 y += 30; 861 862 Label lblLangDesc = new Label(); 863 lblLangDesc.Text = "Detects wrong keyboard layout and auto-corrects typed word"; 864 lblLangDesc.Location = new Point(34, y); 865 lblLangDesc.AutoSize = true; 866 lblLangDesc.ForeColor = Color.FromArgb(80, AdaptiveTextColor); 867 lblLangDesc.BackColor = Color.Transparent; 868 lblLangDesc.Font = new Font("Segoe UI", 10f, GraphicsUnit.Pixel); 869 page.Controls.Add(lblLangDesc); 870 shimmerLabels.Add(lblLangDesc); 871 y += 35; 872 873 // Section: T9 Autocorrect 874 Label lblT9Section = new Label(); 875 lblT9Section.Text = "AUTOCORRECT"; 876 lblT9Section.Location = new Point(15, y); 877 lblT9Section.AutoSize = true; 878 lblT9Section.ForeColor = AccentColor; 879 lblT9Section.BackColor = Color.Transparent; 880 lblT9Section.Font = new Font("Segoe UI Semibold", 10f, GraphicsUnit.Pixel); 881 page.Controls.Add(lblT9Section); 882 shimmerLabels.Add(lblT9Section); 883 y += 22; 884 885 chkAutoT9 = new CheckBox(); 886 chkAutoT9.Text = "Enable T9 autocorrection"; 887 chkAutoT9.Location = new Point(15, y); 888 chkAutoT9.Size = new Size(360, 24); 889 chkAutoT9.Checked = Settings.AutoT9; 890 chkAutoT9.ForeColor = AdaptiveDimColor; 891 chkAutoT9.BackColor = Color.Transparent; 892 chkAutoT9.Font = new Font("Segoe UI", 11f, GraphicsUnit.Pixel); 893 chkAutoT9.FlatStyle = FlatStyle.Flat; 894 page.Controls.Add(chkAutoT9); 895 glowControls.Add(chkAutoT9); 896 y += 35; 897 898 Label lblSensitivity = new Label(); 899 lblSensitivity.Text = "Sensitivity:"; 900 lblSensitivity.Location = new Point(15, y + 4); 901 lblSensitivity.AutoSize = true; 902 lblSensitivity.ForeColor = AdaptiveDimColor; 903 lblSensitivity.BackColor = Color.Transparent; 904 lblSensitivity.Font = new Font("Segoe UI", 11f, GraphicsUnit.Pixel); 905 page.Controls.Add(lblSensitivity); 906 shimmerLabels.Add(lblSensitivity); 907 908 nudT9Sensitivity = new DarkNumeric(); 909 nudT9Sensitivity.Minimum = 1; 910 nudT9Sensitivity.Maximum = 5; 911 nudT9Sensitivity.Value = Settings.T9Sensitivity; 912 nudT9Sensitivity.Location = new Point(170, y); 913 nudT9Sensitivity.Size = new Size(80, 28); 914 page.Controls.Add(nudT9Sensitivity); 915 glowControls.Add(nudT9Sensitivity); 916 y += 40; 917 918 chkT9ShowTooltip = new CheckBox(); 919 chkT9ShowTooltip.Text = "Show correction tooltip"; 920 chkT9ShowTooltip.Location = new Point(15, y); 921 chkT9ShowTooltip.Size = new Size(360, 24); 922 chkT9ShowTooltip.Checked = Settings.T9ShowTooltip; 923 chkT9ShowTooltip.ForeColor = AdaptiveDimColor; 924 chkT9ShowTooltip.BackColor = Color.Transparent; 925 chkT9ShowTooltip.Font = new Font("Segoe UI", 11f, GraphicsUnit.Pixel); 926 chkT9ShowTooltip.FlatStyle = FlatStyle.Flat; 927 page.Controls.Add(chkT9ShowTooltip); 928 glowControls.Add(chkT9ShowTooltip); 929 930 return page; 931 } 932 933 private void AddKeyRow(Panel parent, string actionName, Keys key, int index, ref int y) 934 { 935 Label lblAction = new Label(); 936 lblAction.Text = actionName; 937 lblAction.Location = new Point(15, y + 8); 938 lblAction.Size = new Size(180, 24); 939 lblAction.ForeColor = AdaptiveDimColor; 940 lblAction.BackColor = Color.Transparent; 941 lblAction.Font = new Font("Segoe UI", 11f, GraphicsUnit.Pixel); 942 parent.Controls.Add(lblAction); 943 shimmerLabels.Add(lblAction); 944 945 Button btnKey = CreateButton(key.ToString(), 200, y, 170, 32); 946 btnKey.Tag = index; 947 btnKey.Click += BtnKey_Click; 948 parent.Controls.Add(btnKey); 949 950 y += 45; 951 } 952 953 private void BtnKey_Click(object sender, EventArgs e) 954 { 955 Button btn = (Button)sender; 956 int index = (int)btn.Tag; 957 958 string[] actions = { "Capture Screen", "Copy and Close", "Undo", "Cancel" }; 959 960 using (var dlg = new KeyCaptureDialog(actions[index])) 961 { 962 if (dlg.ShowDialog() == DialogResult.OK) 963 { 964 btn.Text = dlg.CapturedKey.ToString(); 965 } 966 } 967 } 968 969 private Button CreateButton(string text, int x, int y, int w, int h) 970 { 971 var btn = new Button(); 972 btn.Text = text; 973 btn.Location = new Point(x, y); 974 btn.Size = new Size(w, h); 975 btn.FlatStyle = FlatStyle.Flat; 976 btn.FlatAppearance.BorderSize = 0; 977 btn.FlatAppearance.MouseOverBackColor = Color.FromArgb(40, AdaptiveTextColor); 978 btn.FlatAppearance.MouseDownBackColor = Color.FromArgb(60, AdaptiveTextColor); 979 btn.BackColor = Color.FromArgb(15, AdaptiveTextColor); 980 btn.ForeColor = AdaptiveTextColor; 981 btn.Font = new Font("Segoe UI", 11f, GraphicsUnit.Pixel); 982 btn.Cursor = Cursors.Hand; 983 // Custom paint for glow border + adaptive text color 984 btn.Paint += (s, pe) => 985 { 986 var b = (Button)s; 987 b.ForeColor = AdaptiveTextColor; 988 float glow = ComputeGlow(b); 989 int borderA = 40 + (int)(60 * glow); 990 using (var pen = new Pen(Color.FromArgb(borderA, AdaptiveTextColor), 1f)) 991 pe.Graphics.DrawRectangle(pen, 0, 0, b.Width - 1, b.Height - 1); 992 }; 993 glowControls.Add(btn); 994 return btn; 995 } 996 997 private Label AddLabel(Control parent, string text, int x, int y) 998 { 999 Label lbl = new Label(); 1000 lbl.Text = text; 1001 lbl.Location = new Point(x, y + 4); 1002 lbl.AutoSize = true; 1003 lbl.ForeColor = AdaptiveDimColor; 1004 lbl.BackColor = Color.Transparent; 1005 lbl.Font = new Font("Segoe UI", 11f, GraphicsUnit.Pixel); 1006 parent.Controls.Add(lbl); 1007 shimmerLabels.Add(lbl); 1008 return lbl; 1009 } 1010 1011 private void AddSectionHeader(Control parent, string text, int x, int y) 1012 { 1013 var lbl = new Label(); 1014 lbl.Text = text; 1015 lbl.Location = new Point(x, y + 4); 1016 lbl.AutoSize = false; 1017 lbl.Size = new Size(parent.Width > 0 ? parent.Width - x * 2 : 380, 20); 1018 lbl.ForeColor = Color.FromArgb(140, AdaptiveTextColor); 1019 lbl.BackColor = Color.Transparent; 1020 lbl.Font = new Font("Segoe UI", 10f, GraphicsUnit.Pixel); 1021 lbl.Paint += (s, ev) => 1022 { 1023 var g = ev.Graphics; 1024 float glow = ComputeGlow(lbl); 1025 var sz = g.MeasureString(text, lbl.Font); 1026 int lineX = (int)sz.Width + 6; 1027 int lineA = 30 + (int)(40 * glow); 1028 using (var pen = new Pen(Color.FromArgb(lineA, AdaptiveTextColor), 1.0f)) 1029 g.DrawLine(pen, lineX, lbl.Height / 2, lbl.Width - 4, lbl.Height / 2); 1030 }; 1031 parent.Controls.Add(lbl); 1032 shimmerLabels.Add(lbl); 1033 glowControls.Add(lbl); 1034 } 1035 1036 private DarkNumeric AddNumeric(Control parent, int x, int y, int min, int max, int value) 1037 { 1038 DarkNumeric nud = new DarkNumeric(); 1039 nud.Location = new Point(x, y); 1040 nud.Size = new Size(80, 26); 1041 nud.Minimum = min; 1042 nud.Maximum = max; 1043 nud.Value = Math.Max(min, Math.Min(max, value)); 1044 parent.Controls.Add(nud); 1045 glowControls.Add(nud); 1046 return nud; 1047 } 1048 1049 private DarkFloatNumeric AddFloatNumeric(Control parent, int x, int y, float min, float max, float step, float value) 1050 { 1051 DarkFloatNumeric nud = new DarkFloatNumeric(); 1052 nud.Location = new Point(x, y); 1053 nud.Size = new Size(80, 26); 1054 nud.Minimum = min; 1055 nud.Maximum = max; 1056 nud.Step = step; 1057 nud.Value = Math.Max(min, Math.Min(max, value)); 1058 parent.Controls.Add(nud); 1059 glowControls.Add(nud); 1060 return nud; 1061 } 1062 1063 private CheckBox AddCheckBox(Control parent, int x, int y, bool isChecked) 1064 { 1065 CheckBox chk = new CheckBox(); 1066 chk.Location = new Point(x, y + 2); 1067 chk.Checked = isChecked; 1068 chk.AutoSize = false; 1069 chk.Size = new Size(22, 22); 1070 chk.ForeColor = AdaptiveTextColor; 1071 chk.BackColor = Color.Transparent; 1072 chk.FlatStyle = FlatStyle.Flat; 1073 chk.FlatAppearance.BorderSize = 0; 1074 chk.Font = new Font("Segoe UI", 11f, GraphicsUnit.Pixel); 1075 chk.Appearance = Appearance.Button; 1076 // Custom paint: dark-themed toggle 1077 chk.Paint += (s, pe) => 1078 { 1079 var cb = (CheckBox)s; 1080 var g = pe.Graphics; 1081 g.SmoothingMode = SmoothingMode.AntiAlias; 1082 float glow = ComputeGlow(cb); 1083 1084 // Glass box 1085 int fillA = cb.Checked ? 30 + (int)(20 * glow) : 8 + (int)(12 * glow); 1086 Color ge = Color.FromArgb(225, 232, 245); 1087 using (var brush = new SolidBrush(Color.FromArgb(fillA, ge))) 1088 g.FillRectangle(brush, 2, 2, cb.Width - 4, cb.Height - 4); 1089 int borderA = 40 + (int)(60 * glow); 1090 using (var pen = new Pen(Color.FromArgb(borderA, ge), 1f)) 1091 g.DrawRectangle(pen, 2, 2, cb.Width - 5, cb.Height - 5); 1092 1093 // Checkmark 1094 if (cb.Checked) 1095 { 1096 int a = 180 + (int)(60 * glow); 1097 using (var pen = new Pen(Color.FromArgb(a, AccentColor), 2f)) 1098 { 1099 pen.StartCap = System.Drawing.Drawing2D.LineCap.Round; 1100 pen.EndCap = System.Drawing.Drawing2D.LineCap.Round; 1101 g.DrawLine(pen, 6, cb.Height / 2, 9, cb.Height / 2 + 3); 1102 g.DrawLine(pen, 9, cb.Height / 2 + 3, cb.Width - 6, cb.Height / 2 - 4); 1103 } 1104 } 1105 }; 1106 parent.Controls.Add(chk); 1107 glowControls.Add(chk); 1108 return chk; 1109 } 1110 1111 private Button AddColorButton(Control parent, int x, int y, Color color) 1112 { 1113 Button btn = new Button(); 1114 btn.Location = new Point(x, y); 1115 btn.Size = new Size(80, 26); 1116 btn.BackColor = color; 1117 btn.FlatStyle = FlatStyle.Flat; 1118 btn.FlatAppearance.BorderSize = 0; 1119 btn.Cursor = Cursors.Hand; 1120 // Custom paint — explicitly draw color swatch so it works on DWM-blurred windows 1121 btn.Paint += (s, pe) => 1122 { 1123 var b = (Button)s; 1124 var g = pe.Graphics; 1125 // Draw solid color fill (the actual selected color) 1126 using (var brush = new SolidBrush(b.BackColor)) 1127 g.FillRectangle(brush, 2, 2, b.Width - 4, b.Height - 4); 1128 // Glass border with glow 1129 float glow = ComputeGlow(b); 1130 int borderA = 40 + (int)(60 * glow); 1131 using (var pen = new Pen(Color.FromArgb(borderA, AdaptiveTextColor), 1f)) 1132 g.DrawRectangle(pen, 0, 0, b.Width - 1, b.Height - 1); 1133 }; 1134 btn.Click += delegate 1135 { 1136 using (var dlg = new DarkColorPicker(btn.BackColor)) 1137 { 1138 if (dlg.ShowDialog() == DialogResult.OK) 1139 { 1140 btn.BackColor = dlg.SelectedColor; 1141 } 1142 } 1143 }; 1144 parent.Controls.Add(btn); 1145 glowControls.Add(btn); 1146 return btn; 1147 } 1148 1149 private void LoadSettings() 1150 { 1151 } 1152 1153 /// <summary>Restore original blur settings when Cancel is pressed.</summary> 1154 private void RestoreBlurSettings() 1155 { 1156 Settings.BlurTintAlpha = origBlurTintAlpha; 1157 Settings.BlurTintColor = origBlurTintColor; 1158 Settings.CornerRadius = origCornerRadius; 1159 Settings.ShowWindowBorder = origShowBorder; 1160 Settings.NoiseIntensity = origNoiseIntensity; 1161 1162 foreach (Form f in Application.OpenForms) 1163 { 1164 var editor = f as EditorForm; 1165 if (editor != null) 1166 { 1167 Helpers.BlurHelper.Apply(editor.Handle); 1168 editor.ApplyRoundedCorners(); 1169 editor.Invalidate(true); 1170 } 1171 } 1172 } 1173 1174 /// <summary>Live preview: apply appearance changes to the parent editor window in real-time.</summary> 1175 private void ApplyBlurPreview() 1176 { 1177 if (nudBlurTintAlpha == null || btnBlurTintColor == null) return; 1178 1179 Settings.BlurTintAlpha = nudBlurTintAlpha.Value; 1180 Settings.BlurTintColor = btnBlurTintColor.BackColor; 1181 if (nudCornerRadius != null) Settings.CornerRadius = nudCornerRadius.Value; 1182 if (chkWindowBorder != null) Settings.ShowWindowBorder = chkWindowBorder.Checked; 1183 if (nudNoiseIntensity != null) Settings.NoiseIntensity = nudNoiseIntensity.Value; 1184 1185 // Apply to ALL open editor forms 1186 foreach (Form f in Application.OpenForms) 1187 { 1188 var editor = f as EditorForm; 1189 if (editor != null) 1190 { 1191 Helpers.BlurHelper.Apply(editor.Handle); 1192 editor.ApplyRoundedCorners(); 1193 editor.Invalidate(true); 1194 } 1195 } 1196 1197 // Also update this dialog 1198 Helpers.BlurHelper.Apply(Handle); 1199 1200 // Recompute adaptive colors based on new tint 1201 ComputeAdaptiveColors(); 1202 Invalidate(true); 1203 } 1204 1205 private void SaveSettings() 1206 { 1207 Settings.HighlightAlpha = nudHighlightAlpha.Value; 1208 Settings.HighlightColor = btnHighlightColor.BackColor; 1209 Settings.ShowHighlightBorder = chkShowBorder.Checked; 1210 Settings.DimAroundSelection = chkDimAround.Checked; 1211 Settings.HighlightBorderColor = btnHighlightBorderColor.BackColor; 1212 Settings.HighlightBorderWidth = nudBorderWidth.Value; 1213 Settings.MarkerSize = nudMarkerSize.Value; 1214 Settings.MarkerColor = btnMarkerColor.BackColor; 1215 Settings.ArrowColor = btnArrowColor.BackColor; 1216 Settings.AutoFitToWindow = chkAutoFit.Checked; 1217 Settings.DefaultWindowWidth = nudDefaultWidth.Value; 1218 Settings.DefaultWindowHeight = nudDefaultHeight.Value; 1219 Settings.BlurTintAlpha = nudBlurTintAlpha.Value; 1220 Settings.BlurTintColor = btnBlurTintColor.BackColor; 1221 Settings.BlurMode = 0; 1222 Settings.CornerRadius = nudCornerRadius.Value; 1223 Settings.ShowWindowBorder = chkWindowBorder.Checked; 1224 Settings.NoiseIntensity = nudNoiseIntensity.Value; 1225 1226 Settings.BlurRadius = nudBlurRadius.Value; 1227 Settings.MotionBlurDistance = nudMotionBlurDistance.Value; 1228 Settings.DimAlpha = nudDimAlpha.Value; 1229 Settings.FeatherWidth = nudFeatherWidth.Value; 1230 Settings.EnableFadeBlur = chkEnableFadeBlur.Checked; 1231 Settings.FadeBlurWidth = nudFadeBlurWidth.Value; 1232 Settings.TextBlockFont = cmbTextFont.SelectedItem; 1233 Settings.TextBlockFontSize = (float)nudTextFontSize.Value; 1234 Settings.TextBlockColor = btnTextColor.BackColor; 1235 Settings.TextBlockShadowColor = btnTextShadowColor.BackColor; 1236 Settings.TextBlockShadowOffset = nudShadowOffset.Value; 1237 1238 Settings.VideoFps = nudVideoFps.Value; 1239 Settings.VideoJpegQuality = nudVideoJpegQuality.Value; 1240 Settings.RecordSystemAudio = chkRecordSystemAudio.Checked; 1241 Settings.RecordMicrophone = chkRecordMicrophone.Checked; 1242 1243 // Save text processing settings 1244 Settings.AutoLangSwitch = chkAutoLangSwitch.Checked; 1245 Settings.AutoT9 = chkAutoT9.Checked; 1246 Settings.T9Sensitivity = nudT9Sensitivity.Value; 1247 Settings.T9ShowTooltip = chkT9ShowTooltip.Checked; 1248 1249 // Save activation key 1250 if (cmbActivationKey != null && cmbActivationKey.SelectedIndex >= 0) 1251 { 1252 string keyName = cmbActivationKey.SelectedItem; 1253 Settings.ActivationKeyName = keyName; 1254 Settings.ActivationKey = GetVirtualKeyCode(keyName); 1255 } 1256 1257 foreach (Control c in keysListPanel.Controls) 1258 { 1259 Button btn = c as Button; 1260 if (btn != null && btn.Tag != null) 1261 { 1262 int index = (int)btn.Tag; 1263 Keys key; 1264 if (Enum.TryParse(btn.Text, out key)) 1265 { 1266 switch (index) 1267 { 1268 case 0: KeyBindings.CaptureKey = key; break; 1269 case 1: KeyBindings.CopyAndClose = key; break; 1270 case 2: KeyBindings.Undo = key; break; 1271 case 3: KeyBindings.Cancel = key; break; 1272 } 1273 } 1274 } 1275 } 1276 1277 Settings.Save(); 1278 KeyBindings.Save(); 1279 } 1280 1281 private void ResetToDefaults() 1282 { 1283 Settings.ResetDefaults(); 1284 KeyBindings.ResetDefaults(); 1285 1286 nudHighlightAlpha.Value = Settings.HighlightAlpha; 1287 btnHighlightColor.BackColor = Settings.HighlightColor; 1288 chkShowBorder.Checked = Settings.ShowHighlightBorder; 1289 chkDimAround.Checked = Settings.DimAroundSelection; 1290 btnHighlightBorderColor.BackColor = Settings.HighlightBorderColor; 1291 nudBorderWidth.Value = (int)Settings.HighlightBorderWidth; 1292 nudMarkerSize.Value = Settings.MarkerSize; 1293 btnMarkerColor.BackColor = Settings.MarkerColor; 1294 btnArrowColor.BackColor = Settings.ArrowColor; 1295 chkAutoFit.Checked = Settings.AutoFitToWindow; 1296 nudDefaultWidth.Value = Settings.DefaultWindowWidth; 1297 nudDefaultHeight.Value = Settings.DefaultWindowHeight; 1298 nudBlurTintAlpha.Value = Settings.BlurTintAlpha; 1299 btnBlurTintColor.BackColor = Settings.BlurTintColor; 1300 1301 nudCornerRadius.Value = Settings.CornerRadius; 1302 chkWindowBorder.Checked = Settings.ShowWindowBorder; 1303 nudBlurRadius.Value = Settings.BlurRadius; 1304 nudMotionBlurDistance.Value = Settings.MotionBlurDistance; 1305 nudDimAlpha.Value = Settings.DimAlpha; 1306 nudFeatherWidth.Value = Settings.FeatherWidth; 1307 chkEnableFadeBlur.Checked = Settings.EnableFadeBlur; 1308 nudFadeBlurWidth.Value = Settings.FadeBlurWidth; 1309 var fonts = GetSystemFonts(); 1310 int fontIdx = fonts.IndexOf(Settings.TextBlockFont); 1311 if (fontIdx >= 0) cmbTextFont.SelectedIndex = fontIdx; 1312 nudTextFontSize.Value = (int)Settings.TextBlockFontSize; 1313 btnTextColor.BackColor = Settings.TextBlockColor; 1314 btnTextShadowColor.BackColor = Settings.TextBlockShadowColor; 1315 nudShadowOffset.Value = Settings.TextBlockShadowOffset; 1316 1317 foreach (Control c in keysListPanel.Controls) 1318 { 1319 Button btn = c as Button; 1320 if (btn != null && btn.Tag != null) 1321 { 1322 int index = (int)btn.Tag; 1323 switch (index) 1324 { 1325 case 0: btn.Text = KeyBindings.CaptureKey.ToString(); break; 1326 case 1: btn.Text = KeyBindings.CopyAndClose.ToString(); break; 1327 case 2: btn.Text = KeyBindings.Undo.ToString(); break; 1328 case 3: btn.Text = KeyBindings.Cancel.ToString(); break; 1329 } 1330 } 1331 } 1332 1333 // Reset activation key 1334 int activationIdx = cmbActivationKey.FindItem(Settings.ActivationKeyName); 1335 if (activationIdx >= 0) cmbActivationKey.SelectedIndex = activationIdx; 1336 1337 // Reset text processing 1338 chkAutoLangSwitch.Checked = Settings.AutoLangSwitch; 1339 chkAutoT9.Checked = Settings.AutoT9; 1340 nudT9Sensitivity.Value = Settings.T9Sensitivity; 1341 chkT9ShowTooltip.Checked = Settings.T9ShowTooltip; 1342 } 1343 1344 private int GetVirtualKeyCode(string keyName) 1345 { 1346 switch (keyName) 1347 { 1348 case "Alt": return 0xA4; // VK_LMENU 1349 case "Ctrl": return 0xA2; // VK_LCONTROL 1350 case "Shift": return 0xA0; // VK_LSHIFT 1351 case "F1": return 0x70; 1352 case "F2": return 0x71; 1353 case "F3": return 0x72; 1354 case "F4": return 0x73; 1355 case "F5": return 0x74; 1356 case "F6": return 0x75; 1357 case "F7": return 0x76; 1358 case "F8": return 0x77; 1359 case "F9": return 0x78; 1360 case "F10": return 0x79; 1361 case "F11": return 0x7A; 1362 case "F12": return 0x7B; 1363 default: return 0xA4; // Default to Alt 1364 } 1365 } 1366 1367 protected override void Dispose(bool disposing) 1368 { 1369 if (disposing) 1370 { 1371 if (shimmerTimer != null) { shimmerTimer.Stop(); shimmerTimer.Dispose(); shimmerTimer = null; } 1372 if (bgCapture != null) { bgCapture.Dispose(); bgCapture = null; } 1373 } 1374 base.Dispose(disposing); 1375 } 1376 } 1377}