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()
def push( self ):
img = self.canvas.get_image()
self.last_images.append( img )
self.button.set_active()
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()
class Tool( object ):
"""Interface to be implemented by tools."""
def set_active( self, app ):
"""This tool is now active."""
pass
def set_inactive( self, app ):
"""This tool is now inactive. """
pass
def mouse( self, app, canvas, buttons, x, y ):
"""This tool have a user feedback using mouse on canvas."""
pass
class Line( Tool ):
def __init__( self ):
self.first_point = None
self.message_id = None
def set_active( self, app ):
self.message_id = app.status_message(
"Press the left mouse button to mark the first point." )
def set_inactive( self, app ):
if self.message_id is not None:
app.remove_status_message( self.message_id )
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 )
self.inner_message_id = app.status_message(
( "First poit at ( %d, %d ). Now mark the second." ) %
( 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
app.remove_status_message( self.inner_message_id )
class Pencil( Tool ):
def __init__( self ):
self.last_point = None
self.message_id = None
self.changed = False
def set_active( self, app ):
self.message_id = app.status_message(
"Press the left mouse button and move your mouse." )
def set_inactive( self, app ):
if self.message_id is not None:
app.remove_status_message( self.message_id )
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:
self.last_point = None
self.changed = False
class Rectangle( Tool ):
def __init__( self ):
self.first_point = None
self.message_id = None
def set_active( self, app ):
app[ "rectgroup" ].show()
self.message_id = app.status_message(
"Press the left mouse button to mark first point." )
def set_inactive( self, app ):
app[ "rectgroup" ].hide()
if self.message_id is not None:
app.remove_status_message( self.message_id )
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 )
self.inner_message_id = app.status_message(
( "First poit at ( %d, %d ). Now mark the second." ) %
( 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
app.remove_status_message( self.inner_message_id )
class Text( Tool ):
def __init__( self ):
self.message_id = None
def set_active( self, app ):
app[ "textgroup" ].show()
self.message_id = app.status_message(
"Type your text in 'Contents' and press the left button " \
"to place it." )
def set_inactive( self, app ):
app[ "textgroup" ].hide()
if self.message_id is not None:
app.remove_status_message( self.message_id )
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 )
tools = {
"Line": Line(),
"Pencil": Pencil(),
"Rectangle": Rectangle(),
"Text": Text(),
}
def_tool="Line"
def tool_changed( app, tool, value ):
if tool_changed.last_tool:
tool_changed.last_tool.set_inactive( app )
t = tools[ value ]
tool_changed.last_tool = t
t.set_active( app )
tool_changed.last_tool = None
def canvas_action( app, canvas, buttons, x, y ):
tool = app[ "tool" ]
tools[ tool ].mouse( app, canvas, buttons, x, y )
def save( app, button, filename ):
canvas = app[ "canvas" ]
img = canvas.get_image()
try:
img.save( filename )
except Exception, e:
error( str( e ) )
def clear( app, button ):
app.undo.push()
app[ "canvas" ].clear()
def confirm_quit( app ):
return yesno( "Are you sure you want to close '%s'?" % app.title )
def do_undo( app, button ):
app.undo.pop()
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,
callback=tool_changed,
),
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,
),
)
)
for tool in tools.itervalues():
tool.set_inactive( app )
tool_changed( app, app.get_widget_by_id( "tool" ), def_tool )
Undo( app )
run()