myBlog

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

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

2011-07-31 07:55:59 | IronPython
IronPython で、下記のBlogを参考にして、赤い光沢のあるボタン(Button)とプログレスバー(ProgressBar)を
作ってみました。
日向ぼっこデベロッパhandcraftの備忘録 ⇒
[WPF] StyleとTemplateを使用してWPFのButtonとProgressBarのUIを変更する
http://handcraft.blogsite.org/ComponentGeek/ShowArticle/115.aspx
http://www.pine4.net/Memo/Article/Archives/115
『WPFのStyle,Templateを使用してボタンとプログレスバーのUIを変更するサンプルを掲載します。
赤い光沢のあるボタンとプログレスバーを作ってみます。』

そして、Nine WorksさんのBlogを参考にして、プログレス処理を追加しました。
Nine Works ⇒ ProgressBarとBackgroundWorker
http://nine-works.blog.ocn.ne.jp/blog/2011/06/progressbarback.html

赤い光沢のあるボタン XAML ⇒ RedButton.xaml
http://softgarden.lovepop.jp/myBlog/xaml/RedButton.xaml
赤い光沢のあるプログレスバー XAML ⇒ RedProgressBar.xaml
http://softgarden.lovepop.jp/myBlog/xaml/RedProgressBar.xaml
共通リソース XAML ⇒ CommonResource.xaml
http://softgarden.lovepop.jp/myBlog/xaml/CommonResource.xaml

Redglass

#
# RedGlass.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, MessageBox
from System.ComponentModel import BackgroundWorker

xaml_str="""
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="RedGlass.py" Width="300" Height="110">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="http://softgarden137.github.io/RedGlass/RedButton.xaml" />
                <ResourceDictionary Source="http://softgarden137.github.io/RedGlass/RedProgressBar.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

    <Canvas>
        <ProgressBar Name="progressBar"
            Canvas.Left="0" Canvas.Top="0"
            Minimum="0" Maximum="10000"
            Margin="5" Width="200" Height="25"/>
        <TextBlock Name="statusTextBlock" Width="100"
            Canvas.Left="215" Canvas.Top="10"/>
        <Button Name="startButton"  
            Canvas.Left="110" Canvas.Top="35"
            Margin="5" Width="80" Height="25" Content="Start"
            Style="{StaticResource RedButton}"/>
        <Button Name="stopButton"
            Canvas.Left="200" Canvas.Top="35"
            Margin="5" Width="80" Height="25" Content="Stop" IsEnabled="False"
            Style="{StaticResource RedButton}"/>
    </Canvas>
</Window>
"""
class ExWindow(Object):
    def __init__(self):
        self.Root = win = XamlReader.Parse(xaml_str)

        self.progressBar = win.FindName("progressBar")
        self.statusTextBlock = win.FindName("statusTextBlock")
        self.startButton = win.FindName("startButton")
        self.stopButton = win.FindName("stopButton")

        self.startButton.Click += self.startButton_Click
        self.stopButton.Click += self.stopButton_Click 

        self.bw = BackgroundWorker()
        #// 進捗状況の更新を可能にする
        self.bw.WorkerReportsProgress = True
        #// キャンセルを可能にする
        self.bw.WorkerSupportsCancellation = True

        #// バックグラウンド行う処理
        self.bw.DoWork += self.bw_DoWork
        #// 進捗状況の更新を行う処理
        self.bw.ProgressChanged += self.bw_ProgressChanged
        #// バックグラウンドでの処理が終了後の処理
        self.bw.RunWorkerCompleted += self.bw_RunWorkerCompleted

    #// 時間のかかる処理
    def bw_DoWork(self, sender, e):
        import System
        for i in range(1,10001):
            if (self.bw.CancellationPending == True):
                #// キャンセルされたので処理を終了
                e.Cancel = True
                break

            #// 現在の進捗状況(数値)
            currentValue = i

            #// currentValue以外の進捗状況を表す情報(オプション)
            status = str(i) + " / 10000"

            #// 進捗状況を報告
            self.bw.ReportProgress(currentValue, status)

            #// 何らかの処理(ここではスリープさせるだけ)
            System.Threading.Thread.Sleep(1)

        #// 操作の結果を渡したい場合はe.Resultを使う
        e.Result = "[終了結果]"

    #// 進捗状況の更新処理
    def bw_ProgressChanged(self, sender, e):
        #// プログレスバーの値を更新
        self.progressBar.Value = e.ProgressPercentage

        #// プログレスバー以外の状況更新
        self.statusTextBlock.Text = e.UserState.ToString()

    #// 時間のかかる処理が終わった後の後処理
    def bw_RunWorkerCompleted(self, sender, e):
        self.statusTextBlock.Text = ""
        self.progressBar.Value = 0

        if (e.Cancelled == True):
            MessageBox.Show("処理を中断しました。")
        else:
            MessageBox.Show("処理が終了しました。" + e.Result.ToString())

        self.startButton.IsEnabled = True
        self.stopButton.IsEnabled = False

    #// 処理開始
    def startButton_Click(self, sender, e):
        self.startButton.IsEnabled = False
        self.stopButton.IsEnabled = True

        #// 時間のかかる処理を実行する
        self.bw.RunWorkerAsync()
    
    #// 作業を途中で止める
    def stopButton_Click(self, sender, e):
       self.bw.CancelAsync()

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

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

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

