myBlog

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

IronPythonで、動的なアニメーションで変化するボタンを作りました

2011-07-02 22:38:08 | Animation
BLOG: Nine Works ==> 動的なアニメーション作成
http://nine-works.blog.ocn.ne.jp/blog/2011/01/post_8f38.html
を参考にさせていただきました。
C#のプログラムをIronPythonに変換しました。
そして、少しアレンジしました。

C#とIronPyhonを比べてみてください。 ( Dynamic Animation )

Photo



#
# 動的なアニメーション作成.py
#
import clr
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReference('WindowsBase')

from System.Windows.Markup import XamlReader
from System import Object, TimeSpan
from System.Windows import ( Window, Application, NameScope, Thickness, Duration,
                             PropertyPath, HorizontalAlignment, VerticalAlignment )
from System.Windows.Controls import StackPanel, Button, TextBlock
from System.Windows.Media import Color, Colors, SolidColorBrush
from System.Windows.Media.Animation import Storyboard, RepeatBehavior, DoubleAnimation, ColorAnimation 

xaml_str="""
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="動的なアニメーション作成" Height="200" Width="300">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition />
        </Grid.RowDefinitions>

        <Border BorderBrush="Black" BorderThickness="1" CornerRadius="10" 
            Grid.Row="0" Grid.Column="0" Margin="5" 
            ToolTip="ボタン・アニメーションの種類と動作を指定します。" >
            <StackPanel Orientation="Horizontal" VerticalAlignment="Center" >
                <RadioButton x:Name="radioBig" IsChecked="True" Content="大きくなれ" Margin="10,5"/>
                <RadioButton x:Name="radioSmall" Content="小さくなれ" Margin="10,5" />
                <CheckBox x:Name="stopAnimationCheckBox" Content="アニメーション停止" 
                     HorizontalAlignment="Center" Margin="10,5" />
            </StackPanel>
        </Border>

        <Button Name="button1" Grid.Column="0" Grid.Row="1"
            Width="90" Height="20" Content="おっきくなるよ" 
            HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>
</Window>
"""
class ExWindow(Object):
    def __init__(self):
        win = XamlReader.Parse(xaml_str)
        self.Root = win 
        self.setAttr("button1",win)
        self.setAttr("stopAnimationCheckBox",win)
        self.setAttr("radioBig",win)
        self.setAttr("radioSmall",win)

        self.radioBig.Checked += self.radioBig_Checked
        self.radioSmall.Checked += self.radioSmall_Checked

        self.EXPAND = ( 50.0, ) # タップル  変更不可能

        #// アニメーションを行うコントロールをNameScopeに登録
        #NameScope.SetNameScope(win, NameScope())
        #win.RegisterName(self.button1.Name, self.button1)
        #すでに、登録されているから...

        self.CreateExpandAnimation()

    def setAttr(self, name, xaml):
        x = xaml.FindName(name)
        if x != None : setattr(self, name, x)
        else: print "NameError: '%s' object has no Name '%s'" %(type(xaml),name)

    def CreateExpandAnimation(this):
        #// ボタンの幅を拡大するアニメーション
        #// Byは動的に値を設定するためClickイベントで設定
        this._expandWidthAnimation = DoubleAnimation()
        this._expandWidthAnimation.Duration = Duration(TimeSpan.FromMilliseconds(500))

        #// ボタンの高さを拡大するアニメーション
        #// Byは動的に値を設定するためClickイベントで設定
        this._expandHeightAnimation = DoubleAnimation()
        this._expandHeightAnimation.Duration = Duration(TimeSpan.FromMilliseconds(500))

        #// ストーリーボードを作成
        this._expandStoryboard = Storyboard()
        this._expandStoryboard.Children.Add(this._expandWidthAnimation)
        Storyboard.SetTargetName(this._expandWidthAnimation, this.button1.Name)
        Storyboard.SetTargetProperty(
            this._expandWidthAnimation,
            PropertyPath(Button.WidthProperty))

        this._expandStoryboard.Children.Add(this._expandHeightAnimation)
        Storyboard.SetTargetName(this._expandHeightAnimation, this.button1.Name)
        Storyboard.SetTargetProperty(
            this._expandHeightAnimation,
            PropertyPath(Button.HeightProperty))

        #// イベントハンドラ追加
        this.button1.Click += this.button1_Click

    def button1_Click(self, sender, e):
        if (self.stopAnimationCheckBox.IsChecked == False):
            if (self.radioBig.IsChecked == True): by = self.EXPAND[0]
            else:
                if ( self.button1.Height <= self.EXPAND[0] ) : by = 0.0
                else: by = -self.EXPAND[0]
            if by != 0.0 :
                self._expandWidthAnimation.By = by
                self._expandHeightAnimation.By = by
                self._expandStoryboard.Begin(self.Root)

    def radioBig_Checked(self, sender, e):
        self.button1.Content = "大きくなるよ"

    def radioSmall_Checked(self, sender, e):
        self.button1.Content = "小さくなるよ"

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


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

