diff --git a/config/themes.json b/config/themes.json index b657c770..2fa3a498 100644 --- a/config/themes.json +++ b/config/themes.json @@ -46,6 +46,7 @@ "AppInstallUnselectedColor": "#F7F7F7", "AppInstallHighlightedColor": "#CFCFCF", "AppInstallSelectedColor": "#C2C2C2", + "AppInstallOverlayBackgroundColor":"#6A6D72", "ComboBoxForegroundColor": "#232629", "ComboBoxBackgroundColor": "#F7F7F7", "LabelboxForegroundColor": "#232629", @@ -85,6 +86,7 @@ "AppInstallUnselectedColor": "#232629", "AppInstallHighlightedColor": "#3C3C3C", "AppInstallSelectedColor": "#4C4C4C", + "AppInstallOverlayBackgroundColor":"#2E3135", "ComboBoxForegroundColor": "#F7F7F7", "ComboBoxBackgroundColor": "#1E3747", "LabelboxForegroundColor": "#0567ff", @@ -99,7 +101,7 @@ "ProgressBarForegroundColor": "#222222", "ProgressBarBackgroundColor": "Transparent", - "ProgressBarTextColor": "#cccccc", + "ProgressBarTextColor": "#232629", "ButtonInstallBackgroundColor": "#222222", "ButtonTweaksBackgroundColor": "#333333", "ButtonConfigBackgroundColor": "#444444", diff --git a/functions/private/Hide-WPFInstallAppBusy.ps1 b/functions/private/Hide-WPFInstallAppBusy.ps1 new file mode 100644 index 00000000..35646498 --- /dev/null +++ b/functions/private/Hide-WPFInstallAppBusy.ps1 @@ -0,0 +1,12 @@ +function Hide-WPFInstallAppBusy { + <# + .SYNOPSIS + Hides the busy overlay in the install app area of the WPF form. + This is used to indicate that an install or uninstall has finished. + #> + $sync.form.Dispatcher.Invoke([action]{ + $sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Collapsed + $sync.InstallAppAreaBorder.IsEnabled = $true + $sync.InstallAppAreaScrollViewer.Effect.Radius = 0 + }) +} diff --git a/functions/private/Initialize-InstallAppArea.ps1 b/functions/private/Initialize-InstallAppArea.ps1 index ea2f7ee0..85a66836 100644 --- a/functions/private/Initialize-InstallAppArea.ps1 +++ b/functions/private/Initialize-InstallAppArea.ps1 @@ -5,6 +5,8 @@ This is used as the parent object for all category and app entries on the install tab Used to as part of the Install Tab UI generation + Also creates an overlay with a progress bar and text to indicate that an install or uninstall is in progress + .PARAMETER TargetElement The element to which the AppArea shoud be added @@ -17,6 +19,7 @@ $Border = New-Object Windows.Controls.Border $Border.VerticalAlignment = "Stretch" $Border.SetResourceReference([Windows.Controls.Control]::StyleProperty, "BorderStyle") + $sync.InstallAppAreaBorder = $Border # Add a ScrollViewer, because the ItemsControl does not support scrolling by itself $scrollViewer = New-Object Windows.Controls.ScrollViewer @@ -24,11 +27,19 @@ $scrollViewer.HorizontalAlignment = 'Stretch' $scrollViewer.VerticalAlignment = 'Stretch' $scrollViewer.CanContentScroll = $true + $sync.InstallAppAreaScrollViewer = $scrollViewer + $Border.Child = $scrollViewer + + # Initialize the Blur Effect for the ScrollViewer, which will be used to indicate that an install/uninstall is in progress + $blurEffect = New-Object Windows.Media.Effects.BlurEffect + $blurEffect.Radius = 0 + $scrollViewer.Effect = $blurEffect ## Create the ItemsControl, which will be the parent of all the app entries $itemsControl = New-Object Windows.Controls.ItemsControl $itemsControl.HorizontalAlignment = 'Stretch' $itemsControl.VerticalAlignment = 'Stretch' + $scrollViewer.Content = $itemsControl # Enable virtualization for the ItemsControl to improve performance (It's hard to test if this is actually working, so if you know what you're doing, please check this) $itemsPanelTemplate = New-Object Windows.Controls.ItemsPanelTemplate @@ -38,8 +49,64 @@ $itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::IsVirtualizingProperty, $true) $itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::VirtualizationModeProperty, [Windows.Controls.VirtualizationMode]::Recycling) - $scrollViewer.Content = $itemsControl - $Border.Child = $scrollViewer - $null = $targetGrid.Children.Add($Border) + # Add the Border containing the App Area to the target Grid + $targetGrid.Children.Add($Border) | Out-Null + + $overlay = New-Object Windows.Controls.Border + $overlay.CornerRadius = New-Object Windows.CornerRadius(10) + $overlay.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallOverlayBackgroundColor") + $overlay.Visibility = [Windows.Visibility]::Collapsed + + # Also add the overlay to the target Grid on top of the App Area + $targetGrid.Children.Add($overlay) | Out-Null + $sync.InstallAppAreaOverlay = $overlay + + $overlayText = New-Object Windows.Controls.TextBlock + $overlayText.Text = "Installing apps..." + $overlayText.HorizontalAlignment = 'Center' + $overlayText.VerticalAlignment = 'Center' + $overlayText.SetResourceReference([Windows.Controls.TextBlock]::ForegroundProperty, "MainForegroundColor") + $overlayText.Background = "Transparent" + $overlayText.SetResourceReference([Windows.Controls.TextBlock]::FontSizeProperty, "HeaderFontSize") + $overlayText.SetResourceReference([Windows.Controls.TextBlock]::FontFamilyProperty, "MainFontFamily") + $overlayText.SetResourceReference([Windows.Controls.TextBlock]::FontWeightProperty, "MainFontWeight") + $overlayText.SetResourceReference([Windows.Controls.TextBlock]::MarginProperty, "MainMargin") + $sync.InstallAppAreaOverlayText = $overlayText + + $progressbar = New-Object Windows.Controls.ProgressBar + $progressbar.Name = "ProgressBar" + $progressbar.Width = 250 + $progressbar.Height = 50 + $sync.ProgressBar = $progressbar + + # Add a TextBlock overlay for the progress bar text + $progressBarTextBlock = New-Object Windows.Controls.TextBlock + $progressBarTextBlock.Name = "progressBarTextBlock" + $progressBarTextBlock.FontWeight = [Windows.FontWeights]::Bold + $progressBarTextBlock.FontSize = 16 + $progressBarTextBlock.Width = $progressbar.Width + $progressBarTextBlock.Height = $progressbar.Height + $progressBarTextBlock.SetResourceReference([Windows.Controls.TextBlock]::ForegroundProperty, "ProgressBarTextColor") + $progressBarTextBlock.TextTrimming = "CharacterEllipsis" + $progressBarTextBlock.Background = "Transparent" + $sync.progressBarTextBlock = $progressBarTextBlock + + # Create a Grid to overlay the text on the progress bar + $progressGrid = New-Object Windows.Controls.Grid + $progressGrid.Width = $progressbar.Width + $progressGrid.Height = $progressbar.Height + $progressGrid.Margin = "0,10,0,10" + $progressGrid.Children.Add($progressbar) | Out-Null + $progressGrid.Children.Add($progressBarTextBlock) | Out-Null + + $overlayStackPanel = New-Object Windows.Controls.StackPanel + $overlayStackPanel.Orientation = "Vertical" + $overlayStackPanel.HorizontalAlignment = 'Center' + $overlayStackPanel.VerticalAlignment = 'Center' + $overlayStackPanel.Children.Add($overlayText) | Out-Null + $overlayStackPanel.Children.Add($progressGrid) | Out-Null + + $overlay.Child = $overlayStackPanel + return $itemsControl } diff --git a/functions/private/Set-WinUtilProgressbar.ps1 b/functions/private/Set-WinUtilProgressbar.ps1 index e63bd202..9a2402ec 100644 --- a/functions/private/Set-WinUtilProgressbar.ps1 +++ b/functions/private/Set-WinUtilProgressbar.ps1 @@ -7,24 +7,18 @@ function Set-WinUtilProgressbar{ The Text to be overlayed onto the Progress Bar .PARAMETER PERCENT The percentage of the Progress Bar that should be filled (0-100) - .PARAMETER Hide - If provided, the Progress Bar and the label will be hidden #> param( [string]$Label, [ValidateRange(0,100)] - [int]$Percent, - $Hide + [int]$Percent ) - if ($hide) { - $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBarLabel.Visibility = "Collapsed"}) - $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBar.Visibility = "Collapsed"}) - } else { - $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBarLabel.Visibility = "Visible"}) - $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBar.Visibility = "Visible"}) + + $sync.form.Dispatcher.Invoke([action]{$sync.progressBarTextBlock.Text = $label}) + $sync.form.Dispatcher.Invoke([action]{$sync.progressBarTextBlock.ToolTip = $label}) + if ($percent -lt 5 ) { + $percent = 5 # Ensure the progress bar is not empty, as it looks weird } - $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBarLabel.Content.Text = $label}) - $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBarLabel.Content.ToolTip = $label}) $sync.form.Dispatcher.Invoke([action]{ $sync.ProgressBar.Value = $percent}) } diff --git a/functions/private/Show-WPFInstallAppBusy.ps1 b/functions/private/Show-WPFInstallAppBusy.ps1 new file mode 100644 index 00000000..350e3d68 --- /dev/null +++ b/functions/private/Show-WPFInstallAppBusy.ps1 @@ -0,0 +1,21 @@ +function Show-WPFInstallAppBusy { + <# + .SYNOPSIS + Displays a busy overlay in the install app area of the WPF form. + This is used to indicate that an install or uninstall is in progress. + Dynamically updates the size of the overlay based on the app area on each invocation. + .PARAMETER text + The text to display in the busy overlay. Defaults to "Installing apps...". + #> + param ( + $text = "Installing apps..." + ) + $sync.form.Dispatcher.Invoke([action]{ + $sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Visible + $sync.InstallAppAreaOverlay.Width = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4) + $sync.InstallAppAreaOverlay.Height = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4) + $sync.InstallAppAreaOverlayText.Text = $text + $sync.InstallAppAreaBorder.IsEnabled = $false + $sync.InstallAppAreaScrollViewer.Effect.Radius = 5 + }) + } diff --git a/functions/public/Invoke-WPFButton.ps1 b/functions/public/Invoke-WPFButton.ps1 index bad13090..34d789d5 100644 --- a/functions/public/Invoke-WPFButton.ps1 +++ b/functions/public/Invoke-WPFButton.ps1 @@ -15,7 +15,7 @@ function Invoke-WPFButton { # Use this to get the name of the button #[System.Windows.MessageBox]::Show("$Button","Chris Titus Tech's Windows Utility","OK","Info") if (-not $sync.ProcessRunning) { - Set-WinUtilProgressBar -label "" -percent 0 -hide $true + Set-WinUtilProgressBar -label "" -percent 0 } Switch -Wildcard ($Button) { diff --git a/functions/public/Invoke-WPFInstall.ps1 b/functions/public/Invoke-WPFInstall.ps1 index 70b710f5..2aeb8ca5 100644 --- a/functions/public/Invoke-WPFInstall.ps1 +++ b/functions/public/Invoke-WPFInstall.ps1 @@ -34,6 +34,8 @@ function Invoke-WPFInstall { try { $sync.ProcessRunning = $true + Show-WPFInstallAppBusy -text "Installing apps..." + if($packagesWinget.Count -gt 0) { Install-WinUtilWinget Install-WinUtilProgramWinget -Action Install -Programs $packagesWinget @@ -43,6 +45,7 @@ function Invoke-WPFInstall { Install-WinUtilChoco Install-WinUtilProgramChoco -Action Install -Programs $packagesChoco } + Hide-WPFInstallAppBusy Write-Host "===========================================" Write-Host "-- Installs have finished ---" Write-Host "===========================================" diff --git a/functions/public/Invoke-WPFUnInstall.ps1 b/functions/public/Invoke-WPFUnInstall.ps1 index fb3ee499..7f7da2f4 100644 --- a/functions/public/Invoke-WPFUnInstall.ps1 +++ b/functions/public/Invoke-WPFUnInstall.ps1 @@ -41,6 +41,7 @@ function Invoke-WPFUnInstall { try { $sync.ProcessRunning = $true + Show-WPFInstallAppBusy -text "Uninstalling apps..." # Uninstall all selected programs in new window if($packagesWinget.Count -gt 0) { @@ -49,7 +50,7 @@ function Invoke-WPFUnInstall { if($packagesChoco.Count -gt 0) { Install-WinUtilProgramChoco -Action Uninstall -Programs $packagesChoco } - + Hide-WPFInstallAppBusy Write-Host "===========================================" Write-Host "-- Uninstalls have finished ---" Write-Host "===========================================" diff --git a/xaml/inputXML.xaml b/xaml/inputXML.xaml index a319ee90..a747521d 100644 --- a/xaml/inputXML.xaml +++ b/xaml/inputXML.xaml @@ -992,34 +992,6 @@ Margin="210,0,0,0" Visibility="Collapsed"> - - -