05-extra.py

    #!/usr/bin/env python2

    from eagle import *

    class Undo( object ):
        def __init__( self, app ):
            self.last_images = []
            self.app = app
            app.undo = self
            self.canvas = app[ "canvas" ]
            self.button = app[ "undo" ]
            self.button.set_inactive()
        # __init__()

        def push( self ):
            img = self.canvas.get_image()
            self.last_images.append( img )
            self.button.set_active()
        # push()

        def pop( self ):
            if self.last_images:
                img = self.last_images.pop()
                self.canvas.draw_image( img )

            if not self.last_images:
                self.button.set_inactive()
        # pop()
    # Undo

    class Tool( object ):
        """Interface to be implemented by tools."""

        def mouse( self, app, canvas, buttons, x, y ):
            """This tool have a user feedback using mouse on canvas."""
            pass
        # mouse()
    # Tool

    class Line( Tool ):
        def __init__( self ):
            self.first_point = None
        # __init__()

        def mouse( self, app, canvas, buttons, x, y ):
            if buttons & Canvas.MOUSE_BUTTON_1:
                if self.first_point is None:
                    self.first_point = ( x, y )
                else:
                    color = app[ "fg" ]
                    size  = app[ "size" ]
                    x0, y0 = self.first_point
                    app.undo.push()
                    canvas.draw_line( x0, y0, x, y, color, size )
                    self.first_point = None
        # mouse()
    # Line

    class Pencil( Tool ):
        def __init__( self ):
            self.last_point = None
            self.changed = False
        # __init__()

        def mouse( self, app, canvas, buttons, x, y ):
            if buttons & Canvas.MOUSE_BUTTON_1:
                if not self.changed:
                    app.undo.push()
                self.changed = True

                color = app[ "fg" ]
                size  = app[ "size" ]
                if self.last_point is not None:
                    x0, y0 = self.last_point
                else:
                    x0 = x + 1
                    y0 = y

                if size == 1:
                    canvas.draw_point( x, y, color )
                else:
                    half = size / 2
                    canvas.draw_rectangle( x-half, y-half, size, size, color, 1,
                                           color, True )
                canvas.draw_line( x0, y0, x, y, color, size )
                self.last_point = ( x, y )
            else:
                # Button 1 was released, reset last point
                self.last_point = None
                self.changed = False
        # mouse()
    # Pencil

    class Rectangle( Tool ):
        def __init__( self ):
            self.first_point = None
        # __init__()

        def mouse( self, app, canvas, buttons, x, y ):
            if buttons & Canvas.MOUSE_BUTTON_1:
                if self.first_point is None:
                    self.first_point = ( x, y )
                else:
                    fg   = app[ "fg" ]
                    bg   = app[ "bg" ]
                    size = app[ "size" ]
                    fill = app[ "rectfill" ]

                    x0, y0 = self.first_point

                    if x0 > x:
                        x0, x = x, x0
                    if y0 > y:
                        y0, y = y, y0

                    w = x - x0
                    h = y - y0

                    app.undo.push()
                    canvas.draw_rectangle( x0, y0, w, h, fg, size, bg, fill )
                    self.first_point = None
        # mouse()
    # Rectangle

    class Text( Tool ):
        def mouse( self, app, canvas, buttons, x, y ):
            if buttons & Canvas.MOUSE_BUTTON_1 and app[ "text" ]:
                text  = app[ "text" ]
                fg    = app[ "fg" ]
                bg    = app[ "bg" ]
                font  = app[ "font" ]

                if app[ "textbgtransp" ]:
                    bg = None

                app.undo.push()
                canvas.draw_text( text, x, y, fg, bg, font )
        # mouse()
    # Text

    tools = {
        "Line": Line(),
        "Pencil": Pencil(),
        "Rectangle": Rectangle(),
        "Text": Text(),
        }
    def_tool="Line"

    def canvas_action( app, canvas, buttons, x, y ):
        tool = app[ "tool" ]
        tools[ tool ].mouse( app, canvas, buttons, x, y )
    # canvas_action()

    def save( app, button, filename ):
        canvas = app[ "canvas" ]
        img = canvas.get_image()
        try:
            img.save( filename )
        except Exception, e:
            error( str( e ) )
    # save()

    def clear( app, button ):
        app.undo.push()
        app[ "canvas" ].clear()
    # clear()

    def confirm_quit( app ):
        return yesno( "Are you sure you want to close '%s'?" % app.title )
    # confirm_quit()

    def do_undo( app, button ):
        app.undo.pop()
    # do_undo()

    app = App( title="Paint",
               id="paint",
               statusbar=True,
               quit_callback=confirm_quit,
               left=( Color( id="fg",
                             label="Foreground:",
                             color="black",
                             ),
                      Color( id="bg",
                             label="Background:",
                             color=( 255, 0, 0 ),
                             ),
                      Selection( id="tool",
                                 label="Tool:",
                                 options=tools.keys(),
                                 active=def_tool,
                                 ),
                      UIntSpin( id="size",
                                label="Line Size:",
                                min=1,
                                value=1,
                                ),
                      ),
               right=( Group( id="textgroup",
                              label="Text Properties:",
                              children=( Entry( id="text",
                                                label="Contents:",
                                                ),
                                         Font( id="font",
                                               label="Font:",
                                               ),
                                         CheckBox( id="textbgtransp",
                                                   label="Transparent background?",
                                                   ),
                                         ),
                              ),
                       Group( id="rectgroup",
                              label="Rectangle Properties:",
                              children=( CheckBox( id="rectfill",
                                                   label="Fill?",
                                                   ),
                                         ),
                              ),
                       ),
               top=( SaveFileButton( callback=save ),
                     CloseButton(),
                     Button( id="undo",
                             stock="undo",
                             callback=do_undo,
                             ),
                     Button( id="clear",
                             stock="clear",
                             callback=clear,
                             ),
                     ),
               center=( Canvas( id="canvas",
                                label="Draw Here:",
                                width=400,
                                height=400,
                                bgcolor="white",
                                callback=canvas_action,
                                ),
                        )
               )

    Undo( app )

    run()