2011-07-30 10:24:06 | IronPython
IronPython WPF サンプルの calc を myBlog用に変換しました。
下記のBlogを参考にして、Drag可能な、電卓(calc)にしました。
Blog: jimmy.thinking ⇒ Dragging elements in Silverlight with DLRConsole
http://blog.jimmy.schementi.com/2008/08/dragging-elements-in-silverlight-with.html

MSDN Blogs ⇒ 荒井省三のBlog ⇒ DLR Console を使って時計をドラッグするサンプル
http://blogs.msdn.com/b/shozoa/archive/2008/09/03/dragging-clock-on-dlr-console.aspx

Calc XAML⇒calc.xaml ⇒ 電卓(calc)
http://softgarden.lovepop.jp/myBlog/xaml/calc.xaml

Calc

#####################################################################################
#
#  Copyright (c) Microsoft Corporation. All rights reserved.
#
# This source code is subject to terms and conditions of the Microsoft Public License. A 
# copy of the license can be found in the License.html file at the root of this distribution. If 
# you cannot locate the  Microsoft Public License, please send an email to 
# ironpy@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
# by the terms of the Microsoft Public License.
#
# You must not remove this notice, or any other, from this software.
#
#
#####################################################################################
#
# calculator.py
#
from System.Windows.Controls import *

def Walk(tree):
    yield tree
    if hasattr(tree, 'Children'):
        for child in tree.Children:
            for x in Walk(child):
                yield x
    elif hasattr(tree, 'Child'):
        for x in Walk(tree.Child):
            yield x
    elif hasattr(tree, 'Content'):
        for x in Walk(tree.Content):
            yield x

def enliven(w):
    try:
        controls = [ n for n in Walk(w) if isinstance(n, Button) or isinstance(n, TextBox) ]
        Calculator(controls)
    except:
        print "Function failed. Did you pass in the Calculator window?"

class Calculator:

    def __init__(self, controls):
        self.expression = ""

        for i in controls:
            if isinstance(i, Button):
                if hasattr(self, "on_" + i.Name):
                    print "Registering self.on_" + i.Name + " to handle " + i.Name + ".Click"
                    i.Click += getattr(self, "on_" + i.Name)
            elif isinstance(i, TextBox):
                if i.Name == "Result":
                    self.result = i
        self.result.Text = self.expression
        

    def on_Button(self, c):
        self.expression += c
        self.result.Text = self.expression

    def on_Clear(self, b, e):
        self.expression = ""
        self.result.Text = self.expression

    def on_Equals(self, b, e):
        try:
            result = str(eval(self.expression))
            self.result.Text = result
            self.expression = result
        except:
            self.result.Text = "<<ERROR>>"
            self.expression = ""

    def on_One(self, b, e):
        self.on_Button('1')
    def on_Nine(self, b, e):
        self.on_Button('9')
    def on_Eight(self, b, e):
        self.on_Button('8')
    def on_Five(self, b, e):
        self.on_Button('5')
    def on_Four(self, b, e):
        self.on_Button('4')
    def on_Two(self, b, e):
        self.on_Button('2')
    def on_Three(self, b, e):
        self.on_Button('3')
    def on_Six(self, b, e):
        self.on_Button('6')
    def on_Multiply(self, b, e):
        self.on_Button('*')
    def on_Seven(self, b, e):
        self.on_Button('7')
    def on_Subtract(self, b, e):
        self.on_Button('-')
    def on_Zero(self, b, e):
        self.on_Button('0')
    def on_DecimalPoint(self, b, e):
        self.on_Button('.')
    def on_Plus(self, b, e):
        self.on_Button('+')
    def on_Divide(self, b, e):
        self.on_Button('/')
