Exemplo n.º 1
0
class App(Frame):
	def __init__(self, master, settings):
		self.master = master
		self.settings = settings
		Frame.__init__(self, master, relief=SUNKEN, bd=2)
		self.master.protocol('WM_DELETE_WINDOW', self.quitApp)
		self.objNumber = 1
		
		self.modified = False
		self.preview = True
		
		self.lbMap = []
		self.lbSelection = None
		
		self.stlFrame =  StlFrame(self, scale=settings.scale)
		self.stlFrame.grid(row=1, column=1, rowspan=4, sticky=N)
		self.lbFrame = LabelFrame(self, text=" File List ")
		self.lbFrame.grid(row=1, column=2, padx=5, pady=5, sticky=N)
		self.bFrame = Frame(self)
		self.bFrame.grid(row=2, column=2, padx=5, sticky=N)
		
		self.lbFiles = Listbox(self.lbFrame, width=60)
		self.lbFiles.grid(row=1,column=1,sticky=N+E+W+S)
		self.sbFiles = Scrollbar(self.lbFrame, command=self.lbFiles.yview, orient="vertical")
		self.sbFiles.grid(column=2, row=1, sticky=N+S+E)
		self.lbFiles.config(yscrollcommand=self.sbFiles.set)
		self.lbFiles.bind("<ButtonRelease>", self.doClickList)
		
		self.imgAdd = self.loadImage("add.gif")
		self.bAdd = Button(self.bFrame, image=self.imgAdd, width=48, height=48, command=self.doAdd)
		self.bAdd.grid(row=1, column=1, pady=2, padx=2, sticky=N)
		createToolTip(self.bAdd, "Add an STL file to the plate")

		self.imgClone = self.loadImage("clone.gif")		
		self.bClone = Button(self.bFrame, image=self.imgClone, width=48, height=48, command=self.doClone, state=DISABLED)
		self.bClone.grid(row=1, column=2, pady=2, padx=2, sticky=N)
		createToolTip(self.bClone, "Clone the selected object")
		
		self.imgDel = self.loadImage("del.gif")
		self.bDel = Button(self.bFrame, image=self.imgDel, width=48, height=48, command=self.doDelete, state=DISABLED)
		self.bDel.grid(row=1, column=3, pady=2, padx=2, sticky=N)
		createToolTip(self.bDel, "Delete the selected object")
		
		self.imgDelAll = self.loadImage("delall.gif")
		self.bDelAll = Button(self.bFrame, image=self.imgDelAll, width=48, height=48, command=self.doDelAll, state=DISABLED)
		self.bDelAll.grid(row=1, column=4, pady=2, padx=2, sticky=N)
		createToolTip(self.bDelAll, "Delete all objects from the plate")
		
		self.imgArrange = self.loadImage("arrange.gif")
		self.bArrange = Button(self.bFrame, image=self.imgArrange, width=48, height=48, command=self.doArrange, state=DISABLED)
		self.bArrange.grid(row=2, column=1, pady=2, padx=2, sticky=N)
		createToolTip(self.bArrange, "Arrange the objects to fit")
		
		self.imgExport = self.loadImage("export.gif")
		self.bExport = Button(self.bFrame, image=self.imgExport, width=48, height=48, command=self.doExport, state=DISABLED)
		self.bExport.grid(row=2, column=4, pady=2, padx=2, sticky=N)
		createToolTip(self.bExport, "Save the plate to an STL file")
		
		self.cbPrev = IntVar()
		if self.settings.preview:
			self.cbPrev.set(1)
		else:
			self.cbPrev.set(0)
			
		self.cbPreview = Checkbutton(
            self.bFrame, text="Preview",
            variable=self.cbPrev,
            command=self.doCbPreview)
		self.cbPreview.grid(row=3, column=2, pady=5)

	def doCbPreview(self):
		if self.cbPrev.get() == 0:
			self.preview = False
		else:
			self.preview = True	
			
		self.settings.preview = self.preview
		self.settings.setModified()
	
	def loadImage(self, fn):
		return PhotoImage(file=os.path.join(cmd_folder, "images", fn))

	def checkModified(self):
		if self.modified:
			if not askyesno("Exit?", "Lose unsaved changes?"):
				return True

		return False
		
	def quitApp(self):
		if self.checkModified():
			return False
		
		self.destroy()
		self.master.quit()
		return True
	
	def doAdd(self):
		while True:
			confirmed = False
			fn = askopenfilename(filetypes=[("STL files", "*.stl")], initialdir=self.settings.lastdirectory)
			if fn:
				if self.preview:
					subprocess.Popen([self.settings.viewer, fn])
					if askyesno("Confirm Add", "Add this object?"):
						confirmed = True
				else:
					confirmed = True
			else:
				return
					
			if confirmed:
				self.modified = True
				self.filename = fn
				dn = os.path.dirname(fn)
				if dn != self.settings.lastdirectory:
					self.settings.lastdirectory = dn
					self.settings.setModified()
				
				name = "OBJECT%03d" % self.objNumber
				index = self.lbFiles.index(END)
				self.lbFiles.insert(END, "%2d: %s" % (self.objNumber, fn))
				if self.lbSelection is not None:
					self.lbFiles.selection_clear(self.lbSelection)
				self.lbFiles.selection_set(index)
				self.lbSelection = index
				self.objNumber += 1
				stlFile = stltool.stl(filename=fn, name=name)
				self.lbMap.append(stlFile)
				self.stlFrame.addStl(stlFile, highlight=True)
				self.bDel.config(state=NORMAL)
				self.bDelAll.config(state=NORMAL)
				self.bExport.config(state=NORMAL)
				self.bArrange.config(state=NORMAL)
				self.bClone.config(state=NORMAL)
				return
			
	def doClone(self):
		stlObj = self.stlFrame.getSelectedStl()
		if stlObj is None:
			return
		
		name = "OBJECT%03d" % self.objNumber
		index = self.lbFiles.index(END)
		self.lbFiles.insert(END, "%2d: %s" % (self.objNumber, stlObj.filename))
		if self.lbSelection is not None:
			self.lbFiles.selection_clear(self.lbSelection)
		self.lbFiles.selection_set(index)
		self.lbSelection = index
		self.objNumber += 1
		s = stlObj.clone(name=name)
		self.lbMap.append(s)
		self.stlFrame.addStl(s, highlight=True)
			
	def doDelete(self):
		self.modified = True
		if self.lbSelection is not None:
			del self.lbMap[self.lbSelection]
			self.lbFiles.delete(self.lbSelection)
			self.lbSelection = None
			
		self.stlFrame.delStl()
		if self.stlFrame.countObjects() == 0:
			self.modified = False
			self.bDel.config(state=DISABLED)
			self.bDelAll.config(state=DISABLED)
			self.bExport.config(state=DISABLED)
			self.bArrange.config(state=DISABLED)
			self.bClone.config(state=DISABLED)
			
	def doDelAll(self):
		if askyesno("Confirm Delete All", "Are you sure you want to delete all objects?"):
			self.modified = False
			self.stlFrame.delAll()
			self.bDel.config(state=DISABLED)
			self.bDelAll.config(state=DISABLED)
			self.bExport.config(state=DISABLED)
			self.bArrange.config(state=DISABLED)
			self.bClone.config(state=DISABLED)
			self.lbFiles.delete(0, END)
			self.lbMap = []
			self.lbSelection = None
			self.objNumber = 1
		
	def doExport(self):
		self.stlFrame.commit()
		objs = self.stlFrame.getStls()
		facets = []
		for o in objs:
			facets.extend(o.facets)
			
		fn = asksaveasfilename(parent=self, title="Export to File", filetypes=[("STL files", "*.stl")], initialdir=self.settings.lastdirectory, defaultextension=".stl")
		if not fn:
			return
		
		stltool.emitstl(fn, facets=facets, objname="PlaterObject", binary=False)
		self.modified = False
		
	def setModified(self, flag=True):
		self.modified = flag
		
	def setSelection(self, stlObj):
		found = False
		for i in range(len(self.lbMap)):
			o = self.lbMap[i]
			if o.name == stlObj.name:
				found = True
				break
			
		if not found:
			return
		
		if self.lbSelection is not None:
			self.lbFiles.selection_clear(self.lbSelection)
		self.lbFiles.selection_set(i)
		self.lbSelection = i
		
	def doClickList(self, *arg):
		items = self.lbFiles.curselection()
		try:
			i = int(items[0])
		except:
			return
		
		if i < 0 or i >= len(self.lbMap):
			return	
		
		self.stlFrame.setSelectionByName(self.lbMap[i].name)
		
	def doArrange(self):
		self.stlFrame.arrange()