Skip to content

Commit 8d3adb5

Browse files
MyDrift-userclaudecoderabbitai[bot]
authored
Replace the FOSS dot with a corner badge on app entries (ChrisTitusTech#4924)
* Replace FOSS dot with a corner badge on app entries - Add New-WinUtilFossBadge, the open source keyhole on a green backdrop - Mark FOSS apps with a corner triangle instead of a dot after the name - Give the FOSS legend a circle badge and move it below the buttons - Sort Note entries last, they shared a rank with checkboxes before Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Update functions/private/Initialize-InstallAppEntry.ps1 Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent f7c0723 commit 8d3adb5

3 files changed

Lines changed: 80 additions & 22 deletions

File tree

functions/private/Initialize-InstallAppEntry.ps1

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ function Initialize-InstallAppEntry {
2121
$border.Tag = $appKey
2222
$border.ToolTip = $app.description
2323
$border.Add_MouseLeftButtonUp({
24-
$childCheckbox = ($this.Child | Where-Object {$_.Template.TargetType -eq [System.Windows.Controls.Checkbox]})[0]
25-
$childCheckBox.isChecked = -not $childCheckbox.IsChecked
24+
# Resolve through $sync because the border's child is a layout Grid for FOSS entries
25+
$childCheckbox = $sync.$($this.Tag)
26+
$childCheckbox.IsChecked = -not $childCheckbox.IsChecked
2627
})
2728
$border.Add_MouseEnter({
2829
if (($sync.$($this.Tag).IsChecked) -eq $false) {
@@ -48,15 +49,16 @@ function Initialize-InstallAppEntry {
4849
# Store the original appKey in Tag
4950
$checkBox.Tag = $appKey
5051
$checkbox.Style = $sync.Form.Resources.AppEntryCheckboxStyle
52+
# The checkbox sits inside the entry layout Grid, so the border is one level further up
5153
$checkbox.Add_Checked({
52-
Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $this.Parent.Tag
53-
$borderElement = $this.Parent
54+
Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $this.Tag
55+
$borderElement = $this.Parent.Parent
5456
$borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallSelectedColor")
5557
})
5658

5759
$checkbox.Add_Unchecked({
58-
Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkboxName $this.Parent.Tag
59-
$borderElement = $this.Parent
60+
Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkboxName $this.Tag
61+
$borderElement = $this.Parent.Parent
6062
$borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor")
6163
})
6264

@@ -88,23 +90,27 @@ function Initialize-InstallAppEntry {
8890
$appName = New-Object Windows.Controls.TextBlock
8991
$appName.Style = $sync.Form.Resources.AppEntryNameStyle
9092
$appName.Text = $app.content
91-
92-
# Add FOSS label after the name if FOSS
93-
if ($app.foss -eq $true) {
94-
$fossRun = [System.Windows.Documents.Run]::new(" $([char]0x25CF)")
95-
$fossRun.Foreground = [Windows.Media.SolidColorBrush]::new([Windows.Media.Color]::FromRgb(110, 255, 114))
96-
$fossRun.FontSize = 11.5
97-
98-
[void]$appName.Inlines.Add($fossRun)
99-
}
10093
[void]$contentPanel.Children.Add($appName)
10194
$checkBox.Content = $contentPanel
10295

10396
# Add accessibility properties to make the elements screen reader friendly
10497
$checkBox.SetValue([Windows.Automation.AutomationProperties]::NameProperty, $app.content)
10598
$border.SetValue([Windows.Automation.AutomationProperties]::NameProperty, $app.content)
10699

107-
$border.Child = $checkBox
100+
# Keep the same layout for every entry so the checkbox handlers can reach the border
101+
$entryLayout = New-Object Windows.Controls.Grid
102+
[void]$entryLayout.Children.Add($checkBox)
103+
104+
# Mark FOSS apps with a corner badge, bled into the border padding so it sits on the edge
105+
if ($app.foss -eq $true) {
106+
$fossBadge = New-WinUtilFossBadge
107+
$fossBadge.HorizontalAlignment = "Right"
108+
$fossBadge.VerticalAlignment = "Top"
109+
$fossBadge.Margin = New-Object Windows.Thickness(0, -4, -6, 0)
110+
111+
[void]$entryLayout.Children.Add($fossBadge)
112+
}
113+
$border.Child = $entryLayout
108114
if ($sync.selectedApps -contains $appKey) {
109115
$checkBox.IsChecked = $true
110116
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
function New-WinUtilFossBadge {
2+
<#
3+
.SYNOPSIS
4+
Creates the FOSS marker: the open source keyhole on a green backdrop
5+
.DESCRIPTION
6+
Returns a fresh element on every call, because a WPF element can only have one parent.
7+
The artwork is authored in a 22x22 box and scaled by the Viewbox, so callers only pick a size.
8+
.PARAMETER Size
9+
Edge length of the badge in pixels
10+
.PARAMETER Round
11+
Use a full circle instead of the corner triangle, for the legend rather than an app entry
12+
#>
13+
param(
14+
[double]$Size = 24,
15+
[switch]$Round
16+
)
17+
18+
$artwork = New-Object Windows.Controls.Grid
19+
$artwork.Width = 22
20+
$artwork.Height = 22
21+
22+
$backdrop = New-Object Windows.Shapes.Path
23+
$backdrop.Fill = [Windows.Media.SolidColorBrush]::new([Windows.Media.Color]::FromRgb(19, 143, 83))
24+
$keyhole = New-Object Windows.Shapes.Path
25+
$keyhole.Stroke = [Windows.Media.SolidColorBrush]::new([Windows.Media.Color]::FromRgb(247, 247, 247))
26+
27+
if ($Round) {
28+
$backdrop.Data = [Windows.Media.EllipseGeometry]::new([Windows.Point]::new(11, 11), 11, 11)
29+
# Keyhole centred in the circle, which has room for a larger ring than the triangle does
30+
$keyhole.Data = [Windows.Media.Geometry]::Parse("M 7.673,15.751 A 5.8,5.8 0 1 1 14.327,15.751")
31+
$keyhole.StrokeThickness = 3.4
32+
} else {
33+
# Triangle filling the top right corner, its outer corner rounded to match AppEntryBorderStyle
34+
$backdrop.Data = [Windows.Media.Geometry]::Parse("M 0,0 L 17,0 A 5,5 0 0 1 22,5 L 22,22 Z")
35+
# Keyhole centred on the triangle's incentre (15.56, 6.44) so it keeps the same
36+
# 1.8 clearance from all three edges
37+
$keyhole.Data = [Windows.Media.Geometry]::Parse("M 13.61,9.225 A 3.4,3.4 0 1 1 17.51,9.225")
38+
$keyhole.StrokeThickness = 2.4
39+
}
40+
41+
$keyhole.StrokeStartLineCap = [Windows.Media.PenLineCap]::Round
42+
$keyhole.StrokeEndLineCap = [Windows.Media.PenLineCap]::Round
43+
[void]$artwork.Children.Add($backdrop)
44+
[void]$artwork.Children.Add($keyhole)
45+
46+
$badge = New-Object Windows.Controls.Viewbox
47+
$badge.Width = $Size
48+
$badge.Height = $Size
49+
$badge.Child = $artwork
50+
$badge.ToolTip = "Free and Open Source Software"
51+
52+
return $badge
53+
}

functions/public/Invoke-WPFUIElements.ps1

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,12 @@ function Invoke-WPFUIElements {
143143
$itemsControl.Items.Add($label) | Out-Null
144144
$sync[$category] = $label
145145

146-
# Sort entries by type (checkboxes first, then buttons, then comboboxes) and then alphabetically by Content
146+
# Sort entries by type (checkboxes first, then buttons, then comboboxes, notes last) and then alphabetically by Content
147147
$entries = $organizedData[$panelKey][$category] | Sort-Object @{Expression = {
148148
switch ($_.Type) {
149149
'Button' { 1 }
150150
'Combobox' { 2 }
151+
'Note' { 3 }
151152
default { 0 }
152153
}
153154
}}, Content
@@ -364,17 +365,15 @@ function Invoke-WPFUIElements {
364365
$textBlock.Margin = "5,5,5,5"
365366
$textBlock.UseLayoutRounding = $true
366367

367-
$bulletRun = New-Object Windows.Documents.Run
368-
$bulletRun.Text = [char]0x25CF
369-
$bulletRun.Foreground = [Windows.Media.SolidColorBrush]::new([Windows.Media.Color]::FromRgb(110, 255, 114))
370-
$bulletRun.FontSize = 11.5
368+
$bulletBadge = [Windows.Documents.InlineUIContainer]::new((New-WinUtilFossBadge -Size 18 -Round))
369+
$bulletBadge.BaselineAlignment = [Windows.BaselineAlignment]::Center
371370

372371
$textRun = New-Object Windows.Documents.Run
373372
$textRun.Text = " $($entryInfo.Content)"
374373
$textRun.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize")
375374
$textRun.Foreground = [Windows.Media.SolidColorBrush]::new([Windows.Media.Color]::FromRgb(19, 143, 83))
376375

377-
$textBlock.Inlines.Add($bulletRun)
376+
$textBlock.Inlines.Add($bulletBadge)
378377
$textBlock.Inlines.Add($textRun)
379378

380379
$itemsControl.Items.Add($textBlock) | Out-Null

0 commit comments

Comments
 (0)