Powershell GUI fronted (WPF) to run categorized console scripts

⌈⌋ ⎇ branch:  ClickyColoury


Check-in [8ad68eaa09]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Write-Splash fix for PS2. Release a 0.9.0
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | 0.9.0
Files: files | file ages | folders
SHA1: 8ad68eaa090e519164b8b1153b59a4197cfa6104
User & Date: mario 2018-04-15 18:22:21
Context
2018-04-15
19:05
.output.Parent.Parent.ScrollToEnd() to message ScrollViewer, not RTB check-in: 7cb3a3ddb7 user: mario tags: trunk
18:22
Write-Splash fix for PS2. Release a 0.9.0 check-in: 8ad68eaa09 user: mario tags: trunk, 0.9.0
13:15
More current vars test (multiline definition and filechooser/button). Check all colors in Write-Host test. check-in: 885044ef20 user: mario tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ClickyColoury.cmd.

1
2
3
4
5
@echo off
REM -- depends on -Version 2.0 for now; albeit *did* work with PowerShell 3.0 once
REM -- for debugging, leave out `-WindowStyle Hidden` of course
cd %~dp0
powershell.exe -Version 2.0 -STA -File ./modules/starter.ps1

<


|
1

2
3
4
@echo off

REM -- for debugging, leave out `-WindowStyle Hidden` of course
cd %~dp0
powershell.exe -STA -WindowStyle Hidden -File ./modules/starter.ps1

Changes to NEWS.

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18

0.9.0 (2018-04-10)
 * Ported to Powershell 5.0
 * Toolblocks are just buttons again, in a TreeView;
   for performance reasons (became too slow with 200 scripts)
 * Output pane is a FlowDocument now, allows -XAML passing
 * Extra parameters now bring up a form box, new vars: meta field
 * New darker theme
 * Splash screen added
 * Introducing cross-runspace events now (albeit Cancel non-functional,
   simple $GUI.tasks queue still used)


0.8.0 (2017-09-22)
 * First public (stripped down) release
 * Main code condensed into modules/ directory.
 * Global configuration hash is now populated in starter.ps1
 * Restructured tools/ again into category-nested subfolders.
 * Implemented HTML clipboard kludge (collect alongside Out-Gui).

|









>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

0.9.0 (2018-04-15)
 * Ported to Powershell 5.0
 * Toolblocks are just buttons again, in a TreeView;
   for performance reasons (became too slow with 200 scripts)
 * Output pane is a FlowDocument now, allows -XAML passing
 * Extra parameters now bring up a form box, new vars: meta field
 * New darker theme
 * Splash screen added
 * Introducing cross-runspace events now (albeit Cancel non-functional,
   simple $GUI.tasks queue still used)
 * Proper GUI output to HTML clipboard conversion

0.8.0 (2017-09-22)
 * First public (stripped down) release
 * Main code condensed into modules/ directory.
 * Global configuration hash is now populated in starter.ps1
 * Restructured tools/ again into category-nested subfolders.
 * Implemented HTML clipboard kludge (collect alongside Out-Gui).

Changes to modules/guimenu.psm1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# api: ps
# title: GUI handling, WPF + WinForms
# description: WinForm and WPF interaction, GUI and thread handling
# depends: menu, clipboard, sys:presentationframework, sys:system.windows.forms, sys:system.drawing
# doc: http://fossil.include-once.org/clickycoloury/wiki/W
# version: 1.2.0
# license: MITL
# type: functions
# category: ui
# config:
#   { name: cfg.threading, type: bool, value: 1, description: Enable threading/runspaces for GUI/WPF version }
#   { name: cfg.autoclear, type: int, value: 300, description: Clear output box after N seconds. }
#   { name: cfg.noheader, type: bool, value: 0, description: Disable script info header in output. }
#   { name: cfg.theme, type: select, select: "dark|bunti", value: dark, description: XAML theme file. }
# status: stable
# priority: core
#
# Handles $menu list in WPF window. Creates widgets and menu entries
# for plugin list / $menu entries.
#   · `type: inline` is the implied default, renders output in TextBlock 
#   · `type: cli` or `window` plugins are run in a separate window
#   · `hidden: 1` tools only show up in menus
#   · `keycode:` is used for shortcuts; the CLI `key:` regex ignored
#   · `type: init-gui` plugins are run once during GUI construction
#   · Whereas `type: init` execute in the main/script RunSpace
#













