UI/HDTWizardCredential.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="480" Width="720" WindowStartupLocation="CenterScreen" ResizeMode="NoResize" WindowStyle="None" Background="#FF1E1E1E"> <!-- THE BUTTON TEMPLATE, and it is here because of a real defect: WPF's DEFAULT button template paints its own light hover chrome UNDERNEATH the content, so white text on a dark button becomes unreadable the moment the mouse touches it. Setting Background alone does not fix it - the default template ignores it on hover. So the template is replaced outright with a Border and a ContentPresenter, and the hover and pressed states set the FOREGROUND to black against a light surface. A technician must be able to read the button they are about to press. INLINE, NOT AN EXTERNAL ResourceDictionary. A merged dictionary is another file that has to reach the RAM disk intact, and tests/contract/WinPeUiStack.Contract.Tests.ps1 refuses one. --> <Window.Resources> <Style TargetType="Button"> <Setter Property="Foreground" Value="White" /> <Setter Property="BorderThickness" Value="0" /> <Setter Property="FontSize" Value="13" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border x:Name="HDTButtonSurface" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" /> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="HDTButtonSurface" Property="Background" Value="#FFE6E6E6" /> <Setter Property="Foreground" Value="Black" /> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter TargetName="HDTButtonSurface" Property="Background" Value="#FFBDBDBD" /> <Setter Property="Foreground" Value="Black" /> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter TargetName="HDTButtonSurface" Property="Background" Value="#FF2A2A2A" /> <Setter Property="Foreground" Value="#FF6E6E6E" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <!-- W2: MDT's Bootstrap.ini credential quartet, on screen. DeployRoot the share, and therefore the SERVER UserID the account UserDomain the domain - BLANK MEANS LOCAL to that server UserPassword never prefilled THE DOMAIN BOX MAY BE LEFT EMPTY, and the hint under it says what that means, because "leave it blank for a local account" is the one piece of MDT lore a technician should not have to already know. Get-HDTWizardCredential turns a blank domain into SERVER\user. PasswordBox, NOT TextBox, for the password: it is the only control that does not put the secret on screen or in the automation tree. SAME RULES AS HDTWizard.xaml - no x:Class, no code-behind, no external resource dictionary. XamlReader::Load parses markup only and there is no compiler in WinPE; tests/contract/WinPeUiStack.Contract.Tests.ps1 asserts all three. HDTMessageText IS WHERE A REFUSAL LANDS. Get-HDTWizardCredential never throws for a bad credential - it returns Connected = false and a message - precisely so the window can stay up with the cursor still in the box, and this is where that message goes. --> <Grid Background="#FF1E1E1E"> <Grid.RowDefinitions> <RowDefinition Height="96" /> <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="HDTCredentialTitleText" Foreground="White" FontSize="22" FontWeight="SemiBold" /> <TextBlock x:Name="HDTCredentialSubtitleText" Foreground="#FFD6E9F5" FontSize="13" Margin="0,4,0,0" /> </StackPanel> </Border> <Grid Grid.Row="1" Margin="28,22,28,0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="150" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="42" /> <RowDefinition Height="42" /> <RowDefinition Height="42" /> <RowDefinition Height="26" /> <RowDefinition Height="42" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" x:Name="HDTCredentialShareLabel" Foreground="#FFCCCCCC" FontSize="13" VerticalAlignment="Center" /> <TextBox Grid.Row="0" Grid.Column="1" x:Name="HDTDeployRootBox" Height="28" VerticalContentAlignment="Center" Background="#FF2D2D30" Foreground="White" BorderBrush="#FF3F3F46" /> <TextBlock Grid.Row="1" Grid.Column="0" x:Name="HDTCredentialUserIdLabel" Foreground="#FFCCCCCC" FontSize="13" VerticalAlignment="Center" /> <TextBox Grid.Row="1" Grid.Column="1" x:Name="HDTUserIdBox" Height="28" VerticalContentAlignment="Center" Background="#FF2D2D30" Foreground="White" BorderBrush="#FF3F3F46" /> <TextBlock Grid.Row="2" Grid.Column="0" x:Name="HDTCredentialUserDomainLabel" Foreground="#FFCCCCCC" FontSize="13" VerticalAlignment="Center" /> <TextBox Grid.Row="2" Grid.Column="1" x:Name="HDTUserDomainBox" Height="28" VerticalContentAlignment="Center" Background="#FF2D2D30" Foreground="White" BorderBrush="#FF3F3F46" /> <TextBlock Grid.Row="3" Grid.Column="1" x:Name="HDTUserDomainHint" Foreground="#FF8A8A8A" FontSize="11" Margin="2,2,0,0" /> <TextBlock Grid.Row="4" Grid.Column="0" x:Name="HDTCredentialPasswordLabel" Foreground="#FFCCCCCC" FontSize="13" VerticalAlignment="Center" /> <!-- THE EYE, AND THIS IS THE WINDOW THAT NEEDS IT MOST. THIS WINDOW IS ONLY EVER ON SCREEN BECAUSE A CREDENTIAL WAS REJECTED - Get-HDTWizardCredential connects, refuses, and comes back with Connected = false so the boxes can be retyped. So everything on it has already been typed once and at least one of the four is wrong. HIDING WHAT WAS TYPED IS THE ONE THING THAT CANNOT HELP HERE: the technician is holding a written credential, standing at a bench, being asked to type the same secret again into a box that shows dots and to guess which of the four was the mistake. TWO BOXES IN ONE CELL, AND ONLY ONE VISIBLE AT A TIME. PasswordBox.Password is not a DependencyProperty, so it cannot be bound, styled or DataTriggered, and there is no code-behind in WinPE - the swap is done by New-HDTWizardHost.Apply, which loops Get-HDTWizardRevealPair. That loop reads THE TOGGLE'S OWN NAME: strip RevealToggle and the base must resolve <base>Box and <base>RevealBox. HDTPasswordBox / HDTPasswordRevealBox / HDTPasswordRevealToggle is that convention, and the same three names HDTWelcome.xaml uses - so this costs the host nothing and needs no new entry in the string table either: the caption comes from Common's HDTPasswordReveal.ShowToolTip. THE COLUMN THAT HOLDS THE BOX IS *, NOT A FIXED WIDTH. The wizard PAGES put their reveal boxes in a 380-wide column because nothing above them stretches. Here the three boxes above this one fill the field column, so a fixed width would make the password box the one narrow box on the window - the eye moving the layout around, which is exactly what it must not do. Auto beside it is what keeps the eye still when the boxes swap. NO COLOURS ON EITHER CONTROL. The window's older controls spell their brushes inline; these take them from HDTTheme.xaml, which New-HDTWizardHost.Show merges after the load. A local value beats a style setter silently, so a control that spelled them would be the one control a retheme could not reach. HEIGHT IS NOT A COLOUR: the theme's field height is 34 and this window's boxes are 28, so both carry 28 to line up with the PasswordBox they sit beside. OFF BY DEFAULT. A reveal is a deliberate act on a bench screen that gets photographed and shoulder-read, not a state the window opens in. --> <Grid Grid.Row="4" Grid.Column="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <PasswordBox Grid.Column="0" x:Name="HDTPasswordBox" Height="28" VerticalContentAlignment="Center" Background="#FF2D2D30" Foreground="White" BorderBrush="#FF3F3F46" /> <TextBox Grid.Column="0" x:Name="HDTPasswordRevealBox" Height="28" VerticalContentAlignment="Center" Visibility="Collapsed" /> <!-- A DRAWN EYE, AND THE PAGES NO LONGER DIFFER. This comment used to explain why a window drew the eye while the pages under Templates\Wizard typed it as U+1F441: only windows are scanned by StringTable.Contract.Tests.ps1, so the entity - which .NET's WebUtility.HtmlDecode leaves above the BMP undecoded, letting the letter in its hex convict it as prose - survived on a page and not here. That was an accident of scope defending a font dependency WinPE does not guarantee, not a design. Both reasons, and the geometry itself, now live once in HDTTheme.xaml beside HDTRevealEye. THE SIZE STAYS HERE. 36x28 is what lines this eye up with the 28-high boxes on this window; the shared style sets no size precisely so it can also sit in a 36x34 button on a page. --> <ToggleButton Grid.Column="1" x:Name="HDTPasswordRevealToggle" Style="{DynamicResource HDTRevealEye}" Width="36" Height="28" Margin="8,0,0,0" /> </Grid> <TextBlock Grid.Row="5" Grid.Column="1" x:Name="HDTMessageText" Text="" Foreground="#FFF48771" FontSize="12" Margin="0,16,0,0" TextWrapping="Wrap" /> </Grid> <Border Grid.Row="2" Background="#FF252526"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,28,0"> <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> </Border> </Grid> </Window> |