PoshCode Archive  Artifact [507a587778]

Artifact 507a58777870eff9cd9eab3e6d0c4ea551e91ba01bf2712f46a98c52ffeadeba:

  • File BinaryClock.ps1 — part of check-in [c93c24b5db] at 2018-06-10 13:16:09 on branch trunk — My updated version of my original binary clock. (user: Boe Prox size: 15059)

# encoding: utf-8
# api: powershell
# title: BinaryClock
# description: My updated version of my original binary clock.
# version: 2.0
# type: function
# author: Boe Prox
# license: CC0
# function: Start-BinaryClock
# x-poshcode-id: 2819
# x-archived: 2016-05-06T05:19:18
# x-published: 2012-07-24T20:01:00
#
# More information can be found here: 
# http://learn-powershell.net/2011/07/24/powershell-binary-clock-round-2/
# Fixed a bug in code.
#
Function Start-BinaryClock {
<#
.SYNOPSIS
    This is a binary clock that lists the time in hours, minutes and seconds
    
.DESCRIPTION
    This is a binary clock that lists the time in hours, minutes and seconds.
    
    Key Input Tips:
    r: Toggles the resize mode of the clock so you can adjust the size.
    d: Toggles the date to hide/show
    o: Toggles whether the clock remains on top of windows or not.
    +: Increases the opacity of the clock so it is less transparent.
    -: Decreases the opacity of the clock so it appears more transparent.
    
    Right-Click to close.
    Use left mouse button to drag clock.
    
.PARAMETER OnColor
    Define the color used for the active time (1).
    
.PARAMETER OffColor
    Define the color used for the inactive time (0).
    
.PARAMETER RandomColor    
    Default parameter if manual colors are not used. Picks a random color for On and Off colors.

.NOTES  
    Name: BinaryClock.ps1
    Author: Boe Prox
    DateCreated: 07/05/2011
    Version 2.0 

.EXAMPLE
    Start-BinaryClock
    
Description
-----------
Starts the binary clock using randomly generated colors 

.EXAMPLE
    Start-BinaryClock -OnColor Red -OffColor Gold -DateColor Black
    
Description
-----------
Starts the binary clock using using specified colors.        
#>
[cmdletbinding(
    DefaultParameterSetName = 'RandomColor'
    )]
Param (
    [parameter(Mandatory = 'True',ParameterSetName = 'SetColor')]
    [String] $OnColor,
    [parameter(Mandatory = 'True',ParameterSetName = 'SetColor')]
    [String] $OffColor,
    [parameter(ParameterSetName = 'RandomColor')]
    [Switch]$RandomColor, 
    [parameter(Mandatory = 'True',ParameterSetName = 'SetColor')]
    [String] $DateColor   
    )
If ($PSCmdlet.ParameterSetName -eq 'RandomColor') {
    [switch]$RandomColor = $True
    }
   
$Global:rs = [RunspaceFactory]::CreateRunspace()
$rs.ApartmentState = “STA”
$rs.ThreadOptions = “ReuseThread”
$rs.Open() 
$psCmd = {Add-Type -AssemblyName PresentationCore,PresentationFramework,WindowsBase}.GetPowerShell() 
$rs.SessionStateProxy.SetVariable('OnColor',$OnColor)
$rs.SessionStateProxy.SetVariable('OffColor',$OffColor)
$rs.SessionStateProxy.SetVariable('RandomColor',$RandomColor)
$rs.SessionStateProxy.SetVariable('DateColor',$DateColor)
$psCmd.Runspace = $rs 
$psCmd.Invoke() 
$psCmd.Commands.Clear() 
$psCmd.AddScript({ 

#Load Required Assemblies
Add-Type –assemblyName PresentationFramework
Add-Type –assemblyName PresentationCore
Add-Type –assemblyName WindowsBase

##Colors
If ($RandomColor) {
    #On Color
    $OnColor = "#{0:X}" -f (Get-Random -min 1 -max 16777215)
    Try {
        [system.windows.media.brush]$OnColor | Out-Null
        }
    Catch {
        $OnColor = "White"
        }
    #Off Color
    $OffColor = "#{0:X}" -f (Get-Random -min 1 -max 16777215)
    Try {
        [system.windows.media.brush]$OffColor | Out-Null
        }
    Catch {
        $OffColor = "Black"
        }
    #DateColor Color
    $DateColor = "#{0:X}" -f (Get-Random -min 1 -max 16777215)
    Try {
        [system.windows.media.brush]$DateColor | Out-Null
        }
    Catch {
        $DateColor = "Black"
        }        
    }

[xml]$xaml = @"
<Window
    xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
    xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
    x:Name='Window' WindowStyle = 'None' WindowStartupLocation = 'CenterScreen' Width = '170' Height = '101' ShowInTaskbar = 'True' 
    ResizeMode = 'NoResize' Title = 'Clock' AllowsTransparency = 'True' Background = 'Transparent' Opacity = '1' Topmost = 'True'>
        <Grid x:Name = 'Grid' HorizontalAlignment="Stretch" ShowGridLines='false'  Background = 'Transparent'>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="2"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="5"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="2"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="5"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="2"/>
                <ColumnDefinition Width="*"/>                
                <ColumnDefinition Width="2"/>
                <ColumnDefinition Width="*" x:Name = 'DayColumn'/> 
                <ColumnDefinition Width="*" x:Name = 'MonthColumn'/> 
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height = '*'/>
                <RowDefinition Height = '2'/>
                <RowDefinition Height = '*'/>
                <RowDefinition Height = '2'/>
                <RowDefinition Height = '*'/>                
                <RowDefinition Height = '2'/>
                <RowDefinition Height = '*'/>
                <RowDefinition Height = '2'/>
                <RowDefinition x:Name = 'timerow' Height = '0'/>
            </Grid.RowDefinitions>
            <Ellipse Grid.Row = '0' Grid.Column = '0' Fill = 'Transparent'/>
            <Ellipse Grid.Row = '2' Grid.Column = '0' Fill = 'Transparent' />
            <Ellipse x:Name = 'HourA0' Grid.Row = '6' Grid.Column = '0' Fill = 'Transparent' />
            <Ellipse x:Name = 'HourA1' Grid.Row = '4' Grid.Column = '0' Fill = 'Transparent' />    
            <Ellipse x:Name = 'HourB0' Grid.Row = '6' Grid.Column = '2' Fill = 'Transparent'/>
            <Ellipse x:Name = 'HourB1' Grid.Row = '4' Grid.Column = '2' Fill = 'Transparent' />
            <Ellipse x:Name = 'HourB2' Grid.Row = '2' Grid.Column = '2' Fill = 'Transparent' />
            <Ellipse x:Name = 'HourB3' Grid.Row = '0' Grid.Column = '2' Fill = 'Transparent' />
            <Ellipse Grid.Row = '0' Grid.Column = '4' Fill = 'Transparent'/>
            <Ellipse x:Name = 'MinuteA0' Grid.Row = '6' Grid.Column = '4' Fill = 'Transparent' />
            <Ellipse x:Name = 'MinuteA1' Grid.Row = '4' Grid.Column = '4' Fill = 'Transparent' />
            <Ellipse x:Name = 'MinuteA2' Grid.Row = '2' Grid.Column = '4' Fill = 'Transparent' /> 
            <Ellipse x:Name = 'MinuteB0' Grid.Row = '6' Grid.Column = '6' Fill = 'Transparent'/>
            <Ellipse x:Name = 'MinuteB1' Grid.Row = '4' Grid.Column = '6' Fill = 'Transparent' />
            <Ellipse x:Name = 'MinuteB2' Grid.Row = '2' Grid.Column = '6' Fill = 'Transparent' />
            <Ellipse x:Name = 'MinuteB3' Grid.Row = '0' Grid.Column = '6' Fill = 'Transparent' />  
            <Ellipse Grid.Row = '0' Grid.Column = '8' Fill = 'Transparent'/>
            <Ellipse x:Name = 'SecondA0' Grid.Row = '6' Grid.Column = '8' Fill = 'Transparent' />
            <Ellipse x:Name = 'SecondA1' Grid.Row = '4' Grid.Column = '8' Fill = 'Transparent' />
            <Ellipse x:Name = 'SecondA2' Grid.Row = '2' Grid.Column = '8' Fill = 'Transparent' />  
            <Ellipse x:Name = 'SecondB0' Grid.Row = '6' Grid.Column = '10' Fill = 'Transparent'/>
            <Ellipse x:Name = 'SecondB1' Grid.Row = '4' Grid.Column = '10' Fill = 'Transparent' />
            <Ellipse x:Name = 'SecondB2' Grid.Row = '2' Grid.Column = '10' Fill = 'Transparent' />
            <Ellipse x:Name = 'SecondB3' Grid.Row = '0' Grid.Column = '10' Fill = 'Transparent' />                                                                                  
            <Viewbox VerticalAlignment = 'Stretch' HorizontalAlignment = 'Stretch' Grid.Column = '12' Grid.RowSpan = '7'
            StretchDirection = 'Both' Stretch = 'Fill'>
                <TextBlock x:Name = 'DayLabel' VerticalAlignment = 'Stretch' HorizontalAlignment = 'Stretch'
                FontWeight = 'Bold'> 
                    <TextBlock.LayoutTransform>
                        <RotateTransform Angle="90" />
                    </TextBlock.LayoutTransform>            
                </TextBlock>
            </Viewbox>
            <Viewbox VerticalAlignment = 'Stretch' HorizontalAlignment = 'Stretch' Grid.Column = '13' Grid.RowSpan = '7'
            StretchDirection = 'Both' Stretch = 'Fill'>
                <TextBlock x:Name = 'MonthLabel' VerticalAlignment = 'Stretch' HorizontalAlignment = 'Stretch'
                FontWeight = 'Bold'>
                    <TextBlock.LayoutTransform>
                        <RotateTransform Angle="90" />
                    </TextBlock.LayoutTransform>               
                </TextBlock>
            </Viewbox>
        </Grid>
</Window>
"@ 

$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$Global:Window=[Windows.Markup.XamlReader]::Load( $reader )
$Global:DayLabel = $Global:window.FindName("DayLabel")
$Global:MonthLabel = $Global:window.FindName("MonthLabel")
$Global:DayColumn = $Global:window.FindName("DayColumn")
$Global:MonthColumn = $Global:window.FindName("MonthColumn")
$Global:TimeRow = $Global:window.FindName("TimeRow")
$Global:Grid = $Global:window.FindName("Grid")

##Events 
#Key Events
$Global:Window.Add_KeyDown({
    Switch ($_.Key) {
        {'Add','OemPlus' -contains $_} {
            If ($Window.Opacity -lt 1) {
                $Window.Opacity = $Window.Opacity + .1
                $Window.UpdateLayout()
                }            
            }
        {'Subtract','OemMinus' -contains $_} {
            If ($Window.Opacity -gt .2) {
                $Window.Opacity = $Window.Opacity - .1
                $Window.UpdateLayout()
                }             
            }
        "r" {
            If ($Window.ResizeMode -eq 'NoResize') {
                $Window.ResizeMode = 'CanResizeWithGrip'
                }      
            Else {
                $Window.ResizeMode = 'NoResize'             
                }       
            } 
        "d" {
            Switch ($MonthLabel.visibility) {
                'Collapsed' {$MonthLabel.visibility = 'Visible';$DayLabel.Visibility = 'Visible'}
                'Visible' {$MonthLabel.visibility = 'Collapsed ';$DayLabel.Visibility = 'Collapsed '}
                }
            }    
        "o" {
            If ($Window.TopMost) {
                $Window.TopMost = $False
                }
            Else {
                $Window.TopMost = $True
                }
            }     
        }
    }) 
        
$Window.Add_MouseRightButtonUp({
    $This.close()
    })
$Window.Add_MouseLeftButtonDown({
    $This.DragMove()
    })  
         
$update = {
$DayLabel.Text = "$(((Get-Date).ToLongDateString() -split ',')[0] -split '')"
$DayLabel.Foreground = $DateColor
$MonthLabel.Text = Get-Date -u "%B %d %G"
$MonthLabel.Foreground = $DateColor
$hourA,$hourB = [string](Get-Date -f HH) -split "" | Where {$_}
$minuteA,$minuteB = [string](Get-Date -f mm) -split "" | Where {$_}
$secondA,$secondB = [string](Get-Date -f ss) -split "" | Where {$_}

$hourAdock = $grid.children | Where {$_.Name -like "hourA*"}
$minuteAdock = $grid.children | Where {$_.Name -like "minuteA*"}
$secondAdock = $grid.children | Where {$_.Name -like "secondA*"}
$hourBdock = $grid.children | Where {$_.Name -like "hourB*"}
$minuteBdock = $grid.children | Where {$_.Name -like "minuteB*"}
$secondBdock = $grid.children | Where {$_.Name -like "secondB*"}

#hourA
[array]$splittime = ([convert]::ToString($houra,2)) -split"" | Where {$_}
[array]::Reverse($splittime)
$i = 0
ForEach ($hdock in $hourAdock) {
    Write-Verbose "i: $($i)"
    Write-Verbose "split: $($splittime[$i])"
    If ($splittime[$i] -eq "1") {
        $hdock.Fill = $OnColor
        }
    Else {
        $hdock.Fill = $OffColor
        }
    $i++
    }
$i = 0

#hourB
[array]$splittime = ([convert]::ToString($hourb,2)) -split"" | Where {$_}
[array]::Reverse($splittime)
$i = 0
ForEach ($hdock in $hourBdock) {
    Write-Verbose "i: $($i)"
    Write-Verbose "split: $($splittime[$i])"
    If ($splittime[$i] -eq "1") {
        $hdock.Fill = $OnColor
        }
    Else {
        $hdock.Fill = $OffColor
        }
    $i++
    }
$i = 0

#minuteA
[array]$splittime = ([convert]::ToString($minutea,2)) -split"" | Where {$_}
[array]::Reverse($splittime)
$i = 0
ForEach ($hdock in $minuteAdock) {
    Write-Verbose "i: $($i)"
    Write-Verbose "split: $($splittime[$i])"
    If ($splittime[$i] -eq "1") {
        $hdock.Fill = $OnColor
        }
    Else {
        $hdock.Fill = $OffColor
        }
    $i++
    }
$i = 0

#minuteB
[array]$splittime = ([convert]::ToString($minuteb,2)) -split"" | Where {$_}
[array]::Reverse($splittime)
$i = 0
ForEach ($hdock in $minuteBdock) {
    Write-Verbose "i: $($i)"
    Write-Verbose "split: $($splittime[$i])"
    If ($splittime[$i] -eq "1") {
        $hdock.Fill = $OnColor
        }
    Else {
        $hdock.Fill = $OffColor
        }
    $i++
    }
$i = 0

#secondA
[array]$splittime = ([convert]::ToString($seconda,2)) -split"" | Where {$_}
[array]::Reverse($splittime)
$i = 0
ForEach ($hdock in $secondAdock) {
    Write-Verbose "i: $($i)"
    Write-Verbose "split: $($splittime[$i])"
    If ($splittime[$i] -eq "1") {
        $hdock.Fill = $OnColor
        }
    Else {
        $hdock.Fill = $OffColor
        }
    $i++
    }
$i = 0

#secondB
[array]$splittime = ([convert]::ToString($secondb,2)) -split"" | Where {$_}
[array]::Reverse($splittime)
$i = 0
ForEach ($hdock in $secondBdock) {
    Write-Verbose "i: $($i)"
    Write-Verbose "split: $($splittime[$i])"
    If ($splittime[$i] -eq "1") {
        $hdock.Fill = $OnColor
        }
    Else {
        $hdock.Fill = $OffColor
        }
    $i++
    }
$i = 0
}

$Global:Window.Add_KeyDown({
    If ($_.Key -eq "F5") {
        &$update 
        }
    })

#Timer Event
$Window.Add_SourceInitialized({
    #Create Timer object
    Write-Verbose "Creating timer object"
    $Global:timer = new-object System.Windows.Threading.DispatcherTimer 

    Write-Verbose "Adding interval to timer object"
    $timer.Interval = [TimeSpan]"0:0:.10"
    #Add event per tick
    Write-Verbose "Adding Tick Event to timer object"
    $timer.Add_Tick({
        &$update
        Write-Verbose "Updating Window"
        })
    #Start timer
    Write-Verbose "Starting Timer"
    $timer.Start()
    If (-NOT $timer.IsEnabled) {
        $Window.Close()
        }
    })

&$update
$window.Showdialog() | Out-Null             
}).BeginInvoke() | out-null
}