UIfiedOouiBase.ps1
using namespace System.Collections.Generic using namespace Ooui class OouiElement : UIElement { OouiElement() { $this.WrapNegatedProperty("Enable", "IsDisabled") $this.WrapNegatedProperty("Visible", "IsHidden") $this.AddNativeUIChild = { param ( [OouiElement] $element ) $this.NativeUI.AppendChild($element.NativeUI) | Out-Null } $this.RemoveNativeUIChild = { param ( [OouiElement] $element ) $this.NativeUI.RemoveChild($element.NativeUI) | Out-Null } } } class OouiHost : UIHost { $Shared = $true $Port = 8185 $CreateElement [void] ShowFrame([ScriptBlock] $frameScriptBlock) { #$Global:SyncHash = [HashTable]::Synchronized(@{ # Window = $null # Errors = @() #}) $this.CreateElement = $frameScriptBlock if ($this.Shared) { $this.ShowSharedFrame() } else { $this.ShowNotSharedFrame() } } [void] ShowSharedFrame() { $frame = Invoke-Command -ScriptBlock $this.CreateElement [UI]::Port = $this.Port [UI]::Publish("/Form", $frame.NativeUI) } [void] ShowNotSharedFrame() { $notSharedForm = [NotSharedForm]::new() $notSharedForm.CreateElement = $this.CreateElement [UI]::Port = $this.Port [UI]::Publish("/Form", $notSharedForm) } } class NotSharedForm : Div { [Anchor] $Anchor $CreateElement NotSharedForm() { $this.Anchor = [Anchor]::new() $this.Anchor.Text = "Go to Not Shared Form" $this.AppendChild($this.Anchor) | Out-Null Register-ObjectEvent -InputObject $this.Anchor -EventName Click -MessageData $this -Action { $this = $event.MessageData $notSharedForm = [NotSharedForm]::new() $notSharedForm.CreateElement = $this.CreateElement [Ooui.UI]::Publish("/Form", $notSharedForm) $frame = Invoke-Command -ScriptBlock $this.CreateElement $guid = [Guid]::NewGuid().ToString() [Ooui.UI]::Publish("/$guid", $frame.NativeUI) $this.Document.Window.Location = "/$guid" } | Out-Null } } class OouiWindow : WindowBase { OouiWindow() { $this.SetNativeUI([Div]::new()) $this.WrapProperty("Caption", "Title") $this.AddScriptBlockProperty("Loaded") $this.AddNativeUIChild = { param ( [OouiElement] $element ) $this.NativeUI.AppendChild($element.NativeUI) } } [void] ShowDialog() { } [void] OnLoaded() { Invoke-Command -ScriptBlock $this._Loaded -ArgumentList $this } } class OouiStackPanel : OouiElement { #Divs https://jsfiddle.net/rwe8hp6f/ OouiStackPanel() { $this.SetNativeUI([Div]::new()) $this.AddProperty("Orientation") $this.AddNativeUIChild = { param ( [OouiElement] $element ) $listItem = [Div]::new() if ($this._Orientation -eq [Orientation]::Horizontal) { $listItem.Style.float = "left" } else { $listItem.Style.Display = "" } $this.NativeUI.AppendChild($listItem) | Out-Null $listItem.AppendChild($element.NativeUI) | Out-Null } } } class OouiLabel : OouiElement { OouiLabel() { $this.SetNativeUI([Span]::new()) $this.WrapProperty("Caption", "Text") } } class OouiButton : OouiElement { OouiButton() { $nativeUI = [Button]::new("NotSet") $this.SetNativeUI($nativeUI) $this.WrapProperty("Caption", "Text") $this.AddScriptBlockProperty("Action") Register-ObjectEvent -InputObject $this.NativeUI -EventName Click -MessageData $this -Action { $this = $event.MessageData $this.Control.OnAction() } | Out-Null } [void] OnAction() { Invoke-Command -ScriptBlock $this._Action -ArgumentList $this } } class OouiTextBox : OouiElement { OouiTextBox() { $this.SetNativeUI([TextInput]::new()) $this.WrapProperty("Text", "Value") $this.AddScriptBlockProperty("Change") Register-ObjectEvent -InputObject $this.NativeUI -EventName Change -MessageData $this -Action { $this = $event.MessageData $this.Control.OnChange() } | Out-Null } [void] OnChange() { Invoke-Command -ScriptBlock $this._Change -ArgumentList $this } } class OouiCheckBox : OouiElement { hidden [Div] $ListNativeUI hidden [Span] $LabelNativeUI hidden [Input] $CheckBoxNativeUI OouiCheckBox() { $this.ListNativeUI = [Div]::new() $this.LabelNativeUI = [Span]::new() $this.CheckBoxNativeUI = [Input]::new("CheckBox") $this.ListNativeUI.AppendChild($this.CheckBoxNativeUI) $this.ListNativeUI.AppendChild($this.LabelNativeUI) $this.SetNativeUI($this.ListNativeUI) $this.WrapProperty("Caption", "Text", "LabelNativeUI") $this.WrapProperty("IsChecked", "IsChecked", "CheckBoxNativeUI") $this.AddScriptBlockProperty("Click") Register-ObjectEvent -InputObject $this.CheckBoxNativeUI -EventName Change -MessageData $this -Action { $this = $event.MessageData $this.Control.OnClick() } | Out-Null } [void] OnClick() { Invoke-Command -ScriptBlock $this._Click -ArgumentList $this } } class OouiRadioButton : OouiElement { hidden [Div] $ListNativeUI hidden [Span] $LabelNativeUI hidden [Input] $RadioButtonNativeUI OouiRadioButton() { $this.ListNativeUI = [Div]::new() $this.LabelNativeUI = [Span]::new() $this.RadioButtonNativeUI = [Input]::new("Radio") $this.ListNativeUI.AppendChild($this.RadioButtonNativeUI) $this.ListNativeUI.AppendChild($this.LabelNativeUI) $this.SetNativeUI($this.ListNativeUI) $this.WrapProperty("Caption", "Text", "LabelNativeUI") $this.WrapProperty("IsChecked", "IsChecked", "RadioButtonNativeUI") $this.AddScriptBlockProperty("Click") Register-ObjectEvent -InputObject $this.RadioButtonNativeUI -EventName Change -MessageData $this -Action { $this = $event.MessageData $this.Control.OnClick() } | Out-Null } [void] OnClick() { Invoke-Command -ScriptBlock $this._Click -ArgumentList $this } } class OouiRadioGroup : OouiElement { hidden [String] $ChildName = "" OouiRadioGroup() { $this.SetNativeUI([Div]::new()) $this.AddNativeUIChild = { param ( [OouiElement] $element ) if ($this.Control.ChildName -eq "") { if ($this.Control.Name -ne "") { $this.Control.ChildName = $this.Control.Name } else { $this.Control.ChildName = "A" + [Guid]::NewGuid().ToString() } } $element.RadioButtonNativeUI.Name = $this.Control.ChildName $this.NativeUI.AppendChild($element.NativeUI) | Out-Null } } } class OouiList : OouiStackPanel { [List[ListItem]] $Items = [List[ListItem]]::new() OouiList() { $this.Orientation = [Orientation]::Horizontal } [void] AddColumn([OouiListColumn] $listColumn) { $column = [OouiStackPanel]::new() $column.Orientation = [Orientation]::Vertical $title = [OouiLabel]::new() $title.Caption = $listColumn.Title $column.AddChild($title) $this.AddChild($column) } [void] AddItem([ListItem] $listItem) { $this.Items.Add($listItem) $columnIndex = 0 $this.Children | ForEach-Object { $column = $_ $cell = $listItem.Children.Item($columnIndex) $column.AddChild($cell) $columnIndex++ } } [void] RemoveItem([ListItem] $listItem) { $itemIndex = $this.Items.IndexOf($listItem) + 1 $this.Children | ForEach-Object { $column = $_ $cell = $column.NativeUI.Children.Item($itemIndex) $column.NativeUI.RemoveChild($cell) } $columnIndex = 0 $this.Children | ForEach-Object { $column = $_ $cell = $listItem.Children.Item($columnIndex) $column.Children.Remove($cell) $columnIndex++ } $this.Items.Remove($listItem) } } class OouiListColumn { [String] $Name [String] $Title } class OouiTabItem : OouiStackPanel { [String] $Caption = "" } class OouiTabControl : OouiStackPanel { [Ooui.List] $List = [Ooui.List]::new() OouiTabControl() { $this.List.ClassName = "nav nav-tabs" $this.NativeUI.AppendChild($this.List) $this.AddNativeUIChild = { param ( [OouiElement] $element ) $item = [Ooui.ListItem]::new() $item.ClassName = "nav-item" $anchor = [Ooui.Anchor]::new() $anchor.ClassName = "nav-link" $anchor.Text = $element.Caption Register-ObjectEvent -InputObject $anchor -EventName Click -MessageData @($this, $anchor) -Action { $event.MessageData $Control = $event.MessageData[0] $anchor = $event.MessageData[1] $Control.SelectTab($anchor.Text) } | Out-Null $item.AppendChild($anchor) | Out-Null $this.List.AppendChild($item) | Out-Null $this.NativeUI.AppendChild($element.NativeUI) | Out-Null $firstTab = $this.GetTabs() | Select-Object -First 1 $this.SelectTab($firstTab.Caption) } } [OOuiTabItem[]] GetTabs() { return $this.Children | Where-Object { $_.GetType() -eq [OOuiTabItem] } } [void] SelectTab([String] $tabCaption) { $this.GetTabs() | ForEach-Object { if ($_.Caption -eq $tabCaption) { $_.Visible = $true } else { $_.Visible = $false } } $this.List.Children | ForEach-Object { $anchor = $_.FirstChild if ($anchor.Text -eq $tabCaption) { $_.ClassName = "nav-link active" } else { $_.ClassName = "nav-link" } } } } class OouiModal : OouiElement { [Div] $DialogDiv = [Div]::new() [Div] $DocumentDiv = [Div]::new() [Div] $ContentDiv = [Div]::new() OouiModal() { $this.DialogDiv.ClassName = "modal" $this.DialogDiv.Style.display = "none" $this.DialogDiv.SetAttribute("role", "dialog") $this.DocumentDiv.ClassName = "modal-dialog" $this.DocumentDiv.SetAttribute("role", "document") $this.DialogDiv.AppendChild($this.DocumentDiv) $this.ContentDiv.ClassName = "modal-content" $this.DocumentDiv.AppendChild($this.ContentDiv) $this.SetNativeUI($this.DialogDiv) $this.AddNativeUIChild = { param ( [OouiElement] $element ) $this.ContentDiv.AppendChild($element.NativeUI) } } [void] Show() { $this.DialogDiv.Style.display = "block" } [void] Hide() { $this.DialogDiv.Style.display = "none" } } class OouiTimer : OouiElement { [System.Timers.Timer] $Timer [Double] $Interval = 1000 OouiTimer() { $label = [Span]::new() $label.IsHidden = $true $this.SetNativeUI($label) $this.AddScriptBlockProperty("Elapsed") $this.Timer = New-Object System.Timers.Timer Register-ObjectEvent -InputObject $this.Timer -EventName Elapsed -MessageData $this -Action { $this = $event.MessageData $this.Control.OnElapsed() } } [void] OnElapsed() { Invoke-Command -ScriptBlock $this._Elapsed -ArgumentList $this } [void] Start() { $this.Timer.Interval = $this.Interval $this.Timer.Start() } [void] Stop() { $this.Timer.Stop() } } class OouiDatePicker : OouiElement { OouiDatePicker() { $this.SetNativeUI([Input]::new("Date")) $this.AddScriptBlockProperty("Change") Register-ObjectEvent -InputObject $this.NativeUI -EventName Change -MessageData $this -Action { $this = $event.MessageData $this.Control.OnChange() } | Out-Null Add-Member -InputObject $this -Name Value -MemberType ScriptProperty -Value { [DateTime]::Parse($this.NativeUI.Value) } -SecondValue { $this.NativeUI.Value = $args[0].ToString("yyyy-MM-dd") } } [void] OnChange() { Invoke-Command -ScriptBlock $this._Change -ArgumentList $this } } class OouiTimePicker : OouiElement { OouiTimePicker() { $this.SetNativeUI([Input]::new("Time")) $this.AddScriptBlockProperty("Change") Register-ObjectEvent -InputObject $this.NativeUI -EventName Change -MessageData $this -Action { $this = $event.MessageData $this.Control.OnChange() } | Out-Null Add-Member -InputObject $this -Name Value -MemberType ScriptProperty -Value { if ($this.IsTime($this.NativeUI.Value)) { $this.NativeUI.Value } else { "00:00" } } -SecondValue { if ($this.IsTime($args[0])) { $this.NativeUI.Value = $args[0] } else { "00:00" } } } hidden [Boolean] IsTime([String] $timeText) { [DateTime] $dateTime = [DateTime]::Today return [DateTime]::TryParse( "2000-01-01 " + $timeText, [ref] $dateTime) } [void] OnChange() { Invoke-Command -ScriptBlock $this._Change -ArgumentList $this } } |