myBlog

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

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

2011-07-22 23:57:47 | Animation
IronPythonで、Storyboard.Begin メソッド の HandoffBehavior を使って 動的にアニメーションを変化させます。
MSDNを調べていると、面白いサンプルがあったので、IronPython に変換して実行してみました。
http://207.46.16.248/ja-jp/library/ms605722(VS.90).aspx

ユーザーがクリックしたときに SnapshotAndReplace の HandoffBehavior を使用してアニメーション化し、
ユーザーが右クリックしたときには Compose の HandoffBehavior を使用する例を次に示します。
微妙に動作に違いがあります。

Interactiveanimationexample

#
# InteractiveAnimationExample.py
#   This sample animates the position of an ellipse when 
#   the user clicks within the main border. If the user
#   left-clicks, the SnapshotAndReplace HandoffBehavior
#   is used when applying the animations. If the user
#   right-clicks, the Compose HandoffBehavior is used
#   instead.
#
import clr
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReference('WindowsBase')  # for Point
from System import TimeSpan
from System.Windows import( Window, Application, NameScope, Thickness, Point,
        PropertyPath, HorizontalAlignment, VerticalAlignment )
from System.Windows.Controls import DockPanel, Border
from System.Windows.Media import Brushes, TranslateTransform
from System.Windows.Media.Animation import Storyboard, DoubleAnimation, HandoffBehavior
from System.Windows.Shapes import Ellipse
from System.Windows.Input import Mouse

class ExWindow(Window):
    def __init__(self):
        self.Title = "InteractiveAnimationExample.py"
        self.Width = 600
        self.Height = 400
        #// Create a name scope for the page.
        NameScope.SetNameScope(self, NameScope())

        myPanel = DockPanel()
        myPanel.Margin = Thickness(20.0)          

        containerBorder = Border();
        containerBorder.Background = Brushes.White
        containerBorder.BorderBrush = Brushes.Black
        containerBorder.BorderThickness = Thickness(2.0)
        containerBorder.VerticalAlignment = VerticalAlignment.Stretch

        interactiveEllipse = Ellipse()
        interactiveEllipse.Fill = Brushes.Lime
        interactiveEllipse.Stroke = Brushes.Black
        interactiveEllipse.StrokeThickness = 2.0
        interactiveEllipse.Width = 25
        interactiveEllipse.Height = 25
        interactiveEllipse.HorizontalAlignment = HorizontalAlignment.Left
        interactiveEllipse.VerticalAlignment = VerticalAlignment.Top

        interactiveTranslateTransform = TranslateTransform()      
        self.RegisterName("InteractiveTranslateTransform", interactiveTranslateTransform)

        interactiveEllipse.RenderTransform = interactiveTranslateTransform

        xAnimation = DoubleAnimation()
        xAnimation.Duration = TimeSpan.FromSeconds(4)
        yAnimation = xAnimation.Clone()
        Storyboard.SetTargetName(xAnimation, "InteractiveTranslateTransform")
        Storyboard.SetTargetProperty(xAnimation, PropertyPath(TranslateTransform.XProperty))
        Storyboard.SetTargetName(yAnimation, "InteractiveTranslateTransform")
        Storyboard.SetTargetProperty(yAnimation, PropertyPath(TranslateTransform.YProperty))           

        theStoryboard = Storyboard()
        theStoryboard.Children.Add(xAnimation)
        theStoryboard.Children.Add(yAnimation)

        containerBorder.MouseLeftButtonDown += self.border_mouseLeftButtonDown
        containerBorder.MouseRightButtonDown += self.border_mouseRightButtonDown             

        containerBorder.Child = interactiveEllipse
        myPanel.Children.Add(containerBorder)
        self.Content = myPanel

        self.containerBorder = containerBorder
        self.interactiveEllipse = interactiveEllipse
        self.theStoryboard = theStoryboard
        self.xAnimation = xAnimation
        self.yAnimation = yAnimation

    #// When the user left-clicks, use the 
    #// SnapshotAndReplace HandoffBehavior when applying the animation.        
    def border_mouseLeftButtonDown(self, sender, e):
        clickPoint = Mouse.GetPosition(self.containerBorder)

        #// Set the target point so the center of the ellipse
        #// ends up at the clicked point.
        targetPoint = Point()
        targetPoint.X = clickPoint.X - self.interactiveEllipse.Width / 2
        targetPoint.Y = clickPoint.Y - self.interactiveEllipse.Height / 2  

        #// Animate to the target point.
        self.xAnimation.To = targetPoint.X
        self.yAnimation.To = targetPoint.Y
        self.theStoryboard.Begin(self, HandoffBehavior.SnapshotAndReplace)

        #// Change the color of the ellipse.
        self.interactiveEllipse.Fill = Brushes.Lime

    #// When the user right-clicks, use the 
    #// Compose HandoffBehavior when applying the animation.
    def border_mouseRightButtonDown(self, sender, e):
        #// Find the point where the use clicked.
        clickPoint = Mouse.GetPosition(self.containerBorder)

        #// Set the target point so the center of the ellipse
        #// ends up at the clicked point.
        targetPoint = Point()
        targetPoint.X = clickPoint.X - self.interactiveEllipse.Width / 2
        targetPoint.Y = clickPoint.Y - self.interactiveEllipse.Height / 2

        #// Animate to the target point.
        self.xAnimation.To = targetPoint.X
        self.yAnimation.To = targetPoint.Y
        self.theStoryboard.Begin(self, HandoffBehavior.Compose)

        #// Change the color of the ellipse.
        self.interactiveEllipse.Fill = Brushes.Orange

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

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

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で、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スタートブック
辻 真吾
技術評論社