IronPythonで、3つのSliderからRectangleの背景色を設定 《MultiBinding を使って》

2011-07-02 10:25:57 | DataBinding
e-manual ==> WPF(データバインディング) ==> 複合データバインディング
複合データバインディングとは複数のデータとバインドすることです。
このような場合は、MultiBinding クラスを利用するとともに、
データを変換するクラスを作成しなければなりません。
http://www.kanazawa-net.ne.jp/~pmansato/wpf/wpf_databinding.htm
を参考にしました。C# から IronPython へ 変換。

IronPython から MultiBinding.Converter (IMultiValueConverter) を使用。

Imultivalueconverter_2


#
# IMultiValueConverter.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.Media import Color,SolidColorBrush
from System.Windows.Shapes import Rectangle
from System.Windows.Data import ( Binding,BindingOperations,IValueConverter,
                                  MultiBinding, IMultiValueConverter )
import System

xaml_str="""
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Binding (IMultiValueConverter)" Height="300" Width="320">
  <Window.Resources>
   <Style x:Key="sliderStyle" TargetType="Slider">
      <Setter Property="Width" Value="180" />
      <Setter Property="Minimum" Value="0" />
      <Setter Property="Maximum" Value="255" />
      <Setter Property="LargeChange" Value="16" />
      <Setter Property="SmallChange" Value="1" />
      <Setter Property="TickFrequency" Value="16" />
      <Setter Property="TickPlacement" Value="TopLeft" />
      <Setter Property="IsSnapToTickEnabled" Value="True" />
      <Setter Property="Margin" Value="10" />
    </Style>
  </Window.Resources>
  
  <StackPanel Orientation="Vertical">
    <Slider Name="sliderRed" Style="{StaticResource sliderStyle}" />
    <Slider Name="sliderGreen" Style="{StaticResource sliderStyle}" />
    <Slider Name="sliderBlue" Style="{StaticResource sliderStyle}" />

    <Rectangle Name="rectangle1" Width="200" Height="60" HorizontalAlignment="Center">
      <Rectangle.Fill>
        <SolidColorBrush  x:Name="brush1" />
      </Rectangle.Fill>
    </Rectangle>
  </StackPanel>
</Window>
"""

class ColorConverter(IMultiValueConverter):
    def Convert(self,values, targetType, parameter, culture):
        R = System.Convert.ToByte(values[0])
        G = System.Convert.ToByte(values[1])
        B = System.Convert.ToByte(values[2])  
        return Color.FromRgb(R, G, B)

    def ConvertBack(self,value, targetTypes, parameter, culture):
        return None

