myBlog

IronPython, Silverlight, WPF, XAML, HTML5, ...

IronPythonで、ColorListView を作りました

2011-07-05 03:50:48 | DataBinding
カラー・リストビュー ( ColorListView )を作ってみました。
BLOG: 続・ひよ子のきもち ==> ListView
http://d.hatena.ne.jp/kotsubu-chan/20090706
から、XAML と IronPython のコード を myBlog 用に少しアレンジしています。
XAMLのなかで、DataBinding が使われています。

続・ひよ子のきもち は、とても興味深いPageです。
WPF・IronPythonについて、色々と教えてもらいました。

Exlistview

#
# exListView.py
#
import clr
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReference('WindowsBase')
from System import Object
from System.Windows.Markup import XamlReader
from System.Windows import Window, Application
from System.Windows.Media import SolidColorBrush, Brushes
#from System.Windows.Controls import Grid
#from System.Windows.Data import Binding, BindingOperations
from System.Collections.ObjectModel import ObservableCollection

xaml_str="""
<DockPanel LastChildFill="True"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ListView Name="listView" DockPanel.Dock="Left">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Color Name" 
                    DisplayMemberBinding="{Binding Path=name}"  Width="90" />
                <GridViewColumn Header="Red" 
                    DisplayMemberBinding="{Binding Path=red}"   Width="45" />
                <GridViewColumn Header="Green" 
                    DisplayMemberBinding="{Binding Path=green}" Width="45" />
                <GridViewColumn Header="Blue" 
                    DisplayMemberBinding="{Binding Path=blue}"  Width="45" />
            </GridView>
        </ListView.View>
    </ListView>
    <Canvas Name="colorBox" />
</DockPanel>
"""
class ColorItem:
    def __init__(self, name):
        e = getattr(Brushes, name).Color
        self.name  = name
        self.red   = e.R
        self.green = e.G
        self.blue  = e.B
    def __str__(self):
        return "'%s'(%d,%d,%d)"%(
            self.name, self.red, self.green, self.blue)

class ExWindow(Window):
    def __init__(self, Content=None, **args):
        for key,value in args.items():
            setattr(self, key, value)
        self.InitializeComponent(Content)
        self.init()
        
    def InitializeComponent(self, Content):
        self.Content = XamlReader.Parse(Content)
        
    def init(self):
        target = "listView", "colorBox"
        for e in target:
            control = self.Content.FindName(e)
            setattr(self, e, control)     
        self.listView.ItemsSource = ObservableCollection[Object]()
        for e in self.colorBrushes():
            self.listView.ItemsSource.Add(ColorItem(e))            
        self.listView.SelectionChanged += self.selectionChanged
        
    def colorBrushes(self):
        return [e for e in dir(Brushes)
            if isinstance(getattr(Brushes, e), SolidColorBrush)]
    
    def selectionChanged(self, sender, e):
        e = sender.SelectedItem
        print e
        self.colorBox.Background = getattr(Brushes, e.name)        

if __name__ == "__main__":
    win = ExWindow(Title="exListView", Width=380, Height=150, Content=xaml_str)
    Application().Run(win)


IronPythonの世界 (Windows Script Programming)
荒井 省三
ソフトバンク クリエイティブ
エキスパートPythonプログラミング
Tarek Ziade
アスキー・メディアワークス
Pythonスタートブック
辻 真吾
技術評論社

IronPythonで、System.Reflection を使って ColorComboBoxを作りました

2011-07-04 22:21:20 | Animation
BLOG: Nine Works ==> 色を選択するComboBoxの作り方
http://nine-works.blog.ocn.ne.jp/blog/2011/01/combobox_f98e.html
を参考にさせていただきました。
C# のプログラムを IronPython に変換しました。

前回のカラー・コンボボックスは、Python の dir(Colors) を利用しました。
今回は、Type.GetProperties(Colors) を使いました。
( System.Reflection も使用 )

Colorcombobox_reflection

#
# ColorComboBox_Reflection.py
#
import clr
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReference('WindowsBase')
from System.Windows.Markup import XamlReader
from System import Object, Type
from System.Windows import Window, Application, Thickness
from System.Windows.Controls import StackPanel, Button, TextBlock
from System.Windows.Media import Color, Colors, SolidColorBrush

