<# Рисует эталонный кадр с англоязычным интерфейсом: мелкое меню, заголовки, абзац, кнопки, светлая и тёмная зоны. Нужен, чтобы прогонять конвейер на предсказуемом входе. #> param([string]$Out = "$PSScriptRoot\..\dist\sample.png") Add-Type -AssemblyName System.Drawing $W, $H = 1600, 900 $bmp = New-Object Drawing.Bitmap($W, $H, [Drawing.Imaging.PixelFormat]::Format32bppArgb) $g = [Drawing.Graphics]::FromImage($bmp) $g.SmoothingMode = 'AntiAlias' $g.TextRenderingHint = 'ClearTypeGridFit' function Brush($r, $gg, $b) { New-Object Drawing.SolidBrush ([Drawing.Color]::FromArgb($r, $gg, $b)) } function Fnt($size, $style = 'Regular') { New-Object Drawing.Font('Segoe UI', $size, [Drawing.FontStyle]::$style, [Drawing.GraphicsUnit]::Pixel) } function Text($s, $font, $brush, $x, $y) { $g.DrawString($s, $font, $brush, [single]$x, [single]$y) } # фон приложения $g.FillRectangle((Brush 250 250 252), 0, 0, $W, $H) # сайдбар $g.FillRectangle((Brush 32 34 42), 0, 0, 240, $H) # верхняя панель $g.FillRectangle((Brush 255 255 255), 240, 0, $W - 240, 56) $g.DrawLine((New-Object Drawing.Pen(([Drawing.Color]::FromArgb(226, 228, 233)))), 240, 56, $W, 56) $white = Brush 236 238 243 $grey = Brush 150 155 168 $dark = Brush 28 30 36 $body = Brush 70 74 84 $blue = Brush 46 108 220 # --- сайдбар: мелкий текст на тёмном --- Text 'Workspace' (Fnt 12) $grey 20 18 Text 'Dashboard' (Fnt 14) $white 20 46 Text 'Recent files' (Fnt 14) $white 20 76 Text 'Shared with me' (Fnt 14) $white 20 106 Text 'Notifications' (Fnt 14) $white 20 136 Text 'Trash' (Fnt 14) $white 20 166 Text 'Storage almost full' (Fnt 12) $grey 20 210 Text 'Upgrade your plan to continue' (Fnt 12) $grey 20 230 # --- верхняя панель --- Text 'Project settings' (Fnt 15 'Bold') $dark 264 18 Text 'Save changes' (Fnt 13) $blue 1360 20 Text 'Cancel' (Fnt 13) $body 1480 20 # --- заголовок и абзац --- Text 'Network configuration' (Fnt 30 'Bold') $dark 264 100 Text 'Choose how this device connects to the internet.' (Fnt 16) $body 264 148 $para = @( 'When automatic configuration is enabled, the application selects the fastest available', 'connection and switches between them without interrupting downloads. Manual mode gives', 'you full control over the proxy address, port and authentication method, but requires', 'the settings to be updated whenever the server changes.' ) $y = 200 foreach ($line in $para) { Text $line (Fnt 15) $body 264 $y; $y += 26 } # --- карточка со списком --- $g.FillRectangle((Brush 255 255 255), 264, 330, 700, 250) $g.DrawRectangle((New-Object Drawing.Pen(([Drawing.Color]::FromArgb(224, 226, 232)))), 264, 330, 700, 250) Text 'Connection status' (Fnt 17 'Bold') $dark 288 350 Text 'Interface' (Fnt 13) $grey 288 392 Text 'Wireless adapter' (Fnt 14) $dark 288 412 Text 'IP address' (Fnt 13) $grey 288 448 Text 'Assigned automatically' (Fnt 14) $dark 288 468 Text 'Last error' (Fnt 13) $grey 288 504 Text 'The remote server did not respond in time' (Fnt 14) $dark 288 524 # --- кнопки --- $g.FillRectangle((Brush 46 108 220), 264, 620, 170, 40) Text 'Apply and restart' (Fnt 14) (Brush 255 255 255) 282 631 $g.FillRectangle((Brush 238 240 244), 450, 620, 130, 40) Text 'Restore defaults' (Fnt 14) $body 464 631 # --- тёмная плашка с предупреждением --- $g.FillRectangle((Brush 58 30 30), 264, 700, 700, 90) Text 'Warning' (Fnt 15 'Bold') (Brush 255 180 170) 288 716 Text 'Changing these values may disconnect active sessions.' (Fnt 14) (Brush 240 200 195) 288 742 Text 'Make sure no downloads are running before you continue.' (Fnt 14) (Brush 240 200 195) 288 764 # --- правая колонка, мелкий текст --- Text 'Activity' (Fnt 15 'Bold') $dark 1020 100 $log = @( 'Connection established', 'Certificate verified', 'Profile synchronised', 'Background sync paused', 'Waiting for network' ) $y = 140 foreach ($line in $log) { Text $line (Fnt 12) $body 1020 $y; $y += 22 } $g.Dispose() $dir = Split-Path $Out -Parent New-Item -ItemType Directory -Force -Path $dir | Out-Null $bmp.Save($Out, [Drawing.Imaging.ImageFormat]::Png) $bmp.Dispose() Write-Host "Эталонный кадр: $Out"