public/dialogs/Show-UiGlyphBrowser.ps1
|
function Show-UiGlyphBrowser { <# .SYNOPSIS Opens a child window displaying all available glyphs. .DESCRIPTION Shows a searchable grid of all glyphs defined in CharList.json. Click a glyph to copy its name to the clipboard. .PARAMETER Parent The parent window. If not specified, uses the current session's window. .EXAMPLE Show-UiGlyphBrowser .EXAMPLE $parentSession = Get-UiSession Show-UiGlyphBrowser -Parent $parentSession.Window #> [CmdletBinding()] param( [System.Windows.Window]$Parent ) if (!$Parent) { $session = Get-UiSession if ($session -and $session.Window) { $Parent = $session.Window } } $iconDict = [PsUi.ModuleContext]::Icons # Deduplicate (keep first occurrence of each glyph character) $seenChars = @{} $glyphList = [System.Collections.Generic.List[object]]::new() foreach ($kvp in $iconDict.GetEnumerator()) { $char = $kvp.Value if (!$seenChars.ContainsKey($char)) { $seenChars[$char] = $kvp.Key $glyphList.Add([PSCustomObject]@{ Name = $kvp.Key; Char = $char }) } } $glyphList = $glyphList | Sort-Object Name # Pre-create brushes BEFORE the content block since private functions aren't accessible inside $colors = Get-ThemeColors $tileBgBrush = ConvertTo-UiBrush $colors.ControlBg $borderBrush = ConvertTo-UiBrush $colors.Border $fgBrush = ConvertTo-UiBrush $colors.ControlFg $secondaryTextBrush = ConvertTo-UiBrush $colors.SecondaryText $childParams = @{ Title = "Glyph Browser ($($glyphList.Count) unique)" Width = 867.5 Height = 600 Content = { New-UiLabel -Text "Segoe MDL2 Assets Icon Browser" -Style Title New-UiLabel -Text "Click any icon to copy its name to clipboard. Use -Icon 'Name' with buttons, cards, and panels." -Style Note New-UiInput -Label 'Search' -Variable 'glyphSearch' -Placeholder 'Type to filter glyphs...' $session = Get-UiSession # WrapPanel for glyph tiles - child window already has a ScrollViewer $wrapPanel = [System.Windows.Controls.WrapPanel]@{ Orientation = 'Horizontal' Margin = [System.Windows.Thickness]::new(0, 8, 0, 0) } # Create glyph tiles using pre-created brushes (captured via AST) foreach ($glyph in $glyphList) { $tile = [System.Windows.Controls.Border]@{ Width = 75 Height = 75 Margin = [System.Windows.Thickness]::new(3) Background = $tileBgBrush BorderBrush = $borderBrush BorderThickness = [System.Windows.Thickness]::new(1) CornerRadius = [System.Windows.CornerRadius]::new(4) Cursor = 'Hand' ToolTip = $glyph.Name Tag = @{ Name = $glyph.Name } } $stack = [System.Windows.Controls.StackPanel]@{ Orientation = 'Vertical' HorizontalAlignment = 'Center' VerticalAlignment = 'Center' IsHitTestVisible = $false } $icon = [System.Windows.Controls.TextBlock]@{ Text = $glyph.Char FontFamily = [System.Windows.Media.FontFamily]::new('Segoe MDL2 Assets') FontSize = 24 Foreground = $fgBrush HorizontalAlignment = 'Center' Margin = [System.Windows.Thickness]::new(0, 6, 0, 2) } $labelText = if ($glyph.Name.Length -gt 9) { $glyph.Name.Substring(0, 7) + '..' } else { $glyph.Name } $label = [System.Windows.Controls.TextBlock]@{ Text = $labelText FontSize = 9 Foreground = $secondaryTextBrush HorizontalAlignment = 'Center' TextTrimming = 'CharacterEllipsis' } $stack.Children.Add($icon) | Out-Null $stack.Children.Add($label) | Out-Null $tile.Child = $stack # Register for theme updates (ThemeEngine is a static class, always available) try { [PsUi.ThemeEngine]::RegisterElement($tile) [PsUi.ThemeEngine]::RegisterElement($icon) [PsUi.ThemeEngine]::RegisterElement($label) } catch { Write-Debug "ThemeEngine registration failed: $_" } # Click to copy name to clipboard $tile.Add_MouseLeftButtonUp({ param($sender, $eventArgs) $data = $sender.Tag [System.Windows.Clipboard]::SetText($data.Name) # Flash accent color then restore - fetch fresh colors for theme support $flashColors = Get-ThemeColors $sender.Background = ConvertTo-UiBrush $flashColors.Accent $timer = [System.Windows.Threading.DispatcherTimer]::new() $timer.Interval = [TimeSpan]::FromMilliseconds(200) $ref = $sender $timer.Add_Tick({ $restoreColors = Get-ThemeColors $ref.Background = ConvertTo-UiBrush $restoreColors.ControlBg $this.Stop() }.GetNewClosure()) $timer.Start() }.GetNewClosure()) $wrapPanel.Children.Add($tile) | Out-Null } # Add wrap panel directly to parent - child window already provides ScrollViewer $session.CurrentParent.Children.Add($wrapPanel) | Out-Null # Store reference for filtering $session.Variables['_glyphWrapPanel'] = $wrapPanel $searchBox = $session.GetControl('glyphSearch') if ($searchBox) { $searchBox.Add_TextChanged({ $sess = Get-UiSession $panel = $sess.Variables['_glyphWrapPanel'] $filter = $this.Text.ToLower() foreach ($child in $panel.Children) { $name = $child.Tag.Name if ([string]::IsNullOrEmpty($filter) -or $name.ToLower().Contains($filter)) { $child.Visibility = 'Visible' } else { $child.Visibility = 'Collapsed' } } }.GetNewClosure()) } } } if ($Parent) { $childParams['Parent'] = $Parent } New-UiChildWindow @childParams } |