function Get-TabXaml {
<#
.SYNOPSIS
Generates XAML for a tab in the WinUtil GUI
This function is used to generate the XAML for the applications tab in the WinUtil GUI
It takes the tabname and the number of columns to display the applications in as input and returns the XAML for the tab as output
.PARAMETER tabname
The name of the tab to generate XAML for
Note: the 'tabname' parameter must equal one of the json files found in $sync.configs variable
Otherwise, it'll throw an exception
.PARAMETER columncount
The number of columns to display the applications in, default is 0
.OUTPUTS
The XAML for the tab
.EXAMPLE
Get-TabXaml "applications" 3
#>
param(
[Parameter(Mandatory, position=0)]
[string]$tabname,
[Parameter(position=1)]
[ValidateRange(0,10)] # 10 panels as max number is more then enough
[int]$columncount = 0
)
# Validate tabname
if ($sync.configs.$tabname -eq $null) {
throw "Invalid parameter passed, can't find '$tabname' in '`$sync.configs' variable, please double check any calls to 'Get-TabXaml' function."
}
$organizedData = @{}
# Iterate through JSON data and organize by panel and category
foreach ($appName in $sync.configs.$tabname.PSObject.Properties.Name) {
$appInfo = $sync.configs.$tabname.$appName
# Create an object for the application
$appObject = [PSCustomObject]@{
Name = $appName
Category = $appInfo.Category
Content = $appInfo.Content
Choco = $appInfo.choco
Winget = $appInfo.winget
Panel = if ($columncount -gt 0 ) { "0" } else {$appInfo.panel}
Link = $appInfo.link
Description = $appInfo.description
# Type is (Checkbox,Toggle,Button,Combobox ) (Default is Checkbox)
Type = $appInfo.type
ComboItems = $appInfo.ComboItems
# Checked is the property to set startup checked status of checkbox (Default is false)
Checked = $appInfo.Checked
ButtonWidth = $appInfo.ButtonWidth
}
if (-not $organizedData.ContainsKey($appObject.panel)) {
$organizedData[$appObject.panel] = @{}
}
if (-not $organizedData[$appObject.panel].ContainsKey($appObject.Category)) {
$organizedData[$appObject.panel][$appObject.Category] = @{}
}
# Store application data in a sub-array under the category
# Add Order property to keep the original order of tweaks and features
$organizedData[$appObject.panel][$appInfo.Category]["$($appInfo.order)$appName"] = $appObject
}
# Same tab amount in last line of 'inputXML.xaml' file
# TODO: Get the base repeat (amount) of tabs from last line (or even lines)
# so it can dynamicly react to whatever is before this generated XML string.
# .. may be solve this even before calling this function, and pass the result as a parameter?
$tab_repeat = 7
$spaces_per_tab = 4 # The convenction used across the code base
$tab_as_spaces = $(" " * $spaces_per_tab)
$precal_indent = $($tab_as_spaces * $tab_repeat)
$precal_indent_p1 = $($tab_as_spaces * ($tab_repeat + 1))
$precal_indent_p2 = $($tab_as_spaces * ($tab_repeat + 2))
$precal_indent_m1 = $($tab_as_spaces * ($tab_repeat - 1))
$precal_indent_m2 = $($tab_as_spaces * ($tab_repeat - 2))
# Calculate the needed number of panels
$panelcount = 0
$paneltotal = $organizedData.Keys.Count
if ($columncount -gt 0) {
$appcount = $sync.configs.$tabname.PSObject.Properties.Name.count + $organizedData["0"].Keys.count
$maxcount = [Math]::Round( $appcount / $columncount + 0.5)
$paneltotal = $columncount
}
# add ColumnDefinitions to evenly draw colums
$blockXml = ""
$blockXml += $("`r`n" + " " * ($spaces_per_tab * $tab_repeat) +
"") * $paneltotal
$blockXml += $("`r`n" + " " * ($spaces_per_tab * ($tab_repeat - 1))) +
"" + "`r`n"
# Iterate through 'organizedData' by panel, category, and application
$count = 0
foreach ($panel in ($organizedData.Keys | Sort-Object)) {
$blockXml += $precal_indent_m1 + "" + "`r`n"
$blockXml += $precal_indent + "" + "`r`n"
$panelcount++
foreach ($category in ($organizedData[$panel].Keys | Sort-Object)) {
$count++
if ($columncount -gt 0) {
$panelcount2 = [Int](($count)/$maxcount-0.5)
if ($panelcount -eq $panelcount2 ) {
$blockXml += $precal_indent_p2 + "" + "`r`n"
$blockXml += $precal_indent_p1 + "" + "`r`n"
$blockXml += $precal_indent_p1 + "" + "`r`n"
$blockXml += $precal_indent_p2 + "" + "`r`n"
$panelcount++
}
}
# Dot-source the Get-WPFObjectName function
. "$($sync.PSScriptRoot)\functions\private\Get-WPFObjectName.ps1"
$categorycontent = $($category -replace '^.__', '')
$categoryname = Get-WPFObjectName -type "Label" -name $categorycontent
$blockXml += $("`r`n" + " " * ($spaces_per_tab * $tab_repeat)) +
"" + "`r`n" + "`r`n"
$sortedApps = $organizedData[$panel][$category].Keys | Sort-Object
foreach ($appName in $sortedApps) {
$count++
if ($columncount -gt 0) {
$panelcount2 = [Int](($count)/$maxcount-0.5)
# Verify the indentation actually works...
if ($panelcount -eq $panelcount2 ) {
$blockXml += $precal_indent_m1 +
"" + "`r`n"
$blockXml += $precal_indent_m2 +
"" + "`r`n"
$blockXml += $precal_indent_m2 +
"" + "`r`n"
$blockXml += $precal_indent_m1 +
"" + "`r`n"
$panelcount++
}
}
$appInfo = $organizedData[$panel][$category][$appName]
switch ($appInfo.Type) {
"Toggle" {
$blockXml += $precal_indent_m1 +
"" + "`r`n"
$blockXml += $precal_indent +
"" + "`r`n"
$blockXml += $precal_indent +
"" + "`r`n"
$blockXml += $precal_indent_m1 +
"" + "`r`n"
}
"Combobox" {
$blockXml += $precal_indent_m1 +
"" + "`r`n"
$blockXml += $precal_indent + "" + "`r`n"
$blockXml += $precal_indent +
"" + "`r`n"
$addfirst="IsSelected=""True"""
foreach ($comboitem in ($appInfo.ComboItems -split " ")) {
$blockXml += $precal_indent_p1 +
"" + "`r`n"
$addfirst=""
}
$blockXml += $precal_indent_p1 + "" + "`r`n"
$blockXml += $precal_indent + "" + "`r`n"
}
"Button" {
if ($appInfo.ButtonWidth -ne $null) {
$ButtonWidthStr = "Width=""$($appInfo.ButtonWidth)"""
}
$blockXml += $precal_indent +
"" + "`r`n"
}
# else it is a checkbox
default {
$checkedStatus = If ($appInfo.Checked -eq $null) {""} else {" IsChecked=""$($appInfo.Checked)"""}
if ($appInfo.Link -eq $null) {
$blockXml += $precal_indent +
"" + "`r`n"
} else {
$blockXml += $precal_indent +
"" + "`r`n"
$blockXml += $precal_indent_p1 +
"" + "`r`n"
$blockXml += $precal_indent_p1 +
"" + "`r`n"
$blockXml += $precal_indent +
"" + "`r`n"
}
}
}
}
}
$blockXml += $precal_indent_p1 + "" + "`r`n"
$blockXml += $precal_indent + "" + "`r`n"
}
return ($blockXml)
}