From fd39b0008e13ab672dcd377f0f054e0acab53f7e Mon Sep 17 00:00:00 2001 From: rbalsleyMSFT <53497092+rbalsleyMSFT@users.noreply.github.com> Date: Wed, 18 Jun 2025 13:07:07 -0700 Subject: [PATCH] Refactor: Centralize Install Apps checkbox logic Consolidates the state management for the "Install Apps" checkbox into a single, reusable function. Previously, the logic to automatically check and disable "Install Apps" when selecting an update or installing Office was duplicated and scattered across multiple event handlers and files. This change introduces a new core function that centralizes this behavior. A single event handler is now used for all relevant checkboxes (Updates and Office), simplifying the UI code, reducing redundancy, and making the logic more robust and maintainable. The initial state is also set correctly on startup. --- FFUDevelopment/BuildFFUVM_UI.ps1 | 54 ------------------- .../FFUUI.Core/FFUUI.Core.Handlers.psm1 | 42 +++++++++------ .../FFUUI.Core/FFUUI.Core.Initialize.psm1 | 3 ++ FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 | 37 +++++++++++++ 4 files changed, 66 insertions(+), 70 deletions(-) diff --git a/FFUDevelopment/BuildFFUVM_UI.ps1 b/FFUDevelopment/BuildFFUVM_UI.ps1 index d5a5b93..49afac7 100644 --- a/FFUDevelopment/BuildFFUVM_UI.ps1 +++ b/FFUDevelopment/BuildFFUVM_UI.ps1 @@ -188,60 +188,6 @@ $window.Add_Loaded({ $script:uiState.Controls.OfficeConfigurationXMLFileGrid.Visibility = 'Collapsed' } - # Updates/InstallApps interplay (Keep existing logic) - $script:uiState.Flags.installAppsForcedByUpdates = $false - $script:uiState.Flags.prevInstallAppsStateBeforeUpdates = $null - # Define the scriptblock within the Loaded event and assign it to the state object - $script:uiState.Controls.UpdateInstallAppsBasedOnUpdates = { - param($State) # Pass state object to avoid using $script: scope inside - $anyUpdateChecked = $State.Controls.chkUpdateLatestDefender.IsChecked -or $State.Controls.chkUpdateEdge.IsChecked -or $State.Controls.chkUpdateOneDrive.IsChecked -or $State.Controls.chkUpdateLatestMSRT.IsChecked - if ($anyUpdateChecked) { - if (-not $State.Flags.installAppsForcedByUpdates) { - $State.Flags.prevInstallAppsStateBeforeUpdates = $State.Controls.chkInstallApps.IsChecked - $State.Flags.installAppsForcedByUpdates = $true - } - $State.Controls.chkInstallApps.IsChecked = $true - $State.Controls.chkInstallApps.IsEnabled = $false - } - else { - if ($State.Flags.installAppsForcedByUpdates) { - $State.Controls.chkInstallApps.IsChecked = $State.Flags.prevInstallAppsStateBeforeUpdates - $State.Flags.installAppsForcedByUpdates = $false - $State.Flags.prevInstallAppsStateBeforeUpdates = $null - } - # Only re-enable InstallApps if not forced by Office - if (-not $State.Controls.chkInstallOffice.IsChecked) { - $State.Controls.chkInstallApps.IsEnabled = $true - } - } - } - $script:uiState.Controls.chkUpdateLatestDefender.Add_Checked({ - & $script:uiState.Controls.UpdateInstallAppsBasedOnUpdates -State $script:uiState - }) - $script:uiState.Controls.chkUpdateLatestDefender.Add_Unchecked({ - & $script:uiState.Controls.UpdateInstallAppsBasedOnUpdates -State $script:uiState - }) - $script:uiState.Controls.chkUpdateEdge.Add_Checked({ - & $script:uiState.Controls.UpdateInstallAppsBasedOnUpdates -State $script:uiState - }) - $script:uiState.Controls.chkUpdateEdge.Add_Unchecked({ - & $script:uiState.Controls.UpdateInstallAppsBasedOnUpdates -State $script:uiState - }) - $script:uiState.Controls.chkUpdateOneDrive.Add_Checked({ - & $script:uiState.Controls.UpdateInstallAppsBasedOnUpdates -State $script:uiState - }) - $script:uiState.Controls.chkUpdateOneDrive.Add_Unchecked({ - & $script:uiState.Controls.UpdateInstallAppsBasedOnUpdates -State $script:uiState - }) - $script:uiState.Controls.chkUpdateLatestMSRT.Add_Checked({ - & $script:uiState.Controls.UpdateInstallAppsBasedOnUpdates -State $script:uiState - }) - $script:uiState.Controls.chkUpdateLatestMSRT.Add_Unchecked({ - & $script:uiState.Controls.UpdateInstallAppsBasedOnUpdates -State $script:uiState - }) - # Initial check for Updates/InstallApps state - & $script:uiState.Controls.UpdateInstallAppsBasedOnUpdates -State $script:uiState - # CU interplay (Keep existing logic) $script:uiState.Controls.chkLatestCU.Add_Checked({ $script:uiState.Controls.chkPreviewCU.IsEnabled = $false diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1 index 5021f68..1d2d21c 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1 @@ -57,17 +57,36 @@ function Register-EventHandlers { if ($ofd.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { $localState.Controls.txtISOPath.Text = $ofd.FileName } }) + # Updates Tab Event Handlers + # Define a single handler scriptblock for all update checkboxes that affect the main InstallApps checkbox + $updateCheckboxHandler = { + param($eventSource, $routedEventArgs) + $window = [System.Windows.Window]::GetWindow($eventSource) + if ($null -ne $window) { + # The function to call now lives in the Applications module + Update-InstallAppsState -State $window.Tag + } + } + + # Attach the handler to all relevant update checkboxes + $State.Controls.chkUpdateLatestDefender.Add_Checked($updateCheckboxHandler) + $State.Controls.chkUpdateLatestDefender.Add_Unchecked($updateCheckboxHandler) + $State.Controls.chkUpdateEdge.Add_Checked($updateCheckboxHandler) + $State.Controls.chkUpdateEdge.Add_Unchecked($updateCheckboxHandler) + $State.Controls.chkUpdateOneDrive.Add_Checked($updateCheckboxHandler) + $State.Controls.chkUpdateOneDrive.Add_Unchecked($updateCheckboxHandler) + $State.Controls.chkUpdateLatestMSRT.Add_Checked($updateCheckboxHandler) + $State.Controls.chkUpdateLatestMSRT.Add_Unchecked($updateCheckboxHandler) + + # Also attach the handler to the Office checkbox + $State.Controls.chkInstallOffice.Add_Checked($updateCheckboxHandler) + $State.Controls.chkInstallOffice.Add_Unchecked($updateCheckboxHandler) + # M365 Apps/Office tab Event Handlers $State.Controls.chkInstallOffice.Add_Checked({ param($eventSource, $routedEventArgs) $window = [System.Windows.Window]::GetWindow($eventSource) $localState = $window.Tag - - if (-not $localState.Controls.chkInstallApps.IsChecked) { - $localState.Controls.chkInstallApps.IsChecked = $true - $localState.Flags.installAppsCheckedByOffice = $true - } - $localState.Controls.chkInstallApps.IsEnabled = $false $localState.Controls.OfficePathStackPanel.Visibility = 'Visible' $localState.Controls.OfficePathGrid.Visibility = 'Visible' $localState.Controls.CopyOfficeConfigXMLStackPanel.Visibility = 'Visible' @@ -79,15 +98,6 @@ function Register-EventHandlers { param($eventSource, $routedEventArgs) $window = [System.Windows.Window]::GetWindow($eventSource) $localState = $window.Tag - - if ($localState.Flags.installAppsCheckedByOffice) { - $localState.Controls.chkInstallApps.IsChecked = $false - $localState.Flags.installAppsCheckedByOffice = $false - } - # Only re-enable InstallApps if not forced by Updates - if (-not $localState.Flags.installAppsForcedByUpdates) { - $localState.Controls.chkInstallApps.IsEnabled = $true - } $localState.Controls.OfficePathStackPanel.Visibility = 'Collapsed' $localState.Controls.OfficePathGrid.Visibility = 'Collapsed' $localState.Controls.CopyOfficeConfigXMLStackPanel.Visibility = 'Collapsed' @@ -110,7 +120,7 @@ function Register-EventHandlers { $localState.Controls.OfficeConfigurationXMLFileStackPanel.Visibility = 'Collapsed' $localState.Controls.OfficeConfigurationXMLFileGrid.Visibility = 'Collapsed' }) - + # Drivers Tab Event Handlers $State.Controls.chkDownloadDrivers.Add_Checked({ param($eventSource, $routedEventArgs) diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 index a870890..b52a905 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 @@ -235,6 +235,9 @@ function Initialize-UIDefaults { $State.Controls.chkInstallDrivers.IsChecked = $State.Defaults.generalDefaults.InstallDrivers $State.Controls.chkCopyDrivers.IsChecked = $State.Defaults.generalDefaults.CopyDrivers $State.Controls.chkCopyPEDrivers.IsChecked = $State.Defaults.generalDefaults.CopyPEDrivers + + # Set initial state for InstallApps checkbox based on updates + Update-InstallAppsState -State $State } function Initialize-DynamicUIElements { diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 index 195f5c5..0ba6f17 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 @@ -188,6 +188,43 @@ function Get-USBDrives { } } +# Function to manage the state of the main "Install Apps" checkbox based on selections in Updates/Office +function Update-InstallAppsState { + param([PSCustomObject]$State) + + $installAppsChk = $State.Controls.chkInstallApps + $installOfficeChk = $State.Controls.chkInstallOffice + + # Determine if any checkbox that forces "Install Apps" is checked + $anyUpdateChecked = $State.Controls.chkUpdateLatestDefender.IsChecked -or ` + $State.Controls.chkUpdateEdge.IsChecked -or ` + $State.Controls.chkUpdateOneDrive.IsChecked -or ` + $State.Controls.chkUpdateLatestMSRT.IsChecked + + $isForced = $anyUpdateChecked -or $installOfficeChk.IsChecked + + if ($isForced) { + # If InstallApps is not already forced (i.e., it's enabled), save its current state. + if ($installAppsChk.IsEnabled) { + $State.Flags.prevInstallAppsState = $installAppsChk.IsChecked + } + $installAppsChk.IsChecked = $true + $installAppsChk.IsEnabled = $false + } + else { + # No longer forced. Restore the previous state if it was saved. + if ($State.Flags.ContainsKey('prevInstallAppsState')) { + $installAppsChk.IsChecked = $State.Flags.prevInstallAppsState + $State.Flags.Remove('prevInstallAppsState') # Use the saved state only once + } + else { + # If no state was saved (e.g., it was never forced), ensure it's unchecked. + $installAppsChk.IsChecked = $false + } + $installAppsChk.IsEnabled = $true + } +} + # -------------------------------------------------------------------------- # SECTION: Module Export # --------------------------------------------------------------------------