xaml_str="""
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mscorlib="clr-namespace:System.Reflection;assembly=mscorlib"
    Title="MainWindow" Height="168" Width="244">
    <Window.Resources>
        <DataTemplate x:Key="ColorBoxTemplate" 
                      DataType="{x:Type mscorlib:PropertyInfo}">
            <StackPanel Orientation="Horizontal" Margin="3">
                <Border BorderBrush="Black" BorderThickness="2"
                        CornerRadius="5" Width="20" Height="20"
                        VerticalAlignment="Center"
                        Background="{Binding Path=Name}" />

                <TextBlock Margin="5,0,5,0" Text="{Binding Path=Name}" 
                           VerticalAlignment="Center"/>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <ComboBox Name="ColorBox" Height="35" Width="200" MaxDropDownHeight="210"
                  ItemTemplate="{StaticResource ColorBoxTemplate}"/>
     </Grid>
</Window>
"""

class ExWindow(Object):
    def __init__(self):
        self.Root = win = XamlReader.Parse(xaml_str)
        self.ColorBox = win.FindName("ColorBox")
        self.ColorBox.Loaded += self.ColorBox_Loaded
        self.ColorBox.SelectionChanged += self.ColorBox_SelectionChanged

    def ColorBox_Loaded(self, sender, e):
        #PropertyInfo[] colorProps = typeof(Colors).GetProperties();
        colorProps = Type.GetProperties(Colors)
        self.ColorBox.ItemsSource = colorProps
        self.ColorBox.SelectedIndex = 0

    def ColorBox_SelectionChanged(self, sender, e):
        selected = self.ColorBox.SelectedItem
        if (selected != None):
            color = selected.GetValue(None, None)
            self.Root.Background = SolidColorBrush(color)

if __name__ == "__main__":
    win = ExWindow()
    Application().Run(win.Root)

IronPythonの世界 (Windows Script Programming)
荒井 省三
ソフトバンク クリエイティブ
エキスパートPythonプログラミング
Tarek Ziade
アスキー・メディアワークス
Pythonスタートブック
辻 真吾
技術評論社

IronPythonで、動的に IValueConverter を使う

2011-07-04 14:43:57 | DataBinding
e-manual ⇒ WPF(データバインディング). ⇒ もっとも単純なデータバンディング
Slider コントロールの操作結果を TextBox コントロールに表示します。
次のコードは TextBox コントロールの Text プロパティに、
Slider コントロールの Value プロパティをバインドしています。
http://www.kanazawa-net.ne.jp/~pmansato/wpf/wpf_databinding.htm
を参考にしました。 C# から IronPython へ 変換し、動的要素を追加しました。

Ivalueconverter

#
# IValueConverter.py
#
import clr
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReference('WindowsBase')
from System import Object,String
from System.Windows.Markup import XamlReader
from System.Windows import Window, Application
from System.Windows.Controls import TextBox
from System.Windows.Data import Binding, BindingOperations, IValueConverter

xaml_str="""
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Binding (IValueConverter)" Height="300" Width="300">
    <!-- 
        xmlns:c="clr-namespace:BindingTest" >
    <Window.Resources>
        <c:IntToHexValueConverter x:Key="valueConverter" />
    </Window.Resources>
    -->
    <StackPanel Orientation="Vertical">
        <!--
        <TextBox Name="textBox1" Width="100" Height="25" HorizontalAlignment="Left" Margin="30,10,0,0"
             Text="{Binding ElementName=slider1, Path=Value, Converter={StaticResource valueConverter}}"/>
        -->
        <TextBox Name="textBox1" Width="100" Height="25" HorizontalAlignment="Left" Margin="30,10,0,0"
             Text="{Binding ElementName=slider1, Path=Value, Converter={x:Null}}"/>
        <Slider Name="slider1" Height="22" Margin="30,20,60,0" Maximum="255" Minimum="0"
            TickPlacement="TopLeft" TickFrequency="16" SmallChange="1" LargeChange="16"
            IsSnapToTickEnabled="True" />
    </StackPanel>
</Window>
"""

class IntToHexValueConverter(IValueConverter):
    def Convert(self,value, targetType, parameter, culture):
        textValue = value
        return String.Format("{0} (0x{1:X2})", int(textValue), int(textValue) )

    def ConvertBack(self,value, TargetType, parameter, culture):
       return Binding.DoNothing
    #// end of IntToHexValueConverter class
 
class ExWindow(Object):
    def __init__(self):
        self.Root = win = XamlReader.Parse(xaml_str)
        self.textBox1 = win.FindName("textBox1")
        self.slider1 = win.FindName("slider1")
        #myBinding = BindingOperations.GetBinding(self.textBox1, TextBox.TextProperty)
        BindingOperations.ClearBinding(self.textBox1, TextBox.TextProperty)
        myBinding = Binding("Value")
        myBinding.Source = self.slider1
        myBinding.Converter = IntToHexValueConverter()
        myBinding.ConverterParameter = "Value"
        self.textBox1.SetBinding(TextBox.TextProperty, myBinding)

if __name__ == "__main__":
    win = ExWindow()
    Application().Run(win.Root)

