Improve app page with table-like structure

This commit is contained in:
Raphire
2026-02-18 00:26:10 +01:00
parent f47b0531a4
commit 754c3cee4c
4 changed files with 138 additions and 35 deletions

View File

@@ -1,8 +1,8 @@
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Win11Debloat" Title="Win11Debloat"
MinWidth="1024" MinHeight="600" MinWidth="1080" MinHeight="600"
MaxWidth="1280" MaxWidth="1400"
ResizeMode="CanResize" ResizeMode="CanResize"
SnapsToDevicePixels="True" SnapsToDevicePixels="True"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
@@ -420,8 +420,35 @@
<!-- CheckBox style for apps panels --> <!-- CheckBox style for apps panels -->
<Style x:Key="AppsPanelCheckBoxStyle" TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}"> <Style x:Key="AppsPanelCheckBoxStyle" TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
<Setter Property="Margin" Value="2,3,2,3"/> <Setter Property="Margin" Value="2,3,2,3"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style> </Style>
<!-- TextBlock style for App ID column in apps table -->
<Style x:Key="AppIdTextStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{DynamicResource AppIdColor}"/>
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<!-- TextBlock style for App Name column in apps table -->
<Style x:Key="AppNameTextStyle" TargetType="TextBlock">
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<!-- TextBlock style for Description column in apps table -->
<Style x:Key="AppDescTextStyle" TargetType="TextBlock">
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="8,0,8,0"/>
</Style>
<!-- Column widths for the apps table row grid -->
<GridLength x:Key="AppTableCol0Width">160</GridLength>
<GridLength x:Key="AppTableCol1Width">1*</GridLength>
<GridLength x:Key="AppTableCol2Width">286</GridLength>
<!-- Button Style --> <!-- Button Style -->
<Style x:Key="PrimaryButtonStyle" TargetType="Button"> <Style x:Key="PrimaryButtonStyle" TargetType="Button">
<Setter Property="Background" Value="{DynamicResource ButtonBg}"/> <Setter Property="Background" Value="{DynamicResource ButtonBg}"/>
@@ -826,16 +853,36 @@
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Apps List --> <!-- Apps List -->
<Border Grid.Row="0" BorderBrush="{DynamicResource BorderColor}" CornerRadius="4" BorderThickness="1" Margin="20,0,20,10" Background="{DynamicResource CardBgColor}"> <Grid Grid.Row="0" Margin="20,0,20,10">
<Grid> <Grid.RowDefinitions>
<ScrollViewer VerticalScrollBarVisibility="Auto"> <RowDefinition Height="Auto"/>
<StackPanel x:Name="AppSelectionPanel" Margin="8"/> <RowDefinition Height="*"/>
</ScrollViewer> </Grid.RowDefinitions>
<Border x:Name="LoadingAppsIndicator" CornerRadius="4" Background="{DynamicResource ScrollBarThumbColor}" Opacity="0.8" Visibility="Collapsed"> <!-- Column Headers -->
<TextBlock Text="Loading apps..." FontSize="16" FontWeight="SemiBold" Foreground="{DynamicResource FgColor}" HorizontalAlignment="Center" VerticalAlignment="Center"/> <Border Grid.Row="0" Background="{DynamicResource ComboBgColor}" BorderBrush="{DynamicResource BorderColor}" BorderThickness="1,1,1,0" CornerRadius="4,4,0,0">
</Border> <Grid Margin="26,6,8,7">
</Grid> <Grid.ColumnDefinitions>
</Border> <ColumnDefinition Width="160"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="300"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="App Name" FontWeight="SemiBold" FontSize="14" Foreground="{DynamicResource FgColor}" Margin="16,0,0,0"/>
<TextBlock Grid.Column="1" Text="Description" FontWeight="SemiBold" FontSize="14" Foreground="{DynamicResource FgColor}" Margin="24,0,0,0"/>
<TextBlock Grid.Column="2" Text="App ID" FontWeight="SemiBold" FontSize="14" Foreground="{DynamicResource FgColor}"/>
</Grid>
</Border>
<!-- Apps content -->
<Border Grid.Row="1" BorderBrush="{DynamicResource BorderColor}" CornerRadius="0,0,4,4" BorderThickness="1" Background="{DynamicResource CardBgColor}">
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Visible">
<StackPanel x:Name="AppSelectionPanel" Margin="10,4,0,4"/>
</ScrollViewer>
<Border x:Name="LoadingAppsIndicator" CornerRadius="0,0,4,4" Background="{DynamicResource CardBgColor}" Opacity="0.8" Visibility="Collapsed">
<TextBlock Text="Loading apps..." FontSize="16" FontWeight="SemiBold" Foreground="{DynamicResource FgColor}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
</Border>
</Grid>
<!-- Status Info --> <!-- Status Info -->
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="20,0,20,0"> <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="20,0,20,0">

