Files
winutil/functions/private/Initialize-InstallCategoryAppList.ps1
2026-02-05 15:50:15 -06:00

97 lines
4.7 KiB
PowerShell

function Initialize-InstallCategoryAppList {
<#
.SYNOPSIS
Clears the Target Element and sets up a "Loading" message. This is done, because loading of all apps can take a bit of time in some scenarios
Iterates through all Categories and Apps and adds them to the UI
Used to as part of the Install Tab UI generation
.PARAMETER TargetElement
The Element into which the Categories and Apps should be placed
.PARAMETER Apps
The Hashtable of Apps to be added to the UI
The Categories are also extracted from the Apps Hashtable
#>
param(
$TargetElement,
$Apps
)
# Pre-group apps by category
$appsByCategory = @{}
foreach ($appKey in $Apps.Keys) {
$category = $Apps.$appKey.Category
if (-not $appsByCategory.ContainsKey($category)) {
$appsByCategory[$category] = @()
}
$appsByCategory[$category] += $appKey
}
foreach ($category in $($appsByCategory.Keys | Sort-Object)) {
# Create a container for category label + apps
$categoryContainer = New-Object Windows.Controls.StackPanel
$categoryContainer.Orientation = "Vertical"
$categoryContainer.Margin = New-Object Windows.Thickness(0, 0, 0, 0)
$categoryContainer.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch
# Bind Width to the ItemsControl's ActualWidth to force full-row layout in WrapPanel
$binding = New-Object Windows.Data.Binding
$binding.Path = New-Object Windows.PropertyPath("ActualWidth")
$binding.RelativeSource = New-Object Windows.Data.RelativeSource([Windows.Data.RelativeSourceMode]::FindAncestor, [Windows.Controls.ItemsControl], 1)
[void][Windows.Data.BindingOperations]::SetBinding($categoryContainer, [Windows.FrameworkElement]::WidthProperty, $binding)
# Add category label to container
$toggleButton = New-Object Windows.Controls.Label
$toggleButton.Content = "- $Category"
$toggleButton.Tag = "CategoryToggleButton"
$toggleButton.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "HeaderFontSize")
$toggleButton.SetResourceReference([Windows.Controls.Control]::FontFamilyProperty, "HeaderFontFamily")
$toggleButton.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "LabelboxForegroundColor")
$toggleButton.Cursor = [System.Windows.Input.Cursors]::Hand
$toggleButton.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch
$sync.$Category = $toggleButton
# Add click handler to toggle category visibility
$toggleButton.Add_MouseLeftButtonUp({
param($sender, $e)
# Find the parent StackPanel (categoryContainer)
$categoryContainer = $sender.Parent
if ($categoryContainer -and $categoryContainer.Children.Count -ge 2) {
# The WrapPanel is the second child
$wrapPanel = $categoryContainer.Children[1]
# Toggle visibility
if ($wrapPanel.Visibility -eq [Windows.Visibility]::Visible) {
$wrapPanel.Visibility = [Windows.Visibility]::Collapsed
# Change - to +
$sender.Content = $sender.Content -replace "^- ", "+ "
} else {
$wrapPanel.Visibility = [Windows.Visibility]::Visible
# Change + to -
$sender.Content = $sender.Content -replace "^\+ ", "- "
}
}
})
$null = $categoryContainer.Children.Add($toggleButton)
# Add wrap panel for apps to container
$wrapPanel = New-Object Windows.Controls.WrapPanel
$wrapPanel.Orientation = "Horizontal"
$wrapPanel.HorizontalAlignment = "Left"
$wrapPanel.VerticalAlignment = "Top"
$wrapPanel.Margin = New-Object Windows.Thickness(0, 0, 0, 0)
$wrapPanel.Visibility = [Windows.Visibility]::Visible
$wrapPanel.Tag = "CategoryWrapPanel_$category"
$null = $categoryContainer.Children.Add($wrapPanel)
# Add the entire category container to the target element
$null = $TargetElement.Items.Add($categoryContainer)
# Add apps to the wrap panel
$appsByCategory[$category] | Sort-Object | ForEach-Object {
$sync.$_ = $(Initialize-InstallAppEntry -TargetElement $wrapPanel -AppKey $_)
}
}
}