mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2026-08-10 18:11:16 +10:00
* Turn the Install category filters into toggle chips - Replace the filter buttons with toggles that show which ones are active - Add ctrl click to select more than one category - Keep the search box and the category filter independent of each other - Expand matching categories while a filter is active * Fix the filter interactions the category chips missed - Pass the selected categories to the lazy rendering batches, the old call used a parameter that no longer exists and threw while typing - Keep the category filter when switching tabs, the chips stayed checked while the filter itself was dropped - Put a category back to collapsed once the filter that expanded it is gone * Document the Install category filters - Add a guide section for the chips, ctrl click and clearing the filter - Note that search and the category chips apply together * Correct the category filter guide wording - Clearing by clicking the chip only applies when it is the only one selected - Only categories with matches expand, and only auto expanded ones re-collapse
108 lines
5.3 KiB
PowerShell
108 lines
5.3 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 before creating WPF controls.
|
|
$appsByCategory = @{}
|
|
foreach ($appKey in $Apps.Keys) {
|
|
$category = $Apps.$appKey.Category
|
|
if (-not $appsByCategory.ContainsKey($category)) {
|
|
$appsByCategory[$category] = @()
|
|
}
|
|
$appsByCategory[$category] += $appKey
|
|
}
|
|
$sync.InstallAppRenderQueue = [System.Collections.Queue]::new()
|
|
|
|
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
|
|
[System.Windows.Automation.AutomationProperties]::SetName($categoryContainer, $Category)
|
|
|
|
# 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($categoryToggle)
|
|
|
|
# Find the parent StackPanel (categoryContainer)
|
|
$categoryContainer = $categoryToggle.Parent
|
|
if ($categoryContainer -and $categoryContainer.Children.Count -ge 2) {
|
|
# The WrapPanel is the second child
|
|
$wrapPanel = $categoryContainer.Children[1]
|
|
|
|
# An explicit click wins over anything filtering expanded automatically
|
|
if ($sync.AppCategoryAutoExpanded) {
|
|
$sync.AppCategoryAutoExpanded.Remove(($categoryToggle.Content -replace '^[+-] ', ''))
|
|
}
|
|
|
|
# Toggle visibility
|
|
if ($wrapPanel.Visibility -eq [Windows.Visibility]::Visible) {
|
|
$wrapPanel.Visibility = [Windows.Visibility]::Collapsed
|
|
# Change - to +
|
|
$categoryToggle.Content = $categoryToggle.Content -replace "^- ", "+ "
|
|
} else {
|
|
$wrapPanel.Visibility = [Windows.Visibility]::Visible
|
|
# Change + to -
|
|
$categoryToggle.Content = $categoryToggle.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)
|
|
|
|
$sync.InstallAppRenderQueue.Enqueue([pscustomobject]@{
|
|
Category = $category
|
|
TargetElement = $wrapPanel
|
|
AppKeys = @($appsByCategory[$category] | Sort-Object)
|
|
})
|
|
}
|
|
|
|
Start-WinUtilInstallAppRendering
|
|
}
|