diff --git a/FFUDevelopment/BuildFFUVM_UI.ps1 b/FFUDevelopment/BuildFFUVM_UI.ps1 index 636d3fd..a6eaeb7 100644 --- a/FFUDevelopment/BuildFFUVM_UI.ps1 +++ b/FFUDevelopment/BuildFFUVM_UI.ps1 @@ -139,95 +139,16 @@ function Update-WingetVersionFields { $window.Add_Loaded({ # Pass the state object to all initialization functions $script:uiState.Window = $window - $window.Tag = $script:uiState # Store state in the window's Tag property + $window.Tag = $script:uiState Initialize-UIControls -State $script:uiState - - # Set ListViewItem style to stretch content horizontally so cell templates fill the cell - $itemStyleDriverModels = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem]) - $itemStyleDriverModels.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch))) - $script:uiState.Controls.lstDriverModels.ItemContainerStyle = $itemStyleDriverModels - - # Driver Models ListView setup - $driverModelsGridView = New-Object System.Windows.Controls.GridView - $script:uiState.Controls.lstDriverModels.View = $driverModelsGridView # Assign GridView to ListView first - - # Add the selectable column using the new function - Add-SelectableGridViewColumn -ListView $script:uiState.Controls.lstDriverModels -HeaderCheckBoxScriptVariableName "chkSelectAllDriverModels" -ColumnWidth 70 - - # Add other sortable columns with left-aligned headers - Add-SortableColumn -gridView $driverModelsGridView -header "Make" -binding "Make" -width 100 -headerHorizontalAlignment Left - Add-SortableColumn -gridView $driverModelsGridView -header "Model" -binding "Model" -width 200 -headerHorizontalAlignment Left - Add-SortableColumn -gridView $driverModelsGridView -header "Download Status" -binding "DownloadStatus" -width 150 -headerHorizontalAlignment Left - $script:uiState.Controls.lstDriverModels.AddHandler( - [System.Windows.Controls.GridViewColumnHeader]::ClickEvent, - [System.Windows.RoutedEventHandler] { - param($eventSource, $e) - $header = $e.OriginalSource - if ($header -is [System.Windows.Controls.GridViewColumnHeader] -and $header.Tag) { - Invoke-ListViewSort -listView $script:uiState.Controls.lstDriverModels -property $header.Tag -State $script:uiState - } - } - ) - # Set ListViewItem style to stretch content horizontally so cell templates fill the cell - $itemStyleWingetResults = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem]) - $itemStyleWingetResults.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch))) - $script:uiState.Controls.lstWingetResults.ItemContainerStyle = $itemStyleWingetResults - - # Bind ItemsSource to the data list - $script:uiState.Controls.lstAppsScriptVariables.ItemsSource = $script:uiState.Data.appsScriptVariablesDataList.ToArray() - - # Set ListViewItem style to stretch content horizontally so cell templates fill the cell - $itemStyleAppsScriptVars = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem]) - $itemStyleAppsScriptVars.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch))) - $script:uiState.Controls.lstAppsScriptVariables.ItemContainerStyle = $itemStyleAppsScriptVars - - # The GridView for lstAppsScriptVariables is defined in XAML. We need to get it and add the column. - if ($script:uiState.Controls.lstAppsScriptVariables.View -is [System.Windows.Controls.GridView]) { - Add-SelectableGridViewColumn -ListView $script:uiState.Controls.lstAppsScriptVariables -HeaderCheckBoxScriptVariableName "chkSelectAllAppsScriptVariables" -ColumnWidth 60 - - # Make Key and Value columns sortable - $appsScriptVarsGridView = $script:uiState.Controls.lstAppsScriptVariables.View - - # Key Column (should be at index 1 after selectable column is inserted at 0) - if ($appsScriptVarsGridView.Columns.Count -gt 1) { - $keyColumn = $appsScriptVarsGridView.Columns[1] - $keyHeader = New-Object System.Windows.Controls.GridViewColumnHeader - $keyHeader.Content = "Key" - $keyHeader.Tag = "Key" # Property to sort by - $keyHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left - $keyColumn.Header = $keyHeader - } - - # Value Column (should be at index 2) - if ($appsScriptVarsGridView.Columns.Count -gt 2) { - $valueColumn = $appsScriptVarsGridView.Columns[2] - $valueHeader = New-Object System.Windows.Controls.GridViewColumnHeader - $valueHeader.Content = "Value" - $valueHeader.Tag = "Value" # Property to sort by - $valueHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left - $valueColumn.Header = $valueHeader - } - - # Add Click event handler for sorting - $script:uiState.Controls.lstAppsScriptVariables.AddHandler( - [System.Windows.Controls.GridViewColumnHeader]::ClickEvent, - [System.Windows.RoutedEventHandler] { - param($eventSource, $e) - $header = $e.OriginalSource - if ($header -is [System.Windows.Controls.GridViewColumnHeader] -and $header.Tag) { - Invoke-ListViewSort -listView $script:uiState.Controls.lstAppsScriptVariables -property $header.Tag -State $script:uiState - } - } - ) - } - else { - WriteLog "Warning: lstAppsScriptVariables.View is not a GridView. Selectable column not added, and sorting cannot be enabled." - } # Get Windows Settings defaults and lists from helper module $script:uiState.Defaults.windowsSettingsDefaults = Get-WindowsSettingsDefaults + # Get General defaults from helper module $script:uiState.Defaults.generalDefaults = Get-GeneralDefaults -FFUDevelopmentPath $FFUDevelopmentPath + + Initialize-DynamicUIElements -State $script:uiState # Initialize Windows Settings UI using data from helper module Refresh-WindowsSettingsCombos -isoPath $script:uiState.Defaults.windowsSettingsDefaults.DefaultISOPath -State $script:uiState # Use combined refresh function @@ -710,9 +631,6 @@ $window.Add_Loaded({ $script:uiState.Controls.OfficeConfigurationXMLFileGrid.Visibility = 'Collapsed' }) - # Build dynamic multi-column checkboxes for optional features (Keep existing logic) - if ($script:uiState.Controls.featuresPanel) { BuildFeaturesGrid -parent $script:uiState.Controls.featuresPanel -allowedFeatures $script:uiState.Defaults.windowsSettingsDefaults.AllowedFeatures -State $script:uiState } - # Updates/InstallApps interplay (Keep existing logic) $script:uiState.Flags.installAppsForcedByUpdates = $false $script:uiState.Flags.prevInstallAppsStateBeforeUpdates = $null @@ -928,30 +846,6 @@ $window.Add_Loaded({ $window.Cursor = $null } }) - - # Winget Search ListView setup - $wingetGridView = New-Object System.Windows.Controls.GridView - $script:uiState.Controls.lstWingetResults.View = $wingetGridView # Assign GridView to ListView first - - # Add the selectable column using the new function - Add-SelectableGridViewColumn -ListView $script:uiState.Controls.lstWingetResults -HeaderCheckBoxScriptVariableName "chkSelectAllWingetResults" -ColumnWidth 60 - - # Add other sortable columns with left-aligned headers - Add-SortableColumn -gridView $wingetGridView -header "Name" -binding "Name" -width 200 -headerHorizontalAlignment Left - Add-SortableColumn -gridView $wingetGridView -header "Id" -binding "Id" -width 200 -headerHorizontalAlignment Left - Add-SortableColumn -gridView $wingetGridView -header "Version" -binding "Version" -width 100 -headerHorizontalAlignment Left - Add-SortableColumn -gridView $wingetGridView -header "Source" -binding "Source" -width 100 -headerHorizontalAlignment Left - Add-SortableColumn -gridView $wingetGridView -header "Download Status" -binding "DownloadStatus" -width 150 -headerHorizontalAlignment Left - $script:uiState.Controls.lstWingetResults.AddHandler( - [System.Windows.Controls.GridViewColumnHeader]::ClickEvent, - [System.Windows.RoutedEventHandler] { - param($eventSource, $e) - $header = $e.OriginalSource - if ($header -is [System.Windows.Controls.GridViewColumnHeader] -and $header.Tag) { - Invoke-ListViewSort -listView $script:uiState.Controls.lstWingetResults -property $header.Tag -State $script:uiState - } - } - ) $script:uiState.Controls.btnWingetSearch.Add_Click({ Search-WingetApps -State $script:uiState }) $script:uiState.Controls.txtWingetSearch.Add_KeyDown({ param($eventSrc, $keyEvent) diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 index 3b096fa..bbd862c 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 @@ -147,4 +147,141 @@ function Initialize-UIControls { $State.Controls.chkUpdateADK = $window.FindName('chkUpdateADK') } -Export-ModuleMember -Function * +function Initialize-DynamicUIElements { + param([PSCustomObject]$State) + WriteLog "Initializing dynamic UI elements (Grids, Columns)..." + + # Driver Models ListView setup + # Set ListViewItem style to stretch content horizontally so cell templates fill the cell + $itemStyleDriverModels = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem]) + $itemStyleDriverModels.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch))) + $State.Controls.lstDriverModels.ItemContainerStyle = $itemStyleDriverModels + + $driverModelsGridView = New-Object System.Windows.Controls.GridView + $State.Controls.lstDriverModels.View = $driverModelsGridView # Assign GridView to ListView first + + # Add the selectable column using the new function + Add-SelectableGridViewColumn -ListView $State.Controls.lstDriverModels -HeaderCheckBoxScriptVariableName "chkSelectAllDriverModels" -ColumnWidth 70 + + # Add other sortable columns with left-aligned headers + Add-SortableColumn -gridView $driverModelsGridView -header "Make" -binding "Make" -width 100 -headerHorizontalAlignment Left + Add-SortableColumn -gridView $driverModelsGridView -header "Model" -binding "Model" -width 200 -headerHorizontalAlignment Left + Add-SortableColumn -gridView $driverModelsGridView -header "Download Status" -binding "DownloadStatus" -width 150 -headerHorizontalAlignment Left + $State.Controls.lstDriverModels.AddHandler( + [System.Windows.Controls.GridViewColumnHeader]::ClickEvent, + [System.Windows.RoutedEventHandler] { + param($eventSource, $e) # $eventSource is the ListView control + $header = $e.OriginalSource + if ($header -is [System.Windows.Controls.GridViewColumnHeader] -and $header.Tag) { + # Retrieve the main UI state object from the window's Tag property + $listViewControl = $eventSource + $window = [System.Windows.Window]::GetWindow($listViewControl) + $uiStateFromWindowTag = $window.Tag + + Invoke-ListViewSort -listView $eventSource -property $header.Tag -State $uiStateFromWindowTag + } + } + ) + + # Winget Search ListView setup + $wingetGridView = New-Object System.Windows.Controls.GridView + $State.Controls.lstWingetResults.View = $wingetGridView # Assign GridView to ListView first + + # Set ListViewItem style to stretch content horizontally so cell templates fill the cell + $itemStyleWingetResults = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem]) + $itemStyleWingetResults.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch))) + $State.Controls.lstWingetResults.ItemContainerStyle = $itemStyleWingetResults + + # Add the selectable column using the new function + Add-SelectableGridViewColumn -ListView $State.Controls.lstWingetResults -HeaderCheckBoxScriptVariableName "chkSelectAllWingetResults" -ColumnWidth 60 + + # Add other sortable columns with left-aligned headers + Add-SortableColumn -gridView $wingetGridView -header "Name" -binding "Name" -width 200 -headerHorizontalAlignment Left + Add-SortableColumn -gridView $wingetGridView -header "Id" -binding "Id" -width 200 -headerHorizontalAlignment Left + Add-SortableColumn -gridView $wingetGridView -header "Version" -binding "Version" -width 100 -headerHorizontalAlignment Left + Add-SortableColumn -gridView $wingetGridView -header "Source" -binding "Source" -width 100 -headerHorizontalAlignment Left + Add-SortableColumn -gridView $wingetGridView -header "Download Status" -binding "DownloadStatus" -width 150 -headerHorizontalAlignment Left + + $State.Controls.lstWingetResults.AddHandler( + [System.Windows.Controls.GridViewColumnHeader]::ClickEvent, + [System.Windows.RoutedEventHandler] { + param($eventSource, $e) # $eventSource is the ListView control + $header = $e.OriginalSource + if ($header -is [System.Windows.Controls.GridViewColumnHeader] -and $header.Tag) { + # Retrieve the main UI state object from the window's Tag property + $listViewControl = $eventSource + $window = [System.Windows.Window]::GetWindow($listViewControl) + $uiStateFromWindowTag = $window.Tag + + Invoke-ListViewSort -listView $eventSource -property $header.Tag -State $uiStateFromWindowTag + } + } + ) + + # Apps Script Variables ListView setup + # Bind ItemsSource to the data list + $State.Controls.lstAppsScriptVariables.ItemsSource = $State.Data.appsScriptVariablesDataList.ToArray() + + # Set ListViewItem style to stretch content horizontally so cell templates fill the cell + $itemStyleAppsScriptVars = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem]) + $itemStyleAppsScriptVars.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch))) + $State.Controls.lstAppsScriptVariables.ItemContainerStyle = $itemStyleAppsScriptVars + + # The GridView for lstAppsScriptVariables is defined in XAML. We need to get it and add the column. + if ($State.Controls.lstAppsScriptVariables.View -is [System.Windows.Controls.GridView]) { + Add-SelectableGridViewColumn -ListView $State.Controls.lstAppsScriptVariables -HeaderCheckBoxScriptVariableName "chkSelectAllAppsScriptVariables" -ColumnWidth 60 + + # Make Key and Value columns sortable + $appsScriptVarsGridView = $State.Controls.lstAppsScriptVariables.View + + # Key Column (should be at index 1 after selectable column is inserted at 0) + if ($appsScriptVarsGridView.Columns.Count -gt 1) { + $keyColumn = $appsScriptVarsGridView.Columns[1] + $keyHeader = New-Object System.Windows.Controls.GridViewColumnHeader + $keyHeader.Content = "Key" + $keyHeader.Tag = "Key" # Property to sort by + $keyHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left + $keyColumn.Header = $keyHeader + } + + # Value Column (should be at index 2) + if ($appsScriptVarsGridView.Columns.Count -gt 2) { + $valueColumn = $appsScriptVarsGridView.Columns[2] + $valueHeader = New-Object System.Windows.Controls.GridViewColumnHeader + $valueHeader.Content = "Value" + $valueHeader.Tag = "Value" # Property to sort by + $valueHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left + $valueColumn.Header = $valueHeader + } + + # Add Click event handler for sorting + $State.Controls.lstAppsScriptVariables.AddHandler( + [System.Windows.Controls.GridViewColumnHeader]::ClickEvent, + [System.Windows.RoutedEventHandler] { + param($eventSource, $e) # $eventSource is the ListView control + $header = $e.OriginalSource + if ($header -is [System.Windows.Controls.GridViewColumnHeader] -and $header.Tag) { + # Retrieve the main UI state object from the window's Tag property + $listViewControl = $eventSource + $window = [System.Windows.Window]::GetWindow($listViewControl) + $uiStateFromWindowTag = $window.Tag + + Invoke-ListViewSort -listView $eventSource -property $header.Tag -State $uiStateFromWindowTag + } + } + ) + } + else { + WriteLog "Warning: lstAppsScriptVariables.View is not a GridView. Selectable column not added, and sorting cannot be enabled." + } + + # Build dynamic multi-column checkboxes for optional features + if ($State.Controls.featuresPanel -and $State.Defaults.windowsSettingsDefaults) { + BuildFeaturesGrid -parent $State.Controls.featuresPanel -allowedFeatures $State.Defaults.windowsSettingsDefaults.AllowedFeatures -State $State + } + else { + WriteLog "Initialize-DynamicUIElements: Could not build features grid. Panel or defaults missing." + } +} + +Export-ModuleMember -Function Initialize-UIControls, Initialize-DynamicUIElements diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Shared.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Shared.psm1 index 8821d24..e0673c8 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Shared.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Shared.psm1 @@ -437,6 +437,26 @@ function Invoke-ListViewSort { [PSCustomObject]$State ) + # Ensure $State.Flags is a hashtable and contains the required sort properties + if ($State.Flags -is [hashtable]) { + if (-not $State.Flags.ContainsKey('lastSortProperty')) { + $State.Flags['lastSortProperty'] = $null + } + if (-not $State.Flags.ContainsKey('lastSortAscending')) { + $State.Flags['lastSortAscending'] = $true # Default to ascending + } + } + else { + Write-Warning "Invoke-ListViewSort: \$State.Flags is not a hashtable or is null. Sort state may not work correctly." + # Attempt to initialize if $State.Flags is null or unexpectedly not a hashtable, + # though this might indicate a deeper issue with $State.Flags initialization. + if ($null -eq $State.Flags) { $State.Flags = @{} } + if ($State.Flags -is [hashtable]) { # Check again after potential initialization + if (-not $State.Flags.ContainsKey('lastSortProperty')) { $State.Flags['lastSortProperty'] = $null } + if (-not $State.Flags.ContainsKey('lastSortAscending')) { $State.Flags['lastSortAscending'] = $true } + } + } + # Toggle sort direction if clicking the same column if ($State.Flags.lastSortProperty -eq $property) { $State.Flags.lastSortAscending = -not $State.Flags.lastSortAscending