# encoding: ascii
# author: mario
# x-poshcode-id: 6830
# x-archived: 2017-04-08T04:42:35
# x-published: 2017-04-04T18:17:00
#
# api: ps
# title: WPF + WinForms
# description: WinForm and WPF shortcuts
# depends: sys:presentationframework, sys:system.windows.forms, sys:system.drawing
# version: 0.9
# type: functions
# category: ui
# config: -
# status: beta
# license: PD
# priority: default
#
# Simple aliases to `New-Object System.Windows.Controls.Widget`, which
# ease parameter definition + method invocation using a hashtable arg:
#
#    $w_btn = W Button @{Content="Text"; Border="2"; add_Click=$cb}
#    $w_grd = W Grid @{Add=$w1, $w2, $w3}
#
# Or augment existing form objects:
#
#    W $w_btn @{Background="Black"; Foreground="White"}
#
# Perhaps even nesting if you can stand the parentheses/curly braces:
#
#    $form = W Window @{Width=800; Height=600; Add=@(
#        (W StackPanel @{Orientation="Vertical"; Add=@(
#            (W Label @{Content="title"; Foreground="Blue"}),
#            (W Button @{Content="Click me"; Background="Red"})
#        )})
#    )}
#
# The `W` shortcut is for WPF, whereas `WF` summons WinForms widgets.
# While `WD` is an alias to System.Windows.Document.xyz elements.


#-- register libs
Add-Type -AN PresentationCore, PresentationFramework, WindowsBase
Add-Type -AN System.Drawing, System.Windows.Forms, Microsoft.VisualBasic


#-- WPF/WinForms widget wrapper
function W {
    [CmdletBinding()]
    Param($type = "Button", $prop = @{}, $Base="Controls")

    # new object
    if ($type.getType().Name -eq "String") {
        $w = New-Object System.Windows.$Base.$type
    }
    else {
        $w = $type
    }

    # apply options+methods
    $prop.keys | % {
        $key = $_
        $val = $prop[$_]
        if ($pt = ($w | Get-Member -Force -Name $key)) { $pt = $pt.MemberType }

        # properties
        if ($pt -eq "Property") {
            if (($Base -eq "Forms") -and (@("Size" , "ItemSize", "Location") -contains $key)) {
                $val = New-Object System.Drawing.Size($val[0], $val[1])
            }
            $w.$key = $val
        }
        # check for methods in widget and common subcontainers
        else {
            ForEach ($obj in @($w, $w.Children, $w.Child, $w.Container)) {
                if ($obj.psobject -and $obj.psobject.methods.match($key) -and $obj.$key) {
                    ([array]$val) | % { $obj.$key.Invoke($_) } | Out-Null
                    break
                }
            }
        }
    }
    return $w
}

#-- WinForms version
function WF {
    Param($type, $prop, $add=@{}, $click=$null)
    W -Base Forms -Type $type -Prop ($prop + @{add=$add; add_click=$click})
}

#-- Document "widgets"
function WD {
    Param($type, $prop=@{})
    W -Base Documents -Type $type -Prop $prop
}
