mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2025-07-03 03:23:31 -05:00
Compare commits
46 Commits
24.10.24
...
a6bababb43
Author | SHA1 | Date | |
---|---|---|---|
a6bababb43 | |||
5514025577 | |||
c46a7eaa40 | |||
e0e8daf4e2 | |||
cf2f741408 | |||
7d0e4df4ec | |||
7e6634d99d | |||
f04b52d0db | |||
402082b376 | |||
79fb48e4df | |||
3faa3bad3d | |||
d441952e5e | |||
c0d6e0bbc7 | |||
fd4d783a04 | |||
e048097c78 | |||
4bfeacf80d | |||
80a933db8e | |||
9dd89136e8 | |||
7b273d5634 | |||
2d0e68c90f | |||
ba968d0cb3 | |||
8d34e2fa30 | |||
dcf752fdeb | |||
a839acd949 | |||
f05fece2e5 | |||
cf664bd1d3 | |||
6d88e51462 | |||
5bbc6c6a92 | |||
fdb156a450 | |||
7d90ab8660 | |||
f576d57ffc | |||
4889c1c508 | |||
ae1a9530f9 | |||
0467c3a7c8 | |||
7686e7fff4 | |||
468b7209be | |||
15c84f2a1f | |||
5b0ea0b373 | |||
e8de029483 | |||
af39f43cec | |||
5bb940d4d5 | |||
4c38768b32 | |||
6229ab6dd4 | |||
71c35eccd6 | |||
db521534bc | |||
a1188871f4 |
55
config/appnavigation.json
Normal file
55
config/appnavigation.json
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"WPFToggleView": {
|
||||||
|
"Content": ["Expanded View", "Compact View"],
|
||||||
|
"Category": "____Actions",
|
||||||
|
"Type": "ToggleButton",
|
||||||
|
"Order": "1",
|
||||||
|
"Description": "Toggle between a list and a compact grid like view"
|
||||||
|
},
|
||||||
|
"WPFSelectedFilter": {
|
||||||
|
"Content": [ "Show All", "Show Selected"],
|
||||||
|
"Category": "____Actions",
|
||||||
|
"Type": "ToggleButton",
|
||||||
|
"Order": "2",
|
||||||
|
"Description": "Toggle between showing all or only the selected applications"
|
||||||
|
},
|
||||||
|
"WPFClearInstallSelection": {
|
||||||
|
"Content": "Clear Selection",
|
||||||
|
"Category": "____Actions",
|
||||||
|
"Type": "Button",
|
||||||
|
"Order": "3",
|
||||||
|
"Description": "Clear the selection of applications"
|
||||||
|
},
|
||||||
|
"WPFGetInstalled": {
|
||||||
|
"Content": "Get Installed",
|
||||||
|
"Category": "____Actions",
|
||||||
|
"Type": "Button",
|
||||||
|
"Order": "4",
|
||||||
|
"Description": "Show installed applications"
|
||||||
|
},
|
||||||
|
"WingetRadioButton": {
|
||||||
|
"Content": "Winget",
|
||||||
|
"Category": "__Package Manager",
|
||||||
|
"Type": "RadioButton",
|
||||||
|
"GroupName": "PackageManagerGroup",
|
||||||
|
"Checked": true,
|
||||||
|
"Order": "1",
|
||||||
|
"Description": "Use Winget for package management"
|
||||||
|
},
|
||||||
|
"ChocoRadioButton": {
|
||||||
|
"Content": "Chocolatey",
|
||||||
|
"Category": "__Package Manager",
|
||||||
|
"Type": "RadioButton",
|
||||||
|
"GroupName": "PackageManagerGroup",
|
||||||
|
"Checked": false,
|
||||||
|
"Order": "2",
|
||||||
|
"Description": "Use Chocolatey for package management"
|
||||||
|
},
|
||||||
|
"autofallback": {
|
||||||
|
"Content": "Auto Fallback",
|
||||||
|
"Category": "__Package Manager",
|
||||||
|
"Checked": true,
|
||||||
|
"Order": "3",
|
||||||
|
"Description": "If the selected package manager fails, automatically switch to the other one"
|
||||||
|
}
|
||||||
|
}
|
@ -38,6 +38,9 @@
|
|||||||
"ButtonCornerRadius": "2"
|
"ButtonCornerRadius": "2"
|
||||||
},
|
},
|
||||||
"Light": {
|
"Light": {
|
||||||
|
"AppInstallUnselectedColor": "#F0F0F0",
|
||||||
|
"AppInstallHighlightedColor": "#CFCFCF",
|
||||||
|
"AppInstallSelectedColor": "#C2C2C2",
|
||||||
"ComboBoxForegroundColor": "#232629",
|
"ComboBoxForegroundColor": "#232629",
|
||||||
"ComboBoxBackgroundColor": "#F7F7F7",
|
"ComboBoxBackgroundColor": "#F7F7F7",
|
||||||
"LabelboxForegroundColor": "#232629",
|
"LabelboxForegroundColor": "#232629",
|
||||||
@ -73,6 +76,9 @@
|
|||||||
|
|
||||||
},
|
},
|
||||||
"Dark": {
|
"Dark": {
|
||||||
|
"AppInstallUnselectedColor": "#232629",
|
||||||
|
"AppInstallHighlightedColor": "#3C3C3C",
|
||||||
|
"AppInstallSelectedColor": "#4C4C4C",
|
||||||
"ComboBoxForegroundColor": "#F7F7F7",
|
"ComboBoxForegroundColor": "#F7F7F7",
|
||||||
"ComboBoxBackgroundColor": "#1E3747",
|
"ComboBoxBackgroundColor": "#1E3747",
|
||||||
"LabelboxForegroundColor": "#0567ff",
|
"LabelboxForegroundColor": "#0567ff",
|
||||||
|
@ -2584,36 +2584,6 @@
|
|||||||
],
|
],
|
||||||
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveCopilot"
|
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveCopilot"
|
||||||
},
|
},
|
||||||
"WPFTweaksRecallOff": {
|
|
||||||
"Content": "Disable Recall",
|
|
||||||
"Description": "Turn Recall off",
|
|
||||||
"category": "Essential Tweaks",
|
|
||||||
"panel": "1",
|
|
||||||
"Order": "a011_",
|
|
||||||
"registry": [
|
|
||||||
{
|
|
||||||
|
|
||||||
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsAI",
|
|
||||||
"Name": "DisableAIDataAnalysis",
|
|
||||||
"Type": "DWord",
|
|
||||||
"Value": "1",
|
|
||||||
"OriginalValue": "0"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"InvokeScript": [
|
|
||||||
"
|
|
||||||
Write-Host \"Disable Recall\"
|
|
||||||
DISM /Online /Disable-Feature /FeatureName:Recall
|
|
||||||
"
|
|
||||||
],
|
|
||||||
"UndoScript": [
|
|
||||||
"
|
|
||||||
Write-Host \"Enable Recall\"
|
|
||||||
DISM /Online /Enable-Feature /FeatureName:Recall
|
|
||||||
"
|
|
||||||
],
|
|
||||||
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/DisableRecall"
|
|
||||||
},
|
|
||||||
"WPFTweaksDisableLMS1": {
|
"WPFTweaksDisableLMS1": {
|
||||||
"Content": "Disable Intel MM (vPro LMS)",
|
"Content": "Disable Intel MM (vPro LMS)",
|
||||||
"Description": "Intel LMS service is always listening on all ports and could be a huge security risk. There is no need to run LMS on home machines and even in the Enterprise there are better solutions.",
|
"Description": "Intel LMS service is always listening on all ports and could be a huge security risk. There is no need to run LMS on home machines and even in the Enterprise there are better solutions.",
|
||||||
|
@ -1,91 +0,0 @@
|
|||||||
# Disable Microsoft Recall
|
|
||||||
|
|
||||||
Last Updated: 2024-10-24
|
|
||||||
|
|
||||||
|
|
||||||
!!! info
|
|
||||||
The Development Documentation is auto generated for every compilation of WinUtil, meaning a part of it will always stay up-to-date. **Developers do have the ability to add custom content, which won't be updated automatically.**
|
|
||||||
## Description
|
|
||||||
|
|
||||||
Disables MS Recall built into Windows since 24H2.
|
|
||||||
|
|
||||||
<!-- BEGIN CUSTOM CONTENT -->
|
|
||||||
|
|
||||||
<!-- END CUSTOM CONTENT -->
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Preview Code</summary>
|
|
||||||
|
|
||||||
```json
|
|
||||||
"WPFTweaksRecallOff": {
|
|
||||||
"Content": "Disable Recall",
|
|
||||||
"Description": "Turn Recall off",
|
|
||||||
"category": "Essential Tweaks",
|
|
||||||
"panel": "1",
|
|
||||||
"Order": "a011_",
|
|
||||||
"registry": [
|
|
||||||
{
|
|
||||||
|
|
||||||
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsAI",
|
|
||||||
"Name": "DisableAIDataAnalysis",
|
|
||||||
"Type": "DWord",
|
|
||||||
"Value": "1",
|
|
||||||
"OriginalValue": "0"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"InvokeScript": [
|
|
||||||
"
|
|
||||||
Write-Host \"Disable Recall\"
|
|
||||||
DISM /Online /Disable-Feature /FeatureName:Recall
|
|
||||||
"
|
|
||||||
],
|
|
||||||
"UndoScript": [
|
|
||||||
"
|
|
||||||
Write-Host \"Enable Recall\"
|
|
||||||
DISM /Online /Enable-Feature /FeatureName:Recall
|
|
||||||
"
|
|
||||||
],
|
|
||||||
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/DisableRecall"
|
|
||||||
},
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## Invoke Script
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
|
|
||||||
Write-Host "Disable Recall"
|
|
||||||
DISM /Online /Disable-Feature /FeatureName:Recall
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
## Undo Script
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
|
|
||||||
Write-Host "Enable Recall"
|
|
||||||
DISM /Online /Enable-Feature /FeatureName:Recall
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
## Registry Changes
|
|
||||||
Applications and System Components store and retrieve configuration data to modify windows settings, so we can use the registry to change many settings in one place.
|
|
||||||
|
|
||||||
|
|
||||||
You can find information about the registry on [Wikipedia](https://www.wikiwand.com/en/Windows_Registry) and [Microsoft's Website](https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry).
|
|
||||||
|
|
||||||
### Registry Key: DisableAIDataAnalysis
|
|
||||||
|
|
||||||
**Type:** DWord
|
|
||||||
|
|
||||||
**Original Value:** 0
|
|
||||||
|
|
||||||
**New Value:** 1
|
|
||||||
|
|
||||||
<!-- BEGIN SECOND CUSTOM CONTENT -->
|
|
||||||
|
|
||||||
<!-- END SECOND CUSTOM CONTENT -->
|
|
||||||
|
|
||||||
|
|
||||||
[View the JSON file](https://github.com/ChrisTitusTech/winutil/tree/main/config/tweaks.json)
|
|
50
functions/private/Add-SelectedAppsMenuItem.ps1
Normal file
50
functions/private/Add-SelectedAppsMenuItem.ps1
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
function Add-SelectedAppsMenuItem {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
This is a helper function that generates and adds the Menu Items to the Selected Apps Popup.
|
||||||
|
|
||||||
|
.Parameter name
|
||||||
|
The actual Name of an App like "Chrome" or "Brave"
|
||||||
|
This name is contained in the "Content" property inside the applications.json
|
||||||
|
.PARAMETER key
|
||||||
|
The key which identifies an app object in applications.json
|
||||||
|
For Chrome this would be "WPFInstallchrome" because "WPFInstall" is prepended automatically for each key in applications.json
|
||||||
|
#>
|
||||||
|
|
||||||
|
param ([string]$name, [string]$key)
|
||||||
|
|
||||||
|
$selectedAppGrid = New-Object Windows.Controls.Grid
|
||||||
|
|
||||||
|
$selectedAppGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = "*"}))
|
||||||
|
$selectedAppGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = "30"}))
|
||||||
|
|
||||||
|
# Sets the name to the Content as well as the Tooltip, because the parent Popup Border has a fixed width and text could "overflow".
|
||||||
|
# With the tooltip, you can still read the whole entry on hover
|
||||||
|
$selectedAppLabel = New-Object Windows.Controls.Label
|
||||||
|
$selectedAppLabel.Content = $name
|
||||||
|
$selectedAppLabel.ToolTip = $name
|
||||||
|
$selectedAppLabel.HorizontalAlignment = "Left"
|
||||||
|
$selectedAppLabel.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
|
||||||
|
[System.Windows.Controls.Grid]::SetColumn($selectedAppLabel, 0)
|
||||||
|
$selectedAppGrid.Children.Add($selectedAppLabel)
|
||||||
|
|
||||||
|
$selectedAppRemoveButton = New-Object Windows.Controls.Button
|
||||||
|
$selectedAppRemoveButton.FontFamily = "Segoe MDL2 Assets"
|
||||||
|
$selectedAppRemoveButton.Content = [string]([char]0xE711)
|
||||||
|
$selectedAppRemoveButton.HorizontalAlignment = "Center"
|
||||||
|
$selectedAppRemoveButton.Tag = $key
|
||||||
|
$selectedAppRemoveButton.ToolTip = "Remove the App from Selection"
|
||||||
|
$selectedAppRemoveButton.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
|
||||||
|
$selectedAppRemoveButton.SetResourceReference([Windows.Controls.Control]::StyleProperty, "HoverButtonStyle")
|
||||||
|
|
||||||
|
# Highlight the Remove icon on Hover
|
||||||
|
$selectedAppRemoveButton.Add_MouseEnter({ $this.Foreground = "Red" })
|
||||||
|
$selectedAppRemoveButton.Add_MouseLeave({ $this.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor") })
|
||||||
|
$selectedAppRemoveButton.Add_Click({
|
||||||
|
$sync.($this.Tag).isChecked = $false # On click of the remove button, we only have to uncheck the corresponding checkbox. This will kick of all neccessary changes to update the UI
|
||||||
|
})
|
||||||
|
[System.Windows.Controls.Grid]::SetColumn($selectedAppRemoveButton, 1)
|
||||||
|
$selectedAppGrid.Children.Add($selectedAppRemoveButton)
|
||||||
|
# Add new Element to Popup
|
||||||
|
$sync.selectedAppsstackPanel.Children.Add($selectedAppGrid)
|
||||||
|
}
|
35
functions/private/Find-AppsByNameOrDescription.ps1
Normal file
35
functions/private/Find-AppsByNameOrDescription.ps1
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
function Find-AppsByNameOrDescription {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Searches through the Apps on the Install Tab and hides all entries that do not match the string
|
||||||
|
|
||||||
|
.PARAMETER SearchString
|
||||||
|
The string to be searched for
|
||||||
|
#>
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[string]$SearchString = ""
|
||||||
|
)
|
||||||
|
# Reset the visibility if the search string is empty or the search is cleared
|
||||||
|
if ([string]::IsNullOrWhiteSpace($SearchString)) {
|
||||||
|
Set-CategoryVisibility -Category "*"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$sync.ItemsControl.Items | ForEach-Object {
|
||||||
|
# Hide all CategoryWrapPanel and ToggleButton
|
||||||
|
$_.Visibility = [Windows.Visibility]::Collapsed
|
||||||
|
if ($_.Tag -like "CategoryWrapPanel_*") {
|
||||||
|
# Search for Apps that match the search string
|
||||||
|
$_.Children | Foreach-Object {
|
||||||
|
if ($sync.configs.applicationsHashtable.$($_.Tag).Content -like "*$SearchString*") {
|
||||||
|
# Show the App and the parent CategoryWrapPanel if the string is found
|
||||||
|
$_.Visibility = [Windows.Visibility]::Visible
|
||||||
|
$_.parent.Visibility = [Windows.Visibility]::Visible
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$_.Visibility = [Windows.Visibility]::Collapsed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
197
functions/private/Initalize-InstallAppEntry.ps1
Normal file
197
functions/private/Initalize-InstallAppEntry.ps1
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
function Initialize-InstallAppEntry {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Creates the app entry to be placed on the isntall tab for a given app
|
||||||
|
Used to as part of the Install Tab UI generation
|
||||||
|
.PARAMETER TargetElement
|
||||||
|
The Element into which the Apps should be placed
|
||||||
|
.PARAMETER AppKey
|
||||||
|
The Key of the app inside the $sync.configs.applicationsHashtable
|
||||||
|
#>
|
||||||
|
param(
|
||||||
|
[Windows.Controls.WrapPanel]$TargetElement,
|
||||||
|
$AppKey
|
||||||
|
)
|
||||||
|
$App = $sync.configs.applicationsHashtable.$AppKey
|
||||||
|
# Create the outer Border for the application type
|
||||||
|
$border = New-Object Windows.Controls.Border
|
||||||
|
$border.BorderBrush = [Windows.Media.Brushes]::Gray
|
||||||
|
$border.SetResourceReference([Windows.Controls.Control]::BorderThicknessProperty, "AppTileBorderThickness")
|
||||||
|
$border.CornerRadius = 5
|
||||||
|
$border.SetResourceReference([Windows.Controls.Control]::PaddingProperty, "AppTileMargins")
|
||||||
|
$border.SetResourceReference([Windows.Controls.Control]::WidthProperty, "AppTileWidth")
|
||||||
|
$border.VerticalAlignment = "Top"
|
||||||
|
$border.SetResourceReference([Windows.Controls.Control]::MarginProperty, "AppTileMargins")
|
||||||
|
$border.Cursor = [System.Windows.Input.Cursors]::Hand
|
||||||
|
$border.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor")
|
||||||
|
$border.Tag = $Appkey
|
||||||
|
$border.ToolTip = $App.description
|
||||||
|
$border.Add_MouseUp({
|
||||||
|
$childCheckbox = ($this.Child.Children | Where-Object {$_.Template.TargetType -eq [System.Windows.Controls.Checkbox]})[0]
|
||||||
|
$childCheckBox.isChecked = -not $childCheckbox.IsChecked
|
||||||
|
})
|
||||||
|
$border.Add_MouseEnter({
|
||||||
|
if (($sync.$($this.Tag).IsChecked) -eq $false) {
|
||||||
|
$this.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallHighlightedColor")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$border.Add_MouseLeave({
|
||||||
|
if (($sync.$($this.Tag).IsChecked) -eq $false) {
|
||||||
|
$this.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
# Create a DockPanel inside the Border
|
||||||
|
$dockPanel = New-Object Windows.Controls.DockPanel
|
||||||
|
$dockPanel.LastChildFill = $true
|
||||||
|
$border.Child = $dockPanel
|
||||||
|
|
||||||
|
# Create the CheckBox, vertically centered
|
||||||
|
$checkBox = New-Object Windows.Controls.CheckBox
|
||||||
|
$checkBox.Name = $AppKey
|
||||||
|
$checkBox.Background = "Transparent"
|
||||||
|
$checkBox.HorizontalAlignment = "Left"
|
||||||
|
$checkBox.VerticalAlignment = "Center"
|
||||||
|
$checkBox.SetResourceReference([Windows.Controls.Control]::MarginProperty, "AppTileMargins")
|
||||||
|
$checkBox.SetResourceReference([Windows.Controls.Control]::StyleProperty, "CollapsedCheckBoxStyle")
|
||||||
|
$checkbox.Add_Checked({
|
||||||
|
Invoke-WPFSelectedAppsUpdate -type "Add" -checkbox $this
|
||||||
|
$borderElement = $this.Parent.Parent
|
||||||
|
$borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallSelectedColor")
|
||||||
|
})
|
||||||
|
|
||||||
|
$checkbox.Add_Unchecked({
|
||||||
|
Invoke-WPFSelectedAppsUpdate -type "Remove" -checkbox $this
|
||||||
|
$borderElement = $this.Parent.Parent
|
||||||
|
$borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor")
|
||||||
|
})
|
||||||
|
$sync.$($checkBox.Name) = $checkBox
|
||||||
|
# Create a StackPanel for the image and name
|
||||||
|
$imageAndNamePanel = New-Object Windows.Controls.StackPanel
|
||||||
|
$imageAndNamePanel.Orientation = "Horizontal"
|
||||||
|
$imageAndNamePanel.VerticalAlignment = "Center"
|
||||||
|
|
||||||
|
# Create the Image and set a placeholder
|
||||||
|
$image = New-Object Windows.Controls.Image
|
||||||
|
# $image.Name = "wpfapplogo" + $App.Name
|
||||||
|
$image.Width = 40
|
||||||
|
$image.Height = 40
|
||||||
|
$image.Margin = New-Object Windows.Thickness(0, 0, 10, 0)
|
||||||
|
$image.Source = $noimage # Ensure $noimage is defined in your script
|
||||||
|
|
||||||
|
# Clip the image corners
|
||||||
|
$image.Clip = New-Object Windows.Media.RectangleGeometry
|
||||||
|
$image.Clip.Rect = New-Object Windows.Rect(0, 0, $image.Width, $image.Height)
|
||||||
|
$image.Clip.RadiusX = 5
|
||||||
|
$image.Clip.RadiusY = 5
|
||||||
|
$image.SetResourceReference([Windows.Controls.Control]::VisibilityProperty, "AppTileCompactVisibility")
|
||||||
|
|
||||||
|
$imageAndNamePanel.Children.Add($image) | Out-Null
|
||||||
|
|
||||||
|
# Create the TextBlock for the application name
|
||||||
|
$appName = New-Object Windows.Controls.TextBlock
|
||||||
|
$appName.Text = $App.Content
|
||||||
|
$appName.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "AppTileFontSize")
|
||||||
|
$appName.FontWeight = [Windows.FontWeights]::Bold
|
||||||
|
$appName.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
|
||||||
|
$appName.VerticalAlignment = "Center"
|
||||||
|
$appName.SetResourceReference([Windows.Controls.Control]::MarginProperty, "AppTileMargins")
|
||||||
|
$appName.Background = "Transparent"
|
||||||
|
$imageAndNamePanel.Children.Add($appName) | Out-Null
|
||||||
|
|
||||||
|
# Add the image and name panel to the Checkbox
|
||||||
|
$checkBox.Content = $imageAndNamePanel
|
||||||
|
|
||||||
|
# Add the checkbox to the DockPanel
|
||||||
|
[Windows.Controls.DockPanel]::SetDock($checkBox, [Windows.Controls.Dock]::Left)
|
||||||
|
$dockPanel.Children.Add($checkBox) | Out-Null
|
||||||
|
|
||||||
|
# Create the StackPanel for the buttons and dock it to the right
|
||||||
|
$buttonPanel = New-Object Windows.Controls.StackPanel
|
||||||
|
$buttonPanel.Orientation = "Horizontal"
|
||||||
|
$buttonPanel.HorizontalAlignment = "Right"
|
||||||
|
$buttonPanel.VerticalAlignment = "Center"
|
||||||
|
$buttonPanel.SetResourceReference([Windows.Controls.Control]::MarginProperty, "AppTileMargins")
|
||||||
|
$buttonPanel.SetResourceReference([Windows.Controls.Control]::VisibilityProperty, "AppTileCompactVisibility")
|
||||||
|
[Windows.Controls.DockPanel]::SetDock($buttonPanel, [Windows.Controls.Dock]::Right)
|
||||||
|
|
||||||
|
# Create the "Install" button
|
||||||
|
$installButton = New-Object Windows.Controls.Button
|
||||||
|
$installButton.Width = 45
|
||||||
|
$installButton.Height = 35
|
||||||
|
$installButton.Margin = New-Object Windows.Thickness(0, 0, 10, 0)
|
||||||
|
|
||||||
|
$installIcon = New-Object Windows.Controls.TextBlock
|
||||||
|
$installIcon.Text = [char]0xE118 # Install Icon
|
||||||
|
$installIcon.FontFamily = "Segoe MDL2 Assets"
|
||||||
|
$installIcon.FontSize = 20
|
||||||
|
$installIcon.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
|
||||||
|
$installIcon.Background = "Transparent"
|
||||||
|
$installIcon.HorizontalAlignment = "Center"
|
||||||
|
$installIcon.VerticalAlignment = "Center"
|
||||||
|
|
||||||
|
$installButton.Content = $installIcon
|
||||||
|
$installButton.ToolTip = "Install or Upgrade the application"
|
||||||
|
$buttonPanel.Children.Add($installButton) | Out-Null
|
||||||
|
|
||||||
|
# Add Click event for the "Install" button
|
||||||
|
$installButton.Add_Click({
|
||||||
|
$appKey = $this.Parent.Parent.Parent.Tag
|
||||||
|
$appObject = $sync.configs.applicationsHashtable.$appKey
|
||||||
|
Invoke-WPFInstall -PackagesToInstall $appObject
|
||||||
|
})
|
||||||
|
|
||||||
|
# Create the "Uninstall" button
|
||||||
|
$uninstallButton = New-Object Windows.Controls.Button
|
||||||
|
$uninstallButton.Width = 45
|
||||||
|
$uninstallButton.Height = 35
|
||||||
|
|
||||||
|
$uninstallIcon = New-Object Windows.Controls.TextBlock
|
||||||
|
$uninstallIcon.Text = [char]0xE74D # Uninstall Icon
|
||||||
|
$uninstallIcon.FontFamily = "Segoe MDL2 Assets"
|
||||||
|
$uninstallIcon.FontSize = 20
|
||||||
|
$uninstallIcon.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
|
||||||
|
$uninstallIcon.Background = "Transparent"
|
||||||
|
$uninstallIcon.HorizontalAlignment = "Center"
|
||||||
|
$uninstallIcon.VerticalAlignment = "Center"
|
||||||
|
|
||||||
|
$uninstallButton.Content = $uninstallIcon
|
||||||
|
$buttonPanel.Children.Add($uninstallButton) | Out-Null
|
||||||
|
|
||||||
|
$uninstallButton.ToolTip = "Uninstall the application"
|
||||||
|
$uninstallButton.Add_Click({
|
||||||
|
$appKey = $this.Parent.Parent.Parent.Tag
|
||||||
|
$appObject = $sync.configs.applicationsHashtable.$appKey
|
||||||
|
Invoke-WPFUnInstall -PackagesToUninstall $appObject
|
||||||
|
})
|
||||||
|
|
||||||
|
# Create the "Info" button
|
||||||
|
$infoButton = New-Object Windows.Controls.Button
|
||||||
|
$infoButton.Width = 45
|
||||||
|
$infoButton.Height = 35
|
||||||
|
$infoButton.Margin = New-Object Windows.Thickness(10, 0, 0, 0)
|
||||||
|
|
||||||
|
$infoIcon = New-Object Windows.Controls.TextBlock
|
||||||
|
$infoIcon.Text = [char]0xE946 # Info Icon
|
||||||
|
$infoIcon.FontFamily = "Segoe MDL2 Assets"
|
||||||
|
$infoIcon.FontSize = 20
|
||||||
|
$infoIcon.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
|
||||||
|
$infoIcon.Background = "Transparent"
|
||||||
|
$infoIcon.HorizontalAlignment = "Center"
|
||||||
|
$infoIcon.VerticalAlignment = "Center"
|
||||||
|
|
||||||
|
$infoButton.Content = $infoIcon
|
||||||
|
$infoButton.ToolTip = "Open the application's website in your default browser"
|
||||||
|
$buttonPanel.Children.Add($infoButton) | Out-Null
|
||||||
|
|
||||||
|
$infoButton.Add_Click({
|
||||||
|
$appKey = $this.Parent.Parent.Parent.Tag
|
||||||
|
$appObject = $sync.configs.applicationsHashtable.$appKey
|
||||||
|
Start-Process $appObject.link
|
||||||
|
})
|
||||||
|
|
||||||
|
# Add the button panel to the DockPanel
|
||||||
|
$dockPanel.Children.Add($buttonPanel) | Out-Null
|
||||||
|
|
||||||
|
# Add the border to the corresponding Category
|
||||||
|
$TargetElement.Children.Add($border) | Out-Null
|
||||||
|
}
|
36
functions/private/Initialize-InstallAppArea.ps1
Normal file
36
functions/private/Initialize-InstallAppArea.ps1
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
function Initialize-InstallAppArea {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Creates a [Windows.Controls.ScrollViewer] containing a [Windows.Controls.ItemsControl] which is setup to use Virtualization to only load the visible elements for performance reasons.
|
||||||
|
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
|
||||||
|
|
||||||
|
.PARAMETER TargetElement
|
||||||
|
The element to which the AppArea shoud be added
|
||||||
|
|
||||||
|
#>
|
||||||
|
param($TargetElement)
|
||||||
|
$scrollViewer = New-Object Windows.Controls.ScrollViewer
|
||||||
|
$scrollViewer.VerticalScrollBarVisibility = 'Auto'
|
||||||
|
$scrollViewer.HorizontalAlignment = 'Stretch'
|
||||||
|
$scrollViewer.VerticalAlignment = 'Stretch'
|
||||||
|
$scrollViewer.CanContentScroll = $true
|
||||||
|
|
||||||
|
$itemsControl = New-Object Windows.Controls.ItemsControl
|
||||||
|
$itemsControl.HorizontalAlignment = 'Stretch'
|
||||||
|
$itemsControl.VerticalAlignment = 'Stretch'
|
||||||
|
|
||||||
|
$itemsPanelTemplate = New-Object Windows.Controls.ItemsPanelTemplate
|
||||||
|
$factory = New-Object Windows.FrameworkElementFactory ([Windows.Controls.VirtualizingStackPanel])
|
||||||
|
$itemsPanelTemplate.VisualTree = $factory
|
||||||
|
$itemsControl.ItemsPanel = $itemsPanelTemplate
|
||||||
|
|
||||||
|
$itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::IsVirtualizingProperty, $true)
|
||||||
|
$itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::VirtualizationModeProperty, [Windows.Controls.VirtualizationMode]::Recycling)
|
||||||
|
|
||||||
|
$scrollViewer.Content = $itemsControl
|
||||||
|
|
||||||
|
[Windows.Controls.DockPanel]::SetDock($scrollViewer, [Windows.Controls.Dock]::Bottom)
|
||||||
|
$null = $TargetElement.Children.Add($scrollViewer)
|
||||||
|
return $itemsControl
|
||||||
|
}
|
28
functions/private/Initialize-InstallAppsMainElement.ps1
Normal file
28
functions/private/Initialize-InstallAppsMainElement.ps1
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
function Initialize-InstallAppsMainElement {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Clears the given WPF Grid and creates a [Windows.Controls.Border] containing a [Windows.Controls.StackPanel]
|
||||||
|
Used to as part of the Install Tab UI generation
|
||||||
|
.PARAMETER TargetGridName
|
||||||
|
The WPF Grid name
|
||||||
|
.OUTPUTS
|
||||||
|
Returns the created [Windows.Controls.StackPanel] element
|
||||||
|
#>
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory)]
|
||||||
|
[string]$TargetGridName
|
||||||
|
)
|
||||||
|
$targetGrid = $sync.Form.FindName($TargetGridName)
|
||||||
|
$null = $targetGrid.Children.Clear()
|
||||||
|
|
||||||
|
$Border = New-Object Windows.Controls.Border
|
||||||
|
$Border.VerticalAlignment = "Stretch"
|
||||||
|
$Border.SetResourceReference([Windows.Controls.Control]::StyleProperty, "BorderStyle")
|
||||||
|
|
||||||
|
$dockPanel = New-Object Windows.Controls.DockPanel
|
||||||
|
$Border.Child = $dockPanel
|
||||||
|
|
||||||
|
$null = $targetGrid.Children.Add($Border)
|
||||||
|
|
||||||
|
return $dockPanel
|
||||||
|
}
|
72
functions/private/Initialize-InstallCategoryAppList.ps1
Normal file
72
functions/private/Initialize-InstallCategoryAppList.ps1
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
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
|
||||||
|
)
|
||||||
|
function Add-Category {
|
||||||
|
param(
|
||||||
|
[string]$Category,
|
||||||
|
[Windows.Controls.ItemsControl]$TargetElement
|
||||||
|
)
|
||||||
|
|
||||||
|
$toggleButton = New-Object Windows.Controls.Primitives.ToggleButton
|
||||||
|
$toggleButton.Content = "$Category"
|
||||||
|
$toggleButton.Tag = "CategoryToggleButton"
|
||||||
|
$toggleButton.Cursor = [System.Windows.Input.Cursors]::Hand
|
||||||
|
$toggleButton.SetResourceReference([Windows.Controls.Control]::StyleProperty, "CategoryToggleButtonStyle")
|
||||||
|
$sync.Buttons.Add($toggleButton)
|
||||||
|
$toggleButton.Add_Checked({
|
||||||
|
# Clear the search bar when a category is clicked
|
||||||
|
$sync.SearchBar.Text = ""
|
||||||
|
Set-CategoryVisibility -Category $this.Content -overrideState Expand
|
||||||
|
})
|
||||||
|
$toggleButton.Add_Unchecked({
|
||||||
|
Set-CategoryVisibility -Category $this.Content -overrideState Collapse
|
||||||
|
})
|
||||||
|
$null = $TargetElement.Items.Add($toggleButton)
|
||||||
|
}
|
||||||
|
|
||||||
|
$loadingLabel = New-Object Windows.Controls.Label
|
||||||
|
$loadingLabel.Content = "Loading, please wait..."
|
||||||
|
$loadingLabel.HorizontalAlignment = "Center"
|
||||||
|
$loadingLabel.VerticalAlignment = "Center"
|
||||||
|
$loadingLabel.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSizeHeading")
|
||||||
|
$loadingLabel.FontWeight = [Windows.FontWeights]::Bold
|
||||||
|
$loadingLabel.Foreground = [Windows.Media.Brushes]::Gray
|
||||||
|
$sync.LoadingLabel = $loadingLabel
|
||||||
|
|
||||||
|
$TargetElement.Items.Clear()
|
||||||
|
$null = $TargetElement.Items.Add($sync.LoadingLabel)
|
||||||
|
# Use the Dispatcher to make sure the Loading message is shown before the logic loading the apps starts, and only is removed when the loading is complete and the apps are added to the UI
|
||||||
|
$TargetElement.Dispatcher.Invoke([System.Windows.Threading.DispatcherPriority]::Background, [action]{
|
||||||
|
|
||||||
|
$TargetElement.Items.Clear() # Remove the loading message
|
||||||
|
$categories = $Apps.Values | Select-Object -ExpandProperty category -Unique | Sort-Object
|
||||||
|
foreach ($category in $categories) {
|
||||||
|
Add-Category -Category $category -TargetElement $TargetElement
|
||||||
|
$wrapPanel = New-Object Windows.Controls.WrapPanel
|
||||||
|
$wrapPanel.Orientation = "Horizontal"
|
||||||
|
$wrapPanel.HorizontalAlignment = "Stretch"
|
||||||
|
$wrapPanel.VerticalAlignment = "Center"
|
||||||
|
$wrapPanel.Margin = New-Object Windows.Thickness(0, 0, 0, 20)
|
||||||
|
$wrapPanel.Visibility = [Windows.Visibility]::Collapsed
|
||||||
|
$wrapPanel.Tag = "CategoryWrapPanel_$category"
|
||||||
|
$null = $TargetElement.Items.Add($wrapPanel)
|
||||||
|
$Apps.Keys | Where-Object { $Apps.$_.Category -eq $category } | Sort-Object | ForEach-Object {
|
||||||
|
Initialize-InstallAppEntry -TargetElement $wrapPanel -AppKey $_
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
89
functions/private/Initialize-InstallHeader.ps1
Normal file
89
functions/private/Initialize-InstallHeader.ps1
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
function Initialize-InstallHeader {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Creates the Multi Selection Header Elements on the Install Tab
|
||||||
|
Used to as part of the Install Tab UI generation
|
||||||
|
.PARAMETER TargetElement
|
||||||
|
The Parent Element into which the Header should be placed
|
||||||
|
#>
|
||||||
|
param($TargetElement)
|
||||||
|
function New-WPFButton {
|
||||||
|
param (
|
||||||
|
[string]$Name,
|
||||||
|
[string]$Content
|
||||||
|
)
|
||||||
|
$button = New-Object Windows.Controls.Button
|
||||||
|
$button.Name = $Name
|
||||||
|
$button.Content = $Content
|
||||||
|
$button.Margin = New-Object Windows.Thickness(2)
|
||||||
|
$button.HorizontalAlignment = "Stretch"
|
||||||
|
return $button
|
||||||
|
}
|
||||||
|
|
||||||
|
$wrapPanelTop = New-Object Windows.Controls.WrapPanel
|
||||||
|
$wrapPanelTop.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "MainBackgroundColor")
|
||||||
|
$wrapPanelTop.HorizontalAlignment = "Left"
|
||||||
|
$wrapPanelTop.VerticalAlignment = "Top"
|
||||||
|
$wrapPanelTop.Orientation = "Horizontal"
|
||||||
|
$wrapPanelTop.SetResourceReference([Windows.Controls.Control]::MarginProperty, "TabContentMargin")
|
||||||
|
$buttonConfigs = @(
|
||||||
|
@{Name="WPFInstall"; Content="Install/Upgrade Selected"},
|
||||||
|
@{Name="WPFInstallUpgrade"; Content="Upgrade All"},
|
||||||
|
@{Name="WPFUninstall"; Content="Uninstall Selected"}
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach ($config in $buttonConfigs) {
|
||||||
|
$button = New-WPFButton -Name $config.Name -Content $config.Content
|
||||||
|
$null = $wrapPanelTop.Children.Add($button)
|
||||||
|
$sync[$config.Name] = $button
|
||||||
|
}
|
||||||
|
|
||||||
|
$selectedAppsButton = New-Object Windows.Controls.Button
|
||||||
|
$selectedAppsButton.Name = "WPFselectedAppsButton"
|
||||||
|
$selectedAppsButton.Content = "Selected Apps: 0"
|
||||||
|
$selectedAppsButton.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSizeHeading")
|
||||||
|
$selectedAppsButton.SetResourceReference([Windows.Controls.Control]::MarginProperty, "TabContentMargin")
|
||||||
|
$selectedAppsButton.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
|
||||||
|
$selectedAppsButton.HorizontalAlignment = "Center"
|
||||||
|
$selectedAppsButton.VerticalAlignment = "Center"
|
||||||
|
|
||||||
|
$selectedAppsPopup = New-Object Windows.Controls.Primitives.Popup
|
||||||
|
$selectedAppsPopup.IsOpen = $false
|
||||||
|
$selectedAppsPopup.PlacementTarget = $selectedAppsButton
|
||||||
|
$selectedAppsPopup.Placement = [System.Windows.Controls.Primitives.PlacementMode]::Bottom
|
||||||
|
$selectedAppsPopup.AllowsTransparency = $true
|
||||||
|
|
||||||
|
$selectedAppsBorder = New-Object Windows.Controls.Border
|
||||||
|
$selectedAppsBorder.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "MainBackgroundColor")
|
||||||
|
$selectedAppsBorder.SetResourceReference([Windows.Controls.Control]::BorderBrushProperty, "MainForegroundColor")
|
||||||
|
$selectedAppsBorder.SetResourceReference([Windows.Controls.Control]::BorderThicknessProperty, "ButtonBorderThickness")
|
||||||
|
$selectedAppsBorder.Width = 200
|
||||||
|
$selectedAppsBorder.Padding = 5
|
||||||
|
$selectedAppsPopup.Child = $selectedAppsBorder
|
||||||
|
$sync.selectedAppsPopup = $selectedAppsPopup
|
||||||
|
|
||||||
|
$sync.selectedAppsstackPanel = New-Object Windows.Controls.StackPanel
|
||||||
|
$selectedAppsBorder.Child = $sync.selectedAppsstackPanel
|
||||||
|
|
||||||
|
# Toggle selectedAppsPopup open/close with button
|
||||||
|
$selectedAppsButton.Add_Click({
|
||||||
|
$sync.selectedAppsPopup.IsOpen = -not $sync.selectedAppsPopup.IsOpen
|
||||||
|
})
|
||||||
|
# Close selectedAppsPopup when mouse leaves both button and selectedAppsPopup
|
||||||
|
$selectedAppsButton.Add_MouseLeave({
|
||||||
|
if (-not $sync.selectedAppsPopup.IsMouseOver) {
|
||||||
|
$sync.selectedAppsPopup.IsOpen = $false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$selectedAppsPopup.Add_MouseLeave({
|
||||||
|
if (-not $selectedAppsButton.IsMouseOver) {
|
||||||
|
$sync.selectedAppsPopup.IsOpen = $false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$null = $wrapPanelTop.Children.Add($selectedAppsButton)
|
||||||
|
$sync.$($selectedAppsButton.Name) = $selectedAppsButton
|
||||||
|
|
||||||
|
[Windows.Controls.DockPanel]::SetDock($wrapPanelTop, [Windows.Controls.Dock]::Top)
|
||||||
|
$null = $TargetElement.Children.Add($wrapPanelTop)
|
||||||
|
}
|
@ -110,6 +110,7 @@ function Remove-Features() {
|
|||||||
$_.FeatureName -NotLike "*NFS*" -AND
|
$_.FeatureName -NotLike "*NFS*" -AND
|
||||||
$_.FeatureName -NotLike "*SearchEngine*" -AND
|
$_.FeatureName -NotLike "*SearchEngine*" -AND
|
||||||
$_.FeatureName -NotLike "*RemoteDesktop*" -AND
|
$_.FeatureName -NotLike "*RemoteDesktop*" -AND
|
||||||
|
$_.FeatureName -NotLike "*Recall*" -AND
|
||||||
$_.State -ne "Disabled"
|
$_.State -ne "Disabled"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,31 +277,6 @@ function Remove-ProvisionedPackages() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Get-LocalizedUsers
|
|
||||||
{
|
|
||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
Gets a localized user group representation for ICACLS commands (Port from DISMTools PE Helper)
|
|
||||||
.PARAMETER admins
|
|
||||||
Determines whether to get a localized user group representation for the Administrators user group
|
|
||||||
.OUTPUTS
|
|
||||||
A string containing the localized user group
|
|
||||||
.EXAMPLE
|
|
||||||
Get-LocalizedUsers -admins $true
|
|
||||||
#>
|
|
||||||
param (
|
|
||||||
[Parameter(Mandatory = $true, Position = 0)] [bool]$admins
|
|
||||||
)
|
|
||||||
if ($admins)
|
|
||||||
{
|
|
||||||
return (Get-LocalGroup | Where-Object { $_.SID.Value -like "S-1-5-32-544" }).Name
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (Get-LocalGroup | Where-Object { $_.SID.Value -like "S-1-5-32-545" }).Name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Copy-ToUSB([string]$fileToCopy) {
|
function Copy-ToUSB([string]$fileToCopy) {
|
||||||
foreach ($volume in Get-Volume) {
|
foreach ($volume in Get-Volume) {
|
||||||
if ($volume -and $volume.FileSystemLabel -ieq "ventoy") {
|
if ($volume -and $volume.FileSystemLabel -ieq "ventoy") {
|
||||||
|
44
functions/private/Set-CategoryVisibility.ps1
Normal file
44
functions/private/Set-CategoryVisibility.ps1
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
function Set-CategoryVisibility {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Used to expand or collapse categories and corresponding apps on the install tab
|
||||||
|
|
||||||
|
.PARAMETER Category
|
||||||
|
Can eigther be a specific category name like "Browsers" OR "*" to affect all categories at once
|
||||||
|
|
||||||
|
.PARAMETER overrideState
|
||||||
|
"Expand" => expands the corresponding elements
|
||||||
|
"Collapse" => collapses the corresponding elements
|
||||||
|
N/A => if compactView is active expand, otherwise collapse elements
|
||||||
|
#>
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$Category,
|
||||||
|
[ValidateSet("Expand", "Collapse")]
|
||||||
|
[string]$overrideState
|
||||||
|
)
|
||||||
|
|
||||||
|
switch ($overrideState) {
|
||||||
|
"Expand" {$state = $true}
|
||||||
|
"Collapse" {$state = $false}
|
||||||
|
default {$state = $sync.CompactView}
|
||||||
|
}
|
||||||
|
|
||||||
|
# If all the Categories are affected, update the Checked state of the ToggleButtons.
|
||||||
|
# Otherwise, the state is not synced when toggling between the display modes
|
||||||
|
if ($category -eq "*") {
|
||||||
|
$items = $sync.ItemsControl.Items | Where-Object {($_.Tag -like "CategoryWrapPanel_*")}
|
||||||
|
$sync.ItemsControl.Items | Where-Object {($_.Tag -eq "CategoryToggleButton")} | Foreach-Object { $_.Visibility = [Windows.Visibility]::Visible; $_.IsChecked = $state }
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$items = $sync.ItemsControl.Items | Where-Object {($_.Tag -eq "CategoryWrapPanel_$Category")}
|
||||||
|
}
|
||||||
|
|
||||||
|
$elementVisibility = if ($state -eq $true) {[Windows.Visibility]::Visible} else {[Windows.Visibility]::Collapsed}
|
||||||
|
$items | ForEach-Object {
|
||||||
|
$_.Visibility = $elementVisibility
|
||||||
|
}
|
||||||
|
$items.Children | ForEach-Object {
|
||||||
|
$_.Visibility = $elementVisibility
|
||||||
|
}
|
||||||
|
}
|
54
functions/private/Show-OnlyCheckedApps.ps1
Normal file
54
functions/private/Show-OnlyCheckedApps.ps1
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
function Show-OnlyCheckedApps {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Toggle between showing only the actively selected apps on the Install Tab and hiding everything else and displaying every app.
|
||||||
|
If no apps are selected, dont do anything
|
||||||
|
.PARAMETER appKeys
|
||||||
|
Expects a List of appKeys that are selected at the moment
|
||||||
|
If not provided, or empty, the function exits without any visual change to the ui
|
||||||
|
.EXAMPLE
|
||||||
|
Show-OnlyCheckedApps -appKeys $sync.SelectedApps
|
||||||
|
Show-OnlyCheckedApps -appKeys ("WPFInstallChrome", "WPFInstall7zip")
|
||||||
|
#>
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[String[]]$appKeys
|
||||||
|
)
|
||||||
|
# If no apps are selected, do not allow switching to show only selected
|
||||||
|
if (($false -eq $sync.ShowOnlySelected) -and ($appKeys.Length -eq 0)) {
|
||||||
|
Write-Host "No apps selected"
|
||||||
|
$sync.wpfselectedfilter.IsChecked = $false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$sync.ShowOnlySelected = -not $sync.ShowOnlySelected
|
||||||
|
if ($sync.ShowOnlySelected) {
|
||||||
|
$sync.Buttons | Where-Object {$_.Name -like "ShowSelectedAppsButton"} | ForEach-Object {
|
||||||
|
$_.Content = "Show All"
|
||||||
|
}
|
||||||
|
|
||||||
|
$sync.ItemsControl.Items | Foreach-Object {
|
||||||
|
# Search for App Container and set them to visible
|
||||||
|
if ($_.Tag -like "CategoryWrapPanel_*") {
|
||||||
|
$_.Visibility = [Windows.Visibility]::Visible
|
||||||
|
# Iterate through all the apps in the container and set them to visible if they are in the appKeys array
|
||||||
|
$_.Children | ForEach-Object {
|
||||||
|
if ($appKeys -contains $_.Tag) {
|
||||||
|
$_.Visibility = [Windows.Visibility]::Visible
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$_.Visibility = [Windows.Visibility]::Collapsed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Set all other items to collapsed
|
||||||
|
$_.Visibility = [Windows.Visibility]::Collapsed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$sync.Buttons | Where-Object {$_.Name -like "ShowSelectedAppsButton"} | ForEach-Object {
|
||||||
|
$_.Content = "Show Selected"
|
||||||
|
}
|
||||||
|
Set-CategoryVisibility -Category "*"
|
||||||
|
}
|
||||||
|
}
|
@ -26,7 +26,8 @@ function Invoke-WPFButton {
|
|||||||
"WPFStandard" {Invoke-WPFPresets "Standard" -checkboxfilterpattern "WPFTweak*"}
|
"WPFStandard" {Invoke-WPFPresets "Standard" -checkboxfilterpattern "WPFTweak*"}
|
||||||
"WPFMinimal" {Invoke-WPFPresets "Minimal" -checkboxfilterpattern "WPFTweak*"}
|
"WPFMinimal" {Invoke-WPFPresets "Minimal" -checkboxfilterpattern "WPFTweak*"}
|
||||||
"WPFClearTweaksSelection" {Invoke-WPFPresets -imported $true -checkboxfilterpattern "WPFTweak*"}
|
"WPFClearTweaksSelection" {Invoke-WPFPresets -imported $true -checkboxfilterpattern "WPFTweak*"}
|
||||||
"WPFClearInstallSelection" {Invoke-WPFPresets -imported $true -checkboxfilterpattern "WPFInstall*"}
|
"WPFClearInstallSelection" {Invoke-WPFPresets -imported $true -checkboxfilterpattern "WPFInstall*"; Show-OnlyCheckedApps; $sync.wpfselectedfilter.IsChecked = $false}
|
||||||
|
"WPFSelectedFilter" {Show-OnlyCheckedApps -appKeys $sync.SelectedApps}
|
||||||
"WPFtweaksbutton" {Invoke-WPFtweaksbutton}
|
"WPFtweaksbutton" {Invoke-WPFtweaksbutton}
|
||||||
"WPFOOSUbutton" {Invoke-WPFOOSU}
|
"WPFOOSUbutton" {Invoke-WPFOOSU}
|
||||||
"WPFAddUltPerf" {Invoke-WPFUltimatePerformance -State "Enable"}
|
"WPFAddUltPerf" {Invoke-WPFUltimatePerformance -State "Enable"}
|
||||||
|
@ -9,42 +9,48 @@ function Invoke-WPFGetInstalled {
|
|||||||
|
|
||||||
#>
|
#>
|
||||||
param($checkbox)
|
param($checkbox)
|
||||||
|
if ($sync.ProcessRunning) {
|
||||||
if($sync.ProcessRunning) {
|
|
||||||
$msg = "[Invoke-WPFGetInstalled] Install process is currently running."
|
$msg = "[Invoke-WPFGetInstalled] Install process is currently running."
|
||||||
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if(($sync.WPFpreferChocolatey.IsChecked -eq $false) -and ((Test-WinUtilPackageManager -winget) -eq "not-installed") -and $checkbox -eq "winget") {
|
if (($sync.ChocoRadioButton.IsChecked -eq $false) -and ((Test-WinUtilPackageManager -winget) -eq "not-installed") -and $checkbox -eq "winget") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
$preferChoco = $sync.WPFpreferChocolatey.IsChecked
|
$preferChoco = $sync.ChocoRadioButton.IsChecked
|
||||||
Invoke-WPFRunspace -ArgumentList $checkbox, $preferChoco -DebugPreference $DebugPreference -ScriptBlock {
|
$sync.ItemsControl.Dispatcher.Invoke([action] {
|
||||||
param($checkbox, $preferChoco, $DebugPreference)
|
$sync.ItemsControl.Items | ForEach-Object { $_.Visibility = [Windows.Visibility]::Collapsed }
|
||||||
|
$null = $sync.itemsControl.Items.Add($sync.LoadingLabel)
|
||||||
|
})
|
||||||
|
Invoke-WPFRunspace -ParameterList @(("preferChoco", $preferChoco),("checkbox", $checkbox),("ShowOnlyCheckedApps", ${function:Show-OnlyCheckedApps})) -DebugPreference $DebugPreference -ScriptBlock {
|
||||||
|
param (
|
||||||
|
[string]$checkbox,
|
||||||
|
[boolean]$preferChoco,
|
||||||
|
[scriptblock]$ShowOnlyCheckedApps
|
||||||
|
)
|
||||||
$sync.ProcessRunning = $true
|
$sync.ProcessRunning = $true
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" })
|
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state "Indeterminate" })
|
||||||
|
|
||||||
if($checkbox -eq "winget") {
|
if ($checkbox -eq "winget") {
|
||||||
Write-Host "Getting Installed Programs..."
|
Write-Host "Getting Installed Programs..."
|
||||||
|
if ($preferChoco) { $Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox "choco" }
|
||||||
|
else { $Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox }
|
||||||
}
|
}
|
||||||
if($checkbox -eq "tweaks") {
|
elseif ($checkbox -eq "tweaks") {
|
||||||
Write-Host "Getting Installed Tweaks..."
|
Write-Host "Getting Installed Tweaks..."
|
||||||
}
|
|
||||||
if ($preferChoco -and $checkbox -eq "winget") {
|
|
||||||
$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox "choco"
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox
|
$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox
|
||||||
}
|
}
|
||||||
|
|
||||||
$sync.form.Dispatcher.invoke({
|
$sync.form.Dispatcher.invoke({
|
||||||
foreach($checkbox in $Checkboxes) {
|
foreach ($checkbox in $Checkboxes) {
|
||||||
$sync.$checkbox.ischecked = $True
|
$sync.$checkbox.ischecked = $True
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
$sync.ItemsControl.Dispatcher.Invoke([action] {
|
||||||
|
$ShowOnlyCheckedApps.Invoke($sync.SelectedApps)
|
||||||
|
$sync.ItemsControl.Items.Remove($sync.LoadingLabel)
|
||||||
|
})
|
||||||
Write-Host "Done..."
|
Write-Host "Done..."
|
||||||
$sync.ProcessRunning = $false
|
$sync.ProcessRunning = $false
|
||||||
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state "None" })
|
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state "None" })
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
function Invoke-WPFInstall {
|
function Invoke-WPFInstall {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[PSObject[]]$PackagesToInstall = $($sync.selectedApps | Foreach-Object { $sync.configs.applicationsHashtable.$_ })
|
||||||
|
)
|
||||||
<#
|
<#
|
||||||
|
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
@ -12,14 +16,12 @@ function Invoke-WPFInstall {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
$PackagesToInstall = (Get-WinUtilCheckBoxes)["Install"]
|
|
||||||
Write-Host $PackagesToInstall
|
|
||||||
if ($PackagesToInstall.Count -eq 0) {
|
if ($PackagesToInstall.Count -eq 0) {
|
||||||
$WarningMsg = "Please select the program(s) to install or upgrade"
|
$WarningMsg = "Please select the program(s) to install or upgrade"
|
||||||
[System.Windows.MessageBox]::Show($WarningMsg, $AppTitle, [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
[System.Windows.MessageBox]::Show($WarningMsg, $AppTitle, [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
$ChocoPreference = $($sync.WPFpreferChocolatey.IsChecked)
|
$ChocoPreference = $($sync.ChocoRadioButton.IsChecked)
|
||||||
$installHandle = Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock {
|
$installHandle = Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock {
|
||||||
param($PackagesToInstall, $ChocoPreference, $DebugPreference)
|
param($PackagesToInstall, $ChocoPreference, $DebugPreference)
|
||||||
if ($PackagesToInstall.count -eq 1) {
|
if ($PackagesToInstall.count -eq 1) {
|
||||||
|
@ -5,7 +5,7 @@ function Invoke-WPFInstallUpgrade {
|
|||||||
Invokes the function that upgrades all installed programs
|
Invokes the function that upgrades all installed programs
|
||||||
|
|
||||||
#>
|
#>
|
||||||
if ($sync.WPFpreferChocolatey.IsChecked) {
|
if ($sync.ChocoRadioButton.IsChecked) {
|
||||||
Install-WinUtilChoco
|
Install-WinUtilChoco
|
||||||
$chocoUpgradeStatus = (Start-Process "choco" -ArgumentList "upgrade all -y" -Wait -PassThru -NoNewWindow).ExitCode
|
$chocoUpgradeStatus = (Start-Process "choco" -ArgumentList "upgrade all -y" -Wait -PassThru -NoNewWindow).ExitCode
|
||||||
if ($chocoUpgradeStatus -eq 0) {
|
if ($chocoUpgradeStatus -eq 0) {
|
||||||
|
@ -162,35 +162,6 @@ public class PowerManagement {
|
|||||||
Write-Host "Removing Appx Bloat"
|
Write-Host "Removing Appx Bloat"
|
||||||
Remove-ProvisionedPackages
|
Remove-ProvisionedPackages
|
||||||
|
|
||||||
# Detect Windows 11 24H2 and add dependency to FileExp to prevent Explorer look from going back - thanks @WitherOrNot and @thecatontheceiling
|
|
||||||
if ((Test-CompatibleImage $imgVersion $([System.Version]::new(10,0,26100,1))) -eq $true)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Test-Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" -PathType Leaf)
|
|
||||||
{
|
|
||||||
# Found the culprit. Do the following:
|
|
||||||
|
|
||||||
# 1. Take ownership of the file, from TrustedInstaller to Administrators
|
|
||||||
takeown /F "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" /A
|
|
||||||
|
|
||||||
# 2. Set ACLs so that we can write to it
|
|
||||||
icacls "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" /grant "$(Get-LocalizedUsers -admins $true):(M)" | Out-Host
|
|
||||||
|
|
||||||
# 3. Open the file and do the modification
|
|
||||||
$appxManifest = Get-Content -Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml"
|
|
||||||
$originalLine = $appxManifest[13]
|
|
||||||
$dependency = "`n <PackageDependency Name=`"Microsoft.WindowsAppRuntime.CBS`" MinVersion=`"1.0.0.0`" Publisher=`"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US`" />"
|
|
||||||
$appxManifest[13] = "$originalLine$dependency"
|
|
||||||
Set-Content -Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" -Value $appxManifest -Force -Encoding utf8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LogFiles\WMI\RtBackup" -Directory
|
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LogFiles\WMI\RtBackup" -Directory
|
||||||
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\DiagTrack" -Directory
|
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\DiagTrack" -Directory
|
||||||
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\InboxApps" -Directory
|
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\InboxApps" -Directory
|
||||||
|
43
functions/public/Invoke-WPFSelectedAppsUpdate.ps1
Normal file
43
functions/public/Invoke-WPFSelectedAppsUpdate.ps1
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
function Invoke-WPFSelectedAppsUpdate {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
This is a helper function that is called by the Checked and Unchecked events of the Checkboxes on the install tab.
|
||||||
|
It Updates the "Selected Apps" selectedAppLabel on the Install Tab to represent the current collection
|
||||||
|
.PARAMETER type
|
||||||
|
Eigther: Add | Remove
|
||||||
|
.PARAMETER checkbox
|
||||||
|
should contain the current instance of the checkbox that triggered the Event.
|
||||||
|
Most of the time will be the automatic variable $this
|
||||||
|
.EXAMPLE
|
||||||
|
$checkbox.Add_Unchecked({Invoke-WPFSelectedAppsUpdate -type "Remove" -checkbox $this})
|
||||||
|
OR
|
||||||
|
Invoke-WPFSelectedAppsUpdate -type "Add" -checkbox $specificCheckbox
|
||||||
|
#>
|
||||||
|
param (
|
||||||
|
$type,
|
||||||
|
$checkbox
|
||||||
|
)
|
||||||
|
|
||||||
|
$selectedAppsButton = $sync.WPFselectedAppsButton
|
||||||
|
# Get the actual Name from the selectedAppLabel inside the Checkbox
|
||||||
|
$appKey = $checkbox.Parent.Parent.Tag
|
||||||
|
if ($type -eq "Add") {
|
||||||
|
$sync.selectedApps.Add($appKey)
|
||||||
|
# The List type needs to be specified again, because otherwise Sort-Object will convert the list to a string if there is only a single entry
|
||||||
|
[System.Collections.Generic.List[pscustomobject]]$sync.selectedApps = $sync.SelectedApps | Sort-Object
|
||||||
|
|
||||||
|
}
|
||||||
|
elseif ($type -eq "Remove") {
|
||||||
|
$sync.SelectedApps.Remove($appKey)
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Write-Error "Type: $type not implemented"
|
||||||
|
}
|
||||||
|
|
||||||
|
$count = $sync.SelectedApps.Count
|
||||||
|
$selectedAppsButton.Content = "Selected Apps: $count"
|
||||||
|
# On every change, remove all entries inside the Popup Menu. This is done, so we can keep the alphabetical order even if elements are selected in a random way
|
||||||
|
$sync.selectedAppsstackPanel.Children.Clear()
|
||||||
|
$sync.SelectedApps | Foreach-Object { Add-SelectedAppsMenuItem -name $($sync.configs.applicationsHashtable.$_.Content) -key $_ }
|
||||||
|
|
||||||
|
}
|
@ -27,4 +27,5 @@ function Invoke-WPFTab {
|
|||||||
$sync.$tabNav.Items[$tabNumber].IsSelected = $true
|
$sync.$tabNav.Items[$tabNumber].IsSelected = $true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$sync.currentTab = $sync.$tabNav.Items[$tabNumber].Header
|
||||||
}
|
}
|
||||||
|
22
functions/public/Invoke-WPFUIApps.ps1
Normal file
22
functions/public/Invoke-WPFUIApps.ps1
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
function Invoke-WPFUIApps {
|
||||||
|
[OutputType([void])]
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory, Position = 0)]
|
||||||
|
[PSCustomObject[]]$Apps,
|
||||||
|
[Parameter(Mandatory, Position = 1)]
|
||||||
|
[string]$TargetGridName
|
||||||
|
)
|
||||||
|
|
||||||
|
switch ($TargetGridName) {
|
||||||
|
"appspanel" {
|
||||||
|
$dockPanel = Initialize-InstallAppsMainElement -TargetGridName $TargetGridName
|
||||||
|
$null = Initialize-InstallHeader -TargetElement $dockPanel
|
||||||
|
$sync.ItemsControl = Initialize-InstallAppArea -TargetElement $dockPanel
|
||||||
|
Initialize-InstallCategoryAppList -TargetElement $sync.ItemsControl -Apps $Apps
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
Write-Output "$TargetGridName not yet implemented"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,26 +11,26 @@ function Invoke-WPFUIElements {
|
|||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Invoke-WPFUIElements -configVariable $sync.configs.applications -targetGridName "install" -columncount 5
|
Invoke-WPFUIElements -configVariable $sync.configs.applications -targetGridName "install" -columncount 5
|
||||||
.NOTES
|
.NOTES
|
||||||
Future me/contributer: If possible please wrap this into a runspace to make it load all panels at the same time.
|
Future me/contributor: If possible, please wrap this into a runspace to make it load all panels at the same time.
|
||||||
#>
|
#>
|
||||||
|
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory, position=0)]
|
[Parameter(Mandatory, Position = 0)]
|
||||||
[PSCustomObject]$configVariable,
|
[PSCustomObject]$configVariable,
|
||||||
|
|
||||||
[Parameter(Mandatory, position=1)]
|
[Parameter(Mandatory, Position = 1)]
|
||||||
[string]$targetGridName,
|
[string]$targetGridName,
|
||||||
|
|
||||||
[Parameter(Mandatory, position=2)]
|
[Parameter(Mandatory, Position = 2)]
|
||||||
[int]$columncount
|
[int]$columncount
|
||||||
)
|
)
|
||||||
|
|
||||||
$window = $sync["Form"]
|
$window = $sync.form
|
||||||
|
|
||||||
$theme = $sync.Form.Resources
|
|
||||||
$borderstyle = $window.FindResource("BorderStyle")
|
$borderstyle = $window.FindResource("BorderStyle")
|
||||||
$HoverTextBlockStyle = $window.FindResource("HoverTextBlockStyle")
|
$HoverTextBlockStyle = $window.FindResource("HoverTextBlockStyle")
|
||||||
$ColorfulToggleSwitchStyle = $window.FindResource("ColorfulToggleSwitchStyle")
|
$ColorfulToggleSwitchStyle = $window.FindResource("ColorfulToggleSwitchStyle")
|
||||||
|
$ToggleButtonStyle = $window.FindResource("ToggleButtonStyle")
|
||||||
|
|
||||||
if (!$borderstyle -or !$HoverTextBlockStyle -or !$ColorfulToggleSwitchStyle) {
|
if (!$borderstyle -or !$HoverTextBlockStyle -or !$ColorfulToggleSwitchStyle) {
|
||||||
throw "Failed to retrieve Styles using 'FindResource' from main window element."
|
throw "Failed to retrieve Styles using 'FindResource' from main window element."
|
||||||
@ -59,6 +59,8 @@ function Invoke-WPFUIElements {
|
|||||||
$configHashtable[$_] = $configVariable.$_
|
$configHashtable[$_] = $configVariable.$_
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$radioButtonGroups = @{}
|
||||||
|
|
||||||
$organizedData = @{}
|
$organizedData = @{}
|
||||||
# Iterate through JSON data and organize by panel and category
|
# Iterate through JSON data and organize by panel and category
|
||||||
foreach ($entry in $configHashtable.Keys) {
|
foreach ($entry in $configHashtable.Keys) {
|
||||||
@ -70,8 +72,6 @@ function Invoke-WPFUIElements {
|
|||||||
Order = $entryInfo.order
|
Order = $entryInfo.order
|
||||||
Category = $entryInfo.Category
|
Category = $entryInfo.Category
|
||||||
Content = $entryInfo.Content
|
Content = $entryInfo.Content
|
||||||
Choco = $entryInfo.choco
|
|
||||||
Winget = $entryInfo.winget
|
|
||||||
Panel = if ($entryInfo.Panel) { $entryInfo.Panel } else { "0" }
|
Panel = if ($entryInfo.Panel) { $entryInfo.Panel } else { "0" }
|
||||||
Link = $entryInfo.link
|
Link = $entryInfo.link
|
||||||
Description = $entryInfo.description
|
Description = $entryInfo.description
|
||||||
@ -79,6 +79,7 @@ function Invoke-WPFUIElements {
|
|||||||
ComboItems = $entryInfo.ComboItems
|
ComboItems = $entryInfo.ComboItems
|
||||||
Checked = $entryInfo.Checked
|
Checked = $entryInfo.Checked
|
||||||
ButtonWidth = $entryInfo.ButtonWidth
|
ButtonWidth = $entryInfo.ButtonWidth
|
||||||
|
GroupName = $entryInfo.GroupName # Added for RadioButton groupings
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-not $organizedData.ContainsKey($entryObject.Panel)) {
|
if (-not $organizedData.ContainsKey($entryObject.Panel)) {
|
||||||
@ -96,10 +97,12 @@ function Invoke-WPFUIElements {
|
|||||||
if ($targetGridName -eq "appspanel") {
|
if ($targetGridName -eq "appspanel") {
|
||||||
$panelcount = 0
|
$panelcount = 0
|
||||||
$entrycount = $configHashtable.Keys.Count + $organizedData["0"].Keys.Count
|
$entrycount = $configHashtable.Keys.Count + $organizedData["0"].Keys.Count
|
||||||
$maxcount = [Math]::Round($entrycount / $columncount + 0.5)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Initialize panel count
|
||||||
|
$panelcount = 0
|
||||||
|
|
||||||
# Iterate through 'organizedData' by panel, category, and application
|
# Iterate through 'organizedData' by panel, category, and application
|
||||||
$count = 0
|
$count = 0
|
||||||
foreach ($panelKey in ($organizedData.Keys | Sort-Object)) {
|
foreach ($panelKey in ($organizedData.Keys | Sort-Object)) {
|
||||||
@ -110,68 +113,58 @@ function Invoke-WPFUIElements {
|
|||||||
$border.style = $borderstyle
|
$border.style = $borderstyle
|
||||||
$targetGrid.Children.Add($border) | Out-Null
|
$targetGrid.Children.Add($border) | Out-Null
|
||||||
|
|
||||||
# Create a StackPanel inside the Border
|
# Use a DockPanel to contain both the top buttons and the main content
|
||||||
$stackPanel = New-Object Windows.Controls.StackPanel
|
$dockPanelContainer = New-Object Windows.Controls.DockPanel
|
||||||
$stackPanel.Background = [Windows.Media.Brushes]::Transparent
|
$border.Child = $dockPanelContainer
|
||||||
$stackPanel.SnapsToDevicePixels = $true
|
|
||||||
$stackPanel.VerticalAlignment = "Stretch" # Ensure the stack panel stretches vertically
|
# Create a ScrollViewer to contain the main content (excluding buttons)
|
||||||
$border.Child = $stackPanel
|
$scrollViewer = New-Object Windows.Controls.ScrollViewer
|
||||||
|
$scrollViewer.VerticalScrollBarVisibility = 'Auto'
|
||||||
|
$scrollViewer.HorizontalScrollBarVisibility = 'Auto'
|
||||||
|
$scrollViewer.HorizontalAlignment = 'Stretch'
|
||||||
|
$scrollViewer.VerticalAlignment = 'Stretch'
|
||||||
|
$scrollViewer.CanContentScroll = $true # Enable virtualization
|
||||||
|
|
||||||
|
# Create an ItemsControl inside the ScrollViewer for application content
|
||||||
|
$itemsControl = New-Object Windows.Controls.ItemsControl
|
||||||
|
$itemsControl.HorizontalAlignment = 'Stretch'
|
||||||
|
$itemsControl.VerticalAlignment = 'Stretch'
|
||||||
|
|
||||||
|
# Set the ItemsPanel to a VirtualizingStackPanel
|
||||||
|
$itemsPanelTemplate = New-Object Windows.Controls.ItemsPanelTemplate
|
||||||
|
$factory = New-Object Windows.FrameworkElementFactory ([Windows.Controls.VirtualizingStackPanel])
|
||||||
|
$itemsPanelTemplate.VisualTree = $factory
|
||||||
|
$itemsControl.ItemsPanel = $itemsPanelTemplate
|
||||||
|
|
||||||
|
# Set virtualization properties
|
||||||
|
$itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::IsVirtualizingProperty, $true)
|
||||||
|
$itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::VirtualizationModeProperty, [Windows.Controls.VirtualizationMode]::Recycling)
|
||||||
|
|
||||||
|
# Add the ItemsControl to the ScrollViewer
|
||||||
|
$scrollViewer.Content = $itemsControl
|
||||||
|
|
||||||
|
# Add the ScrollViewer to the DockPanel (it will be below the top buttons StackPanel)
|
||||||
|
[Windows.Controls.DockPanel]::SetDock($scrollViewer, [Windows.Controls.Dock]::Bottom)
|
||||||
|
$dockPanelContainer.Children.Add($scrollViewer) | Out-Null
|
||||||
$panelcount++
|
$panelcount++
|
||||||
|
|
||||||
|
# Now proceed with adding category labels and entries to $itemsControl
|
||||||
foreach ($category in ($organizedData[$panelKey].Keys | Sort-Object)) {
|
foreach ($category in ($organizedData[$panelKey].Keys | Sort-Object)) {
|
||||||
$count++
|
$count++
|
||||||
if ($targetGridName -eq "appspanel" -and $columncount -gt 0) {
|
|
||||||
$panelcount2 = [Int](($count) / $maxcount - 0.5)
|
|
||||||
if ($panelcount -eq $panelcount2) {
|
|
||||||
# Create a new Border for the new column
|
|
||||||
$border = New-Object Windows.Controls.Border
|
|
||||||
$border.VerticalAlignment = "Stretch" # Ensure the border stretches vertically
|
|
||||||
[System.Windows.Controls.Grid]::SetColumn($border, $panelcount)
|
|
||||||
$border.style = $borderstyle
|
|
||||||
$targetGrid.Children.Add($border) | Out-Null
|
|
||||||
|
|
||||||
# Create a new StackPanel inside the Border
|
|
||||||
$stackPanel = New-Object Windows.Controls.StackPanel
|
|
||||||
$stackPanel.Background = [Windows.Media.Brushes]::Transparent
|
|
||||||
$stackPanel.SnapsToDevicePixels = $true
|
|
||||||
$stackPanel.VerticalAlignment = "Stretch" # Ensure the stack panel stretches vertically
|
|
||||||
$border.Child = $stackPanel
|
|
||||||
$panelcount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$label = New-Object Windows.Controls.Label
|
$label = New-Object Windows.Controls.Label
|
||||||
$label.Content = $category -replace ".*__", ""
|
$label.Content = $category -replace ".*__", ""
|
||||||
$label.FontSize = $theme.FontSizeHeading
|
$label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSizeHeading")
|
||||||
$label.FontFamily = $theme.HeaderFontFamily
|
$label.SetResourceReference([Windows.Controls.Control]::FontFamilyProperty, "HeaderFontFamily")
|
||||||
$stackPanel.Children.Add($label) | Out-Null
|
$itemsControl.Items.Add($label) | Out-Null
|
||||||
|
|
||||||
$sync[$category] = $label
|
$sync[$category] = $label
|
||||||
|
|
||||||
# Sort entries by Order and then by Name, but only display Name
|
# Sort entries by Order and then by Name
|
||||||
$entries = $organizedData[$panelKey][$category] | Sort-Object Order, Name
|
$entries = $organizedData[$panelKey][$category] | Sort-Object Order, Name
|
||||||
foreach ($entryInfo in $entries) {
|
foreach ($entryInfo in $entries) {
|
||||||
$count++
|
$count++
|
||||||
if ($targetGridName -eq "appspanel" -and $columncount -gt 0) {
|
# Create the UI elements based on the entry type
|
||||||
$panelcount2 = [Int](($count) / $maxcount - 0.5)
|
|
||||||
if ($panelcount -eq $panelcount2) {
|
|
||||||
# Create a new Border for the new column
|
|
||||||
$border = New-Object Windows.Controls.Border
|
|
||||||
$border.VerticalAlignment = "Stretch" # Ensure the border stretches vertically
|
|
||||||
[System.Windows.Controls.Grid]::SetColumn($border, $panelcount)
|
|
||||||
$border.style = $borderstyle
|
|
||||||
$targetGrid.Children.Add($border) | Out-Null
|
|
||||||
|
|
||||||
# Create a new StackPanel inside the Border
|
|
||||||
$stackPanel = New-Object Windows.Controls.StackPanel
|
|
||||||
$stackPanel.Background = [Windows.Media.Brushes]::Transparent
|
|
||||||
$stackPanel.SnapsToDevicePixels = $true
|
|
||||||
$stackPanel.VerticalAlignment = "Stretch" # Ensure the stack panel stretches vertically
|
|
||||||
$border.Child = $stackPanel
|
|
||||||
$panelcount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($entryInfo.Type) {
|
switch ($entryInfo.Type) {
|
||||||
"Toggle" {
|
"Toggle" {
|
||||||
$dockPanel = New-Object Windows.Controls.DockPanel
|
$dockPanel = New-Object Windows.Controls.DockPanel
|
||||||
@ -185,10 +178,10 @@ function Invoke-WPFUIElements {
|
|||||||
$label.Content = $entryInfo.Content
|
$label.Content = $entryInfo.Content
|
||||||
$label.ToolTip = $entryInfo.Description
|
$label.ToolTip = $entryInfo.Description
|
||||||
$label.HorizontalAlignment = "Left"
|
$label.HorizontalAlignment = "Left"
|
||||||
$label.FontSize = $theme.FontSize
|
$label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize")
|
||||||
$label.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
|
$label.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
|
||||||
$dockPanel.Children.Add($label) | Out-Null
|
$dockPanel.Children.Add($label) | Out-Null
|
||||||
$stackPanel.Children.Add($dockPanel) | Out-Null
|
$itemsControl.Items.Add($dockPanel) | Out-Null
|
||||||
|
|
||||||
$sync[$entryInfo.Name] = $checkBox
|
$sync[$entryInfo.Name] = $checkBox
|
||||||
|
|
||||||
@ -201,35 +194,29 @@ function Invoke-WPFUIElements {
|
|||||||
}
|
}
|
||||||
|
|
||||||
"ToggleButton" {
|
"ToggleButton" {
|
||||||
$toggleButton = New-Object Windows.Controls.ToggleButton
|
$toggleButton = New-Object Windows.Controls.Primitives.ToggleButton
|
||||||
$toggleButton.Name = $entryInfo.Name
|
$toggleButton.Name = $entryInfo.Name
|
||||||
$toggleButton.Name = "WPFTab" + ($stackPanel.Children.Count + 1) + "BT"
|
$toggleButton.Content = $entryInfo.Content[1]
|
||||||
|
$toggleButton.ToolTip = $entryInfo.Description
|
||||||
$toggleButton.HorizontalAlignment = "Left"
|
$toggleButton.HorizontalAlignment = "Left"
|
||||||
$toggleButton.Height = $theme.TabButtonHeight
|
$toggleButton.Style = $ToggleButtonStyle
|
||||||
$toggleButton.Width = $theme.TabButtonWidth
|
|
||||||
$toggleButton.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "ButtonInstallBackgroundColor")
|
|
||||||
$toggleButton.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
|
|
||||||
$toggleButton.FontWeight = [Windows.FontWeights]::Bold
|
|
||||||
|
|
||||||
$textBlock = New-Object Windows.Controls.TextBlock
|
$toggleButton.Tag = @{
|
||||||
$textBlock.FontSize = $theme.TabButtonFontSize
|
contentOn = if ($entryInfo.Content.Count -ge 1) { $entryInfo.Content[0] } else { "" }
|
||||||
$textBlock.Background = [Windows.Media.Brushes]::Transparent
|
contentOff = if ($entryInfo.Content.Count -ge 2) { $entryInfo.Content[1] } else { $contentOn }
|
||||||
$textBlock.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "ButtonInstallForegroundColor")
|
}
|
||||||
|
|
||||||
$underline = New-Object Windows.Documents.Underline
|
$itemsControl.Items.Add($toggleButton) | Out-Null
|
||||||
$underline.Inlines.Add($entryInfo.name -replace "(.).*", "`$1")
|
|
||||||
|
|
||||||
$run = New-Object Windows.Documents.Run
|
|
||||||
$run.Text = $entryInfo.name -replace "^.", ""
|
|
||||||
|
|
||||||
$textBlock.Inlines.Add($underline)
|
|
||||||
$textBlock.Inlines.Add($run)
|
|
||||||
|
|
||||||
$toggleButton.Content = $textBlock
|
|
||||||
|
|
||||||
$stackPanel.Children.Add($toggleButton) | Out-Null
|
|
||||||
|
|
||||||
$sync[$entryInfo.Name] = $toggleButton
|
$sync[$entryInfo.Name] = $toggleButton
|
||||||
|
|
||||||
|
$sync[$entryInfo.Name].Add_Checked({
|
||||||
|
$this.Content = $this.Tag.contentOn
|
||||||
|
})
|
||||||
|
|
||||||
|
$sync[$entryInfo.Name].Add_Unchecked({
|
||||||
|
$this.Content = $this.Tag.contentOff
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
"Combobox" {
|
"Combobox" {
|
||||||
@ -241,26 +228,26 @@ function Invoke-WPFUIElements {
|
|||||||
$label.Content = $entryInfo.Content
|
$label.Content = $entryInfo.Content
|
||||||
$label.HorizontalAlignment = "Left"
|
$label.HorizontalAlignment = "Left"
|
||||||
$label.VerticalAlignment = "Center"
|
$label.VerticalAlignment = "Center"
|
||||||
$label.FontSize = $theme.ButtonFontSize
|
$label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize")
|
||||||
$horizontalStackPanel.Children.Add($label) | Out-Null
|
$horizontalStackPanel.Children.Add($label) | Out-Null
|
||||||
|
|
||||||
$comboBox = New-Object Windows.Controls.ComboBox
|
$comboBox = New-Object Windows.Controls.ComboBox
|
||||||
$comboBox.Name = $entryInfo.Name
|
$comboBox.Name = $entryInfo.Name
|
||||||
$comboBox.Height = $theme.ButtonHeight
|
$comboBox.SetResourceReference([Windows.Controls.Control]::HeightProperty, "ButtonHeight")
|
||||||
$comboBox.Width = $theme.ButtonWidth
|
$comboBox.SetResourceReference([Windows.Controls.Control]::WidthProperty, "ButtonWidth")
|
||||||
$comboBox.HorizontalAlignment = "Left"
|
$comboBox.HorizontalAlignment = "Left"
|
||||||
$comboBox.VerticalAlignment = "Center"
|
$comboBox.VerticalAlignment = "Center"
|
||||||
$comboBox.Margin = $theme.ButtonMargin
|
$comboBox.SetResourceReference([Windows.Controls.Control]::MarginProperty, "ButtonMargin")
|
||||||
|
|
||||||
foreach ($comboitem in ($entryInfo.ComboItems -split " ")) {
|
foreach ($comboitem in ($entryInfo.ComboItems -split " ")) {
|
||||||
$comboBoxItem = New-Object Windows.Controls.ComboBoxItem
|
$comboBoxItem = New-Object Windows.Controls.ComboBoxItem
|
||||||
$comboBoxItem.Content = $comboitem
|
$comboBoxItem.Content = $comboitem
|
||||||
$comboBoxItem.FontSize = $theme.ButtonFontSize
|
$comboBoxItem.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize")
|
||||||
$comboBox.Items.Add($comboBoxItem) | Out-Null
|
$comboBox.Items.Add($comboBoxItem) | Out-Null
|
||||||
}
|
}
|
||||||
|
|
||||||
$horizontalStackPanel.Children.Add($comboBox) | Out-Null
|
$horizontalStackPanel.Children.Add($comboBox) | Out-Null
|
||||||
$stackPanel.Children.Add($horizontalStackPanel) | Out-Null
|
$itemsControl.Items.Add($horizontalStackPanel) | Out-Null
|
||||||
|
|
||||||
$comboBox.SelectedIndex = 0
|
$comboBox.SelectedIndex = 0
|
||||||
|
|
||||||
@ -272,16 +259,50 @@ function Invoke-WPFUIElements {
|
|||||||
$button.Name = $entryInfo.Name
|
$button.Name = $entryInfo.Name
|
||||||
$button.Content = $entryInfo.Content
|
$button.Content = $entryInfo.Content
|
||||||
$button.HorizontalAlignment = "Left"
|
$button.HorizontalAlignment = "Left"
|
||||||
$button.Margin = $theme.ButtonMargin
|
$button.SetResourceReference([Windows.Controls.Control]::MarginProperty, "ButtonMargin")
|
||||||
$button.FontSize = $theme.ButtonFontSize
|
$button.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize")
|
||||||
if ($entryInfo.ButtonWidth) {
|
if ($entryInfo.ButtonWidth) {
|
||||||
$button.Width = $entryInfo.ButtonWidth
|
$button.Width = $entryInfo.ButtonWidth
|
||||||
}
|
}
|
||||||
$stackPanel.Children.Add($button) | Out-Null
|
$itemsControl.Items.Add($button) | Out-Null
|
||||||
|
|
||||||
$sync[$entryInfo.Name] = $button
|
$sync[$entryInfo.Name] = $button
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"RadioButton" {
|
||||||
|
# Check if a container for this GroupName already exists
|
||||||
|
if (-not $radioButtonGroups.ContainsKey($entryInfo.GroupName)) {
|
||||||
|
# Create a StackPanel for this group
|
||||||
|
$groupStackPanel = New-Object Windows.Controls.StackPanel
|
||||||
|
$groupStackPanel.Orientation = "Vertical"
|
||||||
|
|
||||||
|
# Add the group container to the ItemsControl
|
||||||
|
$itemsControl.Items.Add($groupStackPanel) | Out-Null
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Retrieve the existing group container
|
||||||
|
$groupStackPanel = $radioButtonGroups[$entryInfo.GroupName]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create the RadioButton
|
||||||
|
$radioButton = New-Object Windows.Controls.RadioButton
|
||||||
|
$radioButton.Name = $entryInfo.Name
|
||||||
|
$radioButton.GroupName = $entryInfo.GroupName
|
||||||
|
$radioButton.Content = $entryInfo.Content
|
||||||
|
$radioButton.HorizontalAlignment = "Left"
|
||||||
|
$radioButton.SetResourceReference([Windows.Controls.Control]::MarginProperty, "CheckBoxMargin")
|
||||||
|
$radioButton.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize")
|
||||||
|
$radioButton.ToolTip = $entryInfo.Description
|
||||||
|
|
||||||
|
if ($entryInfo.Checked -eq $true) {
|
||||||
|
$radioButton.IsChecked = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add the RadioButton to the group container
|
||||||
|
$groupStackPanel.Children.Add($radioButton) | Out-Null
|
||||||
|
$sync[$entryInfo.Name] = $radioButton
|
||||||
|
}
|
||||||
|
|
||||||
default {
|
default {
|
||||||
$horizontalStackPanel = New-Object Windows.Controls.StackPanel
|
$horizontalStackPanel = New-Object Windows.Controls.StackPanel
|
||||||
$horizontalStackPanel.Orientation = "Horizontal"
|
$horizontalStackPanel.Orientation = "Horizontal"
|
||||||
@ -289,9 +310,9 @@ function Invoke-WPFUIElements {
|
|||||||
$checkBox = New-Object Windows.Controls.CheckBox
|
$checkBox = New-Object Windows.Controls.CheckBox
|
||||||
$checkBox.Name = $entryInfo.Name
|
$checkBox.Name = $entryInfo.Name
|
||||||
$checkBox.Content = $entryInfo.Content
|
$checkBox.Content = $entryInfo.Content
|
||||||
$checkBox.FontSize = $theme.FontSize
|
$checkBox.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize")
|
||||||
$checkBox.ToolTip = $entryInfo.Description
|
$checkBox.ToolTip = $entryInfo.Description
|
||||||
$checkBox.Margin = $theme.CheckBoxMargin
|
$checkBox.SetResourceReference([Windows.Controls.Control]::MarginProperty, "CheckBoxMargin")
|
||||||
if ($entryInfo.Checked -eq $true) {
|
if ($entryInfo.Checked -eq $true) {
|
||||||
$checkBox.IsChecked = $entryInfo.Checked
|
$checkBox.IsChecked = $entryInfo.Checked
|
||||||
}
|
}
|
||||||
@ -309,7 +330,7 @@ function Invoke-WPFUIElements {
|
|||||||
$sync[$textBlock.Name] = $textBlock
|
$sync[$textBlock.Name] = $textBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
$stackPanel.Children.Add($horizontalStackPanel) | Out-Null
|
$itemsControl.Items.Add($horizontalStackPanel) | Out-Null
|
||||||
$sync[$entryInfo.Name] = $checkBox
|
$sync[$entryInfo.Name] = $checkBox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
function Invoke-WPFUnInstall {
|
function Invoke-WPFUnInstall {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[PSObject[]]$PackagesToUninstall = $($sync.selectedApps | Foreach-Object { $sync.configs.applicationsHashtable.$_ })
|
||||||
|
)
|
||||||
<#
|
<#
|
||||||
|
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Uninstalls the selected programs
|
Uninstalls the selected programs
|
||||||
|
|
||||||
#>
|
#>
|
||||||
|
|
||||||
if($sync.ProcessRunning) {
|
if($sync.ProcessRunning) {
|
||||||
@ -12,9 +15,7 @@ function Invoke-WPFUnInstall {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
$PackagesToInstall = (Get-WinUtilCheckBoxes)["Install"]
|
if ($PackagesToUninstall.Count -eq 0) {
|
||||||
|
|
||||||
if ($PackagesToInstall.Count -eq 0) {
|
|
||||||
$WarningMsg = "Please select the program(s) to uninstall"
|
$WarningMsg = "Please select the program(s) to uninstall"
|
||||||
[System.Windows.MessageBox]::Show($WarningMsg, $AppTitle, [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
[System.Windows.MessageBox]::Show($WarningMsg, $AppTitle, [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
||||||
return
|
return
|
||||||
@ -22,17 +23,17 @@ function Invoke-WPFUnInstall {
|
|||||||
|
|
||||||
$ButtonType = [System.Windows.MessageBoxButton]::YesNo
|
$ButtonType = [System.Windows.MessageBoxButton]::YesNo
|
||||||
$MessageboxTitle = "Are you sure?"
|
$MessageboxTitle = "Are you sure?"
|
||||||
$Messageboxbody = ("This will uninstall the following applications: `n $($PackagesToInstall | Format-Table | Out-String)")
|
$Messageboxbody = ("This will uninstall the following applications: `n $($PackagesToUninstall | Select-Object Name, Description| Out-String)")
|
||||||
$MessageIcon = [System.Windows.MessageBoxImage]::Information
|
$MessageIcon = [System.Windows.MessageBoxImage]::Information
|
||||||
|
|
||||||
$confirm = [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon)
|
$confirm = [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon)
|
||||||
|
|
||||||
if($confirm -eq "No") {return}
|
if($confirm -eq "No") {return}
|
||||||
$ChocoPreference = $($sync.WPFpreferChocolatey.IsChecked)
|
$ChocoPreference = $($sync.ChocoRadioButton.IsChecked)
|
||||||
|
|
||||||
Invoke-WPFRunspace -ArgumentList @(("PackagesToInstall", $PackagesToInstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock {
|
Invoke-WPFRunspace -ArgumentList @(("PackagesToUninstall", $PackagesToUninstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock {
|
||||||
param($PackagesToInstall, $ChocoPreference, $DebugPreference)
|
param($PackagesToUninstall, $ChocoPreference, $DebugPreference)
|
||||||
if ($PackagesToInstall.count -eq 1) {
|
if ($PackagesToUninstall.count -eq 1) {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
|
||||||
} else {
|
} else {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
|
||||||
@ -41,7 +42,7 @@ function Invoke-WPFUnInstall {
|
|||||||
$packagesWinget = [System.Collections.ArrayList]::new()
|
$packagesWinget = [System.Collections.ArrayList]::new()
|
||||||
$packagesChoco = [System.Collections.ArrayList]::new()
|
$packagesChoco = [System.Collections.ArrayList]::new()
|
||||||
|
|
||||||
foreach ($package in $PackagesToInstall) {
|
foreach ($package in $PackagesToUninstall) {
|
||||||
if ($ChocoPreference) {
|
if ($ChocoPreference) {
|
||||||
if ($package.choco -eq "na") {
|
if ($package.choco -eq "na") {
|
||||||
$packagesWinget.add($package.winget)
|
$packagesWinget.add($package.winget)
|
||||||
@ -62,7 +63,7 @@ function Invoke-WPFUnInstall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $packagesWinget, $packagesChoco
|
return $packagesWinget, $packagesChoco
|
||||||
}.Invoke($PackagesToInstall)
|
}.Invoke($PackagesToUninstall)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$sync.ProcessRunning = $true
|
$sync.ProcessRunning = $true
|
||||||
|
122
scripts/main.ps1
122
scripts/main.ps1
@ -111,8 +111,27 @@ $sync.Form.Add_Loaded({
|
|||||||
|
|
||||||
Invoke-WinutilThemeChange -init $true
|
Invoke-WinutilThemeChange -init $true
|
||||||
# Load the configuration files
|
# Load the configuration files
|
||||||
#Invoke-WPFUIElements -configVariable $sync.configs.nav -targetGridName "WPFMainGrid"
|
|
||||||
Invoke-WPFUIElements -configVariable $sync.configs.applications -targetGridName "appspanel" -columncount 5
|
$noimage = "https://images.emojiterra.com/google/noto-emoji/unicode-15/color/512px/1f4e6.png"
|
||||||
|
$noimage = [Windows.Media.Imaging.BitmapImage]::new([Uri]::new($noimage))
|
||||||
|
|
||||||
|
$sync.configs.applicationsHashtable = @{}
|
||||||
|
$sync.configs.applications.PSObject.Properties | ForEach-Object {
|
||||||
|
$sync.configs.applicationsHashtable[$_.Name] = $_.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
# Now call the function with the final merged config
|
||||||
|
Invoke-WPFUIElements -configVariable $sync.configs.appnavigation -targetGridName "appscategory" -columncount 1
|
||||||
|
# Add logic to handle click to the ToggleView Button on the Install Tab
|
||||||
|
$sync.WPFToggleView.Add_Click({
|
||||||
|
$sync.CompactView = -not $sync.CompactView
|
||||||
|
Update-AppTileProperties
|
||||||
|
if ($sync.SearchBar.Text -eq "") {
|
||||||
|
Set-CategoryVisibility -Category "*"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Invoke-WPFUIApps -Apps $sync.configs.applicationsHashtable -targetGridName "appspanel"
|
||||||
|
|
||||||
Invoke-WPFUIElements -configVariable $sync.configs.tweaks -targetGridName "tweakspanel" -columncount 2
|
Invoke-WPFUIElements -configVariable $sync.configs.tweaks -targetGridName "tweakspanel" -columncount 2
|
||||||
Invoke-WPFUIElements -configVariable $sync.configs.feature -targetGridName "featurespanel" -columncount 2
|
Invoke-WPFUIElements -configVariable $sync.configs.feature -targetGridName "featurespanel" -columncount 2
|
||||||
|
|
||||||
@ -124,12 +143,18 @@ $xaml.SelectNodes("//*[@Name]") | ForEach-Object {$sync["$("$($psitem.Name)")"]
|
|||||||
|
|
||||||
#Persist the Chocolatey preference across winutil restarts
|
#Persist the Chocolatey preference across winutil restarts
|
||||||
$ChocoPreferencePath = "$env:LOCALAPPDATA\winutil\preferChocolatey.ini"
|
$ChocoPreferencePath = "$env:LOCALAPPDATA\winutil\preferChocolatey.ini"
|
||||||
$sync.WPFpreferChocolatey.Add_Checked({New-Item -Path $ChocoPreferencePath -Force })
|
$sync.ChocoRadioButton.Add_Checked({New-Item -Path $ChocoPreferencePath -Force })
|
||||||
$sync.WPFpreferChocolatey.Add_Unchecked({Remove-Item $ChocoPreferencePath -Force})
|
$sync.ChocoRadioButton.Add_Unchecked({Remove-Item $ChocoPreferencePath -Force})
|
||||||
if (Test-Path $ChocoPreferencePath) {
|
if (Test-Path $ChocoPreferencePath) {
|
||||||
$sync.WPFpreferChocolatey.IsChecked = $true
|
$sync.ChocoRadioButton.IsChecked = $true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$sync.autofallback.IsEnabled = $false
|
||||||
|
$sync.autofallback.Opacity = 0.5
|
||||||
|
$sync.autofallback.ToolTip = "This feature is currently under development."
|
||||||
|
|
||||||
|
[System.Windows.Controls.ToolTipService]::SetShowOnDisabled($sync.autofallback, $true)
|
||||||
|
|
||||||
$sync.keys | ForEach-Object {
|
$sync.keys | ForEach-Object {
|
||||||
if($sync.$psitem) {
|
if($sync.$psitem) {
|
||||||
if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "ToggleButton") {
|
if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "ToggleButton") {
|
||||||
@ -184,6 +209,32 @@ Invoke-WPFRunspace -ScriptBlock {
|
|||||||
|
|
||||||
# Print the logo
|
# Print the logo
|
||||||
Invoke-WPFFormVariables
|
Invoke-WPFFormVariables
|
||||||
|
$sync.CompactView = $false
|
||||||
|
$sync.Form.Resources.AppTileWidth = [double]::NaN
|
||||||
|
$sync.Form.Resources.AppTileCompactVisibility = [Windows.Visibility]::Visible
|
||||||
|
$sync.Form.Resources.AppTileFontSize = [double]16
|
||||||
|
$sync.Form.Resources.AppTileMargins = [Windows.Thickness]5
|
||||||
|
$sync.Form.Resources.AppTileBorderThickness = [Windows.Thickness]0
|
||||||
|
function Update-AppTileProperties {
|
||||||
|
if ($sync.CompactView -eq $true) {
|
||||||
|
$sync.Form.Resources.AppTileWidth = [double]::NaN
|
||||||
|
$sync.Form.Resources.AppTileCompactVisibility = [Windows.Visibility]::Collapsed
|
||||||
|
$sync.Form.Resources.AppTileFontSize = [double]12
|
||||||
|
$sync.Form.Resources.AppTileMargins = [Windows.Thickness]2
|
||||||
|
$sync.Form.Resources.AppTileBorderThickness = [Windows.Thickness]0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$sync.Form.Resources.AppTileWidth = $sync.ItemsControl.ActualWidth -20
|
||||||
|
$sync.Form.Resources.AppTileCompactVisibility = [Windows.Visibility]::Visible
|
||||||
|
$sync.Form.Resources.AppTileFontSize = [double]16
|
||||||
|
$sync.Form.Resources.AppTileMargins = [Windows.Thickness]5
|
||||||
|
$sync.Form.Resources.AppTileBorderThickness = [Windows.Thickness]1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# We need to update the app tile properties when the form is resized because to fill a WrapPanel update the width of the elemenmt manually (afaik)
|
||||||
|
$sync.Form.Add_SizeChanged({
|
||||||
|
Update-AppTileProperties
|
||||||
|
})
|
||||||
|
|
||||||
# Progress bar in taskbaritem > Set-WinUtilProgressbar
|
# Progress bar in taskbaritem > Set-WinUtilProgressbar
|
||||||
$sync["Form"].TaskbarItemInfo = New-Object System.Windows.Shell.TaskbarItemInfo
|
$sync["Form"].TaskbarItemInfo = New-Object System.Windows.Shell.TaskbarItemInfo
|
||||||
@ -425,73 +476,22 @@ if ($sync["ISOLanguage"].Items.Count -eq 1) {
|
|||||||
}
|
}
|
||||||
$sync["ISOLanguage"].SelectedIndex = 0
|
$sync["ISOLanguage"].SelectedIndex = 0
|
||||||
|
|
||||||
|
|
||||||
# Load Checkboxes and Labels outside of the Filter function only once on startup for performance reasons
|
|
||||||
$filter = Get-WinUtilVariables -Type CheckBox
|
|
||||||
$CheckBoxes = ($sync.GetEnumerator()).where{ $psitem.Key -in $filter }
|
|
||||||
|
|
||||||
$filter = Get-WinUtilVariables -Type Label
|
|
||||||
$labels = @{}
|
|
||||||
($sync.GetEnumerator()).where{$PSItem.Key -in $filter} | ForEach-Object {$labels[$_.Key] = $_.Value}
|
|
||||||
|
|
||||||
$allCategories = $checkBoxes.Name | ForEach-Object {$sync.configs.applications.$_} | Select-Object -Unique -ExpandProperty category
|
|
||||||
|
|
||||||
$sync["SearchBar"].Add_TextChanged({
|
$sync["SearchBar"].Add_TextChanged({
|
||||||
if ($sync.SearchBar.Text -ne "") {
|
if ($sync.SearchBar.Text -ne "") {
|
||||||
$sync.SearchBarClearButton.Visibility = "Visible"
|
$sync.SearchBarClearButton.Visibility = "Visible"
|
||||||
} else {
|
} else {
|
||||||
$sync.SearchBarClearButton.Visibility = "Collapsed"
|
$sync.SearchBarClearButton.Visibility = "Collapsed"
|
||||||
}
|
}
|
||||||
|
switch ($sync.currentTab) {
|
||||||
$activeApplications = @()
|
"Install" {
|
||||||
|
Find-AppsByNameOrDescription -SearchString $sync.SearchBar.Text
|
||||||
$textToSearch = $sync.SearchBar.Text.ToLower()
|
|
||||||
|
|
||||||
foreach ($CheckBox in $CheckBoxes) {
|
|
||||||
# Skip if the checkbox is null, it doesn't have content or it is the prefer Choco checkbox
|
|
||||||
if ($CheckBox -eq $null -or $CheckBox.Value -eq $null -or $CheckBox.Value.Content -eq $null -or $CheckBox.Name -eq "WPFpreferChocolatey") {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$checkBoxName = $CheckBox.Key
|
|
||||||
$textBlockName = $checkBoxName + "Link"
|
|
||||||
|
|
||||||
# Retrieve the corresponding text block based on the generated name
|
|
||||||
$textBlock = $sync[$textBlockName]
|
|
||||||
|
|
||||||
if ($CheckBox.Value.Content.ToString().ToLower().Contains($textToSearch)) {
|
|
||||||
$CheckBox.Value.Visibility = "Visible"
|
|
||||||
$activeApplications += $sync.configs.applications.$checkboxName
|
|
||||||
# Set the corresponding text block visibility
|
|
||||||
if ($textBlock -ne $null -and $textBlock -is [System.Windows.Controls.TextBlock]) {
|
|
||||||
$textBlock.Visibility = "Visible"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$CheckBox.Value.Visibility = "Collapsed"
|
|
||||||
# Set the corresponding text block visibility
|
|
||||||
if ($textBlock -ne $null -and $textBlock -is [System.Windows.Controls.TextBlock]) {
|
|
||||||
$textBlock.Visibility = "Collapsed"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$activeCategories = $activeApplications | Select-Object -ExpandProperty category -Unique
|
|
||||||
|
|
||||||
foreach ($category in $activeCategories) {
|
|
||||||
$sync[$category].Visibility = "Visible"
|
|
||||||
}
|
|
||||||
if ($activeCategories) {
|
|
||||||
$inactiveCategories = Compare-Object -ReferenceObject $allCategories -DifferenceObject $activeCategories -PassThru
|
|
||||||
} else {
|
|
||||||
$inactiveCategories = $allCategories
|
|
||||||
}
|
|
||||||
foreach ($category in $inactiveCategories) {
|
|
||||||
$sync[$category].Visibility = "Collapsed"
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
$sync["Form"].Add_Loaded({
|
$sync["Form"].Add_Loaded({
|
||||||
param($e)
|
param($e)
|
||||||
|
$sync.Form.MinWidth = "1000"
|
||||||
$sync["Form"].MaxWidth = [Double]::PositiveInfinity
|
$sync["Form"].MaxWidth = [Double]::PositiveInfinity
|
||||||
$sync["Form"].MaxHeight = [Double]::PositiveInfinity
|
$sync["Form"].MaxHeight = [Double]::PositiveInfinity
|
||||||
})
|
})
|
||||||
@ -618,5 +618,7 @@ $sync["SponsorMenuItem"].Add_Click({
|
|||||||
Show-CustomDialog -Message $authorInfo -EnableScroll $true
|
Show-CustomDialog -Message $authorInfo -EnableScroll $true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$sync["Form"].ShowDialog() | out-null
|
$sync["Form"].ShowDialog() | out-null
|
||||||
Stop-Transcript
|
Stop-Transcript
|
||||||
|
@ -37,7 +37,15 @@ $sync = [Hashtable]::Synchronized(@{})
|
|||||||
$sync.PSScriptRoot = $PSScriptRoot
|
$sync.PSScriptRoot = $PSScriptRoot
|
||||||
$sync.version = "#{replaceme}"
|
$sync.version = "#{replaceme}"
|
||||||
$sync.configs = @{}
|
$sync.configs = @{}
|
||||||
|
$sync.Buttons = [System.Collections.Generic.List[PSObject]]::new()
|
||||||
$sync.ProcessRunning = $false
|
$sync.ProcessRunning = $false
|
||||||
|
$sync.selectedApps = [System.Collections.Generic.List[string]]::new()
|
||||||
|
$sync.ShowOnlySeleced = $false
|
||||||
|
$sync.currentTab = "Install"
|
||||||
|
$sync.ShowOnlySelected = $false
|
||||||
|
$sync.selectedAppsStackPanel
|
||||||
|
$sync.selectedAppsPopup
|
||||||
|
|
||||||
|
|
||||||
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
||||||
Write-Output "Winutil needs to be run as Administrator. Attempting to relaunch."
|
Write-Output "Winutil needs to be run as Administrator. Attempting to relaunch."
|
||||||
|
@ -197,6 +197,45 @@
|
|||||||
<Setter Property="Background" Value="{DynamicResource LabelBackgroundColor}"/>
|
<Setter Property="Background" Value="{DynamicResource LabelBackgroundColor}"/>
|
||||||
<Setter Property="FontFamily" Value="{DynamicResource FontFamily}"/>
|
<Setter Property="FontFamily" Value="{DynamicResource FontFamily}"/>
|
||||||
</Style>
|
</Style>
|
||||||
|
<!-- Category Toggle Button Style for the Apps Window-->
|
||||||
|
<Style x:Key="CategoryToggleButtonStyle" TargetType="ToggleButton">
|
||||||
|
<Setter Property="Foreground" Value="{DynamicResource LabelboxForegroundColor}"/>
|
||||||
|
<Setter Property="Background" Value="{DynamicResource MainBackgroundColor}"/>
|
||||||
|
<Setter Property="FontFamily" Value="{DynamicResource HeaderFontFamily}"/>
|
||||||
|
<Setter Property="FontSize" Value="{DynamicResource FontSizeHeading}"/>
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||||
|
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Left"/>
|
||||||
|
<Setter Property="Padding" Value="10,2,10,2"/>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="ToggleButton">
|
||||||
|
<Border Background="{TemplateBinding Background}"
|
||||||
|
BorderBrush="{DynamicResource BorderColor}"
|
||||||
|
BorderThickness="0"
|
||||||
|
CornerRadius="{DynamicResource ButtonCornerRadius}">
|
||||||
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}">
|
||||||
|
<TextBlock x:Name="PrefixTextBlock"/>
|
||||||
|
<ContentPresenter Content="{TemplateBinding Content}" />
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="IsChecked" Value="True">
|
||||||
|
<Setter TargetName="PrefixTextBlock" Property="Text" Value="[-] "/>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsChecked" Value="False">
|
||||||
|
<Setter TargetName="PrefixTextBlock" Property="Text" Value="[+] "/>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter Property="Background" Value="{DynamicResource ButtonBackgroundMouseoverColor}"/>
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
|
||||||
<!-- TextBlock template -->
|
<!-- TextBlock template -->
|
||||||
<Style TargetType="TextBlock">
|
<Style TargetType="TextBlock">
|
||||||
@ -298,6 +337,103 @@
|
|||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="ToggleButtonStyle" TargetType="ToggleButton">
|
||||||
|
<Setter Property="Margin" Value="{DynamicResource ButtonMargin}"/>
|
||||||
|
<Setter Property="Foreground" Value="{DynamicResource ButtonForegroundColor}"/>
|
||||||
|
<Setter Property="Background" Value="{DynamicResource ButtonBackgroundColor}"/>
|
||||||
|
<Setter Property="Height" Value="{DynamicResource ButtonHeight}"/>
|
||||||
|
<Setter Property="Width" Value="{DynamicResource ButtonWidth}"/>
|
||||||
|
<Setter Property="FontSize" Value="{DynamicResource ButtonFontSize}"/>
|
||||||
|
<Setter Property="FontFamily" Value="{DynamicResource FontFamily}"/>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="ToggleButton">
|
||||||
|
<Grid>
|
||||||
|
<Border x:Name="BackgroundBorder"
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
BorderThickness="{DynamicResource ButtonBorderThickness}"
|
||||||
|
CornerRadius="{DynamicResource ButtonCornerRadius}">
|
||||||
|
<Grid>
|
||||||
|
<!-- Toggle Dot Background -->
|
||||||
|
<Ellipse Width="8" Height="16"
|
||||||
|
Fill="{DynamicResource ToggleButtonOnColor}"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="0,3,5,0" />
|
||||||
|
|
||||||
|
<!-- Toggle Dot with hover grow effect -->
|
||||||
|
<Ellipse x:Name="ToggleDot"
|
||||||
|
Width="8" Height="8"
|
||||||
|
Fill="{DynamicResource ButtonForegroundColor}"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="0,3,5,0"
|
||||||
|
RenderTransformOrigin="0.5,0.5">
|
||||||
|
<Ellipse.RenderTransform>
|
||||||
|
<ScaleTransform ScaleX="1" ScaleY="1"/>
|
||||||
|
</Ellipse.RenderTransform>
|
||||||
|
</Ellipse>
|
||||||
|
|
||||||
|
<!-- Content Presenter -->
|
||||||
|
<ContentPresenter HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="10,2,10,2"/>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Triggers for ToggleButton states -->
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<!-- Hover effect -->
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter TargetName="BackgroundBorder" Property="Background" Value="{DynamicResource ButtonBackgroundMouseoverColor}"/>
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<!-- Animation to grow the dot when hovered -->
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ToggleDot"
|
||||||
|
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
|
||||||
|
To="1.2" Duration="0:0:0.1"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ToggleDot"
|
||||||
|
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
|
||||||
|
To="1.2" Duration="0:0:0.1"/>
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<!-- Animation to shrink the dot back to original size when not hovered -->
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ToggleDot"
|
||||||
|
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
|
||||||
|
To="1.0" Duration="0:0:0.1"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ToggleDot"
|
||||||
|
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
|
||||||
|
To="1.0" Duration="0:0:0.1"/>
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
|
</Trigger>
|
||||||
|
|
||||||
|
<!-- IsChecked state -->
|
||||||
|
<Trigger Property="IsChecked" Value="True">
|
||||||
|
<Setter TargetName="ToggleDot" Property="VerticalAlignment" Value="Bottom"/>
|
||||||
|
<Setter TargetName="ToggleDot" Property="Margin" Value="0,0,5,3"/>
|
||||||
|
</Trigger>
|
||||||
|
|
||||||
|
<!-- IsEnabled state -->
|
||||||
|
<Trigger Property="IsEnabled" Value="False">
|
||||||
|
<Setter TargetName="BackgroundBorder" Property="Background" Value="{DynamicResource ButtonBackgroundSelectedColor}"/>
|
||||||
|
<Setter Property="Foreground" Value="DimGray"/>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
<Style x:Key="SearchBarClearButtonStyle" TargetType="Button">
|
<Style x:Key="SearchBarClearButtonStyle" TargetType="Button">
|
||||||
<Setter Property="FontFamily" Value="{DynamicResource FontFamily}"/>
|
<Setter Property="FontFamily" Value="{DynamicResource FontFamily}"/>
|
||||||
<Setter Property="FontSize" Value="{DynamicResource SearchBarClearButtonFontSize}"/>
|
<Setter Property="FontSize" Value="{DynamicResource SearchBarClearButtonFontSize}"/>
|
||||||
@ -366,6 +502,19 @@
|
|||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
|
<!-- Collapsed Checkbox Style -->
|
||||||
|
<Style x:Key="CollapsedCheckBoxStyle" TargetType="CheckBox">
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="CheckBox">
|
||||||
|
<ContentPresenter Content="{TemplateBinding Content}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Margin="{TemplateBinding Padding}"/>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
<Style TargetType="RadioButton">
|
<Style TargetType="RadioButton">
|
||||||
<Setter Property="Foreground" Value="{DynamicResource MainForegroundColor}"/>
|
<Setter Property="Foreground" Value="{DynamicResource MainForegroundColor}"/>
|
||||||
<Setter Property="Background" Value="{DynamicResource MainBackgroundColor}"/>
|
<Setter Property="Background" Value="{DynamicResource MainBackgroundColor}"/>
|
||||||
@ -864,7 +1013,6 @@
|
|||||||
</Border>
|
</Border>
|
||||||
</Popup>
|
</Popup>
|
||||||
|
|
||||||
|
|
||||||
<Button Name="SettingsButton"
|
<Button Name="SettingsButton"
|
||||||
Style="{StaticResource HoverButtonStyle}"
|
Style="{StaticResource HoverButtonStyle}"
|
||||||
Grid.Column="3" BorderBrush="Transparent"
|
Grid.Column="3" BorderBrush="Transparent"
|
||||||
@ -917,29 +1065,18 @@
|
|||||||
<TabItem Header="Install" Visibility="Collapsed" Name="WPFTab1">
|
<TabItem Header="Install" Visibility="Collapsed" Name="WPFTab1">
|
||||||
<Grid Background="Transparent" >
|
<Grid Background="Transparent" >
|
||||||
|
|
||||||
<Grid.RowDefinitions>
|
<Grid Grid.Row="0" Grid.Column="0" Margin="{DynamicResource TabContentMargin}">
|
||||||
<RowDefinition Height="45px"/>
|
<Grid.ColumnDefinitions>
|
||||||
<RowDefinition Height="0.95*"/>
|
<ColumnDefinition Width="225" />
|
||||||
</Grid.RowDefinitions>
|
<ColumnDefinition Width="*" />
|
||||||
<StackPanel Background="{DynamicResource MainBackgroundColor}" Orientation="Horizontal" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Column="0" Grid.ColumnSpan="3" Margin="{DynamicResource TabContentMargin}">
|
</Grid.ColumnDefinitions>
|
||||||
<Button Name="WPFInstall" Content=" Install/Upgrade Selected" Margin="2" />
|
|
||||||
<Button Name="WPFInstallUpgrade" Content=" Upgrade All" Margin="2"/>
|
|
||||||
<Button Name="WPFUninstall" Content=" Uninstall Selected" Margin="2"/>
|
|
||||||
<Button Name="WPFGetInstalled" Content=" Get Installed" Margin="2"/>
|
|
||||||
<Button Name="WPFClearInstallSelection" Content=" Clear Selection" Margin="2"/>
|
|
||||||
<CheckBox Name="WPFpreferChocolatey" VerticalAlignment="Center" VerticalContentAlignment="Center">
|
|
||||||
<TextBlock Text="Prefer Chocolatey" ToolTip="Prefers Chocolatey as Download Engine instead of Winget" VerticalAlignment="Center" />
|
|
||||||
</CheckBox>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<ScrollViewer x:Name="scrollViewer" Grid.Row="1" Grid.Column="0" Margin="{DynamicResource TabContentMargin}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
|
<Grid Name="appscategory" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||||
BorderBrush="Transparent" BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
|
||||||
<Grid Name="appspanel" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
|
||||||
|
|
||||||
<Rectangle Grid.Row="1" Grid.Column="0" Width="22" Height="22" Fill="{DynamicResource MainBackgroundColor}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Style="{StaticResource ScrollVisibilityRectangle}"/>
|
|
||||||
|
|
||||||
|
<Grid Name="appspanel" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
<TabItem Header="Tweaks" Visibility="Collapsed" Name="WPFTab2">
|
<TabItem Header="Tweaks" Visibility="Collapsed" Name="WPFTab2">
|
||||||
|
Reference in New Issue
Block a user