From c741e006eb21a60a4560327208b0c0cc87896073 Mon Sep 17 00:00:00 2001 From: MyDrift Date: Wed, 28 Aug 2024 18:13:23 +0200 Subject: [PATCH] [Refactoring UI Code] WIP: Inline UI Definition instead of xaml compilation (#2629) * try1: apps panel * refractor - removed Get-TabXaml.ps1 - removed compilation part from compile.ps1 - removed existing changes from main.ps1 - added Invoke-WinUtilUIElements.ps1 - refractor existing changes into new function - modified inputXML to call function * removed unused replacementlogics * fix toggle style * move naming from winutil to wpf * hotfixes - reworked function calling - working on correct theming support * hotfix * hotfix fix missing elements fix var naming * some fixes * hotfixes * add image logic * fix ? issue in search * filter out unneeded categories * cleanup * fix border styling * fixes * preprocessing * fix typo * last fixes & add notes * Update functions/public/Invoke-WPFUIElements.ps1 Co-authored-by: Mr.k * fix margin * fix tabcontent margin * fix some other margin issues * move fixed values outside of iterations * little fix * add Dispatcher.Invoke * add error handling for styles * Update functions/public/Invoke-WPFUIElements.ps1 Co-authored-by: Mr.k * remove dispatcher * fix search * move run & undo tweaks to be fixed * add error handling * fix throw exception * fixed accidental removal of findname grid call * add padding & margin to make search look good * remove grid to make it look correctly on small window * fix rectangle * Compiler Improvements for PR #2465 (#7) * Remove the Special Character Escaping for Json Files as there's no need for it anymore * Simplify 'application.json' Json Prefix Addition in 'Compile.ps1' Script Thanks to @fam007e for improving this section in his PR #2587 changes Co-authored-by: fam007e --------- Co-authored-by: fam007e * fix margin of search clear * fix cursor on clear search button * undo fixed run & undo * refractor themes.json * undo themes.json --------- Co-authored-by: Mr.k Co-authored-by: fam007e Co-authored-by: Chris Titus --- Compile.ps1 | 41 +-- functions/private/Get-TabXaml.ps1 | 221 --------------- functions/public/Invoke-WPFUIElements.ps1 | 325 ++++++++++++++++++++++ scripts/main.ps1 | 36 ++- xaml/inputXML.xaml | 105 +++---- 5 files changed, 401 insertions(+), 327 deletions(-) delete mode 100644 functions/private/Get-TabXaml.ps1 create mode 100644 functions/public/Invoke-WPFUIElements.ps1 diff --git a/Compile.ps1 b/Compile.ps1 index f86fbce6..6f7a0313 100644 --- a/Compile.ps1 +++ b/Compile.ps1 @@ -64,38 +64,14 @@ Get-ChildItem "$workingdir\functions" -Recurse -File | ForEach-Object { } Update-Progress "Adding: Config *.json" 40 Get-ChildItem "$workingdir\config" | Where-Object {$psitem.extension -eq ".json"} | ForEach-Object { - $json = (Get-Content $psitem.FullName).replace("'","''") - - # Replace every XML Special Character so it'll render correctly in final build - # Only do so if json files has content to be displayed (for example the applications, tweaks, features json files) - # Make an Array List containing every name at first level of Json File - $jsonAsObject = $json | convertfrom-json - $firstLevelJsonList = [System.Collections.ArrayList]::new() - $jsonAsObject.PSObject.Properties.Name | ForEach-Object {$null = $firstLevelJsonList.Add($_)} - # Note: - # Avoid using HTML Entity Codes, for example '”' (stands for "Right Double Quotation Mark"), - # Use **HTML decimal/hex codes instead**, as using HTML Entity Codes will result in XML parse Error when running the compiled script. - for ($i = 0; $i -lt $firstLevelJsonList.Count; $i += 1) { - $firstLevelName = $firstLevelJsonList[$i] - if ($jsonAsObject.$firstLevelName.content -ne $null) { - $jsonAsObject.$firstLevelName.content = $jsonAsObject.$firstLevelName.content.replace('&','&').replace('“','“').replace('”','”').replace("'",''').replace('<','<').replace('>','>').replace('—','—') - $jsonAsObject.$firstLevelName.content = $jsonAsObject.$firstLevelName.content.replace('''',"'") # resolves the Double Apostrophe caused by the first replace function in the main loop - } - if ($jsonAsObject.$firstLevelName.description -ne $null) { - $jsonAsObject.$firstLevelName.description = $jsonAsObject.$firstLevelName.description.replace('&','&').replace('“','“').replace('”','”').replace("'",''').replace('<','<').replace('>','>').replace('—','—') - $jsonAsObject.$firstLevelName.description = $jsonAsObject.$firstLevelName.description.replace('''',"'") # resolves the Double Apostrophe caused by the first replace function in the main loop - } - } + $jsonAsObject = $json | convertfrom-json # Add 'WPFInstall' as a prefix to every entry-name in 'applications.json' file if ($psitem.Name -eq "applications.json") { - for ($i = 0; $i -lt $firstLevelJsonList.Count; $i += 1) { - $appEntryName = $firstLevelJsonList[$i] + foreach ($appEntryName in $jsonAsObject.PSObject.Properties.Name) { $appEntryContent = $jsonAsObject.$appEntryName - # Remove the entire app entry, so we could add it later with a different name $jsonAsObject.PSObject.Properties.Remove($appEntryName) - # Add the app entry, but with a different name (WPFInstall + The App Entry Name) $jsonAsObject | Add-Member -MemberType NoteProperty -Name "WPFInstall$appEntryName" -Value $appEntryContent } } @@ -110,20 +86,7 @@ Get-ChildItem "$workingdir\config" | Where-Object {$psitem.extension -eq ".json" $xaml = (Get-Content "$workingdir\xaml\inputXML.xaml").replace("'","''") -# Dot-source the Get-TabXaml function -. "$workingdir\functions\private\Get-TabXaml.ps1" - -Update-Progress "Building: Xaml " 75 -$appXamlContent = Get-TabXaml "applications" 5 -$tweaksXamlContent = Get-TabXaml "tweaks" -$featuresXamlContent = Get-TabXaml "feature" - - Update-Progress "Adding: Xaml " 90 -# Replace the placeholder in $inputXML with the content of inputApp.xaml -$xaml = $xaml -replace "{{InstallPanel_applications}}", $appXamlContent -$xaml = $xaml -replace "{{InstallPanel_tweaks}}", $tweaksXamlContent -$xaml = $xaml -replace "{{InstallPanel_features}}", $featuresXamlContent $script_content.Add($(Write-output "`$inputXML = '$xaml'")) diff --git a/functions/private/Get-TabXaml.ps1 b/functions/private/Get-TabXaml.ps1 deleted file mode 100644 index 5eef6417..00000000 --- a/functions/private/Get-TabXaml.ps1 +++ /dev/null @@ -1,221 +0,0 @@ -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" - $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" - } - - "Combobox" { - $blockXml += $precal_indent_m1 + - "" + "`r`n" - $blockXml += $precal_indent + "" + "`r`n" - } - - "Button" { - if ($appInfo.ButtonWidth -ne $null) { - $ButtonWidthStr = "Width=""$($appInfo.ButtonWidth)""" - } - $blockXml += $precal_indent + - "