Decoupled UI and data (#4051)

* Decoupled UI and data

* Fix bad variable naming

* Fix mistype

* Fix mistype v2

Editing from mobile is hard
This commit is contained in:
KamaleiZestri
2026-02-17 12:39:44 -06:00
committed by GitHub
parent 0e41122d89
commit 70a94abe02
14 changed files with 276 additions and 189 deletions

View File

@@ -12,7 +12,7 @@ function Invoke-WPFFeatureInstall {
return
}
$Features = (Get-WinUtilCheckBoxes)["WPFFeature"]
$Features = $sync.selectedFeatures
Invoke-WPFRunspace -ArgumentList $Features -DebugPreference $DebugPreference -ScriptBlock {
param($Features, $DebugPreference)

View File

@@ -44,7 +44,8 @@ function Invoke-WPFImpex {
try {
$Config = ConfigDialog
if ($Config) {
$jsonFile = Get-WinUtilCheckBoxes -unCheck $false | ConvertTo-Json
$allConfs = $sync.selectedApps + $sync.selectedTweaks + $sync.selectedToggles + $sync.selectedFeatures
$jsonFile = $allConfs | ConvertTo-Json
$jsonFile | Out-File $Config -Force
"iex ""& { `$(irm https://christitus.com/win) } -Config '$Config'""" | Set-Clipboard
}
@@ -66,21 +67,12 @@ function Invoke-WPFImpex {
Write-Error "Failed to load the JSON file from the specified path or URL: $_"
return
}
$flattenedJson = $jsonFile.PSObject.Properties.Where({ $_.Name -ne "Install" -and $_.Name -ne "WPFToggle" }).ForEach({ $_.Value })
Invoke-WPFPresets -preset $flattenedJson -imported $true
# Restore toggle switch states
$importedToggles = if ($jsonFile.WPFToggle) { $jsonFile.WPFToggle } else { @() }
$allToggles = $sync.GetEnumerator() | Where-Object { $_.Key -like "WPFToggle*" -and $_.Value -is [System.Windows.Controls.CheckBox] }
foreach ($toggle in $allToggles) {
if ($importedToggles -contains $toggle.Key) {
$sync[$toggle.Key].IsChecked = $true
Write-Debug "Restoring toggle: $($toggle.Key) = checked"
} else {
$sync[$toggle.Key].IsChecked = $false
Write-Debug "Restoring toggle: $($toggle.Key) = unchecked"
}
}
# TODO how to handle old style? detected json type then flatten it in a func?
# $flattenedJson = $jsonFile.PSObject.Properties.Where({ $_.Name -ne "Install" }).ForEach({ $_.Value })
$flattenedJson = $jsonFile
Update-WinUtilSelections -flatJson $flattenedJson
# TODO test with toggles
Reset-WPFCheckBoxes -doToggles $true
}
} catch {
Write-Error "An error occurred while importing: $_"

View File

@@ -2,10 +2,10 @@ function Invoke-WPFPresets {
<#
.SYNOPSIS
Sets the options in the tweaks panel to the given preset
Sets the checkboxes in winutil to the given preset
.PARAMETER preset
The preset to set the options to
The preset to set the checkboxes to
.PARAMETER imported
If the preset is imported from a file, defaults to false
@@ -17,7 +17,7 @@ function Invoke-WPFPresets {
param (
[Parameter(position=0)]
[Array]$preset = "",
[Array]$preset = $null,
[Parameter(position=1)]
[bool]$imported = $false,
@@ -32,33 +32,19 @@ function Invoke-WPFPresets {
$CheckBoxesToCheck = $sync.configs.preset.$preset
}
$CheckBoxes = ($sync.GetEnumerator()).where{ $_.Value -is [System.Windows.Controls.CheckBox] -and $_.Name -notlike "WPFToggle*" -and $_.Name -like "$checkboxfilterpattern"}
Write-Debug "Getting checkboxes to set, number of checkboxes: $($CheckBoxes.Count)"
if ($CheckBoxesToCheck -ne "") {
$debugMsg = "CheckBoxes to Check are: "
$CheckBoxesToCheck | ForEach-Object { $debugMsg += "$_, " }
$debugMsg = $debugMsg -replace (',\s*$', '')
Write-Debug "$debugMsg"
}
foreach ($CheckBox in $CheckBoxes) {
$checkboxName = $CheckBox.Key
if (-not $CheckBoxesToCheck) {
$sync.$checkboxName.IsChecked = $false
continue
}
# Check if the checkbox name exists in the flattened JSON hashtable
if ($CheckBoxesToCheck -contains $checkboxName) {
# If it exists, set IsChecked to true
$sync.$checkboxName.IsChecked = $true
Write-Debug "$checkboxName is checked"
} else {
# If it doesn't exist, set IsChecked to false
$sync.$checkboxName.IsChecked = $false
Write-Debug "$checkboxName is not checked"
# clear out the filtered pattern
if (!$preset) {
switch ($checkboxfilterpattern) {
"WPFTweak*" { $sync.selectedTweaks = [System.Collections.Generic.List[string]]::new() }
"WPFInstall*" { $sync.selectedApps = [System.Collections.Generic.List[string]]::new() }
"WPFeatures" { $sync.selectedFeatures = [System.Collections.Generic.List[string]]::new() }
"WPFToggle" { $sync.selectedToggles = [System.Collections.Generic.List[string]]::new() }
default {}
}
}
else {
Update-WinUtilSelections -flatJson $CheckBoxesToCheck
}
Reset-WPFCheckBoxes -doToggles $false -checkboxfilterpattern $checkboxfilterpattern
}

View File

@@ -1,43 +0,0 @@
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.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 $_ }
}

View File

@@ -0,0 +1,95 @@
function Invoke-WPFSelectedCheckboxesUpdate{
<#
.SYNOPSIS
This is a helper function that is called by the Checked and Unchecked events of the Checkboxes.
It also Updates the "Selected Apps" selectedAppLabel on the Install Tab to represent the current collection
.PARAMETER type
Either: Add | Remove
.PARAMETER checkboxName
should contain the name of the current instance of the checkbox that triggered the Event.
Most of the time will be the automatic variable $this.Parent.Tag
.EXAMPLE
$checkbox.Add_Unchecked({Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkboxName $this.Parent.Tag})
OR
Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $specificCheckbox.Parent.Tag
#>
param (
$type,
$checkboxName
)
if (($type -ne "Add") -and ($type -ne "Remove"))
{
Write-Error "Type: $type not implemented"
return
}
# Get the actual Name from the selectedAppLabel inside the Checkbox
$appKey = $checkboxName
$group = if ($appKey.StartsWith("WPFInstall")) { "Install" }
elseif ($appKey.StartsWith("WPFTweaks")) { "Tweaks" }
elseif ($appKey.StartsWith("WPFToggle")) { "Toggle" }
elseif ($appKey.StartsWith("WPFFeature")) { "Feature" }
else { "na" }
switch ($group) {
"Install" {
if ($type -eq "Add") {
if (!$sync.selectedApps.Contains($appKey)) {
$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
}
}
else{
$sync.selectedApps.Remove($appKey)
}
$count = $sync.SelectedApps.Count
$sync.WPFselectedAppsButton.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 $_ }
}
"Tweaks" {
if ($type -eq "Add") {
if (!$sync.selectedTweaks.Contains($appKey)) {
$sync.selectedTweaks.Add($appKey)
}
}
else{
$sync.selectedTweaks.Remove($appKey)
}
}
"Toggle" {
if ($type -eq "Add") {
if (!$sync.selectedToggles.Contains($appKey)) {
$sync.selectedToggles.Add($appKey)
}
}
else{
$sync.selectedToggles.Remove($appKey)
}
}
"Feature" {
if ($type -eq "Add") {
if (!$sync.selectedFeatures.Contains($appKey)) {
$sync.selectedFeatures.Add($appKey)
}
}
else{
$sync.selectedFeatures.Remove($appKey)
}
}
default {
Write-Host "Unknown group for checkbox: $($appKey)"
}
}
Write-Debug "-------------------------------------"
Write-Debug "Selected Apps: $($sync.selectedApps)"
Write-Debug "Selected Tweaks: $($sync.selectedTweaks)"
Write-Debug "Selected Toggles: $($sync.selectedToggles)"
Write-Debug "Selected Features: $($sync.selectedFeatures)"
Write-Debug "--------------------------------------"
}

View File

@@ -181,12 +181,14 @@ function Invoke-WPFUIElements {
$sync[$entryInfo.Name].Add_Checked({
[System.Object]$Sender = $args[0]
Invoke-WinUtilTweaks $sender.name
Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $Sender.name
Invoke-WinUtilTweaks $Sender.name
})
$sync[$entryInfo.Name].Add_Unchecked({
[System.Object]$Sender = $args[0]
Invoke-WinUtiltweaks $sender.name -undo $true
Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkboxName $Sender.name
Invoke-WinUtiltweaks $Sender.name -undo $true
})
}
@@ -355,6 +357,16 @@ function Invoke-WPFUIElements {
$itemsControl.Items.Add($horizontalStackPanel) | Out-Null
$sync[$entryInfo.Name] = $checkBox
$sync[$entryInfo.Name].Add_Checked({
[System.Object]$Sender = $args[0]
Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $Sender.name
})
$sync[$entryInfo.Name].Add_Unchecked({
[System.Object]$Sender = $args[0]
Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkbox $Sender.name
})
}
}
}

View File

@@ -12,7 +12,7 @@ function Invoke-WPFtweaksbutton {
return
}
$Tweaks = (Get-WinUtilCheckBoxes)["WPFTweaks"]
$Tweaks = $sync.selectedTweaks
Set-WinUtilDNS -DNSProvider $sync["WPFchangedns"].text

View File

@@ -12,7 +12,7 @@ function Invoke-WPFundoall {
return
}
$tweaks = (Get-WinUtilCheckBoxes)["WPFtweaks"]
$tweaks = $sync.selectedTweaks
if ($tweaks.count -eq 0) {
$msg = "Please check the tweaks you wish to undo."