class ExWindow(Object):
    def __init__(self):
        win = XamlReader.Parse(xaml_str)
        self.Root = win

        self.rectangle1 = win.FindName("rectangle1")
        self.brush1 = win.FindName("brush1")
        self.sliderRed=win.FindName("sliderRed")
        self.sliderGreen=win.FindName("sliderGreen")
        self.sliderBlue=win.FindName("sliderBlue")

        myMultiBinding = MultiBinding()
        myMultiBinding.Converter = ColorConverter()

        myBinding1 = Binding("Value")
        myBinding1.Source = self.sliderRed
        myBinding1.ConverterParameter = "Value"

        myBinding2 = Binding("Value")
        myBinding2.Source = self.sliderGreen
        myBinding2.ConverterParameter = "Value"

        myBinding3 = Binding("Value")
        myBinding3.Source = self.sliderBlue
        myBinding3.ConverterParameter = "Value"

        myMultiBinding.AddChild(myBinding1)
        myMultiBinding.AddChild(myBinding2)
        myMultiBinding.AddChild(myBinding3)

        BindingOperations.SetBinding(self.brush1,
                                     SolidColorBrush.ColorProperty,
                                     myMultiBinding)

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

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

IronPythonで、カウンターを作りました《 MVVM を使って 》

2011-07-02 04:32:03 | DataBinding
Blog:"[WPF]レイアウトに飽きてきたのでバインディングしてみる"
http://blogs.wankuma.com/kazuki/archive/2007/10/13/101894.aspx
を参考にしました。C# から IronPython へ変換しました。

MVVM 処理を追加しました。

Counterdatabindingnew


#
# CounterDataBindingNew.py
#      MVVM を使用!
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, MessageBox
from System.Windows.Controls import Label
from System.Windows.Data import Binding,IValueConverter
from System.ComponentModel import INotifyPropertyChanged
from System.ComponentModel import PropertyChangedEventArgs

xaml_str="""
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="NewDataBinding" Width="220" SizeToContent="Height">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions> 

        <Label Content="値:" Grid.Row="0" Grid.Column="0" />
        <Label Name="valueLabel" Grid.Row="0" Grid.Column="1" 
               Content="ここに値がきますよと" />
        <Label Content="概要:" Grid.Row="1" Grid.Column="0" />
        <Label Name="descriptionLabel" Grid.Row ="1" Grid.Column="1" 
               Content="ここに概要がきますよと" /> 

        <StackPanel Grid.Row="2" Grid.Column="1" 
                    Orientation="Horizontal" HorizontalAlignment="Right">
            <Button Name="incrButton" Content="インクリメント" Margin="2" />
            <Button Name="decrButton" Content="デクリメント" Margin="2" />
            <Button Name="dumpButton" Content="Dump" Margin="2" />
        </StackPanel>
    </Grid>
</Window>
"""
class ViewModelBase(INotifyPropertyChanged):
     def __init__(self):
         self.propertyChangedHandlers = []
     def RaisePropertyChanged(self, propertyName):
         args = PropertyChangedEventArgs(propertyName)
         for handler in self.propertyChangedHandlers:
             handler(self, args)
     def add_PropertyChanged(self, handler):
         self.propertyChangedHandlers.append(handler)
     def remove_PropertyChanged(self, handler):
         self.propertyChangedHandlers.remove(handler)

class Counter(ViewModelBase):
    def __init__(self):
        ViewModelBase.__init__(self)
        self._Value = 0
        self._Description = ""

    def _getValue(self):
        return self._Value
    def _setValue(self,value):
        self._Value = value
        self.RaisePropertyChanged("Value")
    Value = property(_getValue, _setValue)

    def _getDescription(self):
        return self._Description
    def _setDescription(self,description):
        self._Description = description
        self.RaisePropertyChanged("Description")
    Description = property(_getDescription, _setDescription)

    def Incr(self):
        self.Value += 1

    def Decr(self):
        self.Value -= 1

