windowcapture
исходный код / Models/Settings.cs

Settings.cs

389 строк · 21,955 байт · модуль Models
  1using System;
  2using System.Collections.Generic;
  3using System.Drawing;
  4using System.IO;
  5using WindowCapture.Helpers;
  6
  7namespace WindowCapture.Models
  8{
  9    public static class Settings
 10    {
 11        static string settingsPath = Path.Combine(
 12            AppDomain.CurrentDomain.BaseDirectory, "settings.ini");
 13
 14        // Arrow settings
 15        public static Color ArrowColor = Color.FromArgb(255, 220, 60, 60);
 16        public static float ArrowWidth = 3f;
 17        public static int ShadowOffset = 3;
 18        public static int ShadowAlpha = 100;
 19
 20        // Marker settings
 21        public static Color MarkerColor = Color.FromArgb(230, 220, 60, 60);
 22        public static Color MarkerTextColor = Color.White;
 23        public static int MarkerRadius = 16;
 24        public static string MarkerFont = "Segoe UI";
 25        public static float MarkerFontSize = 12f;
 26
 27        // Highlight settings
 28        public static Color HighlightColor = Color.FromArgb(255, 255, 255, 0);
 29        public static int HighlightAlpha = 60;
 30        public static Color HighlightBorderColor = Color.FromArgb(255, 255, 100, 100);
 31        public static float HighlightBorderWidth = 2f;
 32        public static int DimAlpha = 120;
 33        public static bool ShowHighlightBorder = true;
 34        // When true, drawing a highlight automatically dims everything around it (spotlight focus).
 35        public static bool DimAroundSelection = true;
 36
 37        // Marker settings (extended)
 38        public static int MarkerSize = 32;
 39        public static Color MarkerBorderColor = Color.FromArgb(255, 180, 40, 40);
 40
 41        // Text block settings
 42        public static string TextBlockFont = "Segoe UI";
 43        public static float TextBlockFontSize = 14f;
 44        public static Color TextBlockColor = Color.White;
 45        public static Color TextBlockShadowColor = Color.FromArgb(150, 0, 0, 0);
 46        public static int TextBlockShadowOffset = 2;
 47
 48        // Comment bubble settings
 49        public static string BubbleFont = "Segoe UI";
 50        public static float BubbleFontSize = 12f;
 51        public static Color BubbleFillColor = Color.White;
 52        public static Color BubbleBorderColor = Color.Black;
 53        public static int BubbleBorderWidth = 2;
 54
 55        // Blur settings
 56        public static float BlurRadius = 1.0f; // Base blur radius (will be scaled by resolution)
 57        public static int MotionBlurDistance = 15;
 58        public static int ReferenceResolution = 1920; // Reference width for blur scaling
 59        public static int FeatherWidth = 5;
 60        public static bool EnableFadeBlur = false;
 61        public static int FadeBlurWidth = 20;
 62
 63        // Window settings
 64        public static int DefaultWindowWidth = 1200;
 65        public static int DefaultWindowHeight = 800;
 66        public static bool AutoFitToWindow = true;
 67
 68        // Window appearance
 69        public static int BlurTintAlpha = 232; // 0xE8
 70        public static Color BlurTintColor = Color.FromArgb(255, 24, 20, 20);
 71        public static int BlurMode = 0; // 0=BlurBehind (less blur), 1=Acrylic (more blur)
 72        public static int CornerRadius = 12;
 73        public static bool ShowWindowBorder = true;
 74        public static int NoiseIntensity = 12; // 0=none, 1-30 grain alpha
 75
 76        // Activation key (virtual key code)
 77        // Default is Alt (VK_MENU = 0x12, VK_LMENU = 0xA4, VK_RMENU = 0xA5)
 78        public static int ActivationKey = 0xA4; // Left Alt by default
 79        public static string ActivationKeyName = "Alt";
 80
 81        // Video recording settings
 82        public static int VideoFps = 60;
 83        public static int VideoJpegQuality = 90;
 84        public static bool RecordSystemAudio = true;
 85        public static bool RecordMicrophone = false;
 86
 87        // Audio player window size
 88        public static int AudioPlayerW = 440;
 89        public static float AudioVolume = 0.85f;
 90
 91        // Text processing: auto language switch + T9
 92        public static bool AutoLangSwitch = true;
 93        public static bool AutoT9 = true;
 94        public static int T9Sensitivity = 3; // 1-5
 95        public static bool T9ShowTooltip = true;
 96        public static bool AutoCapitalize = true;
 97        public static bool AutoPunctuation = true;
 98        public static bool ClipboardHistory = true;
 99        // Live SAGE full-sentence suggestion on sentence end (non-destructive tooltip). Off by default.
100        public static bool SentenceAiSuggest = false;
101        // Auto-apply the SAGE sentence correction in place (backspace+type at caret). Experimental, off.
102        public static bool SentenceAiAutoApply = false;
103        // Per-word context neural rescore (rubert-tiny2 stage-2 of the pipeline). Experimental, off.
104        public static bool ContextNnRescore = false;
105        // Localhost bridge for the native TSF TIP (universal in-place edit, Tip/WCTip.cpp). Experimental, off.
106        public static bool TsfBridge = false;
107
108        // ===== Unified MediaCore app: which modules are active (toggled live from the tray menu) =====
109        // Only Screenshot defaults ON (benign Alt+Win hotkey). The modules that inject keystrokes or
110        // hook the mouse — autocorrect, clipboard Ctrl+V intercept, gestures — are OPT-IN so a fresh
111        // launch never touches the user's typing or mouse until they knowingly enable it.
112        public static bool ModuleScreenshot = true;
113        public static bool ModuleTextAssist = false;
114        public static bool ModuleClipboard = false;
115        public static bool ModuleGestures = false;
116
117        public static void Load()
118        {
119            try
120            {
121                if (!File.Exists(settingsPath)) return;
122                foreach (var line in File.ReadAllLines(settingsPath))
123                {
124                    // Split on the first '=' only, so values containing '=' are preserved.
125                    int eq = line.IndexOf('=');
126                    if (eq < 0) continue;
127                    var key = line.Substring(0, eq).Trim();
128                    var val = line.Substring(eq + 1).Trim();
129
130                    // Per-line guard: a single malformed value must not abort the whole load.
131                    try
132                    {
133                    switch (key)
134                    {
135                        case "ArrowColor": ArrowColor = ColorFromHex(val); break;
136                        case "ArrowWidth": ArrowWidth = float.Parse(val, System.Globalization.CultureInfo.InvariantCulture); break;
137                        case "ShadowOffset": ShadowOffset = int.Parse(val); break;
138                        case "ShadowAlpha": ShadowAlpha = int.Parse(val); break;
139                        case "MarkerColor": MarkerColor = ColorFromHex(val); break;
140                        case "MarkerTextColor": MarkerTextColor = ColorFromHex(val); break;
141                        case "MarkerRadius": MarkerRadius = int.Parse(val); break;
142                        case "MarkerFont": MarkerFont = val; break;
143                        case "MarkerFontSize": MarkerFontSize = float.Parse(val, System.Globalization.CultureInfo.InvariantCulture); break;
144                        case "HighlightBorderColor": HighlightBorderColor = ColorFromHex(val); break;
145                        case "HighlightBorderWidth": HighlightBorderWidth = float.Parse(val, System.Globalization.CultureInfo.InvariantCulture); break;
146                        case "DimAlpha": DimAlpha = int.Parse(val); break;
147                        case "ShowHighlightBorder": ShowHighlightBorder = val == "1" || val.ToLower() == "true"; break;
148                        case "DimAroundSelection": DimAroundSelection = val == "1" || val.ToLower() == "true"; break;
149                        case "TextBlockFont": TextBlockFont = val; break;
150                        case "TextBlockFontSize": TextBlockFontSize = float.Parse(val, System.Globalization.CultureInfo.InvariantCulture); break;
151                        case "TextBlockColor": TextBlockColor = ColorFromHex(val); break;
152                        case "TextBlockShadowColor": TextBlockShadowColor = ColorFromHex(val); break;
153                        case "TextBlockShadowOffset": TextBlockShadowOffset = int.Parse(val); break;
154                        case "BubbleFont": BubbleFont = val; break;
155                        case "BubbleFontSize": BubbleFontSize = float.Parse(val, System.Globalization.CultureInfo.InvariantCulture); break;
156                        case "BubbleFillColor": BubbleFillColor = ColorFromHex(val); break;
157                        case "BubbleBorderColor": BubbleBorderColor = ColorFromHex(val); break;
158                        case "BubbleBorderWidth": BubbleBorderWidth = int.Parse(val); break;
159                        case "BlurRadius": BlurRadius = float.Parse(val, System.Globalization.CultureInfo.InvariantCulture); break;
160                        case "MotionBlurDistance": MotionBlurDistance = int.Parse(val); break;
161                        case "FeatherWidth": FeatherWidth = int.Parse(val); break;
162                        case "EnableFadeBlur": EnableFadeBlur = val == "1" || val.ToLower() == "true"; break;
163                        case "FadeBlurWidth": FadeBlurWidth = int.Parse(val); break;
164                        case "DefaultWindowWidth": DefaultWindowWidth = int.Parse(val); break;
165                        case "DefaultWindowHeight": DefaultWindowHeight = int.Parse(val); break;
166                        case "AutoFitToWindow": AutoFitToWindow = val == "1" || val.ToLower() == "true"; break;
167                        case "BlurTintAlpha": BlurTintAlpha = int.Parse(val); break;
168                        case "BlurTintColor": BlurTintColor = ColorFromHex(val); break;
169                        case "BlurMode": BlurMode = int.Parse(val); break;
170                        case "CornerRadius": CornerRadius = int.Parse(val); break;
171                        case "ShowWindowBorder": ShowWindowBorder = val == "1" || val.ToLower() == "true"; break;
172                        case "NoiseIntensity": NoiseIntensity = Math.Max(0, Math.Min(30, int.Parse(val))); break;
173                        case "ActivationKey": ActivationKey = int.Parse(val); break;
174                        case "ActivationKeyName": ActivationKeyName = val; break;
175                        case "VideoFps": VideoFps = Math.Max(1, Math.Min(120, int.Parse(val))); break;
176                        case "VideoJpegQuality": VideoJpegQuality = Math.Max(10, Math.Min(100, int.Parse(val))); break;
177                        case "RecordSystemAudio": RecordSystemAudio = val == "1" || val.ToLower() == "true"; break;
178                        case "RecordMicrophone": RecordMicrophone = val == "1" || val.ToLower() == "true"; break;
179                        case "AudioPlayerW": AudioPlayerW = int.Parse(val); break;
180                        case "AudioVolume": AudioVolume = float.Parse(val, System.Globalization.CultureInfo.InvariantCulture); break;
181                        case "AutoLangSwitch": AutoLangSwitch = val == "1" || val.ToLower() == "true"; break;
182                        case "AutoT9": AutoT9 = val == "1" || val.ToLower() == "true"; break;
183                        case "T9Sensitivity": T9Sensitivity = Math.Max(1, Math.Min(5, int.Parse(val))); break;
184                        case "T9ShowTooltip": T9ShowTooltip = val == "1" || val.ToLower() == "true"; break;
185                        case "AutoCapitalize": AutoCapitalize = val == "1" || val.ToLower() == "true"; break;
186                        case "AutoPunctuation": AutoPunctuation = val == "1" || val.ToLower() == "true"; break;
187                        case "ClipboardHistory": ClipboardHistory = val == "1" || val.ToLower() == "true"; break;
188                        case "SentenceAiSuggest": SentenceAiSuggest = val == "1" || val.ToLower() == "true"; break;
189                        case "SentenceAiAutoApply": SentenceAiAutoApply = val == "1" || val.ToLower() == "true"; break;
190                        case "ContextNnRescore": ContextNnRescore = val == "1" || val.ToLower() == "true"; break;
191                        case "TsfBridge": TsfBridge = val == "1" || val.ToLower() == "true"; break;
192                        case "ModuleScreenshot": ModuleScreenshot = val == "1" || val.ToLower() == "true"; break;
193                        case "ModuleTextAssist": ModuleTextAssist = val == "1" || val.ToLower() == "true"; break;
194                        case "ModuleClipboard": ModuleClipboard = val == "1" || val.ToLower() == "true"; break;
195                        case "ModuleGestures": ModuleGestures = val == "1" || val.ToLower() == "true"; break;
196                        // Previously missing from Load() — these silently reverted to defaults on every restart.
197                        case "HighlightColor": HighlightColor = ColorFromHex(val); break;
198                        case "HighlightAlpha": HighlightAlpha = Math.Max(0, Math.Min(255, int.Parse(val))); break;
199                        case "MarkerSize": MarkerSize = int.Parse(val); break;
200                        case "MarkerBorderColor": MarkerBorderColor = ColorFromHex(val); break;
201                        case "ReferenceResolution": ReferenceResolution = int.Parse(val); break;
202                    }
203                    }
204                    catch { /* skip this malformed line, keep loading the rest */ }
205                }
206            }
207            catch { }
208        }
209
210        public static void Save()
211        {
212            try
213            {
214                var dir = Path.GetDirectoryName(settingsPath);
215                if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
216
217                var lines = new List<string>
218                {
219                    "ArrowColor=" + ColorToHex(ArrowColor),
220                    "ArrowWidth=" + ArrowWidth.ToString(System.Globalization.CultureInfo.InvariantCulture),
221                    "ShadowOffset=" + ShadowOffset,
222                    "ShadowAlpha=" + ShadowAlpha,
223                    "MarkerColor=" + ColorToHex(MarkerColor),
224                    "MarkerTextColor=" + ColorToHex(MarkerTextColor),
225                    "MarkerRadius=" + MarkerRadius,
226                    "MarkerFont=" + MarkerFont,
227                    "MarkerFontSize=" + MarkerFontSize.ToString(System.Globalization.CultureInfo.InvariantCulture),
228                    "HighlightBorderColor=" + ColorToHex(HighlightBorderColor),
229                    "HighlightBorderWidth=" + HighlightBorderWidth.ToString(System.Globalization.CultureInfo.InvariantCulture),
230                    "DimAlpha=" + DimAlpha,
231                    "ShowHighlightBorder=" + (ShowHighlightBorder ? "1" : "0"),
232                    "DimAroundSelection=" + (DimAroundSelection ? "1" : "0"),
233                    "TextBlockFont=" + TextBlockFont,
234                    "TextBlockFontSize=" + TextBlockFontSize.ToString(System.Globalization.CultureInfo.InvariantCulture),
235                    "TextBlockColor=" + ColorToHex(TextBlockColor),
236                    "TextBlockShadowColor=" + ColorToHex(TextBlockShadowColor),
237                    "TextBlockShadowOffset=" + TextBlockShadowOffset,
238                    "BubbleFont=" + BubbleFont,
239                    "BubbleFontSize=" + BubbleFontSize.ToString(System.Globalization.CultureInfo.InvariantCulture),
240                    "BubbleFillColor=" + ColorToHex(BubbleFillColor),
241                    "BubbleBorderColor=" + ColorToHex(BubbleBorderColor),
242                    "BubbleBorderWidth=" + BubbleBorderWidth,
243                    "BlurRadius=" + BlurRadius.ToString(System.Globalization.CultureInfo.InvariantCulture),
244                    "MotionBlurDistance=" + MotionBlurDistance,
245                    "FeatherWidth=" + FeatherWidth,
246                    "EnableFadeBlur=" + (EnableFadeBlur ? "1" : "0"),
247                    "FadeBlurWidth=" + FadeBlurWidth,
248                    "DefaultWindowWidth=" + DefaultWindowWidth,
249                    "DefaultWindowHeight=" + DefaultWindowHeight,
250                    "AutoFitToWindow=" + (AutoFitToWindow ? "1" : "0"),
251                    "BlurTintAlpha=" + BlurTintAlpha,
252                    "BlurTintColor=" + ColorToHex(BlurTintColor),
253                    "BlurMode=" + BlurMode,
254                    "CornerRadius=" + CornerRadius,
255                    "ShowWindowBorder=" + (ShowWindowBorder ? "1" : "0"),
256                    "NoiseIntensity=" + NoiseIntensity,
257                    "ActivationKey=" + ActivationKey,
258                    "ActivationKeyName=" + ActivationKeyName,
259                    "VideoFps=" + VideoFps,
260                    "VideoJpegQuality=" + VideoJpegQuality,
261                    "RecordSystemAudio=" + (RecordSystemAudio ? "1" : "0"),
262                    "RecordMicrophone=" + (RecordMicrophone ? "1" : "0"),
263                    "AudioPlayerW=" + AudioPlayerW,
264                    "AudioVolume=" + AudioVolume.ToString(System.Globalization.CultureInfo.InvariantCulture),
265                    "AutoLangSwitch=" + (AutoLangSwitch ? "1" : "0"),
266                    "AutoT9=" + (AutoT9 ? "1" : "0"),
267                    "T9Sensitivity=" + T9Sensitivity,
268                    "T9ShowTooltip=" + (T9ShowTooltip ? "1" : "0"),
269                    "AutoCapitalize=" + (AutoCapitalize ? "1" : "0"),
270                    "AutoPunctuation=" + (AutoPunctuation ? "1" : "0"),
271                    "ClipboardHistory=" + (ClipboardHistory ? "1" : "0"),
272                    "SentenceAiSuggest=" + (SentenceAiSuggest ? "1" : "0"),
273                    "SentenceAiAutoApply=" + (SentenceAiAutoApply ? "1" : "0"),
274                    "ContextNnRescore=" + (ContextNnRescore ? "1" : "0"),
275                    "TsfBridge=" + (TsfBridge ? "1" : "0"),
276                    "ModuleScreenshot=" + (ModuleScreenshot ? "1" : "0"),
277                    "ModuleTextAssist=" + (ModuleTextAssist ? "1" : "0"),
278                    "ModuleClipboard=" + (ModuleClipboard ? "1" : "0"),
279                    "ModuleGestures=" + (ModuleGestures ? "1" : "0"),
280                    "HighlightColor=" + ColorToHex(HighlightColor),
281                    "HighlightAlpha=" + HighlightAlpha,
282                    "MarkerSize=" + MarkerSize,
283                    "MarkerBorderColor=" + ColorToHex(MarkerBorderColor),
284                    "ReferenceResolution=" + ReferenceResolution
285                };
286                File.WriteAllLines(settingsPath, lines);
287            }
288            catch { }
289        }
290
291        public static void ResetDefaults()
292        {
293            ArrowColor = Color.FromArgb(255, 220, 60, 60);
294            ArrowWidth = 3f;
295            ShadowOffset = 3;
296            ShadowAlpha = 100;
297            MarkerColor = Color.FromArgb(230, 220, 60, 60);
298            MarkerTextColor = Color.White;
299            MarkerRadius = 16;
300            MarkerFont = "Segoe UI";
301            MarkerFontSize = 12f;
302            HighlightBorderColor = Color.FromArgb(255, 255, 100, 100);
303            HighlightBorderWidth = 2f;
304            DimAlpha = 120;
305            ShowHighlightBorder = true;
306            DimAroundSelection = true;
307            HighlightColor = Color.FromArgb(255, 255, 255, 0);
308            HighlightAlpha = 60;
309            MarkerSize = 32;
310            MarkerBorderColor = Color.FromArgb(255, 180, 40, 40);
311            TextBlockFont = "Segoe UI";
312            TextBlockFontSize = 14f;
313            TextBlockColor = Color.White;
314            TextBlockShadowColor = Color.FromArgb(150, 0, 0, 0);
315            TextBlockShadowOffset = 2;
316            BubbleFont = "Segoe UI";
317            BubbleFontSize = 12f;
318            BubbleFillColor = Color.White;
319            BubbleBorderColor = Color.Black;
320            BubbleBorderWidth = 2;
321            BlurRadius = 1.0f;
322            MotionBlurDistance = 15;
323            ReferenceResolution = 1920;
324            FeatherWidth = 5;
325            EnableFadeBlur = false;
326            FadeBlurWidth = 20;
327            DefaultWindowWidth = 1200;
328            DefaultWindowHeight = 800;
329            AutoFitToWindow = true;
330            BlurTintAlpha = 232;
331            BlurTintColor = Color.FromArgb(255, 24, 20, 20);
332            BlurMode = 0;
333            CornerRadius = 12;
334            ShowWindowBorder = true;
335            NoiseIntensity = 12;
336            ActivationKey = 0xA4;
337            ActivationKeyName = "Alt";
338            VideoFps = 60;
339            VideoJpegQuality = 90;
340            RecordSystemAudio = true;
341            RecordMicrophone = false;
342            AudioPlayerW = 440;
343            AudioVolume = 0.85f;
344            AutoLangSwitch = true;
345            AutoT9 = true;
346            T9Sensitivity = 3;
347            T9ShowTooltip = true;
348            AutoCapitalize = true;
349            AutoPunctuation = true;
350            ClipboardHistory = true;
351            SentenceAiSuggest = false;
352            SentenceAiAutoApply = false;
353            ContextNnRescore = false;
354            TsfBridge = false;
355            ModuleScreenshot = true;
356            ModuleTextAssist = false;
357            ModuleClipboard = false;
358            ModuleGestures = false;
359        }
360
361        public static Color ColorFromHex(string hex)
362        {
363            if (string.IsNullOrEmpty(hex)) return Color.Black;
364            if (hex.StartsWith("#")) hex = hex.Substring(1);
365            // Only 6 (RGB) and 8 (ARGB) hex digit forms are supported; anything else is malformed.
366            if (hex.Length != 6 && hex.Length != 8) return Color.Black;
367            int a = 255, r, g, b;
368            if (hex.Length == 8)
369            {
370                a = Convert.ToInt32(hex.Substring(0, 2), 16);
371                r = Convert.ToInt32(hex.Substring(2, 2), 16);
372                g = Convert.ToInt32(hex.Substring(4, 2), 16);
373                b = Convert.ToInt32(hex.Substring(6, 2), 16);
374            }
375            else
376            {
377                r = Convert.ToInt32(hex.Substring(0, 2), 16);
378                g = Convert.ToInt32(hex.Substring(2, 2), 16);
379                b = Convert.ToInt32(hex.Substring(4, 2), 16);
380            }
381            return Color.FromArgb(a, r, g, b);
382        }
383
384        public static string ColorToHex(Color c)
385        {
386            return ColorHelper.ColorToHex(c);
387        }
388    }
389}