IronPythonの世界 (Windows Script Programming)
荒井 省三
ソフトバンク クリエイティブ
エキスパートPythonプログラミング
Tarek Ziade
アスキー・メディアワークス
Pythonスタートブック
辻 真吾
技術評論社

IronPythonで、四角形(Rect)の大きさが変化するアニメーション

2011-07-04 11:58:04 | Animation
プログラムを実行すると、四角形が伸び縮みします。
クリックするとアニメーションを停止し、
再クリックで、再開します。
( Storyboard は使っていません。Animation のみです。)

#
# RectAnimation.py
#
import clr
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReference('WindowsBase') # for Rect
from System import Object, TimeSpan
from System.Windows.Markup import XamlReader
from System.Windows import Window, Application, Rect, Duration
from System.Windows.Media import RectangleGeometry
from System.Windows.Media.Animation import RectAnimation, RepeatBehavior

xaml_str="""
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="RectAnimation2" Width="170" Height="200" Background="Black">
    <Grid>
        <Path Fill="Blue" Stroke="Red" StrokeThickness="1">
            <Path.Data>
                <RectangleGeometry x:Name="myRectangleGeometry" />
            </Path.Data>
        </Path>
    </Grid>
</Window>
"""
# アニメーション部分だけをIronPythonで実装
class ExWindow(object):
    def __init__(self):
        self.Root = win = XamlReader.Parse(xaml_str)
        win.Loaded += self.win_Loaded
        win.MouseLeftButtonDown += self.animation_stop_start

    def win_Loaded(self, sender, e):
        self.myRectAnimation = RectAnimation(
            From = Rect(80, 80, 0, 0),
            To = Rect(30, 30, 100, 100),
            Duration = Duration( TimeSpan.FromSeconds(1) ),
            AutoReverse = True,
            RepeatBehavior = RepeatBehavior.Forever )
 
        self.myRectangleGeometry=self.Root.FindName("myRectangleGeometry")
        self.myRectangleGeometry.BeginAnimation(RectangleGeometry.RectProperty, self.myRectAnimation)
        self.swAnimation = 1       

    def animation_stop_start(self, sender, e):
        if self.swAnimation == 1:
            rect = self.myRectangleGeometry.Rect
            self.myRectangleGeometry.BeginAnimation(RectangleGeometry.RectProperty, None)
            self.myRectangleGeometry.Rect= rect
            self.swAnimation = 0
        else:
            self.myRectangleGeometry.BeginAnimation(RectangleGeometry.RectProperty, self.myRectAnimation)
            self.swAnimation = 1

if __name__ == "__main__":
    win = ExWindow()
    Application().Run(win.Root)

IronPythonの世界 (Windows Script Programming)
荒井 省三
ソフトバンク クリエイティブ
エキスパートPythonプログラミング
Tarek Ziade
アスキー・メディアワークス
Pythonスタートブック
辻 真吾
技術評論社

IronPythonで、TextEffect 《 FlowDocument 》をアニメーション化する

2011-07-04 04:53:49 | Animation
MSDNを検索していると、興味をひかれるサンプルコードが目にとまった。
http://msdn.microsoft.com/ja-jp/library/ms605762(VS.90).aspx
制御可能なストーリーボードを使用して、
TextEffect をアニメーション化する例を次に示します。
TextEffect は、FrameworkContentElement の名前のスコープに含まれます。

さっそくIronPythonに変換して、実行してみた。
予想以上に、おもしろいサンプルであった。
FlowDocumentという新しい課題が見つかった。
WPFは、機能に富んでいると感じた。

Frameworkcontentelementcontrolstory



#
# FrameworkContentElementControlStoryboardExample.py
#
#/*
#    This example shows how to control
#    a storyboard after it has started.
#*/
import clr
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReference('WindowsBase')

from System import TimeSpan
from System.Windows import Window, Application, NameScope, Thickness, Duration, PropertyPath
from System.Windows.Controls import StackPanel, Button, TextBlock, Orientation
from System.Windows.Media import Brushes, TextEffect,TextEffectCollection
from System.Windows.Media.Animation import Int32Animation, Storyboard
from System.Windows.Documents import Run, Paragraph, BlockUIContainer, FlowDocument