class ExWindow(Object):
    def __init__(self):
        xaml = XamlReader.Parse(xaml_str)
        self.Root = xaml

        self.setAttr("valueLabel",xaml)
        self.setAttr("descriptionLabel",xaml)
        self.setAttr("incrButton",xaml)
        self.setAttr("decrButton",xaml)
        self.setAttr("dumpButton",xaml)

        self.incrButton.Click += self.incrButton_Click
        self.decrButton.Click += self.decrButton_Click
        self.dumpButton.Click += self.dumpButton_Click

        #// カウンタを作る
        self.counter = Counter()
        self.counter.Description = "これはサンプル用のカウンタです"

        #// Bainding の設定
        self.InitializeBinding()

    def setAttr(self, name, xaml):
        x = xaml.FindName(name)
        if x != None: setattr(self, name, x)
        else: print "NameError: '%s' object has no Name '%s'" %(type(xaml),name)

    def InitializeBinding(self):
        valueBinding = Binding("Value")
        self.valueLabel.SetBinding(Label.ContentProperty, valueBinding) 
        descriptionBinding = Binding("Description")
        self.descriptionLabel.SetBinding(Label.ContentProperty, descriptionBinding)
        #// カウンタをDataContextに!
        self.Root.DataContext = self.counter

    def incrButton_Click(self,sender, e):
        self.counter.Incr()

    def decrButton_Click(self, sender, e):
        self.counter.Decr()

    def dumpButton_Click(self, sender, e):
        #// カウンタの中身を確認
        MessageBox.Show("%d: %s"  % (self.counter.Value, self.counter.Description) )

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


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

IronPythonで、グラデーション色を変更できるボタンを作りました

2011-07-02 01:55:08 | IronPython

IronPythonで、動的にグラデーション色を変更できるボタンを作成。

Yamada Program Blogから グラデーション色を変更できるボタンテンプレート ( http://yamada-program.blogspot.com/2011/04/wpf.html ) を参考にさせていただきました。 C#のプログラムをIronPythonに変換しました。とても、勉強になる。 IValueConverter, Binding.Converter, ControlTemplate, TemplateBinding, TemplateBindingExtension を使用。

Dynamicgradientbutton

#
# DynamicGradientButton.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, Point, Style, Setter, 
                            FrameworkElementFactory, TemplateBindingExtension,
                            HorizontalAlignment, VerticalAlignment, Thickness )
from System.Windows.Controls import ( TextBox, Button, Grid,
                                      ControlTemplate, ContentPresenter )
from System.Windows.Media import (LinearGradientBrush, GradientStop, 
                                  Color, Colors, SolidColorBrush, Brushes )
from System.Windows.Shapes import Ellipse
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="MainWindow" Height="350" Width="525"> 

    <StackPanel x:Name="sp1">
        <Button x:Name="bt1" Content="Button1" Background="Red"/> 
        <Button x:Name="bt2" Content="Button2" Background="Green"/> 
        <Button x:Name="bt3" Content="Button3" Background="Blue"/>
    </StackPanel> 