|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# api: ps
# title: GUI handling, WPF + WinForms
# description: WinForm and WPF interaction, GUI and thread handling
# depends: menu, clipboard, sys:presentationframework, sys:system.windows.forms, sys:system.drawing
# doc: http://fossil.include-once.org/clickycoloury/wiki/W
# version: 1.2.0
# license: MITL
# type: functions
# category: ui
# config:
#   { name: cfg.threading, type: bool, value: 1, description: Enable threading/runspaces for GUI/WPF version }
#   { name: cfg.autoclear, type: int, value: 300, description: Clear output box after N seconds. }
#   { name: cfg.noheader, type: bool, value: 0, description: Disable script info header in output. }
#   { name: cfg.theme, type: select, select: "dark|bunti|beta", value: dark, description: XAML theme file. }
# status: stable
# priority: core
#
# Handles $menu list in WPF window. Creates widgets and menu entries
# for plugin list / $menu meta data.
#   · `type: inline` is the implied default, renders output in TextBlock 
#   · `type: cli` or `window` plugins are run in a separate window
#   · `hidden: 1` tools only show up in menus
#   · `keycode:` is used for shortcuts; the CLI `key:` regex ignored
#   · `type: init-gui` plugins are run once during GUI construction
#   · Whereas `type: init` execute in the main/script RunSpace
#
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#   · Thus `Out-Gui` manages output, and a few helpers for title, var fetching.
#   · Toolbar actions run entirely in the GUI thread, thus can freeze UI a bit.
#
# Scripts/tools should work identically as for the CLI version:
#   · Aliases for `Write-Host` and `Read-Host` should make it transparent.
#   · However simple console output (typically to the stdout stream) will
#     have to be pipe-captured.
#   · Order of pipe/stream output should meanwhile be catched.
#


#-- register libs
Add-Type -AN PresentationCore, PresentationFramework, WindowsBase
Add-Type -AN System.Drawing, System.Windows.Forms, Microsoft.VisualBasic
[System.Windows.Forms.Application]::EnableVisualStyles()







|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#   · Thus `Out-Gui` manages output, and a few helpers for title, var fetching.
#   · Toolbar actions run entirely in the GUI thread, thus can freeze UI a bit.
#
# Scripts/tools should work identically as for the CLI version:
#   · Aliases for `Write-Host` and `Read-Host` should make it transparent.
#   · However simple console output (typically to the stdout stream) will
#     have to be pipe-captured.
#   · Order of pipe/stream output and Write-Host calls do not intermix still.
#


