private/dialogs/New-DialogWindow.ps1
|
function New-DialogWindow { <# .SYNOPSIS Creates a standard themed dialog window with common boilerplate. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Title, [int]$Width = 420, [int]$MinWidth = 332, [int]$Height, [int]$MinHeight = 182, [int]$MaxHeight = 600, [ValidateSet('Height', 'Manual')] [string]$SizeToContent = 'Height', [ValidateSet('NoResize', 'CanResizeWithGrip')] [string]$ResizeMode = 'NoResize', [string]$AppIdSuffix = 'Dialog', [char]$OverlayGlyph, [string]$OverlayColor, [char]$TitleIcon, [object]$ThemeColors ) $colors = if ($ThemeColors) { $ThemeColors } else { Get-ThemeColors } $overlayColorFinal = if ($OverlayColor) { $OverlayColor } else { $colors.Accent } # Default overlay glyph to Info icon if not specified if (!$OverlayGlyph) { $OverlayGlyph = [PsUi.ModuleContext]::GetIcon('Info') } # Create the dialog window with standard properties $window = [System.Windows.Window]@{ Title = $Title Width = $Width + 32 MinWidth = $MinWidth MinHeight = $MinHeight MaxHeight = $MaxHeight + 32 SizeToContent = $SizeToContent WindowStartupLocation = 'CenterScreen' FontFamily = [System.Windows.Media.FontFamily]::new('Segoe UI') Background = [System.Windows.Media.Brushes]::Transparent Foreground = ConvertTo-UiBrush $colors.ControlFg ResizeMode = $ResizeMode WindowStyle = 'None' AllowsTransparency = $true Opacity = 0 } # Attach to parent so dialog stays with its owner $null = Set-WindowOwner -Window $window # Unique AppUserModelID separates from PowerShell in taskbar $appId = "PsUi.$AppIdSuffix." + [Guid]::NewGuid().ToString("N").Substring(0, 8) [PsUi.WindowManager]::SetWindowAppId($window, $appId) # Set explicit height if provided (used for fixed-size dialogs like PowerShell mode) if ($Height -gt 0) { $window.Height = $Height } # Themed window icon for taskbar $dialogIcon = $null try { $dialogIcon = New-WindowIcon -Colors $colors if ($dialogIcon) { $window.Icon = $dialogIcon } } catch { Write-Debug "Window icon creation failed: $_" } # Overlay icon for taskbar $overlayIcon = $null try { $overlayIcon = New-TaskbarOverlayIcon -GlyphChar $OverlayGlyph -Color $overlayColorFinal } catch { Write-Debug "Overlay icon creation failed: $_" } # Wire up taskbar icon in Loaded event $capturedWindow = $window $capturedIcon = $dialogIcon $capturedOverlay = $overlayIcon $capturedSuffix = $AppIdSuffix $window.Add_Loaded({ if ($capturedIcon) { [PsUi.WindowManager]::SetTaskbarIcon($capturedWindow, $capturedIcon) } if ($capturedOverlay) { [PsUi.WindowManager]::SetTaskbarOverlay($capturedWindow, $capturedOverlay, $capturedSuffix) } }.GetNewClosure()) # Main border with shadow effect $mainBorder = [System.Windows.Controls.Border]@{ Margin = [System.Windows.Thickness]::new(16) BorderBrush = ConvertTo-UiBrush $colors.Border BorderThickness = [System.Windows.Thickness]::new(1) Background = ConvertTo-UiBrush $colors.WindowBg } $shadow = [System.Windows.Media.Effects.DropShadowEffect]@{ BlurRadius = 16 ShadowDepth = 4 Opacity = 0.35 Color = [System.Windows.Media.Colors]::Black Direction = 270 } $mainBorder.Effect = $shadow $window.Content = $mainBorder # Main layout panel $mainPanel = [System.Windows.Controls.DockPanel]@{ LastChildFill = $true Margin = [System.Windows.Thickness]::new(0) } $mainBorder.Child = $mainPanel # Title bar $titleBar = [System.Windows.Controls.Border]@{ Background = ConvertTo-UiBrush $colors.HeaderBackground Height = 36 Padding = [System.Windows.Thickness]::new(12, 8, 12, 8) } [System.Windows.Controls.DockPanel]::SetDock($titleBar, 'Top') # Title bar content - optional icon + text if ($TitleIcon) { $titleStack = [System.Windows.Controls.StackPanel]@{ Orientation = 'Horizontal' VerticalAlignment = 'Center' } $titleIconBlock = [System.Windows.Controls.TextBlock]@{ Text = $TitleIcon FontFamily = [System.Windows.Media.FontFamily]::new('Segoe MDL2 Assets') FontSize = 14 Foreground = ConvertTo-UiBrush $colors.HeaderForeground VerticalAlignment = 'Center' Margin = [System.Windows.Thickness]::new(0, 0, 8, 0) } [void]$titleStack.Children.Add($titleIconBlock) $titleText = [System.Windows.Controls.TextBlock]@{ Text = $Title FontSize = 14 FontWeight = [System.Windows.FontWeights]::SemiBold Foreground = ConvertTo-UiBrush $colors.HeaderForeground VerticalAlignment = 'Center' } [void]$titleStack.Children.Add($titleText) $titleBar.Child = $titleStack } else { $titleText = [System.Windows.Controls.TextBlock]@{ Text = $Title FontSize = 14 FontWeight = [System.Windows.FontWeights]::SemiBold Foreground = ConvertTo-UiBrush $colors.HeaderForeground VerticalAlignment = 'Center' } $titleBar.Child = $titleText } [void]$mainPanel.Children.Add($titleBar) # Wire up drag behavior on title bar $titleBar.Add_MouseLeftButtonDown({ $capturedWindow.DragMove() }.GetNewClosure()) # Content panel for dialog-specific content $contentPanel = [System.Windows.Controls.DockPanel]@{ Margin = [System.Windows.Thickness]::new(16) LastChildFill = $true } [void]$mainPanel.Children.Add($contentPanel) # Return all components for the caller to use return @{ Window = $window MainBorder = $mainBorder MainPanel = $mainPanel TitleBar = $titleBar ContentPanel = $contentPanel Colors = $colors } } |