class AnimatingWithStoryboards:
    class FrameworkContentElementControlStoryboardExample(FlowDocument):
        def __init__(self):
            #// Create a name scope for the document.
            NameScope.SetNameScope(self, NameScope())        
            self.Background = Brushes.White;

            #// Create a run of text.
            theText = Run( 
                "Lorem ipsum dolor sit amet, consectetuer adipiscing elit." + 
                "Ut non lacus. Nullam a ligula id leo adipiscing ornare." +
                " Duis mattis. ") 

            #// Create a TextEffect
            animatedSpecialEffect = TextEffect()
            animatedSpecialEffect.Foreground = Brushes.OrangeRed
            animatedSpecialEffect.PositionStart = 0
            animatedSpecialEffect.PositionCount = 0

            #// Assign the TextEffect a name by 
            #// registering it with the page, so that
            #// it can be targeted by storyboard
            #// animations            
            self.RegisterName("animatedSpecialEffect", animatedSpecialEffect)

            #// Apply the text effect to the run.
            theText.TextEffects = TextEffectCollection()
            theText.TextEffects.Add(animatedSpecialEffect)

            #// Create a paragraph to contain the run.
            animatedParagraph = Paragraph(theText)
            animatedParagraph.Background = Brushes.LightGray
            animatedParagraph.Padding = Thickness(20)

            self.Blocks.Add(animatedParagraph)
            controlsContainer = BlockUIContainer()               

            #//
            #// Create an animation and a storyboard to animate the
            #// text effect.
            #//
            countAnimation = Int32Animation(0, 127, TimeSpan.FromSeconds(10))
            Storyboard.SetTargetName(countAnimation, "animatedSpecialEffect")
            Storyboard.SetTargetProperty(countAnimation, 
                PropertyPath(TextEffect.PositionCountProperty))

            self.myStoryboard = Storyboard()
            self.myStoryboard.Children.Add(countAnimation)

            #//
            #// Create some buttons to control the storyboard
            #// and a panel to contain them.
            #//
            buttonPanel = StackPanel()
            buttonPanel.Orientation = Orientation.Vertical

            beginButton = Button()
            beginButton.Content = "Begin"
            beginButton.Click += self.beginButton_Clicked          
            buttonPanel.Children.Add(beginButton)

            pauseButton = Button()
            pauseButton.Content = "Pause"
            pauseButton.Click += self.pauseButton_Clicked
            buttonPanel.Children.Add(pauseButton)

            resumeButton = Button()
            resumeButton.Content = "Resume"
            resumeButton.Click += self.resumeButton_Clicked
            buttonPanel.Children.Add(resumeButton)

            skipToFillButton = Button()
            skipToFillButton.Content = "Skip to Fill"
            skipToFillButton.Click += self.skipToFillButton_Clicked
            buttonPanel.Children.Add(skipToFillButton)

            setSpeedRatioButton = Button()
            setSpeedRatioButton.Content = "Triple Speed"
            setSpeedRatioButton.Click += self.setSpeedRatioButton_Clicked
            buttonPanel.Children.Add(setSpeedRatioButton)

            stopButton = Button()
            stopButton.Content = "Stop"
            stopButton.Click += self.stopButton_Clicked
            buttonPanel.Children.Add(stopButton)

            removeButton = Button()
            removeButton.Content = "Remove"
            removeButton.Click += self.removeButton_Clicked
            buttonPanel.Children.Add(removeButton) 

            controlsContainer.Child = buttonPanel
            self.Blocks.Add(controlsContainer)

        #// Begins the storyboard.
        def beginButton_Clicked(self, sender, args):
            #// Specifying "true" as the second Begin parameter
            #// makes this storyboard controllable.
            self.myStoryboard.Begin(self, True)          

        #// Pauses the storyboard.
        def pauseButton_Clicked(self, sender, args):
            self.myStoryboard.Pause(self)        

        #// Resumes the storyboard.
        def resumeButton_Clicked(self, sender, args):
            self.myStoryboard.Resume(self)        

        #// Advances the storyboard to its fill period.
        def skipToFillButton_Clicked(self, sender, args):
            self.myStoryboard.SkipToFill(self)         

        #// Updates the storyboard's speed.
        def setSpeedRatioButton_Clicked(self, sender, args):
            #// Makes the storyboard progress three times as fast as normal.
            self.myStoryboard.SetSpeedRatio(self, 3)         

        #// Stops the storyboard.
        def stopButton_Clicked(self,sender, args):
            self.myStoryboard.Stop(self)        

        #// Removes the storyboard.
        def removeButton_Clicked(self, sender, args):
             self.myStoryboard.Remove(self);          

    class Window1(Window):
        def __init__(self):
            self.Title = "FrameworkContentElement Control Storyboard Example"
            self.Content = AnimatingWithStoryboards.FrameworkContentElementControlStoryboardExample()

if __name__ == "__main__":
    app = Application()
    app.Run(AnimatingWithStoryboards.Window1())

IronPythonの世界 (Windows Script Programming)
荒井 省三
ソフトバンク クリエイティブ
エキスパートPythonプログラミング
Tarek Ziade
アスキー・メディアワークス
Pythonスタートブック
辻 真吾
技術評論社