#-- register libs
Add-Type -AN PresentationCore, PresentationFramework, WindowsBase
Add-Type -AN System.Drawing, System.Windows.Forms, Microsoft.VisualBasic
[System.Windows.Forms.Application]::EnableVisualStyles()
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
#-- Startup splash screen (WinForms)
#   · runs in main thread, no callbacks or extra background handling
#   · keeps its own reference once initialized by first call
function Write-Splash {
    Param($msg, $progress=25, $TITLE="â–¶ ClickyColoury 0.9", $VENDOR="PWSH")
    $null = &{
        if (!$Splash) {
             $bold = [system.drawing.font]::new("Verdana",13,"Bold","Pixel")
             $impc = [system.drawing.font]::new("Impact",22)
             $v = $PSVersionTable.PSVersion
             $global:Splash = @{
                 psv1 = (WF Label @{Text=$VENDOR; Location=5,5; Size=50,16; Font=$BOLD; ForeColor="Gray"})
                 psv2 = (WF Label @{Text="$($v.Major).$($v.Minor)"; Location=50,5; Size=40,16; Font=$BOLD; ForeColor="Orange"})
                 title = (WF Label @{Text=$TITLE; Location=5,25; Size=280,50; AutoSize=0; TextAlign="MiddleCenter"; Font=$IMPC; ForeColor="#333333"})
                 prg = (WF ProgressBar @{Location=10,80; Size=280,30; Value=1; Step=25; Maximum=1000})
                 msg = (WF Label @{Location=15,120; Size=270,20; Text="..."})







|
|







542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
#-- Startup splash screen (WinForms)
#   · runs in main thread, no callbacks or extra background handling
#   · keeps its own reference once initialized by first call
function Write-Splash {
    Param($msg, $progress=25, $TITLE="â–¶ ClickyColoury 0.9", $VENDOR="PWSH")
    $null = &{
        if (!$Splash) {
             $bold = New-Object System.Drawing.Font -ArgumentList "Verdana",13,"Bold","Pixel"
             $impc = New-Object System.Drawing.Font -ArgumentList "Impact",22
             $v = $PSVersionTable.PSVersion
             $global:Splash = @{
                 psv1 = (WF Label @{Text=$VENDOR; Location=5,5; Size=50,16; Font=$BOLD; ForeColor="Gray"})
                 psv2 = (WF Label @{Text="$($v.Major).$($v.Minor)"; Location=50,5; Size=40,16; Font=$BOLD; ForeColor="Orange"})
                 title = (WF Label @{Text=$TITLE; Location=5,25; Size=280,50; AutoSize=0; TextAlign="MiddleCenter"; Font=$IMPC; ForeColor="#333333"})
                 prg = (WF ProgressBar @{Location=10,80; Size=280,30; Value=1; Step=25; Maximum=1000})
                 msg = (WF Label @{Location=15,120; Size=270,20; Text="..."})
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
    return $GUI.vars
}

#-- print header/title
function Out-GuiHeader($e) {
   Set-GuiTitle "➱ $($cfg.main.title) → $($e.title)"
   if ($e.noheader -or $cfg.noheader) { return; }
   $Host.UI.Write("HDR`r`n")
   $XAML = @"
      <Paragraph xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
       Foreground="#ff9988dd" Background="#ff102070" Margin="0,3"
       ><Image Source='$(Get-IconPath $e.icon $e.img $e.category)' Width='16' Height='16'
       /><Bold><![CDATA[$($e.title)]]></Bold><Span Foreground="#a98d"><![CDATA[ - $($e.description)]]></Span
       ></Paragraph>
"@







|







966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
    return $GUI.vars
}

#-- print header/title
function Out-GuiHeader($e) {
   Set-GuiTitle "➱ $($cfg.main.title) → $($e.title)"
   if ($e.noheader -or $cfg.noheader) { return; }
   #$Host.UI.Write("HDR`r`n")
   $XAML = @"
      <Paragraph xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
       Foreground="#ff9988dd" Background="#ff102070" Margin="0,3"
       ><Image Source='$(Get-IconPath $e.icon $e.img $e.category)' Width='16' Height='16'
       /><Bold><![CDATA[$($e.title)]]></Bold><Span Foreground="#a98d"><![CDATA[ - $($e.description)]]></Span
       ></Paragraph>
"@
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
    Out-GuiHeader $e

    #-- plugins
    TRAP { $_ | out-gui -b red }
    $plugins.before | % { Invoke-Expression ($_.ToString()) }

    #-- Run $menu entry rules (command=, func=, or fn=)
    $Host.UI.Write("INVOKE`r`n")
    try {
        #-- Internal commands
        if ($e.command) {
            [void]((Invoke-Expression $e.command) | Out-String | Out-Gui -f Yellow)
        }
        elseif ($e.func) {
            [void]((Invoke-Expression "$e.func $machine $username") | Out-String | Out-Gui -f Yellow)







|







1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
    Out-GuiHeader $e

    #-- plugins
    TRAP { $_ | out-gui -b red }
    $plugins.before | % { Invoke-Expression ($_.ToString()) }

    #-- Run $menu entry rules (command=, func=, or fn=)
    #$Host.UI.Write("INVOKE`r`n")
    try {
        #-- Internal commands
        if ($e.command) {
            [void]((Invoke-Expression $e.command) | Out-String | Out-Gui -f Yellow)
        }
        elseif ($e.func) {
            [void]((Invoke-Expression "$e.func $machine $username") | Out-String | Out-Gui -f Yellow)