</Window>
"""

class Brush2ColorConverter(IValueConverter):
    def Convert(self, value, targetType, parameter, culture):
        sb = value # as SolidColorBrush;
        if (sb != None):
             return sb.Color
        else:
            return Colors.White

    def ConvertBack(self,value, TargetType, parameter, culture):
       #throw new NotImplementedException();
       return Binding.DoNothing

class ExWindow(Object):
    def __init__(self):
        win = XamlReader.Parse(xaml_str)
        self.Root = win
        self.bt1= win.FindName("bt1")
        self.bt2= win.FindName("bt2")
        self.bt3= win.FindName("bt3")
 
        style = self.setButtonStyle()
        win.Resources.Add(Button().GetType(), style)

        self.bt1.Click += self.bt1_Click
        self.i = 0

    def setButtonStyle(self):
        myButtonStyle = Style( Button().GetType() )
        #--- temmplate start ------
        template = ControlTemplate( TargetType=Button )
        elemFactory = FrameworkElementFactory(Grid)
        template.VisualTree = elemFactory
        elemFactory1 = FrameworkElementFactory(Ellipse)
        elemFactory1.SetValue(Ellipse.DataContextProperty,
            TemplateBindingExtension(Button.BackgroundProperty))
        elemFactory1.SetValue(Ellipse.StrokeProperty,
            TemplateBindingExtension(Button.BackgroundProperty) )
        brush = LinearGradientBrush(StartPoint = Point(0.5, 0.0), 
                                    EndPoint = Point(0.5, 1.0) )
        grStop = GradientStop( Offset= 0.0 )
        BindingOperations.SetBinding(grStop, GradientStop.ColorProperty,
            Binding( Converter = Brush2ColorConverter() ) )
        brush.GradientStops.Add( grStop )
        brush.GradientStops.Add( GradientStop(Colors.White, 1.0) )
        elemFactory1.SetValue(Ellipse.FillProperty, brush )
        elemFactory.AppendChild(elemFactory1)
        elemFactory2 = FrameworkElementFactory(ContentPresenter)
        elemFactory2.SetValue(ContentPresenter.HorizontalAlignmentProperty,
                              HorizontalAlignment.Center)
        elemFactory2.SetValue(ContentPresenter.VerticalAlignmentProperty,
                              VerticalAlignment.Center)
        elemFactory.AppendChild(elemFactory2)
        #--- temmplate end ------
        setter = Setter()
        setter.Property = Button.TemplateProperty
        setter.Value = template
        myButtonStyle.Setters.Add(setter)
        myButtonStyle.Setters.Add(
            Setter(Property = Button.WidthProperty,Value = 80.0 ) )
        myButtonStyle.Setters.Add(
            Setter(Property = Button.HeightProperty, Value = 25.0) )
        myButtonStyle.Setters.Add(
            Setter(Property = Button.MarginProperty, Value = Thickness(5.0)) )
        myButtonStyle.Setters.Add(
            Setter(Property = Button.ForegroundProperty, Value = Brushes.White ) )
        return myButtonStyle

    def bt1_Click(self,sender,e):
        i = self.i % 3
        if i == 0 :
            self.bt2.Background = Brushes.Lime
            self.bt3.Background = Brushes.Black
        elif i == 1 :
            self.bt2.Background = Brushes.Orange
            self.bt3.Background = Brushes.Green
        else:
            self.bt2.Background = Brushes.Blue
            self.bt3.Background = Brushes.Red
        self.i += 1

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

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

IronPythonでColorComboBoxをつくりました

2011-07-01 23:21:17 | IronPython

IronPythonで色を選択するComboBoxをつくりました.。

XAML と IronPythonを1つのファイルに、まとめています。

Colorcombobox

#
# ColorComboBox.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, CornerRadius, Thickness
from System.Windows.Controls import (StackPanel, Border, Orientation,
                    ComboBoxItem, ComboBoxItem, TextBlock )
from System.Windows.Media import Color, Colors, SolidColorBrush, Brushes

xaml_str="""
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Color ComboBox" Height="62" Width="220" >
  <ComboBox Name="comboBox1" Height ="25" MaxDropDownHeight="338"/>
</Window>
"""

class ExWindow(Object):
    def __init__(self):
        win = XamlReader.Parse(xaml_str)
        self.Root = win
        self.comboBox1 = win.FindName("comboBox1")
        win.Loaded += self.window1_Loaded

    def window1_Loaded(self, sender, e):
        self.SetupComboBox()
        if (self.comboBox1.Items.Count > 0):
           self.comboBox1.SelectedIndex = 0

    def SetupComboBox(self):
        item = ComboBoxItem()

        infs=[]
        for name in dir(Colors):
            c = getattr(Colors, name)
            if isinstance(c, Color):
                infs.append([name, SolidColorBrush(c)])

        for name, col in infs:
            brush = col
            item = ComboBoxItem()

            panel = StackPanel()
            panel.Orientation = Orientation.Horizontal

            border = Border()
            border.Background = brush
            border.CornerRadius = CornerRadius(3)
            border.Width = 30
            border.Height = 12
            border.BorderBrush = Brushes.Black
            border.BorderThickness = Thickness(1)

            block = TextBlock()
            block.Text = name
            block.Width = self.comboBox1.Width - border.Width - 20
            block.Margin = Thickness(10, 0, 0, 0)

            panel.Children.Add(border)
            panel.Children.Add(block)

            item.Content = panel
            self.comboBox1.Items.Add(item)

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

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