《付録》VisitorBrush.py

# -*- coding: utf-8 -*-
#===============================================================================
#    Copyright (C) 2000-2008, 小泉ひよ子とタマゴ倶楽部
#
# History: WPF examples
#    2008/01/25, IronPython 1.1.1 (download)
#    2008/08/22, IronPython 1.1.2 (download)
#    2008/03/16, ver.2.0, WPF
#    2008/00/00, ver.2.1, IronPython 1.1.2 
#===============================================================================
from _ant import *
from System import *
from System.Windows import *
from System.Windows.Media import *
from System.Windows.Media.Imaging import *
from System.Windows.Shapes import *

## --------------------                         # Visitor::Element
class XShape:
    def accept(self, v):
        source = "v.visit_%s(self)"%self.__class__.__name__
        eval(source)    ; print source

## --------------------                         # Visitor::ConcreteElement
class EllipseShape(XShape):
    def __init__(self):
        self.shape = Ellipse(
            Stroke=Brushes.Blue,
            StrokeThickness=2,
            Width=100,
            Height=50,
            )

## --------------------                         # Visitor::ConcreteElement
class PolygonShape(XShape):
    def __init__(self):
        points = PointCollection()
        vertices = "0,28 80,28 12,80 40,0 68,80"
        for e in vertices.split(" "):
            x, y = eval(e)
            points.Add(Point(x, y))
        self.shape = Polygon(
            Stroke=Brushes.Blue,
            StrokeThickness=2,
            Points=points,
            )

## --------------------                         # Visitor::Visitor
class XVisitor:
    def visit_EllipseShape(self, e):
        raise NotImplementedError("%s.visit_EllipseShape"
            %self.__class__.__name__)
    def visit_PolygonShape(self, e):
        raise NotImplementedError("%s.visit_PolygonShape"
            %self.__class__.__name__)

## --------------------                         # Visitor::ConcreteVisitor
class SolidColorVisitor(XVisitor):
    def visit_EllipseShape(self, e):
        e.shape.Fill = Brushes.Yellow
    def visit_PolygonShape(self, e):
        e.shape.Stroke = Brushes.Black

## --------------------                         # Visitor::ConcreteVisitor
class LinearGradientVisitor(XVisitor):
    def visit_EllipseShape(self, e):
        brush = LinearGradientBrush()
        for color, offset in [
            ("Yellow", 0.0),
            ("Green" , 1.0),
            ]: 
            brush.GradientStops.Add(GradientStop(
                Color=getattr(Colors, color),
                Offset=offset,
                ))
        e.shape.Fill = brush
    def visit_PolygonShape(self, e):
        e.shape.Stroke = Brushes.Black

## --------------------                         # Visitor::ConcreteVisitor
class RadialGradientVisitor(XVisitor):
    def visit_EllipseShape(self, e):
        brush = RadialGradientBrush()
        for color, offset in [
            ("Yellow", 0.0),
            ("Green" , 1.0),
            ]: 
            brush.GradientStops.Add(GradientStop(
                Color=getattr(Colors, color),
                Offset=offset,
                ))
        e.shape.Fill = brush
    def visit_PolygonShape(self, e):
        e.shape.Stroke = Brushes.Black

## --------------------                         # Visitor::ConcreteVisitor
class ImageVisitor(XVisitor):
    def visit_EllipseShape(self, e):
        brush = ImageBrush(
            ImageSource=BitmapImage(Uri("sunflower.jpg", UriKind.Relative)))
        e.shape.Fill = brush
    def visit_PolygonShape(self, e):
        e.shape.Stroke = Brushes.Black

## --------------------                         # Visitor::ConcreteVisitor
class DrawingVisitor(XVisitor):
    def visit_EllipseShape(self, e):
        brush = DrawingBrush(
            Viewport=Rect(0, 0, 0.1, 0.1),
            TileMode=TileMode.Tile,
            )
        sheet = GeometryDrawing(
            brush=Brushes.Yellow,
            pen=None,
            geometry=RectangleGeometry(Rect(0, 0, 50, 50)))
        geometry = GeometryGroup()
        for (px, py), rx, ry in (
            *1
        marble = GeometryDrawing(
            brush=Brushes.Blue,
            pen=None,
            geometry=geometry)
        drawing = DrawingGroup()
        for g in sheet, marble:
            drawing.Children.Add(g)
        brush.Drawing = drawing
        e.shape.Fill = brush
    def visit_PolygonShape(self, e):
        e.shape.Stroke = Brushes.Black

## --------------------                         # Visitor::ConcreteVisitor
class VisualVisitor(XVisitor):
    def __init__(self, visual):
        self.visual = visual
    def visit_EllipseShape(self, e):
        brush = VisualBrush()
        brush.Visual = self.visual
        e.shape.Fill = brush
    def visit_PolygonShape(self, e):
        e.shape.Stroke = Brushes.Black

## --------------------                         # Visitor::ObjectStructure
class ExWindow(Window):
    def __init__(self, Content=None, **args):
        self.InitializeComponent(Content)
        self.init()

    def InitializeComponent(self, Content):
        self.Content = LoadXaml(Content)
        
    def init(self):
        target = (
            "solidColorBrush",
            "linearGradientBrush",
            "radialGradientBrush",
            "imageBrush",
            "drawingBrush",
            "visualBrush",
            )
        self._Controls(target)

    def _Controls(self, target):
        controls = xaml_controls(self)
        for e in target:
            setattr(self, e, controls[e])
        visitors = (
            SolidColorVisitor(),
            LinearGradientVisitor(),
            RadialGradientVisitor(),
            ImageVisitor(),
            DrawingVisitor(),
            VisualVisitor(self.imageBrush),
            )
        for e, v in zip(target, visitors):
            items = getattr(self, e)
            for s in EllipseShape(), PolygonShape():
                s.accept(v)
                items.Children.Add(s.shape)

## --------------------               
if __name__ == "__main__":
    xaml = __file__.replace(".py",".xaml")
    win = ExWindow(
        Title=xaml,
        Width=280, Height=200,
        Content=xaml,
        )
    Application().Run(win)

## --------------------               

*1:10, 10), 10, 10), ((35, 35), 15, 15), ): geometry.Children.Add(EllipseGeometry( Center=Point(px, py), RadiusX=rx, RadiusY=ry,