UI/HDTWelcome.xaml
|
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Hephaestus Deployment Toolkit" Height="740" Width="760" WindowStartupLocation="CenterScreen" ResizeMode="NoResize" WindowStyle="None" Background="#FF1E1E1E"> <!-- NO STYLES OF ITS OWN, AND THAT IS THE CHANGE. This window used to carry an inline copy of the Button, ToggleButton, TextBox, PasswordBox and HDTAddressBox styles - about 120 lines HDTTheme.xaml already had, in literal colours rather than the theme's tokens. It was the ONE screen a palette change could not reach, because Show-HDTWizard had no theme to merge while Show-HDTWizardShell did, and it had already drifted once: the address boxes stayed 32 high after the theme moved to 34. THE THEME IS MERGED AT RUNTIME, NOT WITH ResourceDictionary Source=. A Source= reference is a second file that has to reach the RAM disk intact, and a half-copied one is a XamlParseException where the first screen of a deployment should be; WinPeUiStack.Contract.Tests.ps1 refuses one. New-HDTWizardHost adds the dictionary to this window's Resources after XamlReader::Load returns - which is why every reference below is a DynamicResource: a StaticResource is resolved during the parse, when the theme is not there yet. WHY THE STYLES EXIST AT ALL is in HDTTheme.xaml beside each one: WPF's default Button template paints its own light hover chrome underneath the content, so white-on-dark becomes unreadable the moment the mouse touches it, and the eye's glyph is drawn from geometry because Segoe MDL2 Assets is not guaranteed to be in a WinPE image. --> <!-- NO TITLE BAR, AND THEREFORE NO X. In WinPE there is no desktop, no taskbar and nothing to switch to, so the chrome is vestigial - but the close button is worse than vestigial: it is a third way out of the wizard that goes round the buttons. Show-HDTWizard maps a dismissed window to Cancel precisely so that cannot mean "yes", but a technician who closes the deployment wizard lands at a bare X:\Windows\System32> prompt with no idea what happened. Cancel and Open CMD are the two ways out, and both of them say what they do. MDT's LiteTouch fills the screen for the same reason. --> <!-- THE WELCOME SCREEN - MDT's LiteTouch Welcome, rebuilt. THIS IS THE ONE PANE THAT MUST LIVE IN THE BOOT IMAGE, and not by preference: it runs BEFORE any share is reachable, so it cannot be read from one. Every pane after it - task sequence, computer name, summary, progress - lives on the share under Scripts\UI\ and is read after connecting, exactly as MDT reads DeployWiz_*.xml, so those can be redesigned without rebuilding anything. THREE PANES, EACH INDEPENDENTLY HIDEABLE (MDT's Skip* properties, under the HDT prefix, resolved by the ordinary rules engine): HDTSkipStaticIp hides the network group; DHCP is used HDTSkipDeployRoot hides the share box; bootstrap.json's value wins HDTSkipCredential hides the account group; the embedded one wins HDTSkipWelcome skips this window entirely A pane appears only when it has something to ask or a rule asks for it, because the UNATTENDED PATH IS THE DEFAULT: an image carrying an embedded credential and a resolved task sequence still deploys with nobody present, and the zero-keystroke E2E proves it. STATIC IP IS APPLIED THROUGH WMI, not NetTCPIP. SPIKES S14: Get-NetIPAddress does not exist in a WinPE image built from the ADK - it is what killed the first SMB probe. Win32_NetworkAdapterConfiguration is guaranteed by WinPE-WMI. No x:Class, no code-behind, no external resource dictionary - there is no compiler in WinPE and every extra file is another thing that has to reach the RAM disk intact. tests/contract/WinPeUiStack.Contract.Tests.ps1 asserts all three, over every window. --> <Grid Background="#FF1E1E1E"> <Grid.RowDefinitions> <RowDefinition Height="104" /> <RowDefinition Height="*" /> <RowDefinition Height="72" /> </Grid.RowDefinitions> <Border Grid.Row="0" Background="#FF0E639C" x:Name="HDTDragBanner"> <StackPanel VerticalAlignment="Center" Margin="28,0,28,0"> <TextBlock x:Name="HDTWelcomeTitleText" Foreground="White" FontSize="30" FontWeight="SemiBold" /> <TextBlock x:Name="HDTWelcomeSubtitleText" Foreground="#FFD6E9F5" FontSize="16" Margin="0,4,0,0" /> </StackPanel> </Border> <!-- NO ScrollViewer. A deployment wizard that scrolls hides a field from a technician who does not know it is there, and this screen is fixed - three panes, known size - so it is laid out to fit instead. The window is sized to the content rather than the content squeezed into the window. --> <StackPanel Grid.Row="1" Margin="28,18,28,0"> <!-- ============ network ============ --> <StackPanel x:Name="HDTNetworkPane"> <TextBlock x:Name="HDTWelcomeNetworkHeading" Foreground="White" FontSize="19" FontWeight="SemiBold" /> <RadioButton x:Name="HDTUseDhcpRadio" GroupName="HDTAddressMode" IsChecked="True" Foreground="#FFCCCCCC" FontSize="16" Margin="0,10,0,0" /> <RadioButton x:Name="HDTUseStaticRadio" GroupName="HDTAddressMode" Foreground="#FFCCCCCC" FontSize="16" Margin="0,6,0,0" /> <Grid x:Name="HDTStaticGrid" Margin="22,8,0,0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="155" /> <ColumnDefinition Width="220" /> <ColumnDefinition Width="130" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="36" /> <RowDefinition Height="36" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" x:Name="HDTWelcomeIpAddressLabel" Foreground="#FFCCCCCC" FontSize="15" VerticalAlignment="Center" /> <TextBox Grid.Row="0" Grid.Column="1" x:Name="HDTIpAddressBox" Style="{DynamicResource HDTAddressBox}" /> <TextBlock Grid.Row="0" Grid.Column="2" x:Name="HDTWelcomeSubnetMaskLabel" Foreground="#FFCCCCCC" FontSize="15" VerticalAlignment="Center" Margin="12,0,0,0" /> <TextBox Grid.Row="0" Grid.Column="3" x:Name="HDTSubnetMaskBox" Style="{DynamicResource HDTAddressBox}" /> <TextBlock Grid.Row="1" Grid.Column="0" x:Name="HDTWelcomeGatewayLabel" Foreground="#FFCCCCCC" FontSize="15" VerticalAlignment="Center" /> <TextBox Grid.Row="1" Grid.Column="1" x:Name="HDTGatewayBox" Style="{DynamicResource HDTAddressBox}" /> <TextBlock Grid.Row="1" Grid.Column="2" x:Name="HDTWelcomeDnsLabel" Foreground="#FFCCCCCC" FontSize="15" VerticalAlignment="Center" Margin="12,0,0,0" /> <TextBox Grid.Row="1" Grid.Column="3" x:Name="HDTDnsBox" Style="{DynamicResource HDTAddressBox}" /> <!-- UNDER THE BOX IT DESCRIBES, NOT A TOOLTIP. It sat under the IP address column while describing a box two columns to its right, which is worse than not being there. A tooltip was the alternative and is wrong here for two reasons: the credential pane already puts its hint directly under the Domain box, so a tooltip would be the one inconsistent affordance on the screen; and hover is invisible - a technician on a bench in WinPE has no reason to discover it, and Set-HDTStaticAddress genuinely needs the comma to split the list. --> <TextBlock Grid.Row="2" Grid.Column="3" x:Name="HDTDnsHint" Foreground="#FF8A8A8A" FontSize="14" Margin="2,2,0,0" TextWrapping="Wrap" /> </Grid> </StackPanel> <!-- ============ share ============ --> <StackPanel x:Name="HDTDeployRootPane" Margin="0,22,0,0"> <TextBlock x:Name="HDTWelcomeShareHeading" Foreground="White" FontSize="19" FontWeight="SemiBold" /> <Grid Margin="0,10,0,0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="155" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" x:Name="HDTWelcomeShareLabel" Foreground="#FFCCCCCC" FontSize="15" VerticalAlignment="Center" /> <TextBox Grid.Row="0" Grid.Column="1" x:Name="HDTDeployRootBox" VerticalContentAlignment="Center" Background="#FF2D2D30" Foreground="White" BorderBrush="#FF3F3F46" /> <!-- THE BOX IS EMPTY AND NOBODY IS COMING TO FILL IT. An image built with no deployRoot reaches this screen with nothing to connect to, and an empty box on its own reads as "optional". This says otherwise, and it is amber rather than red because nothing has failed yet - the technician simply has to type it. Collapsed by default: the host shows it only when the boot image carried no share. --> <TextBlock Grid.Row="1" Grid.Column="1" x:Name="HDTDeployRootHint" Visibility="Collapsed" Foreground="#FFD9A441" FontSize="14" TextWrapping="Wrap" Margin="2,6,0,0" /> </Grid> </StackPanel> <!-- ============ account ============ --> <StackPanel x:Name="HDTCredentialPane" Margin="0,22,0,0"> <TextBlock x:Name="HDTWelcomeAccountHeading" Foreground="White" FontSize="19" FontWeight="SemiBold" /> <Grid Margin="0,10,0,0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="155" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="36" /> <RowDefinition Height="36" /> <RowDefinition Height="20" /> <RowDefinition Height="36" /> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" x:Name="HDTWelcomeUserIdLabel" Foreground="#FFCCCCCC" FontSize="15" VerticalAlignment="Center" /> <TextBox Grid.Row="0" Grid.Column="1" x:Name="HDTUserIdBox" VerticalContentAlignment="Center" Background="#FF2D2D30" Foreground="White" BorderBrush="#FF3F3F46" /> <TextBlock Grid.Row="1" Grid.Column="0" x:Name="HDTWelcomeUserDomainLabel" Foreground="#FFCCCCCC" FontSize="15" VerticalAlignment="Center" /> <TextBox Grid.Row="1" Grid.Column="1" x:Name="HDTUserDomainBox" VerticalContentAlignment="Center" Background="#FF2D2D30" Foreground="White" BorderBrush="#FF3F3F46" /> <TextBlock Grid.Row="2" Grid.Column="1" x:Name="HDTUserDomainHint" Foreground="#FF8A8A8A" FontSize="14" Margin="2,0,0,0" /> <TextBlock Grid.Row="3" Grid.Column="0" x:Name="HDTWelcomePasswordLabel" Foreground="#FFCCCCCC" FontSize="15" VerticalAlignment="Center" /> <!-- TWO BOXES IN ONE CELL, and only one of them visible at a time. PasswordBox.Password is not a DependencyProperty, so it cannot be bound and the reveal cannot be done declaratively: the host swaps the text and the visibility (New-HDTWizardHost), which is why both carry x:Name. --> <Grid Grid.Row="3" Grid.Column="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <PasswordBox Grid.Column="0" x:Name="HDTPasswordBox" VerticalContentAlignment="Center" Background="#FF2D2D30" Foreground="White" BorderBrush="#FF3F3F46" /> <TextBox Grid.Column="0" x:Name="HDTPasswordRevealBox" Visibility="Collapsed" VerticalContentAlignment="Center" Background="#FF2D2D30" Foreground="White" BorderBrush="#FF3F3F46" /> <ToggleButton Grid.Column="1" x:Name="HDTPasswordRevealToggle" Width="38" Height="34" Margin="6,0,0,0"> <Grid Width="22" Height="16"> <Path Data="M 1,8 C 5,2.5 17,2.5 21,8 C 17,13.5 5,13.5 1,8 Z" Stroke="{Binding Foreground, RelativeSource={RelativeSource AncestorType=ToggleButton}}" StrokeThickness="1.3" /> <Ellipse Width="6" Height="6" HorizontalAlignment="Center" VerticalAlignment="Center" Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=ToggleButton}}" /> </Grid> </ToggleButton> </Grid> </Grid> </StackPanel> <TextBlock x:Name="HDTMessageText" Text="" Foreground="#FFF48771" FontSize="15" Margin="0,18,0,12" TextWrapping="Wrap" /> </StackPanel> <!-- A GRID, NOT A StackPanel, because the footer now has two ends: the command prompt on the left and the wizard's own buttons on the right. HDTOpenCmdButton is MDT's "Exit to Command Prompt" - the escape hatch a technician reaches for when the network is wrong, a driver is missing, or they simply need diskpart. WinPE gives it on F8, but F8 is folklore; a button is discoverable. --> <Border Grid.Row="2" Background="#FF252526"> <Grid Margin="28,0,28,0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Button Grid.Column="0" x:Name="HDTOpenCmdButton" Width="120" Height="34" HorizontalAlignment="Left" VerticalAlignment="Center" Background="#FF3C3C3C" BorderThickness="0" /> <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center"> <Button x:Name="HDTCancelButton" Width="112" Height="34" Margin="0,0,12,0" Background="#FF3C3C3C" BorderThickness="0" /> <Button x:Name="HDTNextButton" Width="112" Height="34" Background="#FF0E639C" BorderThickness="0" IsDefault="True" /> </StackPanel> </Grid> </Border> </Grid> </Window> |