ui/splitterui.ps1

using namespace GliderUI
using namespace GliderUI.Avalonia
using namespace GliderUI.Avalonia.Controls
using namespace GliderUI.Avalonia.Platform.Storage

function New-SplitterUiWindow {
    [CmdletBinding()]
    param()

    $win = [Window]::new()
    $win.ExtendClientAreaToDecorationsHint = $true
    $win.ExtendClientAreaTitleBarHeightHint = 40
    $win.Title = 'Splitter UI'
    $win.Width = 1220
    $win.Height = 860
    $win.MinWidth = 980
    $win.MinHeight = 700

    $accentColor = [GliderUI.Avalonia.Media.Brush]::Parse('#3AA0FF')
    $panelColor = [GliderUI.Avalonia.Media.Brush]::Parse('#1A1E26')
    $mutedTextColor = [GliderUI.Avalonia.Media.Brush]::Parse('#A9B4C4')
    $textOnAccentColor = [GliderUI.Avalonia.Media.Brush]::Parse('#FFFFFF')

    $rootGrid = [Grid]::new()
    # Keep content below the extended title bar region to avoid visual overlap.
    $rootGrid.Margin = [Thickness]::new(12, 44, 12, 12)
    $rootGrid.RowSpacing = 10
    $rootGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $rootGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $rootGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::new(1, 'Star')))
    $rootGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))

    $headerGrid = [Grid]::new()
    $headerGrid.ColumnSpacing = 8
    $headerGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(1, 'Star')))

    $headerTextStack = [StackPanel]::new()
    $headerTextStack.Orientation = 'Vertical'
    $headerTextStack.Spacing = 2

    $titleText = [TextBlock]::new()
    $titleText.FontSize = 22
    $titleText.FontWeight = 'SemiBold'
    $titleText.Text = 'Splitter'

    $subtitleText = [TextBlock]::new()
    $subtitleText.Text = 'Edition-aware Windows install media builder'
    $subtitleText.Foreground = $mutedTextColor

    $headerTextStack.Children.Add($titleText)
    $headerTextStack.Children.Add($subtitleText)

    $headerGrid.Children.Add($headerTextStack)
    [Grid]::SetRow($headerGrid, 0)

    $statusText = [TextBlock]::new()
    $statusText.Text = 'Preflight has not run.'
    $statusText.Foreground = $mutedTextColor
    [Grid]::SetRow($statusText, 1)

    $shellGrid = [Grid]::new()
    $shellGrid.ColumnSpacing = 10
    $shellGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(230)))
    $shellGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(1, 'Star')))
    [Grid]::SetRow($shellGrid, 2)

    $navGrid = [Grid]::new()
    $navGrid.RowSpacing = 10
    $navGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $navGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $navGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::new(1, 'Star')))

    $navHeader = [TextBlock]::new()
    $navHeader.FontSize = 16
    $navHeader.FontWeight = 'SemiBold'
    $navHeader.Text = 'Workflows'
    $navHeader.Foreground = $accentColor

    $navHintText = [TextBlock]::new()
    $navHintText.Text = 'Choose a stage for source, split, service, build, or outputs.'
    $navHintText.TextWrapping = 'Wrap'
    $navHintText.Foreground = $mutedTextColor
    $navHintText.FontSize = 12
    [Grid]::SetRow($navHintText, 1)

    $navListBox = [ListBox]::new()
    $navListBox.MinWidth = 200
    $navListBox.Background = $panelColor
    [Grid]::SetRow($navListBox, 2)

    $navItems = @(
        @{ Label = 'Source Media'; Tooltip = 'Select source ISO, run preflight checks, and discover install images.' }
        @{ Label = 'Split Editions'; Tooltip = 'Choose editions and naming options, then run split operations.' }
        @{ Label = 'Image Servicing'; Tooltip = 'Add drivers, packages, unattend files, and payload files to media.' }
        @{ Label = 'Build Outputs'; Tooltip = 'Build bootable ISO files or export selected indexes to a new WIM.' }
    )
    foreach ($navItem in $navItems) {
        $navListItem = [ListBoxItem]::new()
        $navListItem.Content = $navItem.Label
        [GliderUI.Avalonia.Controls.ToolTip]::SetTip($navListItem, $navItem.Tooltip)
        $navListBox.Items.Add($navListItem) | Out-Null
    }

    $navGrid.Children.Add($navHeader)
    $navGrid.Children.Add($navHintText)
    $navGrid.Children.Add($navListBox)

    $pageHostGrid = [Grid]::new()
    [Grid]::SetColumn($pageHostGrid, 1)

    $leftGrid = [Grid]::new()
    $leftGrid.RowSpacing = 8
    $leftGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $leftGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $leftGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))

    $optionsHeader = [TextBlock]::new()
    $optionsHeader.FontSize = 16
    $optionsHeader.FontWeight = 'SemiBold'
    $optionsHeader.Text = 'Build Options'

    $checkStack = [StackPanel]::new()
    $checkStack.Spacing = 8
    [Grid]::SetRow($checkStack, 1)

    $skipBootableIsoCheckBox = [CheckBox]::new()
    $skipBootableIsoCheckBox.Content = 'Skip bootable ISO build'

    $desktopExperienceCheckBox = [CheckBox]::new()
    $desktopExperienceCheckBox.Content = 'Desktop Experience only'

    $serverCoreCheckBox = [CheckBox]::new()
    $serverCoreCheckBox.Content = 'Server Core only'

    $checkStack.Children.Add($skipBootableIsoCheckBox)
    $checkStack.Children.Add($desktopExperienceCheckBox)
    $checkStack.Children.Add($serverCoreCheckBox)

    $runSplitButton = [Button]::new()
    $runSplitButton.Height = 34
    $runSplitButton.Content = 'Run Split'
    $runSplitButton.Background = $accentColor
    $runSplitButton.Foreground = $textOnAccentColor
    [Grid]::SetRow($runSplitButton, 2)

    $leftGrid.Children.Add($optionsHeader)
    $leftGrid.Children.Add($checkStack)
    $leftGrid.Children.Add($runSplitButton)

    $rightGrid = [Grid]::new()
    $rightGrid.RowSpacing = 10
    $rightGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $rightGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::new(1, 'Star')))
    $rightGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::new(1, 'Star')))
    [Grid]::SetColumn($rightGrid, 1)

    $inputGrid = [Grid]::new()
    $inputGrid.ColumnSpacing = 8
    $inputGrid.RowSpacing = 6
    $inputGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $inputGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $inputGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(1.7, 'Star')))
    $inputGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(2, 'Star')))
    $inputGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(2, 'Star')))
    $inputGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(1.4, 'Star')))
    $inputGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(1.1, 'Star')))

    $editionNamesLabel = [TextBlock]::new(); $editionNamesLabel.Text = 'Edition names'; [Grid]::SetColumn($editionNamesLabel, 0); [Grid]::SetRow($editionNamesLabel, 0)
    $workingRootLabel = [TextBlock]::new(); $workingRootLabel.Text = 'Working root'; [Grid]::SetColumn($workingRootLabel, 1); [Grid]::SetRow($workingRootLabel, 0)
    $outputRootLabel = [TextBlock]::new(); $outputRootLabel.Text = 'Output root'; [Grid]::SetColumn($outputRootLabel, 2); [Grid]::SetRow($outputRootLabel, 0)
    $outputBaseLabel = [TextBlock]::new(); $outputBaseLabel.Text = 'Output base'; [Grid]::SetColumn($outputBaseLabel, 3); [Grid]::SetRow($outputBaseLabel, 0)
    $labelPrefixLabel = [TextBlock]::new(); $labelPrefixLabel.Text = 'Label prefix'; [Grid]::SetColumn($labelPrefixLabel, 4); [Grid]::SetRow($labelPrefixLabel, 0)

    $editionNamesTextBox = [TextBox]::new(); $editionNamesTextBox.Watermark = 'Standard,Datacenter'; [Grid]::SetColumn($editionNamesTextBox, 0); [Grid]::SetRow($editionNamesTextBox, 1)
    $workingRootTextBox = [TextBox]::new(); $workingRootTextBox.Watermark = 'C:\work\splitter'; [Grid]::SetColumn($workingRootTextBox, 1); [Grid]::SetRow($workingRootTextBox, 1)
    $outputRootTextBox = [TextBox]::new(); $outputRootTextBox.Watermark = 'C:\out\splitter'; [Grid]::SetColumn($outputRootTextBox, 2); [Grid]::SetRow($outputRootTextBox, 1)
    $outputBaseNameTextBox = [TextBox]::new(); $outputBaseNameTextBox.Watermark = 'WinServer_2025'; [Grid]::SetColumn($outputBaseNameTextBox, 3); [Grid]::SetRow($outputBaseNameTextBox, 1)
    $labelPrefixTextBox = [TextBox]::new(); $labelPrefixTextBox.Text = 'WIN'; [Grid]::SetColumn($labelPrefixTextBox, 4); [Grid]::SetRow($labelPrefixTextBox, 1)

    $inputGrid.Children.Add($editionNamesLabel)
    $inputGrid.Children.Add($workingRootLabel)
    $inputGrid.Children.Add($outputRootLabel)
    $inputGrid.Children.Add($outputBaseLabel)
    $inputGrid.Children.Add($labelPrefixLabel)
    $inputGrid.Children.Add($editionNamesTextBox)
    $inputGrid.Children.Add($workingRootTextBox)
    $inputGrid.Children.Add($outputRootTextBox)
    $inputGrid.Children.Add($outputBaseNameTextBox)
    $inputGrid.Children.Add($labelPrefixTextBox)

    $sourceIsoTextBox = [TextBox]::new()
    $sourceIsoTextBox.Watermark = 'C:\ISO\Windows.iso'

    $browseSourceIsoButton = [Button]::new()
    $browseSourceIsoButton.Width = 82
    $browseSourceIsoButton.Content = 'Browse'

    $runPreflightButton = [Button]::new()
    $runPreflightButton.Width = 130
    $runPreflightButton.Height = 32
    $runPreflightButton.Content = 'Run Preflight'
    $runPreflightButton.Background = $accentColor
    $runPreflightButton.Foreground = $textOnAccentColor

    $discoverImagesButton = [Button]::new()
    $discoverImagesButton.Height = 32
    $discoverImagesButton.Content = 'Discover Source Images'
    $discoverImagesButton.Background = $accentColor
    $discoverImagesButton.Foreground = $textOnAccentColor

    $imagesHeader = [TextBlock]::new()
    $imagesHeader.FontWeight = 'SemiBold'
    $imagesHeader.Text = 'Discovered source images'

    $imagesListBox = [ListBox]::new()

    $executionGrid = [Grid]::new()
    $executionGrid.RowSpacing = 8
    $executionGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $executionGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::new(1, 'Star')))
    [Grid]::SetRow($executionGrid, 1)

    $executionHeader = [TextBlock]::new()
    $executionHeader.FontSize = 16
    $executionHeader.FontWeight = 'SemiBold'
    $executionHeader.Text = 'Execution'

    $logTextBox = [TextBox]::new()
    $logTextBox.AcceptsReturn = $true
    $logTextBox.IsReadOnly = $true
    $logTextBox.TextWrapping = 'NoWrap'
    $logTextBox.IsUndoEnabled = $false
    $logTextBox.FontFamily = 'Cascadia Mono'
    $logTextBox.Padding = [Thickness]::new(8, 6, 8, 30)
    [Grid]::SetRow($logTextBox, 1)

    $executionGrid.Children.Add($executionHeader)
    $executionGrid.Children.Add($logTextBox)

    $resultsGrid = [Grid]::new()
    $resultsGrid.RowSpacing = 8
    $resultsGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $resultsGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::new(1, 'Star')))
    [Grid]::SetRow($resultsGrid, 2)

    $resultsHeader = [TextBlock]::new()
    $resultsHeader.FontSize = 16
    $resultsHeader.FontWeight = 'SemiBold'
    $resultsHeader.Text = 'Latest results'

    $resultsListBox = [ListBox]::new()
    [Grid]::SetRow($resultsListBox, 1)

    $resultsGrid.Children.Add($resultsHeader)
    $resultsGrid.Children.Add($resultsListBox)

    $rightGrid.Children.Add($inputGrid)
    $rightGrid.Children.Add($executionGrid)
    $rightGrid.Children.Add($resultsGrid)

    $splitPageGrid = [Grid]::new()
    $splitPageGrid.RowSpacing = 10
    $splitPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $splitPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $splitPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::new(1, 'Star')))

    $splitTitle = [TextBlock]::new()
    $splitTitle.FontSize = 18
    $splitTitle.FontWeight = 'SemiBold'
    $splitTitle.Text = 'Split'

    $splitHintText = [TextBlock]::new()
    $splitHintText.Text = 'Configure output naming and flavor options, then run split and review logs and results.'
    $splitHintText.TextWrapping = 'Wrap'
    [Grid]::SetRow($splitHintText, 1)

    $splitContentGrid = [Grid]::new()
    $splitContentGrid.ColumnSpacing = 10
    $splitContentGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(300)))
    $splitContentGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(1, 'Star')))
    [Grid]::SetRow($splitContentGrid, 2)

    $splitContentGrid.Children.Add($leftGrid)
    $splitContentGrid.Children.Add($rightGrid)

    $splitPageGrid.Children.Add($splitTitle)
    $splitPageGrid.Children.Add($splitHintText)
    $splitPageGrid.Children.Add($splitContentGrid)

    $mediaPageGrid = [Grid]::new()
    $mediaPageGrid.RowSpacing = 10
    $mediaPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $mediaPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $mediaPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $mediaPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $mediaPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::new(140)))
    $mediaPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $mediaPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::new(1, 'Star')))

    $mediaTitle = [TextBlock]::new()
    $mediaTitle.FontSize = 18
    $mediaTitle.FontWeight = 'SemiBold'
    $mediaTitle.Text = 'Source Media'

    $mediaInputGrid = [Grid]::new()
    $mediaInputGrid.ColumnSpacing = 8
    $mediaInputGrid.RowSpacing = 6
    $mediaInputGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $mediaInputGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $mediaInputGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $mediaInputGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(1, 'Star')))
    $mediaInputGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::Auto))
    $mediaInputGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::Auto))
    [Grid]::SetRow($mediaInputGrid, 1)

    $sourceIsoLabel = [TextBlock]::new()
    $sourceIsoLabel.Text = 'Source ISO'
    [Grid]::SetColumn($sourceIsoLabel, 0)
    [Grid]::SetRow($sourceIsoLabel, 0)

    $sourceIsoContainer = [Grid]::new()
    $sourceIsoContainer.ColumnSpacing = 6
    $sourceIsoContainer.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(1, 'Star')))
    $sourceIsoContainer.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::Auto))
    [Grid]::SetColumn($sourceIsoContainer, 0)
    [Grid]::SetRow($sourceIsoContainer, 1)

    [Grid]::SetColumn($browseSourceIsoButton, 1)
    $sourceIsoContainer.Children.Add($sourceIsoTextBox)
    $sourceIsoContainer.Children.Add($browseSourceIsoButton)

    [Grid]::SetColumn($runPreflightButton, 1)
    [Grid]::SetRow($runPreflightButton, 1)

    [Grid]::SetColumn($discoverImagesButton, 2)
    [Grid]::SetRow($discoverImagesButton, 1)

    $mediaHintText = [TextBlock]::new()
    $mediaHintText.Text = 'Run preflight before discovery to catch ADK, DISM, and source path issues early.'
    $mediaHintText.TextWrapping = 'Wrap'
    [Grid]::SetColumnSpan($mediaHintText, 3)
    [Grid]::SetRow($mediaHintText, 2)

    $mediaInputGrid.Children.Add($sourceIsoLabel)
    $mediaInputGrid.Children.Add($sourceIsoContainer)
    $mediaInputGrid.Children.Add($runPreflightButton)
    $mediaInputGrid.Children.Add($discoverImagesButton)
    $mediaInputGrid.Children.Add($mediaHintText)

    $mediaLogHeader = [TextBlock]::new()
    $mediaLogHeader.FontWeight = 'SemiBold'
    $mediaLogHeader.Text = 'Media activity'
    $mediaLogHeader.Foreground = $accentColor
    [Grid]::SetRow($mediaLogHeader, 2)

    $mediaLogTextBox = [TextBox]::new()
    $mediaLogTextBox.AcceptsReturn = $true
    $mediaLogTextBox.IsReadOnly = $true
    $mediaLogTextBox.TextWrapping = 'NoWrap'
    $mediaLogTextBox.IsUndoEnabled = $false
    $mediaLogTextBox.FontFamily = 'Cascadia Mono'
    $mediaLogTextBox.Padding = [Thickness]::new(8, 6, 8, 30)
    $mediaLogTextBox.MinHeight = 148
    $mediaLogTextBox.Background = $panelColor
    [Grid]::SetRow($mediaLogTextBox, 3)

    [Grid]::SetRow($imagesHeader, 4)
    [Grid]::SetRow($imagesListBox, 6)

    $mediaPageGrid.Children.Add($mediaTitle)
    $mediaPageGrid.Children.Add($mediaInputGrid)
    $mediaPageGrid.Children.Add($mediaLogHeader)
    $mediaPageGrid.Children.Add($mediaLogTextBox)
    $mediaPageGrid.Children.Add($imagesHeader)
    $mediaPageGrid.Children.Add($imagesListBox)

    $servicingPageGrid = [Grid]::new()
    $servicingPageGrid.RowSpacing = 10
    $servicingPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $servicingPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $servicingPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $servicingPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $servicingPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::new(130)))
    $servicingPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $servicingPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::new(1, 'Star')))

    $servicingTitle = [TextBlock]::new()
    $servicingTitle.FontSize = 18
    $servicingTitle.FontWeight = 'SemiBold'
    $servicingTitle.Text = 'Servicing'

    $servicingHintText = [TextBlock]::new()
    $servicingHintText.Text = 'Apply drivers, packages, and unattend to an extracted media root.'
    $servicingHintText.TextWrapping = 'Wrap'
    [Grid]::SetRow($servicingHintText, 1)

    $servicingFormGrid = [Grid]::new()
    $servicingFormGrid.ColumnSpacing = 8
    $servicingFormGrid.RowSpacing = 6
    $servicingFormGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $servicingFormGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $servicingFormGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $servicingFormGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $servicingFormGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $servicingFormGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(2.2, 'Star')))
    $servicingFormGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(2, 'Star')))
    $servicingFormGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(2, 'Star')))
    $servicingFormGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(1.3, 'Star')))
    $servicingFormGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(1.5, 'Star')))
    [Grid]::SetRow($servicingFormGrid, 2)

    $serviceMediaRootLabel = [TextBlock]::new(); $serviceMediaRootLabel.Text = 'Media root'; [Grid]::SetColumn($serviceMediaRootLabel, 0); [Grid]::SetRow($serviceMediaRootLabel, 0)
    $driverPathLabel = [TextBlock]::new(); $driverPathLabel.Text = 'Driver path'; [Grid]::SetColumn($driverPathLabel, 1); [Grid]::SetRow($driverPathLabel, 0)
    $packagePathLabel = [TextBlock]::new(); $packagePathLabel.Text = 'Package path'; [Grid]::SetColumn($packagePathLabel, 2); [Grid]::SetRow($packagePathLabel, 0)
    $serviceIndexesLabel = [TextBlock]::new(); $serviceIndexesLabel.Text = 'Indexes'; [Grid]::SetColumn($serviceIndexesLabel, 3); [Grid]::SetRow($serviceIndexesLabel, 0)
    $unattendPathLabel = [TextBlock]::new(); $unattendPathLabel.Text = 'Unattend XML'; [Grid]::SetColumn($unattendPathLabel, 4); [Grid]::SetRow($unattendPathLabel, 0)

    $serviceMediaRootTextBox = [TextBox]::new(); $serviceMediaRootTextBox.Watermark = 'C:\work\splitter\Standard'; [Grid]::SetColumn($serviceMediaRootTextBox, 0); [Grid]::SetRow($serviceMediaRootTextBox, 1)
    $driverPathTextBox = [TextBox]::new(); $driverPathTextBox.Watermark = 'C:\drivers\net'
    $packagePathTextBox = [TextBox]::new(); $packagePathTextBox.Watermark = 'C:\updates\kb.cab'
    $serviceIndexesTextBox = [TextBox]::new(); $serviceIndexesTextBox.Watermark = '1,2'; [Grid]::SetColumn($serviceIndexesTextBox, 3); [Grid]::SetRow($serviceIndexesTextBox, 1)
    $unattendPathTextBox = [TextBox]::new(); $unattendPathTextBox.Watermark = 'C:\answer\autounattend.xml'

    $serviceOptionsStack = [StackPanel]::new()
    $serviceOptionsStack.Orientation = 'Horizontal'
    $serviceOptionsStack.Spacing = 12
    [Grid]::SetColumnSpan($serviceOptionsStack, 5)
    [Grid]::SetRow($serviceOptionsStack, 2)

    $serviceRecurseDriversCheckBox = [CheckBox]::new(); $serviceRecurseDriversCheckBox.Content = 'Recurse drivers'
    $serviceForceUnsignedDriversCheckBox = [CheckBox]::new(); $serviceForceUnsignedDriversCheckBox.Content = 'Force unsigned drivers'
    $serviceIgnoreCheckCheckBox = [CheckBox]::new(); $serviceIgnoreCheckCheckBox.Content = 'Ignore package check'
    $servicePreventPendingCheckBox = [CheckBox]::new(); $servicePreventPendingCheckBox.Content = 'Prevent pending packages'

    $serviceOptionsStack.Children.Add($serviceRecurseDriversCheckBox)
    $serviceOptionsStack.Children.Add($serviceForceUnsignedDriversCheckBox)
    $serviceOptionsStack.Children.Add($serviceIgnoreCheckCheckBox)
    $serviceOptionsStack.Children.Add($servicePreventPendingCheckBox)

    $unattendDestinationLabel = [TextBlock]::new(); $unattendDestinationLabel.Text = 'Unattend destination'; [Grid]::SetColumn($unattendDestinationLabel, 0); [Grid]::SetRow($unattendDestinationLabel, 3)
    $unattendDestinationTextBox = [TextBox]::new(); $unattendDestinationTextBox.Text = 'autounattend.xml'; [Grid]::SetColumn($unattendDestinationTextBox, 1); [Grid]::SetColumnSpan($unattendDestinationTextBox, 2); [Grid]::SetRow($unattendDestinationTextBox, 3)

    $servicingActionsStack = [StackPanel]::new()
    $servicingActionsStack.Orientation = 'Horizontal'
    $servicingActionsStack.Spacing = 8
    [Grid]::SetColumn($servicingActionsStack, 3)
    [Grid]::SetColumnSpan($servicingActionsStack, 2)
    [Grid]::SetRow($servicingActionsStack, 3)

    $addDriverButton = [Button]::new(); $addDriverButton.Height = 32; $addDriverButton.Content = 'Add Driver'
    $addPackageButton = [Button]::new(); $addPackageButton.Height = 32; $addPackageButton.Content = 'Add Package'
    $addUnattendButton = [Button]::new(); $addUnattendButton.Height = 32; $addUnattendButton.Content = 'Add Unattend'
    $addPayloadFileButton = [Button]::new(); $addPayloadFileButton.Height = 32; $addPayloadFileButton.Content = 'Add Payload File'
    $addDriverButton.Background = $accentColor; $addDriverButton.Foreground = $textOnAccentColor
    $addPackageButton.Background = $accentColor; $addPackageButton.Foreground = $textOnAccentColor
    $addUnattendButton.Background = $accentColor; $addUnattendButton.Foreground = $textOnAccentColor
    $addPayloadFileButton.Background = $accentColor; $addPayloadFileButton.Foreground = $textOnAccentColor

    $payloadSourceTextBox = [TextBox]::new()
    $payloadSourceTextBox.Watermark = 'D:\Packages\PowerShell-7.6.3-win-x64.msi'

    $payloadDestinationTextBox = [TextBox]::new()
    $payloadDestinationTextBox.Text = 'sources\$OEM$\$1\Install\PowerShell-7.6.3-win-x64.msi'

    [Grid]::SetColumn($driverPathTextBox, 1)
    [Grid]::SetRow($driverPathTextBox, 1)
    [Grid]::SetColumn($packagePathTextBox, 2)
    [Grid]::SetRow($packagePathTextBox, 1)
    [Grid]::SetColumn($unattendPathTextBox, 4)
    [Grid]::SetRow($unattendPathTextBox, 1)

    $servicingActionsStack.Children.Add($addDriverButton)
    $servicingActionsStack.Children.Add($addPackageButton)
    $servicingActionsStack.Children.Add($addUnattendButton)

    [Grid]::SetColumn($payloadSourceTextBox, 0)
    [Grid]::SetColumnSpan($payloadSourceTextBox, 3)
    [Grid]::SetRow($payloadSourceTextBox, 4)

    [Grid]::SetColumn($payloadDestinationTextBox, 3)
    [Grid]::SetRow($payloadDestinationTextBox, 4)

    [Grid]::SetColumn($addPayloadFileButton, 4)
    [Grid]::SetRow($addPayloadFileButton, 4)

    $servicingFormGrid.Children.Add($serviceMediaRootLabel)
    $servicingFormGrid.Children.Add($driverPathLabel)
    $servicingFormGrid.Children.Add($packagePathLabel)
    $servicingFormGrid.Children.Add($serviceIndexesLabel)
    $servicingFormGrid.Children.Add($unattendPathLabel)
    $servicingFormGrid.Children.Add($serviceMediaRootTextBox)
    $servicingFormGrid.Children.Add($driverPathTextBox)
    $servicingFormGrid.Children.Add($packagePathTextBox)
    $servicingFormGrid.Children.Add($serviceIndexesTextBox)
    $servicingFormGrid.Children.Add($unattendPathTextBox)
    $servicingFormGrid.Children.Add($serviceOptionsStack)
    $servicingFormGrid.Children.Add($unattendDestinationLabel)
    $servicingFormGrid.Children.Add($unattendDestinationTextBox)
    $servicingFormGrid.Children.Add($servicingActionsStack)
    $servicingFormGrid.Children.Add($payloadSourceTextBox)
    $servicingFormGrid.Children.Add($payloadDestinationTextBox)
    $servicingFormGrid.Children.Add($addPayloadFileButton)

    $servicingLogHeader = [TextBlock]::new()
    $servicingLogHeader.FontWeight = 'SemiBold'
    $servicingLogHeader.Text = 'Servicing activity'
    $servicingLogHeader.Foreground = $accentColor
    [Grid]::SetRow($servicingLogHeader, 3)

    $servicingLogTextBox = [TextBox]::new()
    $servicingLogTextBox.AcceptsReturn = $true
    $servicingLogTextBox.IsReadOnly = $true
    $servicingLogTextBox.TextWrapping = 'NoWrap'
    $servicingLogTextBox.IsUndoEnabled = $false
    $servicingLogTextBox.FontFamily = 'Cascadia Mono'
    $servicingLogTextBox.Padding = [Thickness]::new(8, 6, 8, 30)
    [Grid]::SetRow($servicingLogTextBox, 4)

    $servicingSelectionHeader = [TextBlock]::new()
    $servicingSelectionHeader.FontWeight = 'SemiBold'
    $servicingSelectionHeader.Text = 'Selected and added items'
    $servicingSelectionHeader.Foreground = $accentColor
    [Grid]::SetRow($servicingSelectionHeader, 5)

    $servicingSelectionsListBox = [ListBox]::new()
    [Grid]::SetRow($servicingSelectionsListBox, 6)

    $servicingPageGrid.Children.Add($servicingTitle)
    $servicingPageGrid.Children.Add($servicingHintText)
    $servicingPageGrid.Children.Add($servicingFormGrid)
    $servicingPageGrid.Children.Add($servicingLogHeader)
    $servicingPageGrid.Children.Add($servicingLogTextBox)
    $servicingPageGrid.Children.Add($servicingSelectionHeader)
    $servicingPageGrid.Children.Add($servicingSelectionsListBox)

    $buildPageGrid = [Grid]::new()
    $buildPageGrid.RowSpacing = 10
    $buildPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $buildPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $buildPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $buildPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $buildPageGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::new(1, 'Star')))

    $buildTitle = [TextBlock]::new()
    $buildTitle.FontSize = 18
    $buildTitle.FontWeight = 'SemiBold'
    $buildTitle.Text = 'Build'

    $buildHintText = [TextBlock]::new()
    $buildHintText.Text = 'Build bootable ISO outputs or export selected install image indexes into a new WIM.'
    $buildHintText.TextWrapping = 'Wrap'
    [Grid]::SetRow($buildHintText, 1)

    $buildFormGrid = [Grid]::new()
    $buildFormGrid.ColumnSpacing = 8
    $buildFormGrid.RowSpacing = 6
    $buildFormGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $buildFormGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $buildFormGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $buildFormGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::Auto))
    $buildFormGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(2.2, 'Star')))
    $buildFormGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(2.2, 'Star')))
    $buildFormGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(1.2, 'Star')))
    $buildFormGrid.ColumnDefinitions.Add([ColumnDefinition]::new([GridLength]::new(2.2, 'Star')))
    [Grid]::SetRow($buildFormGrid, 2)

    $buildMediaRootLabel = [TextBlock]::new(); $buildMediaRootLabel.Text = 'Media root'; [Grid]::SetColumn($buildMediaRootLabel, 0); [Grid]::SetRow($buildMediaRootLabel, 0)
    $buildOutputIsoLabel = [TextBlock]::new(); $buildOutputIsoLabel.Text = 'Output ISO'; [Grid]::SetColumn($buildOutputIsoLabel, 1); [Grid]::SetRow($buildOutputIsoLabel, 0)
    $buildLabelLabel = [TextBlock]::new(); $buildLabelLabel.Text = 'ISO label'; [Grid]::SetColumn($buildLabelLabel, 2); [Grid]::SetRow($buildLabelLabel, 0)
    $buildSourceImageLabel = [TextBlock]::new(); $buildSourceImageLabel.Text = 'Source image (install.wim/esd)'; [Grid]::SetColumn($buildSourceImageLabel, 3); [Grid]::SetRow($buildSourceImageLabel, 0)

    $buildMediaRootTextBox = [TextBox]::new(); $buildMediaRootTextBox.Watermark = 'C:\work\splitter\Standard'; [Grid]::SetColumn($buildMediaRootTextBox, 0); [Grid]::SetRow($buildMediaRootTextBox, 1)
    $buildOutputIsoTextBox = [TextBox]::new(); $buildOutputIsoTextBox.Watermark = 'C:\out\Standard.iso'; [Grid]::SetColumn($buildOutputIsoTextBox, 1); [Grid]::SetRow($buildOutputIsoTextBox, 1)
    $buildLabelTextBox = [TextBox]::new(); $buildLabelTextBox.Watermark = 'WINSTD'; [Grid]::SetColumn($buildLabelTextBox, 2); [Grid]::SetRow($buildLabelTextBox, 1)
    $buildSourceImageTextBox = [TextBox]::new(); $buildSourceImageTextBox.Watermark = 'C:\work\splitter\sources\install.wim'; [Grid]::SetColumn($buildSourceImageTextBox, 3); [Grid]::SetRow($buildSourceImageTextBox, 1)

    $buildDestinationWimLabel = [TextBlock]::new(); $buildDestinationWimLabel.Text = 'Destination WIM'; [Grid]::SetColumn($buildDestinationWimLabel, 0); [Grid]::SetRow($buildDestinationWimLabel, 2)
    $buildIndexesLabel = [TextBlock]::new(); $buildIndexesLabel.Text = 'Indexes'; [Grid]::SetColumn($buildIndexesLabel, 1); [Grid]::SetRow($buildIndexesLabel, 2)

    $buildDestinationWimTextBox = [TextBox]::new(); $buildDestinationWimTextBox.Watermark = 'C:\out\install-custom.wim'; [Grid]::SetColumn($buildDestinationWimTextBox, 0); [Grid]::SetRow($buildDestinationWimTextBox, 3)
    $buildIndexesTextBox = [TextBox]::new(); $buildIndexesTextBox.Watermark = '1,2'; [Grid]::SetColumn($buildIndexesTextBox, 1); [Grid]::SetRow($buildIndexesTextBox, 3)

    $buildActionsStack = [StackPanel]::new()
    $buildActionsStack.Orientation = 'Horizontal'
    $buildActionsStack.Spacing = 8
    [Grid]::SetColumn($buildActionsStack, 3)
    [Grid]::SetRow($buildActionsStack, 3)

    $buildBootableIsoButton = [Button]::new(); $buildBootableIsoButton.Height = 32; $buildBootableIsoButton.Content = 'Build Bootable ISO'
    $exportInstallImageButton = [Button]::new(); $exportInstallImageButton.Height = 32; $exportInstallImageButton.Content = 'Export Install Image'
    $buildBootableIsoButton.Background = $accentColor; $buildBootableIsoButton.Foreground = $textOnAccentColor
    $exportInstallImageButton.Background = $accentColor; $exportInstallImageButton.Foreground = $textOnAccentColor

    $buildActionsStack.Children.Add($buildBootableIsoButton)
    $buildActionsStack.Children.Add($exportInstallImageButton)

    $buildFormGrid.Children.Add($buildMediaRootLabel)
    $buildFormGrid.Children.Add($buildOutputIsoLabel)
    $buildFormGrid.Children.Add($buildLabelLabel)
    $buildFormGrid.Children.Add($buildSourceImageLabel)
    $buildFormGrid.Children.Add($buildMediaRootTextBox)
    $buildFormGrid.Children.Add($buildOutputIsoTextBox)
    $buildFormGrid.Children.Add($buildLabelTextBox)
    $buildFormGrid.Children.Add($buildSourceImageTextBox)
    $buildFormGrid.Children.Add($buildDestinationWimLabel)
    $buildFormGrid.Children.Add($buildIndexesLabel)
    $buildFormGrid.Children.Add($buildDestinationWimTextBox)
    $buildFormGrid.Children.Add($buildIndexesTextBox)
    $buildFormGrid.Children.Add($buildActionsStack)

    $buildLogHeader = [TextBlock]::new()
    $buildLogHeader.FontWeight = 'SemiBold'
    $buildLogHeader.Text = 'Build activity'
    $buildLogHeader.Foreground = $accentColor
    [Grid]::SetRow($buildLogHeader, 3)

    $buildLogTextBox = [TextBox]::new()
    $buildLogTextBox.AcceptsReturn = $true
    $buildLogTextBox.IsReadOnly = $true
    $buildLogTextBox.TextWrapping = 'NoWrap'
    $buildLogTextBox.IsUndoEnabled = $false
    $buildLogTextBox.FontFamily = 'Cascadia Mono'
    $buildLogTextBox.Padding = [Thickness]::new(8, 6, 8, 30)
    [Grid]::SetRow($buildLogTextBox, 4)

    $buildPageGrid.Children.Add($buildTitle)
    $buildPageGrid.Children.Add($buildHintText)
    $buildPageGrid.Children.Add($buildFormGrid)
    $buildPageGrid.Children.Add($buildLogHeader)
    $buildPageGrid.Children.Add($buildLogTextBox)

    $pageMap = @{
        'Split Editions' = $splitPageGrid
        'Source Media' = $mediaPageGrid
        'Image Servicing' = $servicingPageGrid
        'Build Outputs' = $buildPageGrid
    }

    $setActivePage = {
        param(
            [Parameter(Mandatory)]
            [string]
            $PageKey
        )

        $pageHostGrid.Children.Clear()
        $pageHostGrid.Children.Add($pageMap[$PageKey])
    }.GetNewClosure()

    $navListBox.AddSelectionChanged({
        if ($null -eq $navListBox.SelectedItem) {
            return
        }

        $selectedPage = $null
        if ($navListBox.SelectedItem -is [ListBoxItem]) {
            $selectedPage = [string] $navListBox.SelectedItem.Content
        }
        else {
            $selectedPage = [string] $navListBox.SelectedItem
        }

        if ($pageMap.ContainsKey($selectedPage)) {
            $setActivePage.Invoke($selectedPage)
        }
    }.GetNewClosure())

    $navListBox.SelectedIndex = 0
    $setActivePage.Invoke('Source Media')

    $shellGrid.Children.Add($navGrid)
    $shellGrid.Children.Add($pageHostGrid)

    $footerText = [TextBlock]::new()
    $footerText.Text = 'Preflight checks help avoid ADK, DISM, and path issues before long-running operations.'
    [Grid]::SetRow($footerText, 3)

    $rootGrid.Children.Add($headerGrid)
    $rootGrid.Children.Add($statusText)
    $rootGrid.Children.Add($shellGrid)
    $rootGrid.Children.Add($footerText)

    $win.Content = $rootGrid

    $controls = @{
        StatusText = $statusText
        FooterText = $footerText
        SourceIsoTextBox = $sourceIsoTextBox
        BrowseSourceIsoButton = $browseSourceIsoButton
        EditionNamesTextBox = $editionNamesTextBox
        WorkingRootTextBox = $workingRootTextBox
        OutputRootTextBox = $outputRootTextBox
        OutputBaseNameTextBox = $outputBaseNameTextBox
        LabelPrefixTextBox = $labelPrefixTextBox
        SkipBootableIsoCheckBox = $skipBootableIsoCheckBox
        DesktopExperienceCheckBox = $desktopExperienceCheckBox
        ServerCoreCheckBox = $serverCoreCheckBox
        DiscoverImagesButton = $discoverImagesButton
        RunSplitButton = $runSplitButton
        RunPreflightButton = $runPreflightButton
        ImagesListBox = $imagesListBox
        MediaLogTextBox = $mediaLogTextBox
        ServiceMediaRootTextBox = $serviceMediaRootTextBox
        DriverPathTextBox = $driverPathTextBox
        PackagePathTextBox = $packagePathTextBox
        ServiceIndexesTextBox = $serviceIndexesTextBox
        UnattendPathTextBox = $unattendPathTextBox
        UnattendDestinationTextBox = $unattendDestinationTextBox
        ServiceRecurseDriversCheckBox = $serviceRecurseDriversCheckBox
        ServiceForceUnsignedDriversCheckBox = $serviceForceUnsignedDriversCheckBox
        ServiceIgnoreCheckCheckBox = $serviceIgnoreCheckCheckBox
        ServicePreventPendingCheckBox = $servicePreventPendingCheckBox
        AddDriverButton = $addDriverButton
        AddPackageButton = $addPackageButton
        AddUnattendButton = $addUnattendButton
        AddPayloadFileButton = $addPayloadFileButton
        PayloadSourceTextBox = $payloadSourceTextBox
        PayloadDestinationTextBox = $payloadDestinationTextBox
        ServicingLogTextBox = $servicingLogTextBox
        ServicingSelectionsListBox = $servicingSelectionsListBox
        BuildMediaRootTextBox = $buildMediaRootTextBox
        BuildOutputIsoTextBox = $buildOutputIsoTextBox
        BuildLabelTextBox = $buildLabelTextBox
        BuildSourceImageTextBox = $buildSourceImageTextBox
        BuildDestinationWimTextBox = $buildDestinationWimTextBox
        BuildIndexesTextBox = $buildIndexesTextBox
        BuildBootableIsoButton = $buildBootableIsoButton
        ExportInstallImageButton = $exportInstallImageButton
        BuildLogTextBox = $buildLogTextBox
        LogTextBox = $logTextBox
        ResultsListBox = $resultsListBox
        NavigationListBox = $navListBox
        PageHostGrid = $pageHostGrid
    }

    $tooltips = @{
        NavigationListBox = 'Select the workflow stage you want to configure and run.'
        SourceIsoTextBox = 'Path to the source Windows ISO used for discovery and split operations.'
        BrowseSourceIsoButton = 'Browse for the source Windows ISO file.'
        EditionNamesTextBox = 'Comma-separated edition names to split, for example: Standard,Datacenter.'
        WorkingRootTextBox = 'Working folder where media is extracted and staged.'
        OutputRootTextBox = 'Destination folder for generated ISO and WIM outputs.'
        OutputBaseNameTextBox = 'Base filename prefix for generated media artifacts.'
        LabelPrefixTextBox = 'Volume label prefix used when creating bootable ISO files.'
        SkipBootableIsoCheckBox = 'Skip ISO creation during split and keep only staged file outputs.'
        DesktopExperienceCheckBox = 'Limit processing to Desktop Experience editions when available.'
        ServerCoreCheckBox = 'Limit processing to Server Core editions when available.'
        DiscoverImagesButton = 'Scan the source media and list install image indexes and names.'
        RunPreflightButton = 'Run ADK, DISM, and path checks before long-running operations.'
        RunSplitButton = 'Run split operations using current settings and selected editions.'
        ImagesListBox = 'Discovered install images from the selected source ISO.'
        MediaLogTextBox = 'Log output for media discovery and preflight operations.'
        LogTextBox = 'Log output for split execution and workflow status.'
        ResultsListBox = 'Latest operation results and produced artifacts.'
        ServiceMediaRootTextBox = 'Extracted media root folder to service with drivers, packages, and unattend.'
        DriverPathTextBox = 'Driver folder or INF path. Leave blank and click Add Driver to choose.'
        PackagePathTextBox = 'CAB or MSU path. Leave blank and click Add Package to choose.'
        ServiceIndexesTextBox = 'Comma-separated image indexes to service, for example: 1,2.'
        UnattendPathTextBox = 'Unattend XML path. Leave blank and click Add Unattend to choose.'
        UnattendDestinationTextBox = 'Destination filename or relative path for unattend XML in media root.'
        ServiceRecurseDriversCheckBox = 'Include subfolders when scanning for driver files.'
        ServiceForceUnsignedDriversCheckBox = 'Allow unsigned drivers when adding drivers to images.'
        ServiceIgnoreCheckCheckBox = 'Ignore package applicability checks during package add.'
        ServicePreventPendingCheckBox = 'Skip package actions when pending operations are detected.'
        AddDriverButton = 'Add drivers from the specified path to selected image indexes.'
        AddPackageButton = 'Add package updates from the specified CAB or MSU file.'
        AddUnattendButton = 'Copy unattend XML into the media root using the destination name.'
        AddPayloadFileButton = 'Copy a payload file like an MSI into media at a relative destination path.'
        PayloadSourceTextBox = 'Payload file path. Leave blank and click Add Payload File to choose.'
        PayloadDestinationTextBox = 'Relative destination under media root, for example sources\\$OEM$\\$1\\Install\\PowerShell-7.6.3-win-x64.msi.'
        ServicingLogTextBox = 'Log output for servicing operations.'
        ServicingSelectionsListBox = 'Shows selected and added servicing items for traceability.'
        BuildMediaRootTextBox = 'Media root folder used to build a bootable ISO.'
        BuildOutputIsoTextBox = 'Output path for the bootable ISO to create.'
        BuildLabelTextBox = 'Volume label to stamp into the generated ISO.'
        BuildSourceImageTextBox = 'Source install.wim or install.esd used for export operations.'
        BuildDestinationWimTextBox = 'Destination path for exported custom install WIM.'
        BuildIndexesTextBox = 'Comma-separated image indexes to export, for example: 1,2.'
        BuildBootableIsoButton = 'Build a bootable ISO from the media root and output settings.'
        ExportInstallImageButton = 'Export selected image indexes into a destination WIM.'
        BuildLogTextBox = 'Log output for build and export operations.'
        StatusText = 'Current preflight and workflow status summary.'
        FooterText = 'General guidance for running preflight before long operations.'
    }

    foreach ($controlName in $tooltips.Keys) {
        if ($controls.ContainsKey($controlName) -and $null -ne $controls[$controlName]) {
            [GliderUI.Avalonia.Controls.ToolTip]::SetTip($controls[$controlName], $tooltips[$controlName])
        }
    }

    [pscustomobject]@{
        Window = $win
        Controls = $controls
    }
}