Flawless Faction Puzzle 3

This topic contains 0 replies, has 1 voice, and was last updated by  Dzmitry Nikalaichyk 3 months, 2 weeks ago.

  • Author
    Posts
  • #92818

    Dzmitry Nikalaichyk
    Participant

    Hi again,

    Here is my version of Puzzle 3 for Flawless Faction.
    For this one, I've decided to go with creating GUI. Also, I've decided to omit part of the task to output text of the link to console, as it doesn't really fit to what I did there.
    Further, you might wonder why this doesn't have much in-line help information in functions. This is because this script is written with the intend to be built-in EXE file.

    Fot those who just want to take a look at how it's looks like:
    This is how it looks like.

    Add-Type -AssemblyName PresentationFramework
    
    #region XAML window definition
    $xaml = @'
    <Window
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
       MinWidth="200"
       Width ="769.111"
       Height="512"
       Title="RSS Reader"
       Topmost="False"
       Background="Black"
       BorderBrush="DarkBlue" WindowStyle="ThreeDBorderWindow" Foreground="#FF65CBEC" WindowStartupLocation="CenterScreen">
        <DockPanel>
            <ScrollViewer HorizontalContentAlignment="Stretch" FlowDirection="RightToLeft" DockPanel.Dock="Left">
                <Grid Name="rss" Margin="0" DockPanel.Dock="Left" Width="220">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Border Height="32" VerticalAlignment="Top" HorizontalAlignment="Stretch" Width="Auto" Margin="0,0,0,0">
                        <Grid Background="Black" HorizontalAlignment="Stretch">
                            <TextBox Height="Auto" VerticalAlignment="Center" FlowDirection="LeftToRight" Margin="0,0,5,0" HorizontalAlignment="Right" Foreground="White" Background="Black" BorderBrush="Black" Width="160" TextAlignment="Left" SelectionBrush="#FF65CBEC" CaretBrush="#FF65CBEC">
                                Enter Uri of RSS feed
                            </TextBox>
                            <Button Name="AddButton" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="10,0,0,0" Width="40" Background="Black" Foreground="White" BorderBrush="Black">
                                Add
                            </Button>
                        </Grid>
                    </Border>
                </Grid>
            </ScrollViewer>
            <ScrollViewer HorizontalContentAlignment="Stretch" DockPanel.Dock="Right">
                <Grid Name="feed" DockPanel.Dock="Right">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                </Grid>
            </ScrollViewer>
        </DockPanel>
    
    </Window>
    '@
    #endregion
    
    #region Initialization
    function Convert-XAMLtoWindow
    {
        param
        (
            [Parameter(Mandatory)]
            [string]
            $xaml
        )
      
        Add-Type -AssemblyName PresentationFramework
      
        $reader = [XML.XMLReader]::Create([IO.StringReader]$xaml)
        $result = [Windows.Markup.XAMLReader]::Load($reader)
        $reader.Close()
        $reader = [XML.XMLReader]::Create([IO.StringReader]$xaml)
        while ($reader.Read())
        {
            $name = $reader.GetAttribute('Name')
            if (!$name) 
            {
                $name = $reader.GetAttribute('x:Name') 
            }
    
            if($name)
            {
                $result | Add-Member -MemberType NoteProperty -Name $name -Value $result.FindName($name) -Force
            }
        }
        $reader.Close()
        $result
    }
    
    function Show-WPFWindow
    {
        param
        (
            [Parameter(Mandatory)]
            [Windows.Window]
            $Window
        )
      
        $result = $null
        $null = $Window.Dispatcher.InvokeAsync{
            $result = $Window.ShowDialog()
        }.Wait()
        $result
    }
    #endregion Initialization
    
    #region Building Functions
    function Get-RssTitle
    {
        param
        (
            [Parameter(Mandatory)]
            [string]
            $Uri
        )
    
        $title = ([xml](Invoke-WebRequest -Method Get -Uri $Uri).content).rss.channel.title
    
        if ($title -isnot [string])
        {
            $title = $title | Select-Object -ExpandProperty '#cdata-section'
        }
    
        if ($title.Length -gt 25)
        {
            $title = '...{0}' -f $title.SubString(0,25)
        }
        $title
    }
    
    function Get-CdataValue
    {
        param
        (
            [Parameter(Mandatory)]
            $Element
        )
        
        if ($Element -isnot [string] -and $Element.Count -gt 1)
        {
            $element = $Element[0]
        }
        elseif ($Element -isnot [string])
        {
            $element = $element | Select-Object -ExpandProperty '#cdata-section'
        }
        $element
    }
    
    function Add-FeedHeader
    {
        param
        (
            [Parameter(Mandatory)]
            [string]
            $Header
        )
    
        $headerItem = New-Object -TypeName System.Windows.Controls.Border -Property @{
            Height              = 32
            VerticalAlignment   = 'Top'
            HorizontalAlignment = 'Stretch'
            Margin              = '0,0,0,0'
        }
    
        $headerGrid = New-Object -TypeName System.Windows.Controls.Grid -Property @{
            Background          = 'Black'
            HorizontalAlignment = 'Stretch'
        }
    
        $headerTitle = New-Object -TypeName System.Windows.Controls.TextBlock -Property @{
            VerticalAlignment   = 'Center'
            Margin              = '0,0,0,0'
            FontSize            = '16'
            HorizontalAlignment = 'Center'
            Text                = $Header
            Foreground          = '#FF65CBEC'
            Background          = 'Black'
            FlowDirection       = 'RightToLeft'
        }
        
        $headerGrid.AddChild($headerTitle)
        $headerItem.AddChild($headerGrid)
        $headerItem
    }
    
    function Add-RssSource
    {
        param
        (
            [Parameter(Mandatory)]
            [string]
            $Uri,
            
            [Parameter(Mandatory)]
            [int]
            $Counter
        )
        
        $rssItem = New-Object -TypeName System.Windows.Controls.Border -Property @{
            Height              = 64
            VerticalAlignment   = 'Top'
            HorizontalAlignment = 'Stretch'
            Margin              = '0,{0},0,0' -f ((64*$Counter)+32)
        }
    
        $rssGrid = New-Object -TypeName System.Windows.Controls.Grid -Property @{
            Background          = 'Black'
            HorizontalAlignment = 'Stretch'
        }
    
        $rssTitle = New-Object -TypeName System.Windows.Controls.TextBlock -Property @{
            VerticalAlignment   = 'Center'
            Margin              = '0,0,0,0'
            FontSize            = '14'
            HorizontalAlignment = 'Center'
            Text                = Get-RssTitle -Uri $Uri
            Foreground          = 'White'
            Name                = 'Title'
        }
    
        $rssUri = New-Object -TypeName System.Windows.Controls.TextBlock -Property @{
            VerticalAlignment   = 'Center'
            Margin              = '0,0,20,0'
            FontSize            = '14'
            HorizontalAlignment = 'Center'
            Text                = $Uri
            Foreground          = 'White'
            Visibility          = 'Hidden'
            Name                = 'Uri'
        }
    
        $rssIndicator = New-Object -TypeName System.Windows.Shapes.Rectangle -Property @{
            Height              = '48'
            Margin              = '0,8,0,8'
            Width               = '6'
            HorizontalAlignment = 'Right'
            Fill                = '#FF65CBEC'
            Visibility          = 'Hidden'
        }
    
        $rssGrid.AddChild($rssIndicator)
        $rssGrid.AddChild($rssTitle)
        $rssGrid.AddChild($rssUri)
        $rssItem.AddChild($rssGrid)
        $rssItem.add_MouseLeftButtonDown{
            $feeds = Invoke-RestMethod -Method Get -Uri ($this.Child.Children | Where-Object -Property Name -eq 'Uri' | Select-Object -ExpandProperty Text)
            $i = 0
            $Window.feed.Children.Clear()
            $Window.feed.AddChild((Add-FeedHeader -Header ($this.Child.Children | Where-Object -Property Name -eq 'Title' | Select-Object -ExpandProperty Text)))
    
            foreach ($feed in $feeds)
            {
                $Window.feed.AddChild((Get-RssFeed -Element $feed -Counter $i))
                $i++
            }
        }
        $rssItem.add_MouseEnter{
            $this.Child.Children | ForEach-Object -Process {
                if ($_ -is [System.Windows.Controls.TextBlock])
                {
                    $_.Foreground = '#FF65CBEC'
                }
                elseif ($_ -is [System.Windows.Shapes.Rectangle])
                {
                    $_.Visibility = 'Visible'
                }
            }
        }
        $rssItem.add_MouseLeave{
            $this.Child.Children | ForEach-Object -Process {
                if ($_ -is [System.Windows.Controls.TextBlock])
                {
                    $_.Foreground = 'White'
                }
                elseif ($_ -is [System.Windows.Shapes.Rectangle])
                {
                    $_.Visibility = 'Hidden'
                }
            }
        }
        $rssItem
    }
    
    function Get-RssFeed
    {
        param
        (
            [Parameter(Mandatory)]
            [System.Xml.XmlElement]
            $Element,
    
            [Parameter(Mandatory)]
            [int]
            $Counter
        )
        
        $newItem = New-Object -TypeName System.Windows.Controls.Border -Property @{
            Height              = 64
            VerticalAlignment   = 'Top'
            HorizontalAlignment = 'Stretch'
            Margin              = '0,{0},0,0' -f ((64*$Counter)+32)
        }
    
        $grid = New-Object -TypeName System.Windows.Controls.Grid -Property @{
            Background          = 'Black'
            HorizontalAlignment = 'Stretch'
        }
    
        $title = New-Object -TypeName System.Windows.Controls.TextBlock -Property @{
            Margin              = '0,0,0,45'
            FontSize            = '12'
            HorizontalAlignment = 'Center'
            Text                = Get-CdataValue -Element $Element.title
            Foreground          = 'White'
        }
    
        if ($Element.pubDate)
        {
            $publishDate = New-Object -TypeName System.Windows.Controls.TextBlock -Property @{
                Margin     = '5,20,0,30'
                FontSize   = '9'
                Text       = 'PublishedOn: {0}' -f (Get-CdataValue -Element $Element.pubDate)
                Foreground = 'White'
            }
            $grid.AddChild($publishDate)
        }
    
        $link = New-Object -TypeName System.Windows.Controls.TextBlock -Property @{
            Margin     = '5,35,0,15'
            FontSize   = '9'
            Text       = Get-CdataValue -Element $Element.link
            Foreground = 'White'
            Name       = 'link'
        }
    
        if ($Element.Creator)
        {
            $author = New-Object -TypeName System.Windows.Controls.TextBlock -Property @{
                Margin     = '5,50,0,0'
                FontSize   = '9'
                Text       = 'PublishedBy: {0}' -f (Get-CdataValue -Element $Element.Creator)
                Foreground = 'White'
            }
            $grid.AddChild($author)
        }
    
        $indicator = New-Object -TypeName System.Windows.Shapes.Rectangle -Property @{
            Height              = '48'
            Margin              = '0,8,0,8'
            Width               = '6'
            HorizontalAlignment = 'Right'
            Fill                = '#FF65CBEC'
            Visibility          = 'Hidden'
        }
    
        $grid.AddChild($title)
        $grid.AddChild($link)
        $grid.AddChild($indicator)
        $newItem.AddChild($grid)
        $newItem.add_MouseEnter{
            $this.child.Background = '#FF111111'
            $this.child.Children | ForEach-Object -Process {
                if ($_ -is [System.Windows.Controls.TextBlock])
                {
                    $_.Foreground = '#FF65CBEC'
                }
                elseif ($_ -is [System.Windows.Shapes.Rectangle])
                {
                    $_.Visibility = 'Visible'
                }
            }
        }
        $newItem.add_MouseLeave{
            $this.child[0].Background = 'Black'
            $this.child.Children | ForEach-Object -Process {
                if ($_ -is [System.Windows.Controls.TextBlock])
                {
                    $_.Foreground = 'White'
                }
                elseif ($_ -is [System.Windows.Shapes.Rectangle])
                {
                    $_.Visibility = 'Hidden'
                }
            }
        }
    
        $newItem.add_MouseLeftButtonDown{
            [Diagnostics.Process]::Start(($this.child.Children | Where-Object -Property Name -eq 'link' | Select-Object -ExpandProperty Text))
        }
        $newItem
    }
    #endregion
    
    $settings = ConvertFrom-Json -InputObject (Get-Content -Path (Join-Path -Path $PSScriptRoot -ChildPath 'settings.json') -raw)
    $window = Convert-XAMLtoWindow -XAML $xaml
    $counter = 0
    foreach ($source in $settings.feeds)
    {
        $window.rss.AddChild((Add-RssSource -Uri $source -Counter $counter))
        $counter++
    }
    
    $window.rss.Children.Child.Children[1].Add_Click{
        $window.rss.AddChild((Add-RssSource -Uri $window.rss.Children.Child.Children[0].Text -Counter $counter))
        $window.rss.Children.Child.Children[0].Text = 'Enter Uri of RSS feed'
        $counter++
    }
    
    $result = Show-WPFWindow -Window $Window
    

You must be logged in to reply to this topic.