View File

@@ -28,11 +28,13 @@ function LoadAppsDetailsFromJson {
} }
} }
$friendlyName = if ($appData.FriendlyName) { $appData.FriendlyName } else { $appId }
$displayName = if ($appData.FriendlyName) { "$($appData.FriendlyName) ($appId)" } else { $appId } $displayName = if ($appData.FriendlyName) { "$($appData.FriendlyName) ($appId)" } else { $appId }
$isChecked = if ($InitialCheckedFromJson) { $appData.SelectedByDefault } else { $false } $isChecked = if ($InitialCheckedFromJson) { $appData.SelectedByDefault } else { $false }
$apps += [PSCustomObject]@{ $apps += [PSCustomObject]@{
AppId = $appId AppId = $appId
FriendlyName = $friendlyName
DisplayName = $displayName DisplayName = $displayName
IsChecked = $isChecked IsChecked = $isChecked
Description = $appData.Description Description = $appData.Description

View File

@@ -30,6 +30,9 @@ function SetWindowThemeResources {
$window.Resources.Add("InputFocusColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#1f1f1f"))) $window.Resources.Add("InputFocusColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#1f1f1f")))
$window.Resources.Add("ScrollBarThumbColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#3d3d3d"))) $window.Resources.Add("ScrollBarThumbColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#3d3d3d")))
$window.Resources.Add("ScrollBarThumbHoverColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#4b4b4b"))) $window.Resources.Add("ScrollBarThumbHoverColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#4b4b4b")))
$window.Resources.Add("AppIdColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#afafaf")))
$window.Resources.Add("SearchHighlightColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#4A4A2A")))
$window.Resources.Add("SearchHighlightActiveColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#8A7000")))
} }
else { else {
$window.Resources.Add("BgColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#f3f3f3"))) $window.Resources.Add("BgColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#f3f3f3")))
@@ -56,6 +59,9 @@ function SetWindowThemeResources {
$window.Resources.Add("InputFocusColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#fbfbfb"))) $window.Resources.Add("InputFocusColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#fbfbfb")))
$window.Resources.Add("ScrollBarThumbColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#b9b9b9"))) $window.Resources.Add("ScrollBarThumbColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#b9b9b9")))
$window.Resources.Add("ScrollBarThumbHoverColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#8b8b8b"))) $window.Resources.Add("ScrollBarThumbHoverColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#8b8b8b")))
$window.Resources.Add("AppIdColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#666666")))
$window.Resources.Add("SearchHighlightColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#FFF4CE")))
$window.Resources.Add("SearchHighlightActiveColor", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#FFD966")))
} }
$window.Resources.Add("ButtonBg", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#0067c0"))) $window.Resources.Add("ButtonBg", [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#0067c0")))

View File

@@ -534,16 +534,45 @@ function Show-MainWindow {
$script:MainWindowLastSelectedCheckbox = $null $script:MainWindowLastSelectedCheckbox = $null
# Sort apps alphabetically and add to panel # Sort apps alphabetically and add to panel
$appsToAdd | Sort-Object -Property DisplayName | ForEach-Object { $appsToAdd | Sort-Object -Property FriendlyName | ForEach-Object {
$checkbox = New-Object System.Windows.Controls.CheckBox $checkbox = New-Object System.Windows.Controls.CheckBox
$checkbox.Content = $_.DisplayName $checkbox.SetValue([System.Windows.Automation.AutomationProperties]::NameProperty, $_.FriendlyName)
$checkbox.SetValue([System.Windows.Automation.AutomationProperties]::NameProperty, $_.DisplayName)
$checkbox.Tag = $_.AppId $checkbox.Tag = $_.AppId
$checkbox.IsChecked = $_.IsChecked $checkbox.IsChecked = $_.IsChecked
$checkbox.ToolTip = $_.Description
$checkbox.Style = $window.Resources["AppsPanelCheckBoxStyle"] $checkbox.Style = $window.Resources["AppsPanelCheckBoxStyle"]
# Build table row content: App Name | Description | App ID
$row = New-Object System.Windows.Controls.Grid
$c0 = New-Object System.Windows.Controls.ColumnDefinition; $c0.Width = [System.Windows.GridLength]::new(160)
$c1 = New-Object System.Windows.Controls.ColumnDefinition; $c1.Width = [System.Windows.GridLength]::new(1, [System.Windows.GridUnitType]::Star)
$c2 = New-Object System.Windows.Controls.ColumnDefinition; $c2.Width = [System.Windows.GridLength]::new(286)
$row.ColumnDefinitions.Add($c0); $row.ColumnDefinitions.Add($c1); $row.ColumnDefinitions.Add($c2)
$tbName = New-Object System.Windows.Controls.TextBlock
$tbName.Text = $_.FriendlyName
$tbName.Style = $window.Resources["AppNameTextStyle"]
[System.Windows.Controls.Grid]::SetColumn($tbName, 0)
$tbDesc = New-Object System.Windows.Controls.TextBlock
$tbDesc.Text = $_.Description
$tbDesc.Style = $window.Resources["AppDescTextStyle"]
$tbDesc.ToolTip = $_.Description
[System.Windows.Controls.Grid]::SetColumn($tbDesc, 1)
$tbId = New-Object System.Windows.Controls.TextBlock
$tbId.Text = $_.AppId
$tbId.Style = $window.Resources["AppIdTextStyle"]
$tbId.ToolTip = $_.AppId
[System.Windows.Controls.Grid]::SetColumn($tbId, 2)
$row.Children.Add($tbName) | Out-Null
$row.Children.Add($tbDesc) | Out-Null
$row.Children.Add($tbId) | Out-Null
$checkbox.Content = $row
# Store metadata in checkbox for later use # Store metadata in checkbox for later use
Add-Member -InputObject $checkbox -MemberType NoteProperty -Name "AppName" -Value $_.FriendlyName
Add-Member -InputObject $checkbox -MemberType NoteProperty -Name "AppDescription" -Value $_.Description
Add-Member -InputObject $checkbox -MemberType NoteProperty -Name "SelectedByDefault" -Value $_.SelectedByDefault Add-Member -InputObject $checkbox -MemberType NoteProperty -Name "SelectedByDefault" -Value $_.SelectedByDefault
# Add event handler to update status # Add event handler to update status
@@ -674,16 +703,6 @@ function Show-MainWindow {
} }
}) })
# Shared search highlighting configuration
$script:SearchHighlightColor = [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#FFF4CE"))
$script:SearchHighlightColorDark = [System.Windows.Media.SolidColorBrush]::new([System.Windows.Media.ColorConverter]::ConvertFromString("#4A4A2A"))
# Helper function to get the appropriate highlight brush based on theme
function GetSearchHighlightBrush {
if ($usesDarkMode) { return $script:SearchHighlightColorDark }
return $script:SearchHighlightColor
}
# Helper function to scroll to an item if it's not visible, centering it in the viewport # Helper function to scroll to an item if it's not visible, centering it in the viewport
function ScrollToItemIfNotVisible { function ScrollToItemIfNotVisible {
param ( param (
@@ -737,6 +756,10 @@ function Show-MainWindow {
$appSearchBox = $window.FindName('AppSearchBox') $appSearchBox = $window.FindName('AppSearchBox')
$appSearchPlaceholder = $window.FindName('AppSearchPlaceholder') $appSearchPlaceholder = $window.FindName('AppSearchPlaceholder')
# Track current search matches and active index for Enter-key navigation
$script:AppSearchMatches = @()
$script:AppSearchMatchIndex = -1
$appSearchBox.Add_TextChanged({ $appSearchBox.Add_TextChanged({
$searchText = $appSearchBox.Text.ToLower().Trim() $searchText = $appSearchBox.Text.ToLower().Trim()
@@ -750,30 +773,55 @@ function Show-MainWindow {
} }
} }
$script:AppSearchMatches = @()
$script:AppSearchMatchIndex = -1
if ([string]::IsNullOrWhiteSpace($searchText)) { return } if ([string]::IsNullOrWhiteSpace($searchText)) { return }
# Find and highlight all matching apps # Find and highlight all matching apps
$firstMatch = $null $highlightBrush = $window.Resources["SearchHighlightColor"]
$highlightBrush = GetSearchHighlightBrush $activeHighlightBrush = $window.Resources["SearchHighlightActiveColor"]
foreach ($child in $appsPanel.Children) { foreach ($child in $appsPanel.Children) {
if ($child -is [System.Windows.Controls.CheckBox] -and $child.Visibility -eq 'Visible') { if ($child -is [System.Windows.Controls.CheckBox] -and $child.Visibility -eq 'Visible') {
if ($child.Content.ToString().ToLower().Contains($searchText)) { $appName = if ($child.AppName) { $child.AppName } else { '' }
$appId = if ($child.Tag) { $child.Tag.ToString() } else { '' }
$appDesc = if ($child.AppDescription) { $child.AppDescription } else { '' }
if ($appName.ToLower().Contains($searchText) -or $appId.ToLower().Contains($searchText) -or $appDesc.ToLower().Contains($searchText)) {
$child.Background = $highlightBrush $child.Background = $highlightBrush
if ($null -eq $firstMatch) { $firstMatch = $child } $script:AppSearchMatches += $child
} }
} }
} }
# Scroll to first match if not visible # Scroll to first match and mark it as active
if ($firstMatch) { if ($script:AppSearchMatches.Count -gt 0) {
$script:AppSearchMatchIndex = 0
$script:AppSearchMatches[0].Background = $activeHighlightBrush
$scrollViewer = FindParentScrollViewer -element $appsPanel $scrollViewer = FindParentScrollViewer -element $appsPanel
if ($scrollViewer) { if ($scrollViewer) {
ScrollToItemIfNotVisible -scrollViewer $scrollViewer -item $firstMatch -container $appsPanel ScrollToItemIfNotVisible -scrollViewer $scrollViewer -item $script:AppSearchMatches[0] -container $appsPanel
} }
} }
}) })
$appSearchBox.Add_KeyDown({
param($sender, $e)
if ($e.Key -eq [System.Windows.Input.Key]::Enter -and $script:AppSearchMatches.Count -gt 0) {
# Reset background of current active match
$script:AppSearchMatches[$script:AppSearchMatchIndex].Background = $window.Resources["SearchHighlightColor"]
# Advance to next match (wrapping)
$script:AppSearchMatchIndex = ($script:AppSearchMatchIndex + 1) % $script:AppSearchMatches.Count
# Highlight new active match
$script:AppSearchMatches[$script:AppSearchMatchIndex].Background = $window.Resources["SearchHighlightActiveColor"]
$scrollViewer = FindParentScrollViewer -element $appsPanel
if ($scrollViewer) {
ScrollToItemIfNotVisible -scrollViewer $scrollViewer -item $script:AppSearchMatches[$script:AppSearchMatchIndex] -container $appsPanel
}
$e.Handled = $true
}
})
# Tweak Search Box functionality # Tweak Search Box functionality
$tweakSearchBox = $window.FindName('TweakSearchBox') $tweakSearchBox = $window.FindName('TweakSearchBox')
$tweakSearchPlaceholder = $window.FindName('TweakSearchPlaceholder') $tweakSearchPlaceholder = $window.FindName('TweakSearchPlaceholder')
@@ -835,7 +883,7 @@ function Show-MainWindow {
# Find and highlight all matching tweaks # Find and highlight all matching tweaks
$firstMatch = $null $firstMatch = $null
$highlightBrush = GetSearchHighlightBrush $highlightBrush = $window.Resources["SearchHighlightColor"]
$columns = @($col0, $col1, $col2) | Where-Object { $_ -ne $null } $columns = @($col0, $col1, $col2) | Where-Object { $_ -ne $null }
foreach ($column in $columns) { foreach ($column in $columns) {