myBlog

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

IronPythonで、Dynamic Buttons (kirupa.com) を実行する!

2011-07-20 14:27:12 | Animation
WPF/IronPythonで、kirupa.com のDynamic Buttons 実行しました。
Snowの補足説明で知った、kirupa.com を閲覧していると、
このプログラムが目にとまった。さっそくC#からIronPythonへ変換した。

[WPF/C#] Dynamic Buttons + Event Handling
http://www.kirupa.com/forum/showthread.php?250392-WPF-C-Dynamic-Buttons-Event-Handling

予想通り、おもしろいプログラムだった。

Dynamicbuttons

#
# DynamicButtons.py
#
import clr
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("PresentationCore")
from System import Random
from System.Windows import(Window, Application,
        Thickness, HorizontalAlignment, VerticalAlignment, MessageBox) 
from System.Windows.Markup import XamlReader
from System.Windows.Controls import Button
xaml_str="""
<Window x:Name="Window"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xml:lang="en-US"
    Title="Dynamic Buttons"
    Width="400" Height="300"
    Icon="http://softgarden.lovepop.jp/myBlog/image/shape_group.png">
    <Window.Resources>
        <Style x:Key="CurvedButton" BasedOn="{x:Null}" TargetType="{x:Type Button}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <ControlTemplate.Resources>
                            <Storyboard x:Key="OnMouseMove1">
                                <ColorAnimationUsingKeyFrames BeginTime="00:00:00" 
                                    Storyboard.TargetName="rectangle"
                                    Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00" Value="#FFFFFFFF"/>
                                    <SplineColorKeyFrame KeyTime="00:00:00.3000000" Value="#7CE1DBDB"/>
                                </ColorAnimationUsingKeyFrames>
                                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                    Storyboard.TargetName="rectangle" 
                                    Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
                                    <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
                                    <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1.66"/>
                                </DoubleAnimationUsingKeyFrames>
                                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                    Storyboard.TargetName="rectangle"
                                    Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
                                    <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
                                    <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1.66"/>
                                </DoubleAnimationUsingKeyFrames>
                            </Storyboard>
                            <Storyboard x:Key="OnMouseLeave1">
                                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                    Storyboard.TargetName="rectangle"
                                    Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
                                    <SplineDoubleKeyFrame KeyTime="00:00:00.8000000" Value="1.78"/>
                                    <SplineDoubleKeyFrame KeyTime="00:00:01" Value="1"/>
                                </DoubleAnimationUsingKeyFrames>
                                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                    Storyboard.TargetName="rectangle"
                                    Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
                                    <SplineDoubleKeyFrame KeyTime="00:00:00.8000000" Value="1.78"/>
                                    <SplineDoubleKeyFrame KeyTime="00:00:01" Value="1"/>
                                </DoubleAnimationUsingKeyFrames>
                            </Storyboard>
                            <Storyboard x:Key="OnClick1">
                                <ColorAnimationUsingKeyFrames BeginTime="00:00:00"
                                    Storyboard.TargetName="rectangle"
                                    Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.2000000" Value="#FFFFFFFF"/>
                                    <SplineColorKeyFrame KeyTime="00:00:00.3000000" Value="#BFA0D1E2"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
                        </ControlTemplate.Resources>
                        <Grid>
                            <Rectangle x:Name="rectangle" RenderTransformOrigin="0.5,0.5" 
                                Fill="#3FFFFFFF" Stroke="{x:Null}" RadiusX="11" RadiusY="11">
                                <Rectangle.RenderTransform>
                                    <TransformGroup>
                                        <ScaleTransform ScaleX="1" ScaleY="1"/>
                                        <SkewTransform AngleX="0" AngleY="0"/>
                                        <RotateTransform Angle="0"/>
                                        <TranslateTransform X="0" Y="0"/>
                                    </TransformGroup>
                                </Rectangle.RenderTransform>
                            </Rectangle>
                            <ContentPresenter 
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                RecognizesAccessKey="True"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <EventTrigger RoutedEvent="ButtonBase.Click">
                                <BeginStoryboard x:Name="OnClick1_BeginStoryboard"
                                    Storyboard="{StaticResource OnClick1}"/>
                            </EventTrigger>
                            <EventTrigger RoutedEvent="Mouse.MouseLeave">
                                <BeginStoryboard x:Name="OnMouseLeave1_BeginStoryboard"
                                    Storyboard="{StaticResource OnMouseLeave1}"/>
                            </EventTrigger>
                            <EventTrigger RoutedEvent="FrameworkElement.Loaded"/>
                            <EventTrigger RoutedEvent="Mouse.MouseEnter">
                                <BeginStoryboard x:Name="OnMouseMove1_BeginStoryboard"
                                    Storyboard="{StaticResource OnMouseMove1}"/>
                            </EventTrigger>
                            <Trigger Property="IsFocused" Value="True"/>
                            <Trigger Property="IsDefaulted" Value="True"/>
                            <Trigger Property="IsMouseOver" Value="True"/>
                            <Trigger Property="IsPressed" Value="True"/>
                            <Trigger Property="IsEnabled" Value="False"/>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="Background">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
                        <GradientStop Color="#FFF3F3F3" Offset="0"/>
                        <GradientStop Color="#FFEBEBEB" Offset="0.5"/>
                        <GradientStop Color="#FFDDDDDD" Offset="0.5"/>
                        <GradientStop Color="#E1CDCDCD" Offset="1"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded"/>
    </Window.Triggers>
    <Window.Background>
        <LinearGradientBrush EndPoint="0.484,0.543" StartPoint="0.478,0.009">
            <GradientStop Color="#FF2A3641" Offset="1"/>
            <GradientStop Color="#FF7B8EA1" Offset="0"/>
        </LinearGradientBrush>
    </Window.Background>

    <Grid x:Name="LayoutRoot">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
    </Grid>
</Window>
"""
class ExWindow(object):
    def __init__(self):
       #this.InitializeComponent();
       self.Root = win = XamlReader.Parse(xaml_str)
       win.Title += " in IronPython"
       self.Window = win.FindName("Window")
       self.LayoutRoot = win.FindName("LayoutRoot")
       #// Insert code required on object creation below this point.
       self.populateButtons()
                
    def populateButtons(self):
        ranNum = Random()
        for i in range(50):
            foo = Button()
            buttonStyle = self.Window.Resources["CurvedButton"]
            sizeValue = ranNum.Next(50)
            foo.Width = sizeValue
            foo.Height = sizeValue
            xPos = ranNum.Next(300)
            yPos = ranNum.Next(200)
            foo.HorizontalAlignment = HorizontalAlignment.Left
            foo.VerticalAlignment = VerticalAlignment.Top
            foo.Margin = Thickness(xPos, yPos, 0, 0)
            foo.Style = buttonStyle
            foo.Name = "button" + str(i)
            foo.Click += self.buttonClick
            self.LayoutRoot.Children.Add(foo)

    def buttonClick(self, sender, e):
        clicked = sender
        #MessageBox.Show("Button's name is: " + clicked.Name)
        print "Button's name is: " + clicked.Name

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

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

IronPython - WPF で、投稿したBlog 一覧

2011-07-19 17:35:15 | IronPython-WPF投稿一覧

Python Tools for Visual Studioで、赤い光沢(RedGlass)のあるボタン(Button)を動かした

Python Tools for Visual Studioで、Art55 衝動アプリ!を動かした

Python Tools for Visual Studioで、clock and calcを動かした

Python Tools for Visual Studioで、Snowを動かした

赤い光沢(RedGlass)のあるボタン(Button)とプログレスバー(ProgressBar)

自由にドラッグできる、電卓を作りました! 《 Drag Calc 》

動的にアニメーションの動作を変える!

Dynamic Buttons (kirupa.com) を実行する!

Art55 の《 衝動アプリ!アニメーションをふんだんに使ってみる!》を実行する!

今度は ViewboxUnits を Absolute で Tile を実行する!

advanced Tile (Gestalt Transformations Pack) を実行する!

Tile (Gestalt Transformations Pack) を実行する!

Snow ( Gastaltのサンプル ) を実行する!

お掃除ロボット( Xamloomba )を動かす!

Gestalt の Sample を動かす! 《 WPF/IronPython 》

自由にドラッグできる、時計を作りました! 《 Drag clock 》

Loose XAML を実行する for Google Chrome12

MouseEnterで図形が動きだすAnimation

Windowの背景をグラデーション表示 《 IMultiValueConverter 使用 》

XAMLから、ドックパネル( DockPanel )を表示

図形とブラシ( Shape, Brush )を動的に作成

ColorListView を作りました

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

動的に IValueConverter を使う

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

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

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

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

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

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

ColorComboBoxをつくりました

TemplateBinding を使う


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

IronPythonで、Art55 の《 衝動アプリ!アニメーションをふんだんに使ってみる!》を実行する!

2011-07-18 12:23:26 | Animation
WPF/IronPythonで、Art55さんの 衝動アプリ!を実行してみました。

創造的プログラミングと粘土細工 ⇒
【WPF】衝動アプリ!アニメーションをふんだんに使ってみる!
http://pro.art55.jp/?eid=1119019
は、本当に衝動アプリだ! 本当に眼から鱗だ!!

Window XAML ⇒ Art55.xaml
http://softgarden.lovepop.jp/myBlog/xaml/Art55.xaml
Resouces XAML ⇒ Art55_Resouces.xaml
http://softgarden.lovepop.jp/myBlog/xaml/Art55_Resouces.xaml

C# から IronPythoon に変換するときに、勝手に myBlog 用に少しアレンジしています。

Art55

#
# Art55.py
#
import clr
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("PresentationCore")
from System.Windows import ( Window, WindowState, Application ,
             MessageBox, MessageBoxButton, MessageBoxImage, MessageBoxResult)
from System.Windows.Markup import XamlReader

def LoadXamlFromNet(strUrl):
    import System
    request = System.Net.WebRequest.Create(strUrl)
    response = request.GetResponse()
    dataStream = response.GetResponseStream()
    try:
        element = XamlReader.Load(dataStream)
    finally:
        dataStream.Close()
        response.Close()
    return element

def mySetWinButton(sender,e):
    win = sender
    wt = win.Template
    (wt.FindName("Label1",win)).MouseLeftButtonDown += OnMove
    (wt.FindName("Label1",win)).MouseDoubleClick += OnMaximam
    (wt.FindName("Button1",win)).Click += OnMimimam
    (wt.FindName("Button2",win)).Click += OnMaximam
    (wt.FindName("Button3",win)).Click += OnClose

def OnClose(sender, e):
        window = sender.TemplatedParent
        r = MessageBox.Show(
            "Window close?",
            window.Title,
            MessageBoxButton.YesNo,
            MessageBoxImage.Warning )
        if r == MessageBoxResult.No:
            pass
        else:
            window.Close()

def OnMove(sender, e):
        window = sender.TemplatedParent
        window.DragMove()

def OnMaximam(sender, e):
        window = sender.TemplatedParent
        if (window.WindowState != WindowState.Maximized) :
            window.WindowState = WindowState.Maximized
        else:
            window.WindowState = WindowState.Normal

def OnMimimam(sender, e):
        window = sender.TemplatedParent
        if (window.WindowState != WindowState.Minimized) :
            window.WindowState = WindowState.Minimized
        else:
            window.WindowState = WindowState.Normal

if __name__ == "__main__":
    win = LoadXamlFromNet("http://softgarden.lovepop.jp/myBlog/xaml/Art55.xaml")
    win.Title = "Art55's Animation in IronPython"
    style = LoadXamlFromNet("http://softgarden.lovepop.jp/myBlog/xaml/Art55_Resouces.xaml")
    win.Style = style["CustomWindowChrome"]
    win.Loaded += mySetWinButton
    Application().Run(win)
IronPythonの世界 (Windows Script Programming)
荒井 省三
ソフトバンク クリエイティブ
エキスパートPythonプログラミング
Tarek Ziade
アスキー・メディアワークス
Pythonスタートブック
辻 真吾
技術評論社

IronPythonで、今度は ViewboxUnits を Absolute で Tile を実行する!

2011-07-17 23:44:49 | Animation
WPF/IronPythonで、ViewboxUnits を Absolute で Tile を実行する。
ImageBrush のViewBoxの使い方に慣れてきました。
つぎのBlogを参考にさせて頂きました。

川西 裕幸のブログ ⇒ WPFでテクスチャ移動アニメーション
http://blogs.msdn.com/b/hiroyuk/archive/2007/09/14/4905174.aspx

創造的プログラミングと粘土細工 ⇒ 【WPF】Visibilityってご存じですよね?
http://pro.art55.jp/?eid=969079

画像の上で、マウスを押しながら移動すると、画像がそれに合わせて移動します。
マウス右クリックで、Coverを表示しません( Visibility.Collapsed )
今度は、Tile の上でマウスのホイールを回すと Coverが表示されます( Visibility.Visible )
もう一度、マウス右クリックで Coverが表示されます( Visibility.Visible )
マウスカーソルの形も変化します。

Viewboxtile_absolute

#
# ViewBoxTile_Absolute.py
#
import clr
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReference('WindowsBase')  # for Point, Rect
from System import Convert, Math, Uri
from System.Windows import Window, Application, Rect, Point, Visibility
from System.Windows.Markup import XamlReader
from System.Windows.Controls import Canvas, UserControl
from System.Windows.Media import( ImageBrush, AlignmentX, AlignmentY, Stretch, 
        BrushMappingMode, Brushes, SolidColorBrush, Colors, Color )
from System.Windows.Media.Imaging import BitmapImage
from System.Windows.Shapes import Rectangle
from System.Windows.Input import Mouse, Cursors

class Tile(Canvas):
    def __init__(self):
        self.targetAngle = 0
        self.layoutRoot = Canvas()
        self.Children.Add(self.layoutRoot)
              
        self.bkgBrush = ImageBrush(
            ImageSource = BitmapImage(Uri("http://softgarden.lovepop.jp/myBlog/image/pic3.png")))
        self.bkgBrush.AlignmentX = AlignmentX.Left
        self.bkgBrush.AlignmentY = AlignmentY.Top
        self.bkgBrush.Stretch = Stretch.None 
        #self.bkgBrush.Viewport = Rect(0,0,1.0,1.0)
        self.bkgBrush.ViewboxUnits = BrushMappingMode.Absolute # New
        self.bkgBrush.Viewbox = Rect(0,0,640,400) # New

        self.bkg = Rectangle()
        self.bkg.Width = 250
        self.bkg.Height = 250
        self.bkg.Fill = self.bkgBrush
        self.layoutRoot.Children.Add(self.bkg)

        self.isMouseDown = False
        self.currentPoint = Point(0,0)
        self.oldPoint = Point(0,0)
        self.layoutRoot.MouseDown += self.LayoutRoot_MouseDown
        self.layoutRoot.MouseUp += self.LayoutRoot_MouseUp
        self.layoutRoot.MouseMove += self.LayoutRoot_MouseMove
        #self.layoutRoot.MouseWheel += self.LayoutRoot_MouseWheel
        self.layoutRoot.MouseRightButtonDown += self.LayoutRoot_MouseRightButtonDown
        self.win = None
  
    def LayoutRoot_MouseDown(self, sender, e):
        self.isMouseDown = True
        self.oldPoint = e.GetPosition(self.layoutRoot)
        self.currentPoint = Point(self.bkgBrush.Viewbox.X, self.bkgBrush.Viewbox.Y)
        self.layoutRoot.CaptureMouse()
        Mouse.OverrideCursor = Cursors.Hand

    def LayoutRoot_MouseUp(self, sender, e):
        self.isMouseDown = False
        self.layoutRoot.ReleaseMouseCapture()
        Mouse.OverrideCursor = Cursors.Arrow

    def LayoutRoot_MouseMove(self, sender, e):
        if (self.isMouseDown):
            newPoint = e.GetPosition(self.layoutRoot)
            r = Rect(self.currentPoint.X - (newPoint.X - self.oldPoint.X) ,
                     self.currentPoint.Y - (newPoint.Y - self.oldPoint.Y), 0 ,0)
            self.bkgBrush.Viewbox = r

#   def LayoutRoot_MouseWheel(self, sender, e):
    def LayoutRoot_MouseRightButtonDown(self, sender, e):
        self.win.cover.Visibility = Visibility.Visible
        self.win.isMouseDown = False
        Mouse.OverrideCursor = Cursors.Arrow

    def SetX(self, value):
        self.SetValue(Canvas.LeftProperty, Convert.ToDouble(value))
    def GetX(self):
        return self.GetValue(Canvas.LeftProperty)
    X = property(GetX, SetX)
          
    def SetY(self, value):
        self.SetValue(Canvas.TopProperty, Convert.ToDouble(value))
    def GetY(self):
        return self.GetValue(Canvas.TopProperty)
    Y = property(GetY, SetY)

class TileWindow(Window):
    def __init__(self):
        self.Title="ViewBoxTile_Absolute.py"
        self.Width = 600
        self.Height= 330
        self.Background = Brushes.Black
        xaml_str="""  
            <UserControl 
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:xaml="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
                Width="600" Height="300">
                <Canvas x:Name="LayoutRoot" Background="LightGray"> <!-- "#222222" -->
                    <Canvas x:Name="tiles"></Canvas>
                    <Image x:Name="cover" 
                        Source="http://softgarden.lovepop.jp/myBlog/image/cover.png" 
                        Width="600" Height="330" Stretch="Fill" Visibility="Collapsed">
                    </Image>
                 </Canvas>
            </UserControl>"""
        userControl = XamlReader.Parse(xaml_str)
        self.layoutRoot = userControl.FindName("LayoutRoot")
        self.tiles = userControl.FindName("tiles")
        self.cover = userControl.FindName("cover")
        self.Content = userControl
      
        self.tile = s = Tile()
        s.X = 160
        s.Y = 25
        s.bkgBrush.Viewbox = Rect(s.X + 40, s.Y + 25, 0, 0 ) # New
        s.win = self # New
        self.tiles.Children.Add(s)

        self.isMouseDown = False
        self.currentPoint = Point(0,0)
        self.oldPoint = Point(0,0)
        self.cover.MouseDown += self.Cover_MouseDown
        self.cover.MouseUp += self.Cover_MouseUp
        self.cover.MouseMove += self.Cover_MouseMove
        self.cover.MouseRightButtonDown += self.Cover_MouseRightButtonDown
        self.cover.Visibility = Visibility.Visible
        self.rectTiles = Rect(166, 33, 409, 276)

    def Cover_MouseDown(self, sender, e):
        position = e.GetPosition(self.cover) #Mouse.GetPosition(sender)
        if self.rectTiles.Contains(position): 
            self.isMouseDown = True
            self.oldPoint = position
            self.currentPoint = Point(self.tile.bkgBrush.Viewbox.X, self.tile.bkgBrush.Viewbox.Y)
            self.cover.CaptureMouse()
            Mouse.OverrideCursor = Cursors.Hand

    def Cover_MouseUp(self, sender, e):
        self.isMouseDown = False
        #self.currentPoint = Point(self.tile.bkgBrush.Viewbox.X, self.tile.bkgBrush.Viewbox.Y)
        self.cover.ReleaseMouseCapture()
        Mouse.OverrideCursor = Cursors.Arrow

    def  Cover_MouseMove(self, sender, e):
        if (self.isMouseDown):
            newPoint = e.GetPosition(self.layoutRoot)
            r = Rect(self.currentPoint.X - (newPoint.X - self.oldPoint.X) ,
                     self.currentPoint.Y - (newPoint.Y - self.oldPoint.Y), 0 ,0)
            self.tile.bkgBrush.Viewbox = r

    def Cover_MouseRightButtonDown(self, sender, e):
        self.cover.Visibility = Visibility.Collapsed

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

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

IronPythonで、advanced Tile (Gestalt Transformations Pack) を実行する!

2011-07-16 14:59:00 | Animation
ひき続き、WPF/IronPythonで、Gestalt advanced Tile(Transformations Pack)サンプルを実行する。
Gestalt ⇒ samples ⇒ Transformations Pack ⇒ view 2
http://www.visitmix.com/labs/gestalt/samples/
ImageBrush の変換に少し苦労しました。
WPFとSilverlightの違いがわかった。
Silverlightは、ほぼ WPFのサブセットだ。
ぜひ、実行してみてください、ダイナッミクに画面が変わる、おもしろいプログラムです。

Advanced_tile

#
# advanced.tile.py
#   from:transform.advanced.python.html
#
import clr
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReference('WindowsBase')  # for Point, Rect
from System import Convert, Math, Uri
from System.Windows import Window, Application, Rect, Point, Visibility
from System.Windows.Markup import XamlReader
from System.Windows.Controls import Canvas, UserControl
from System.Windows.Media import( ImageBrush, TranslateTransform, AlignmentX, AlignmentY, Stretch,
    CompositionTarget, Brushes, ScaleTransform, RotateTransform, TransformGroup )
from System.Windows.Media.Imaging import BitmapImage
from System.Windows.Shapes import Rectangle

class Tile(Canvas):
    def __init__(self):
        self.targetAngle = 0
        layoutRoot = Canvas()
        self.Children.Add(layoutRoot)
        #self.bkgBrushPosition = TranslateTransform()
        #self.bkgBrushPosition = Point(0, 0)
        #self.bkgBrushPosition.X = 0
        #self.bkgBrushPosition.Y = 0
        self.bkgBrush = ImageBrush(
            ImageSource = BitmapImage(Uri("http://softgarden.lovepop.jp/myBlog/image/pic3.png")))
        self.bkgBrush.AlignmentX = AlignmentX.Left
        self.bkgBrush.AlignmentY = AlignmentY.Top
        self.bkgBrush.Stretch = Stretch.None 
        #self.bkgBrush.Transform = self.bkgBrushPosition
        #self.bkgBrush.Viewport = Rect(0,0,1.0,1.0) # New
 
        self.bkg = Rectangle()
        self.bkg.Width = 30
        self.bkg.Height = 30
        self.bkg.Fill = self.bkgBrush
        self.bkg.RenderTransformOrigin = Point (0.45,0.45)
        layoutRoot.Children.Add(self.bkg)
      
        self.scale = ScaleTransform()
        self.scale.ScaleX = 1.0
        self.scale.ScaleY = 1.0
        self.rotation = RotateTransform()
        self.rotation.Angle = 0
        transformGroup = TransformGroup()
        transformGroup.Children.Add(self.scale)
        transformGroup.Children.Add(self.rotation)
        self.bkg.RenderTransform = transformGroup

        CompositionTarget.Rendering += self.compositionTarget_Rendering
                       
    def compositionTarget_Rendering(self, sender, e):
        self.rotation.Angle = self.rotation.Angle + ( self.targetAngle - self.rotation.Angle) * .13

    def SetBkgBrushXY(self, x, y):
        self.bkgBrush.Viewbox = Rect(x/640.0, y/400.0, 0, 0) # New

    def SetX(self, value):
        self.SetValue(Canvas.LeftProperty, Convert.ToDouble(value))
    def GetX(self):
        return self.GetValue(Canvas.LeftProperty)
    X = property(GetX, SetX)
          
    def SetY(self, value):
        self.SetValue(Canvas.TopProperty, Convert.ToDouble(value))
    def GetY(self):
        return self.GetValue(Canvas.TopProperty)
    Y = property(GetY, SetY)

class TileWindow(Window):
    def __init__(self):
        self.Title = "advanced.tile.py" #"Advanced Python Transforms"
        self.Width = 600
        self.Height= 350
        self.Background = Brushes.Black
        xaml_str="""  
            <UserControl 
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:xaml="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
                Width="600" Height="300">
                <Canvas x:Name="LayoutRoot" Background="#222222">
                    <Canvas x:Name="tiles"></Canvas>
                    <Image x:Name="cover" 
                     Source="http://softgarden.lovepop.jp/myBlog/image/cover.png" 
                     Width="600" Height="330" Stretch="Fill" Visibility="Collapsed">
                    </Image>
                </Canvas>
            </UserControl>"""
        userControl = XamlReader.Parse(xaml_str)
        self.layoutRoot = userControl.FindName("LayoutRoot")
        self.tiles = userControl.FindName("tiles")
        self.cover = userControl.FindName("cover")
        self.Content = userControl

        for x in range(0,10):
            for y in range(0, 10):
                s = Tile()
                s.X = 160 + (x * 25)
                s.Y = 25 + (y * 25)
                #s.bkgBrushPosition.X = -s.X - 45;
                #s.bkgBrushPosition.Y = -s.Y - 30;
                s.SetBkgBrushXY(s.X + 40  , s.Y + 25  ) # New
                self.tiles.Children.Add(s)
        self.mouse = Point(0, 0)
        self.layoutRoot.MouseMove += self.LayoutRoot_MouseMove
        self.cover.Visibility = Visibility.Visible
        CompositionTarget.Rendering += self.compositionTarget_Rendering
   
    def LayoutRoot_MouseMove(self,sender, e):
        self.mouse = e.GetPosition(self.layoutRoot)
          
    def compositionTarget_Rendering(self, sender, e):
        for s in self.tiles.Children:
            _y = s.Y - self.mouse.Y
            _x = s.X - self.mouse.X
            distance = Math.Sqrt((_y * _y) + (_x * _x))
            rad = Math.Atan2(_y, _x)
            angle = rad * (180 / Math.PI)
            newScale = .3 + ((distance / 100.0));
            if newScale > 1.2:
                newScale = 1.2
            s.scale.ScaleX = s.scale.ScaleY = newScale
            if distance < 100:
                s.targetAngle = angle - 180
            else: 
                s.targetAngle = 0

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

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