#
# calc.py
# ipy.exe calc.py
# ipyw.exe calc.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.Controls import Canvas, Button, TextBox
from System.Windows.Media import Brushes
import calculator

def LoadXamlNet(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 Walk(tree):
    yield tree
    if hasattr(tree, 'Children'):
        for child in tree.Children:
            for x in Walk(child):
                yield x
    elif hasattr(tree, 'Child'):
        for x in Walk(tree.Child):
            yield x
    elif hasattr(tree, 'Content'):
        for x in Walk(tree.Content):
            yield x

class Calc(Object):
    def __init__(self):
        self.scene = calc = LoadXamlNet("http://softgarden.lovepop.jp/myBlog/xaml/calc.xaml")

        controls = [ n for n in Walk(calc) if isinstance(n, Button) or isinstance(n, TextBox) ]
        for c in controls:
            c.FontSize *=2
        calculator.enliven(calc)

class Drag(object):
    def __init__(self, root, obj):
        self.click = None
        self.obj = obj
        self.root = root
    def OnMouseLeftButtonDown(self, sender, e):
        self.click = e.GetPosition(self.root)
        self.sx = Canvas.GetLeft(self.obj)
        self.sy = Canvas.GetTop(self.obj)
        if (self.sx.IsNaN(self.sx)): self.sx = 0.0
        if (self.sy.IsNaN(self.sy)): self.sy = 0.0
        self.obj.CaptureMouse()
    def OnMouseLeftButtonUp(self, sender, e):
        if(self.click != None):
            self.obj.ReleaseMouseCapture()
            self.click = None
    def OnMouseMove(self, sender, e):
        if(self.click != None):
            mouse_pos = e.GetPosition(self.root)
            Canvas.SetLeft(self.obj, (self.sx + mouse_pos.X - self.click.X))
            Canvas.SetTop(self.obj, (self.sy + mouse_pos.Y - self.click.Y))
    def enable(self):
         self.obj.MouseLeftButtonDown += self.OnMouseLeftButtonDown
         self.obj.MouseLeftButtonUp += self.OnMouseLeftButtonUp
         self.obj.MouseMove += self.OnMouseMove
    def disable(self):
         self.obj.MouseLeftButtonDown -= self.OnMouseLeftButtonDown
         self.obj.MouseLeftButtonUp -= self.OnMouseLeftButtonUp
         self.obj.MouseMove -= self.OnMouseMove

class ExWindow(Window):
    def __init__(self):
        self.Title = "Dynamic Languages Rock!"
        self.Width = 600
        self.Height = 480
        self.Content = canvas = Canvas(Background = Brushes.LightGray)
        self.calc = Calc().scene
        canvas.Children.Add (self.calc)
        Canvas.SetTop(self.calc, 60)
        Canvas.SetLeft(self.calc, 180)
        self.drag = Drag(root=canvas, obj=self.calc)
        self.drag.enable()

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

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

くるくるウィジェットで、STEINS;GATE

2011-07-25 17:19:03 | くるくるウィジェット
Amazonの くるくるウィジェット で STEINS;GATE (シュタインズ・ゲート)に挑戦!
右下にあるボタンをクリックすると、くるくる回りだします。
絵の上にマウスカーソルを持っていくと、情報が表示されます。
好きな絵の上をクリックすると、より詳しい情報を知ることができます。
くるくるウィジェットで、STEINS;GATE





by 未来ウィジェット研究所



Amazonの くるくるウィジェット 使ってみた! 電波女と青春男

2011-07-24 03:57:21 | くるくるウィジェット
右下にあるボタンをクリックすると、くるくる回りだします。
絵の上にマウスカーソルを持っていくと、情報が表示されます。
好きな絵の上をクリックすると、より詳しい情報を知ることができます。
Amazonの くるくるウィジェット 使ってみた! 電波女と青春男

電波女と青春男 ランダムに10個



電波女と青春男 (完全生産限定版) [DVD]



電波女と青春男 (完全生産限定版) [Blu-ray]



by 未来ウィジェット研究所


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