Final Project files for mBed development.

Dependencies:   m3pi mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers user-gui.py Source File

user-gui.py

00001 #!/usr/bin/python
00002 """"
00003 
00004 NOTE: A substantial portion of this code was taken from Dave Michell's
00005 example illustrating how to draw on a Python-generated canvas. All credit
00006 for those portions of the code belong to him. Below is the header from the
00007 original document written by him.
00008     
00009 # Start origin header ########################
00010 
00011 Paint program by Dave Michell.
00012 
00013 Subject: tkinter "paint" example
00014 From: Dave Mitchell <davem@magnet.com>
00015 To: python-list@cwi.nl
00016 Date: Fri, 23 Jan 1998 12:18:05 -0500 (EST)
00017 
00018   Not too long ago (last week maybe?) someone posted a request
00019 for an example of a paint program using Tkinter. Try as I might
00020 I can't seem to find it in the archive, so i'll just post mine
00021 here and hope that the person who requested it sees this!
00022 
00023   All this does is put up a canvas and draw a smooth black line
00024 whenever you have the mouse button down, but hopefully it will
00025 be enough to start with.. It would be easy enough to add some
00026 options like other shapes or colors...
00027 
00028                                                 yours,
00029                                                 dave mitchell
00030                                                 davem@magnet.com
00031     
00032 # End original header #########################
00033     
00034 """
00035 from Tkinter import *
00036 import os
00037 import sys
00038 import re
00039 
00040 """paint.py: not exactly a paint program. just a smooth line drawing demo."""
00041 
00042 TEMP_FILE = "canvas-temp.ps"
00043 OUTPUT_FILE = "test.ps"
00044 b1 = "up"
00045 xold, yold = None, None
00046 height = 600
00047 width = 600
00048 
00049 class popupWindow(object):
00050     def __init__(self,master):
00051         top=self.top=Toplevel(master)
00052         self.l=Label(top,text="Resize Window")
00053         self.l.pack()
00054         self.h=Label(top,text="Height");
00055         self.h.pack()
00056         self.e=Entry(top)
00057         self.e.pack()
00058         self.w=Label(top,text="Width");
00059         self.w.pack()
00060         self.f=Entry(top);
00061         self.f.pack()
00062         self.b=Button(top,text='Ok',command=self.cleanup)
00063         self.b.pack()
00064         self.master = master
00065     def cleanup(self):
00066         global height
00067         global width
00068         h = self.e.get()
00069         w = self.f.get()
00070         self.top.destroy()
00071         self.master.geometry(h+"x"+w)
00072         height = h
00073         width = w
00074 
00075 def loop():
00076     root = Tk()
00077     root.geometry("%dx%d" % (height,width))
00078     root.title("RoboCanvas")
00079     drawing_area = Canvas(root)
00080     drawing_area.pack(fill=BOTH,expand=1)
00081     drawing_area.bind("<Motion>", motion)
00082     drawing_area.bind("<ButtonPress-1>", b1down)
00083     drawing_area.bind("<ButtonRelease-1>", b1up)
00084 
00085     menubar = Menu(root)
00086     control_menu = Menu(root);
00087     control_menu.add_command(label="Deploy       ", \
00088         command=lambda p=drawing_area: build(p));
00089     control_menu.add_command(label="Clear Canvas",\
00090         command=lambda p=drawing_area: p.delete('all'))
00091     control_menu.add_command(label="Resize Canvas", command=lambda p=root:\
00092         resize(root));
00093     control_menu.add_separator()
00094     control_menu.add_command(label="Exit", command=lambda p=root: root.quit())
00095     menubar.add_cascade(label="Control", menu=control_menu);
00096     root.config(menu=menubar);
00097     message = Label(root, text="Press and hold with the mouse to draw");
00098     message.pack(side=BOTTOM)
00099     root.mainloop()
00100 
00101 def resize(root):
00102     """ Resize the root window and expand the canvas to fill """
00103     ans = popupWindow(root);
00104 
00105 def build(canvas):
00106     """
00107     This function is indended to be called from the drawing canvas after
00108     the drawing is complete and the user wishes to push it to the robot.
00109     This function must send (somehow) the appropriate information to the 
00110     robot to make the drawing happen.
00111     """
00112     gen_postscript(canvas)
00113 
00114 def gen_postscript(canvas):
00115     """ Make a postscript capture of the canvas """
00116     
00117     # Get lineto and moveto data from standard postscript output. 
00118     l = []
00119     canvas.update()
00120     canvas.postscript(file=TEMP_FILE);
00121     f = open(TEMP_FILE, "r")
00122     for line in f.readlines():
00123         if 'lineto' in line or 'moveto' in line:
00124             l.append(line)
00125     f.close()
00126 
00127     # Filter the moves list
00128     output = filter_moves(l)
00129 
00130     # Write filtered output to the new canvas file.
00131     l = l[5:]
00132     f = open(OUTPUT_FILE, "w");
00133     f.write(str(height) + "/" + str(width)+"\n");
00134     for line in output:
00135         f.write(line);
00136     f.close()
00137     os.remove(TEMP_FILE);
00138 
00139 def filter_moves(moves):
00140     """ Return a processed list of moves """
00141 
00142     filtered_moves = list(moves)[5:]
00143     output_list = []
00144 
00145     prev = filtered_moves[0]
00146     output_list.append(prev)    # Write the first moveto always.
00147     prev = filtered_moves[1]
00148     output_list.append(prev)
00149 
00150     for move in filtered_moves[2:]:
00151         x_coord = move.split()[0]
00152         x_coord_prev = prev.split()[0]
00153         y_coord = move.split()[1]
00154         y_coord_prev = prev.split()[1]
00155 
00156         # Remove redundant moveto's
00157         if x_coord != x_coord_prev or y_coord != y_coord_prev:
00158             output_list.append(move)
00159             prev = move
00160             
00161     # Flatten on x-coordinate
00162     filtered_moves = list(output_list)
00163     output_list = [filtered_moves.pop(0)]
00164     prev = filtered_moves.pop(0)
00165     prev_s = prev.split()
00166     prev_y = prev_s[1]
00167     prev_x = prev_s[0]
00168     while filtered_moves:
00169         move = filtered_moves.pop(0)
00170         move_s = move.split()
00171         move_x = move_s[0]
00172         move_y = move_s[1]
00173         move_c = move_s[2]
00174         
00175         if move_c == 'moveto':
00176             output_list.append(prev)
00177             prev = None
00178             output_list.append(move)
00179             continue
00180 
00181         if prev and move_x == prev_x:
00182             prev = move
00183             prev_y = move_y
00184             continue
00185         if prev: output_list.append(prev)
00186         prev = move
00187         prev_s = prev.split()
00188         prev_y = prev_s[1]
00189         prev_x = prev_s[0]
00190     if prev: output_list.append(prev)
00191 
00192     # Flatten on y-coordinate   
00193     filtered_moves = list(output_list)
00194     output_list = [filtered_moves.pop(0)]
00195     prev = filtered_moves.pop(0)
00196     prev_s = prev.split()
00197     prev_y = prev_s[1]
00198     prev_x = prev_s[0]
00199     while filtered_moves:
00200         move = filtered_moves.pop(0)
00201         move_s = move.split()
00202         move_x = move_s[0]
00203         move_y = move_s[1]
00204         move_c = move_s[2]
00205         
00206         if move_c == 'moveto':
00207             output_list.append(prev)
00208             prev = None
00209             output_list.append(move)
00210             continue
00211         
00212         if prev and move_y == prev_y:
00213             prev_x = move_x
00214             prev = move
00215             continue
00216         if prev: output_list.append(prev)
00217         prev = move
00218         prev_s = prev.split()
00219         prev_y = prev_s[1]
00220         prev_x = prev_s[0]
00221     if prev: output_list.append(prev)
00222 
00223     x0 = 0
00224     y0 = 0
00225     f_output_list = list()
00226     i = 0
00227     to_app = ""
00228     while i < len(output_list)-1:
00229         line1 = output_list[i].split(' ')
00230         line2 = output_list[i+1].split(' ')
00231         x1 = int(line1[0])
00232         x2 = int(line2[0])
00233         y1 = int(line1[1])
00234         y2 = int(line2[1])
00235         if line1[2] == line2[2] and dist(x0,y0,x1,y1) <= 20\
00236                 and dist(x1,y1,x2,y2) <= 20:
00237             i += 1
00238             to_app = "%d %d %s" % (x2,y2,line1[2])
00239         else:
00240             x0 = x1
00241             y0 = y1
00242             if to_app != "":
00243                 f_output_list.append(to_app)
00244                 to_app = ""
00245             else:
00246                 f_output_list.append(output_list[i])
00247             i += 1
00248     f_output_list.append(output_list[len(output_list)-1])
00249     print "Raw Numbers: ", moves
00250     print "--------------------------------------------"
00251     print "Filtered: ", f_output_list
00252     return f_output_list
00253 
00254 def dist(x1,y1,x2,y2):
00255     return ((x2-x1)**2 + (y2-y1)**2)**.5
00256 
00257 def b1down(event):
00258     global b1
00259     b1 = "down"           # you only want to draw when the button is down
00260                           # because "Motion" events happen -all the time-
00261 
00262 def b1up(event):
00263     global b1, xold, yold
00264     b1 = "up"
00265     xold = None           # reset the line when you let go of the button
00266     yold = None
00267 
00268 def motion(event):
00269     if b1 == "down":
00270         global xold, yold
00271         if xold is not None and yold is not None:
00272             event.widget.create_line(xold,yold,event.x,event.y,smooth=TRUE)
00273         xold = event.x
00274         yold = event.y
00275 
00276 def main():
00277     """ Main program entry point """
00278     loop()
00279 
00280 if __name__ == "__main__":
00281     main()