winutil/functions/public/Invoke-WPFUIElements.ps1

326 lines
15 KiB
PowerShell
Raw Normal View History

2024-08-09 12:40:14 -05:00
function Invoke-WPFUIElements {
<#
.SYNOPSIS
Adds UI elements to a specified Grid in the WinUtil GUI based on a JSON configuration.
.PARAMETER configVariable
The variable/link containing the JSON configuration.
.PARAMETER targetGridName
The name of the grid to which the UI elements should be added.
.PARAMETER columncount
The number of columns to be used in the Grid. If not provided, a default value is used based on the panel.
.EXAMPLE
2024-08-09 16:39:01 -05:00
Invoke-WPFUIElements -configVariable $sync.configs.applications -targetGridName "install" -columncount 5
2024-08-19 15:46:12 -05:00
.NOTES
Future me/contributer: If possible please wrap this into a runspace to make it load all panels at the same time.
#>
param(
[Parameter(Mandatory, position=0)]
[PSCustomObject]$configVariable,
[Parameter(Mandatory, position=1)]
[string]$targetGridName,
[Parameter(Mandatory, position=2)]
[int]$columncount
2024-08-19 06:40:24 -05:00
)
$window = $sync["Form"]
$theme = $sync.configs.themes.$ctttheme
$borderstyle = $window.FindResource("BorderStyle")
$HoverTextBlockStyle = $window.FindResource("HoverTextBlockStyle")
$ColorfulToggleSwitchStyle = $window.FindResource("ColorfulToggleSwitchStyle")
2024-08-22 11:56:12 -05:00
2024-08-20 14:32:16 -05:00
if (!$borderstyle -or !$HoverTextBlockStyle -or !$ColorfulToggleSwitchStyle) {
throw "Failed to retrieve Styles using 'FindResource' from main window element."
}
$targetGrid = $window.FindName($targetGridName)
2024-08-22 14:18:51 -05:00
if (!$targetGrid) {
throw "Failed to retrieve Target Grid by name, provided name: $targetGrid"
2024-08-22 12:35:02 -05:00
}
# Clear existing ColumnDefinitions and Children
$targetGrid.ColumnDefinitions.Clear() | Out-Null
$targetGrid.Children.Clear() | Out-Null
# Add ColumnDefinitions to the target Grid
for ($i = 0; $i -lt $columncount; $i++) {
$colDef = New-Object Windows.Controls.ColumnDefinition
$colDef.Width = New-Object Windows.GridLength(1, [Windows.GridUnitType]::Star)
$targetGrid.ColumnDefinitions.Add($colDef) | Out-Null
}
# Convert PSCustomObject to Hashtable
$configHashtable = @{}
$configVariable.PSObject.Properties.Name | ForEach-Object {
$configHashtable[$_] = $configVariable.$_
}
$organizedData = @{}
# Iterate through JSON data and organize by panel and category
foreach ($entry in $configHashtable.Keys) {
2024-08-09 16:39:01 -05:00
$entryInfo = $configHashtable[$entry]
# Create an object for the application
2024-08-09 16:39:01 -05:00
$entryObject = [PSCustomObject]@{
2024-08-11 07:06:46 -05:00
Name = $entry
2024-08-11 11:23:05 -05:00
Order = $entryInfo.order
2024-08-09 16:39:01 -05:00
Category = $entryInfo.Category
Content = $entryInfo.Content
Choco = $entryInfo.choco
Winget = $entryInfo.winget
2024-08-15 16:53:05 -05:00
Panel = if ($entryInfo.Panel) { $entryInfo.Panel } else { "0" }
2024-08-09 16:39:01 -05:00
Link = $entryInfo.link
Description = $entryInfo.description
Type = $entryInfo.type
ComboItems = $entryInfo.ComboItems
Checked = $entryInfo.Checked
ButtonWidth = $entryInfo.ButtonWidth
}
2024-08-09 16:39:01 -05:00
if (-not $organizedData.ContainsKey($entryObject.Panel)) {
$organizedData[$entryObject.Panel] = @{}
}
2024-08-09 16:39:01 -05:00
if (-not $organizedData[$entryObject.Panel].ContainsKey($entryObject.Category)) {
2024-08-11 11:23:05 -05:00
$organizedData[$entryObject.Panel][$entryObject.Category] = @()
}
2024-08-11 11:23:05 -05:00
# Store application data in an array under the category
$organizedData[$entryObject.Panel][$entryObject.Category] += $entryObject
2024-08-20 13:53:00 -05:00
# Only apply the logic for distributing entries across columns if the targetGridName is "appspanel"
if ($targetGridName -eq "appspanel") {
$panelcount = 0
$entrycount = $configHashtable.Keys.Count + $organizedData["0"].Keys.Count
$maxcount = [Math]::Round($entrycount / $columncount + 0.5)
}
}
# Iterate through 'organizedData' by panel, category, and application
$count = 0
foreach ($panelKey in ($organizedData.Keys | Sort-Object)) {
# Create a Border for each 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 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++
foreach ($category in ($organizedData[$panelKey].Keys | Sort-Object)) {
$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.Content = $category -replace ".*__", ""
$label.FontSize = $theme.FontSizeHeading
$label.FontFamily = $theme.HeaderFontFamily
$stackPanel.Children.Add($label) | Out-Null
2024-08-15 14:52:43 -05:00
$sync[$category] = $label
2024-08-11 11:23:05 -05:00
# Sort entries by Order and then by Name, but only display Name
$entries = $organizedData[$panelKey][$category] | Sort-Object Order, Name
foreach ($entryInfo in $entries) {
$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++
}
}
2024-08-09 16:39:01 -05:00
switch ($entryInfo.Type) {
"Toggle" {
$dockPanel = New-Object Windows.Controls.DockPanel
$checkBox = New-Object Windows.Controls.CheckBox
2024-08-09 16:39:01 -05:00
$checkBox.Name = $entryInfo.Name
$checkBox.HorizontalAlignment = "Right"
$dockPanel.Children.Add($checkBox) | Out-Null
$checkBox.Style = $ColorfulToggleSwitchStyle
$label = New-Object Windows.Controls.Label
2024-08-09 16:39:01 -05:00
$label.Content = $entryInfo.Content
$label.ToolTip = $entryInfo.Description
$label.HorizontalAlignment = "Left"
$label.FontSize = $theme.FontSize
$dockPanel.Children.Add($label) | Out-Null
$stackPanel.Children.Add($dockPanel) | Out-Null
2024-08-11 07:06:46 -05:00
2024-08-11 11:23:05 -05:00
$sync[$entryInfo.Name] = $checkBox
2024-08-11 07:06:46 -05:00
2024-08-11 11:23:05 -05:00
$sync[$entryInfo.Name].IsChecked = Get-WinUtilToggleStatus $sync[$entryInfo.Name].Name
2024-08-11 07:06:46 -05:00
2024-08-11 11:23:05 -05:00
$sync[$entryInfo.Name].Add_Click({
2024-08-11 07:06:46 -05:00
[System.Object]$Sender = $args[0]
Invoke-WPFToggle $Sender.name
})
}
2024-08-11 11:23:05 -05:00
"ToggleButton" {
$toggleButton = New-Object Windows.Controls.ToggleButton
$toggleButton.Name = $entryInfo.Name
$toggleButton.Name = "WPFTab" + ($stackPanel.Children.Count + 1) + "BT"
$toggleButton.HorizontalAlignment = "Left"
$toggleButton.Height = $theme.TabButtonHeight
$toggleButton.Width = $theme.TabButtonWidth
$toggleButton.Background = $theme.ButtonInstallBackgroundColor
$toggleButton.Foreground = [Windows.Media.Brushes]::White
$toggleButton.FontWeight = [Windows.FontWeights]::Bold
$textBlock = New-Object Windows.Controls.TextBlock
$textBlock.FontSize = $theme.TabButtonFontSize
$textBlock.Background = [Windows.Media.Brushes]::Transparent
$textBlock.Foreground = $theme.ButtonInstallForegroundColor
$underline = New-Object Windows.Documents.Underline
$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
}
"Combobox" {
$horizontalStackPanel = New-Object Windows.Controls.StackPanel
$horizontalStackPanel.Orientation = "Horizontal"
$horizontalStackPanel.Margin = "0,5,0,0"
$label = New-Object Windows.Controls.Label
2024-08-09 16:39:01 -05:00
$label.Content = $entryInfo.Content
$label.HorizontalAlignment = "Left"
$label.VerticalAlignment = "Center"
$label.FontSize = $theme.ButtonFontSize
$horizontalStackPanel.Children.Add($label) | Out-Null
$comboBox = New-Object Windows.Controls.ComboBox
2024-08-09 16:39:01 -05:00
$comboBox.Name = $entryInfo.Name
$comboBox.Height = $theme.ButtonHeight
$comboBox.Width = $theme.ButtonWidth
$comboBox.HorizontalAlignment = "Left"
$comboBox.VerticalAlignment = "Center"
2024-08-20 13:09:39 -05:00
$comboBox.Margin = $theme.ButtonMargin
2024-08-09 16:39:01 -05:00
foreach ($comboitem in ($entryInfo.ComboItems -split " ")) {
$comboBoxItem = New-Object Windows.Controls.ComboBoxItem
$comboBoxItem.Content = $comboitem
$comboBoxItem.FontSize = $theme.ButtonFontSize
$comboBox.Items.Add($comboBoxItem) | Out-Null
}
$horizontalStackPanel.Children.Add($comboBox) | Out-Null
$stackPanel.Children.Add($horizontalStackPanel) | Out-Null
2024-08-11 07:06:46 -05:00
$comboBox.SelectedIndex = 0
2024-08-11 11:23:05 -05:00
$sync[$entryInfo.Name] = $comboBox
}
"Button" {
$button = New-Object Windows.Controls.Button
2024-08-09 16:39:01 -05:00
$button.Name = $entryInfo.Name
$button.Content = $entryInfo.Content
$button.HorizontalAlignment = "Left"
2024-08-20 13:09:39 -05:00
$button.Margin = $theme.ButtonMargin
$button.FontSize = $theme.ButtonFontSize
2024-08-15 16:53:05 -05:00
if ($entryInfo.ButtonWidth) {
2024-08-09 16:39:01 -05:00
$button.Width = $entryInfo.ButtonWidth
}
$stackPanel.Children.Add($button) | Out-Null
2024-08-11 07:06:46 -05:00
2024-08-11 11:23:05 -05:00
$sync[$entryInfo.Name] = $button
}
default {
2024-08-15 14:52:43 -05:00
$horizontalStackPanel = New-Object Windows.Controls.StackPanel
$horizontalStackPanel.Orientation = "Horizontal"
$checkBox = New-Object Windows.Controls.CheckBox
2024-08-09 16:39:01 -05:00
$checkBox.Name = $entryInfo.Name
$checkBox.Content = $entryInfo.Content
$checkBox.FontSize = $theme.FontSize
2024-08-09 16:39:01 -05:00
$checkBox.ToolTip = $entryInfo.Description
$checkBox.Margin = $theme.CheckBoxMargin
2024-08-15 16:53:05 -05:00
if ($entryInfo.Checked) {
2024-08-09 16:39:01 -05:00
$checkBox.IsChecked = $entryInfo.Checked
}
2024-08-15 14:52:43 -05:00
$horizontalStackPanel.Children.Add($checkBox) | Out-Null
2024-08-15 16:53:05 -05:00
if ($entryInfo.Link) {
$textBlock = New-Object Windows.Controls.TextBlock
2024-08-15 14:52:43 -05:00
$textBlock.Name = $checkBox.Name + "Link"
$textBlock.Text = "(?)"
2024-08-09 16:39:01 -05:00
$textBlock.ToolTip = $entryInfo.Link
$textBlock.Style = $HoverTextBlockStyle
# Add event handler for click to open link
$handler = [System.Windows.Input.MouseButtonEventHandler]{
param($sender, $e)
Start-Process $sender.ToolTip.ToString()
}
$textBlock.AddHandler([Windows.Controls.TextBlock]::MouseLeftButtonUpEvent, $handler)
$horizontalStackPanel.Children.Add($textBlock) | Out-Null
2024-08-15 14:52:43 -05:00
$sync[$textBlock.Name] = $textBlock
}
2024-08-11 07:06:46 -05:00
2024-08-15 14:52:43 -05:00
$stackPanel.Children.Add($horizontalStackPanel) | Out-Null
2024-08-11 11:23:05 -05:00
$sync[$entryInfo.Name] = $checkBox
}
}
}
}
}
}