winutil/functions/private/Show-CustomDialog.ps1
MyDrift 5059b93cd7
Better Image handling (#2665)
* enhance asset mgmt

- invoke ico directly
- invoke ico only at shortcut creation
- remove "ConvertTo-Icon" Function file

- removed image from xaml
- added stackpanel to xaml
- added functions to create viewbox with image
- added logic to add image via code to xaml & customdialog
- changed title color for customdialog

- remove webinvokes for assets from main.ps1

TODO: convert images into bitmap base64 string & add them directly into invoke-WinUtiltaskbaritem.ps1

* improve viewboxfunction

- add logo + checkmark + warning
- add params
- render on param "render"
- custom dialog logo function call fix
- main logo function call fix
- update winutiltaskbaritem to use new images

* fix sizing

- warning & checkmark sizing fix
- remove unneded comments

* fixes

- remove unneeded redundancy of "$canvas = New-Object Windows.Controls.Canvas"
- adjust empty lines
- use LimeGreen instead of Green

* fix layouting

* fixes

- use correct ctt blue color #0567ff
- remove unneeded comments
- rename Logoview to assets

* performance improvement

instead of rendering the image another time on each item switch, it caches it at the start and uses the render afterwards

* redo gray part of winutil logo

* correct gray shade

* fix coloring

* ise ico if available

---------

Co-authored-by: Chris Titus <contact@christitus.com>
2024-09-09 20:19:34 -05:00

241 lines
9.7 KiB
PowerShell

function Show-CustomDialog {
<#
.SYNOPSIS
Displays a custom dialog box with an image, heading, message, and an OK button.
.DESCRIPTION
This function creates a custom dialog box with the specified message and additional elements such as an image, heading, and an OK button. The dialog box is designed with a green border, rounded corners, and a black background.
.PARAMETER Message
The message to be displayed in the dialog box.
.PARAMETER Width
The width of the custom dialog window.
.PARAMETER Height
The height of the custom dialog window.
.PARAMETER FontSize
The Font Size for text shown inside the custom dialog window.
.PARAMETER HeaderFontSize
The Font Size for the Header of the custom dialog window.
.PARAMETER IconSize
The Size to use for Icon inside the custom dialog window.
.PARAMETER EnableScroll
A flag indicating whether to enable scrolling if the content exceeds the window size.
.EXAMPLE
Show-CustomDialog -Message "This is a custom dialog with a message and an image above." -Width 300 -Height 200
#>
param(
[string]$Message,
[int]$Width = 300,
[int]$Height = 200,
[int]$FontSize = 10,
[int]$HeaderFontSize = 14,
[int]$IconSize = 25,
[bool]$EnableScroll = $false
)
Add-Type -AssemblyName PresentationFramework
# Define theme colors
$foregroundColor = $sync.configs.themes.$ctttheme.MainForegroundColor
$backgroundColor = $sync.configs.themes.$ctttheme.MainBackgroundColor
$font = New-Object Windows.Media.FontFamily("Consolas")
$borderColor = $sync.configs.themes.$ctttheme.BorderColor # ButtonInstallBackgroundColor
$buttonBackgroundColor = $sync.configs.themes.$ctttheme.ButtonInstallBackgroundColor
$buttonForegroundColor = $sync.configs.themes.$ctttheme.ButtonInstallForegroundColor
$shadowColor = [Windows.Media.ColorConverter]::ConvertFromString("#AAAAAAAA")
$logocolor = $sync.configs.themes.$ctttheme.LabelboxForegroundColor
# Create a custom dialog window
$dialog = New-Object Windows.Window
$dialog.Title = "About"
$dialog.Height = $Height
$dialog.Width = $Width
$dialog.Margin = New-Object Windows.Thickness(10) # Add margin to the entire dialog box
$dialog.WindowStyle = [Windows.WindowStyle]::None # Remove title bar and window controls
$dialog.ResizeMode = [Windows.ResizeMode]::NoResize # Disable resizing
$dialog.WindowStartupLocation = [Windows.WindowStartupLocation]::CenterScreen # Center the window
$dialog.Foreground = $foregroundColor
$dialog.Background = $backgroundColor
$dialog.FontFamily = $font
$dialog.FontSize = $FontSize
# Create a Border for the green edge with rounded corners
$border = New-Object Windows.Controls.Border
$border.BorderBrush = $borderColor
$border.BorderThickness = New-Object Windows.Thickness(1) # Adjust border thickness as needed
$border.CornerRadius = New-Object Windows.CornerRadius(10) # Adjust the radius for rounded corners
# Create a drop shadow effect
$dropShadow = New-Object Windows.Media.Effects.DropShadowEffect
$dropShadow.Color = $shadowColor
$dropShadow.Direction = 270
$dropShadow.ShadowDepth = 5
$dropShadow.BlurRadius = 10
# Apply drop shadow effect to the border
$dialog.Effect = $dropShadow
$dialog.Content = $border
# Create a grid for layout inside the Border
$grid = New-Object Windows.Controls.Grid
$border.Child = $grid
# Add the following line to show gridlines
#$grid.ShowGridLines = $true
# Add the following line to set the background color of the grid
$grid.Background = [Windows.Media.Brushes]::Transparent
# Add the following line to make the Grid stretch
$grid.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch
$grid.VerticalAlignment = [Windows.VerticalAlignment]::Stretch
# Add the following line to make the Border stretch
$border.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch
$border.VerticalAlignment = [Windows.VerticalAlignment]::Stretch
# Set up Row Definitions
$row0 = New-Object Windows.Controls.RowDefinition
$row0.Height = [Windows.GridLength]::Auto
$row1 = New-Object Windows.Controls.RowDefinition
$row1.Height = [Windows.GridLength]::new(1, [Windows.GridUnitType]::Star)
$row2 = New-Object Windows.Controls.RowDefinition
$row2.Height = [Windows.GridLength]::Auto
# Add Row Definitions to Grid
$grid.RowDefinitions.Add($row0)
$grid.RowDefinitions.Add($row1)
$grid.RowDefinitions.Add($row2)
# Add StackPanel for horizontal layout with margins
$stackPanel = New-Object Windows.Controls.StackPanel
$stackPanel.Margin = New-Object Windows.Thickness(10) # Add margins around the stack panel
$stackPanel.Orientation = [Windows.Controls.Orientation]::Horizontal
$stackPanel.HorizontalAlignment = [Windows.HorizontalAlignment]::Left # Align to the left
$stackPanel.VerticalAlignment = [Windows.VerticalAlignment]::Top # Align to the top
$grid.Children.Add($stackPanel)
[Windows.Controls.Grid]::SetRow($stackPanel, 0) # Set the row to the second row (0-based index)
# Add SVG path to the stack panel
$stackPanel.Children.Add((Invoke-WinUtilAssets -Type "logo" -Size 25))
# Add "Winutil" text
$winutilTextBlock = New-Object Windows.Controls.TextBlock
$winutilTextBlock.Text = "Winutil"
$winutilTextBlock.FontSize = $HeaderFontSize
$winutilTextBlock.Foreground = $logocolor
$winutilTextBlock.Margin = New-Object Windows.Thickness(10, 10, 10, 5) # Add margins around the text block
$stackPanel.Children.Add($winutilTextBlock)
# Add TextBlock for information with text wrapping and margins
$messageTextBlock = New-Object Windows.Controls.TextBlock
$messageTextBlock.TextWrapping = [Windows.TextWrapping]::Wrap # Enable text wrapping
$messageTextBlock.HorizontalAlignment = [Windows.HorizontalAlignment]::Left
$messageTextBlock.VerticalAlignment = [Windows.VerticalAlignment]::Top
$messageTextBlock.Margin = New-Object Windows.Thickness(10) # Add margins around the text block
# Define the Regex to find hyperlinks formatted as HTML <a> tags
$regex = [regex]::new('<a href="([^"]+)">([^<]+)</a>')
$lastPos = 0
# Iterate through each match and add regular text and hyperlinks
foreach ($match in $regex.Matches($Message)) {
# Add the text before the hyperlink, if any
$textBefore = $Message.Substring($lastPos, $match.Index - $lastPos)
if ($textBefore.Length -gt 0) {
$messageTextBlock.Inlines.Add((New-Object Windows.Documents.Run($textBefore)))
}
# Create and add the hyperlink
$hyperlink = New-Object Windows.Documents.Hyperlink
$hyperlink.NavigateUri = New-Object System.Uri($match.Groups[1].Value)
$hyperlink.Inlines.Add($match.Groups[2].Value)
$hyperlink.TextDecorations = [Windows.TextDecorations]::None # Remove underline
$hyperlink.Foreground = $sync.configs.themes.$ctttheme.LinkForegroundColor
$hyperlink.Add_Click({
param($sender, $args)
Start-Process $sender.NavigateUri.AbsoluteUri
})
$hyperlink.Add_MouseEnter({
param($sender, $args)
$sender.Foreground = $sync.configs.themes.$ctttheme.LinkHoverForegroundColor
})
$hyperlink.Add_MouseLeave({
param($sender, $args)
$sender.Foreground = $sync.configs.themes.$ctttheme.LinkForegroundColor
})
$messageTextBlock.Inlines.Add($hyperlink)
# Update the last position
$lastPos = $match.Index + $match.Length
}
# Add any remaining text after the last hyperlink
if ($lastPos -lt $Message.Length) {
$textAfter = $Message.Substring($lastPos)
$messageTextBlock.Inlines.Add((New-Object Windows.Documents.Run($textAfter)))
}
# If no matches, add the entire message as a run
if ($regex.Matches($Message).Count -eq 0) {
$messageTextBlock.Inlines.Add((New-Object Windows.Documents.Run($Message)))
}
# Create a ScrollViewer if EnableScroll is true
if ($EnableScroll) {
$scrollViewer = New-Object System.Windows.Controls.ScrollViewer
$scrollViewer.VerticalScrollBarVisibility = 'Auto'
$scrollViewer.HorizontalScrollBarVisibility = 'Disabled'
$scrollViewer.Content = $messageTextBlock
$grid.Children.Add($scrollViewer)
[Windows.Controls.Grid]::SetRow($scrollViewer, 1) # Set the row to the second row (0-based index)
} else {
$grid.Children.Add($messageTextBlock)
[Windows.Controls.Grid]::SetRow($messageTextBlock, 1) # Set the row to the second row (0-based index)
}
# Add OK button
$okButton = New-Object Windows.Controls.Button
$okButton.Content = "OK"
$okButton.FontSize = $FontSize
$okButton.Width = 80
$okButton.Height = 30
$okButton.HorizontalAlignment = [Windows.HorizontalAlignment]::Center
$okButton.VerticalAlignment = [Windows.VerticalAlignment]::Bottom
$okButton.Margin = New-Object Windows.Thickness(0, 0, 0, 10)
$okButton.Background = $buttonBackgroundColor
$okButton.Foreground = $buttonForegroundColor
$okButton.BorderBrush = $borderColor
$okButton.Add_Click({
$dialog.Close()
})
$grid.Children.Add($okButton)
[Windows.Controls.Grid]::SetRow($okButton, 2) # Set the row to the third row (0-based index)
# Handle Escape key press to close the dialog
$dialog.Add_KeyDown({
if ($_.Key -eq 'Escape') {
$dialog.Close()
}
})
# Set the OK button as the default button (activated on Enter)
$okButton.IsDefault = $true
# Show the custom dialog
$dialog.ShowDialog()
}