Paint
- a_bertrand
- Posts: 1537
- Joined: Mon Feb 25, 2013 1:46 pm
Re: Paint
Not a bad start, but you could make the code a lot smaller, and not even use things like setInterval.
Creator of Dot World Maker
Mad programmer and annoying composer
Mad programmer and annoying composer
- vitinho444
- Posts: 2825
- Joined: Mon Mar 21, 2011 4:54 pm
- Jackolantern
- Posts: 10893
- Joined: Wed Jul 01, 2009 11:00 pm
Re: Paint
Nice! This reminds me a lot of a project I did last semester while learning Python. We even used a lot of the same methods for drawing. You may want to check out my Python code. Even if you don't use Python, it should be pretty easy to follow (Python is extremely easy to read)
Code: Select all
'''
File: MyPaint.py
Description: A Paint-like program for drawing with a GUI.
Author: Tim Crouch
Date: Nov 13, 2013
'''
from tkinter import *
import tkinter.simpledialog as tksd
import tkinter.messagebox as tkmb
from tkinter import filedialog as tkfd
class PaintGui:
def __init__(self):
#create the main window
window = Tk()
window.title("MyPaint")
#save the window reference
self.window = window
#Create the menu
menubar = Menu(window)
#Add the menu to the window
window.config(menu = menubar)
#Create memory object
self.actionList = ActionList(self)
#Create the shape drawers
self.circleDrawer = CircleDrawer(self, self.actionList)
self.squareDrawer = SquareDrawer(self, self.actionList)
self.lineDrawer = LineDrawer(self, self.actionList)
self.arcDrawer = ArcDrawer(self, self.actionList)
self.freeDrawer = FreeDrawer(self, self.actionList)
#Create the object for saving and opening files
self.fileSaveOpen = FileSaveOpen(self.actionList, self.circleDrawer, self.squareDrawer, self.lineDrawer, self.arcDrawer)
#give a reference to ActionList
self.actionList.drawingObject(self.circleDrawer, self.squareDrawer, self.lineDrawer, self.arcDrawer, self.freeDrawer)
#Create File sub-menu
fileMenu = Menu(menubar, tearoff = 0)
menubar.add_cascade(label = "File", menu = fileMenu)
fileMenu.add_command(label = "Save", command = self.saveFile)
fileMenu.add_command(label = "Open", command = self.openFile)
#Create shape sub-menu
operationMenu = Menu(menubar, tearoff = 0)
menubar.add_cascade(label = "Shapes", menu = operationMenu)
operationMenu.add_command(label = "Draw Circles", command = self.drawCircle)
operationMenu.add_command(label = "Draw Squares", command = self.drawSquare)
operationMenu.add_command(label = "Draw Lines", command = self.drawLine)
operationMenu.add_command(label = "Draw Arcs", command = self.drawArc)
operationMenu.add_command(label = "Free Draw", command = self.freeDraw)
#default color is black
self.color = "black"
#set the mode; default is Circle
self.shapeMode = "circle"
#Create the color menu
settingMenu = Menu(menubar, tearoff = 0)
colorMenu = Menu(settingMenu, tearoff = 0)
menubar.add_cascade(label = "Settings", menu = settingMenu)
settingMenu.add_cascade(label = "Color", menu = colorMenu)
colorMenu.add_command(label = "Black", command = self.setBlack)
colorMenu.add_command(label = "Red", command = self.setRed)
colorMenu.add_command(label = "Blue", command = self.setBlue)
colorMenu.add_command(label = "Green", command = self.setGreen)
colorMenu.add_command(label = "Yellow", command = self.setYellow)
colorMenu.add_command(label = "Orange", command = self.setOrange)
colorMenu.add_command(label = "Purple", command = self.setPurple)
#Create the "change last color" menu
lastColorMenu = Menu(settingMenu, tearoff = 0)
settingMenu.add_cascade(label = "Last Color", menu = lastColorMenu)
lastColorMenu.add_command(label = "Black", command = self.lastBlack)
lastColorMenu.add_command(label = "Red", command = self.lastRed)
lastColorMenu.add_command(label = "Blue", command = self.lastBlue)
lastColorMenu.add_command(label = "Green", command = self.lastGreen)
lastColorMenu.add_command(label = "Yellow", command = self.lastYellow)
lastColorMenu.add_command(label = "Orange", command = self.lastOrange)
lastColorMenu.add_command(label = "Purple", command = self.lastPurple)
#Begin creating context-sensitive tool bars
self.toolFrame = Frame(window)
#Create the images for the toolbar menu
self.circleImage = PhotoImage(file = "images/circle.gif")
self.squareImage = PhotoImage(file = "images/square.gif")
self.lineImage = PhotoImage(file = "images/line.gif")
self.arcImage = PhotoImage(file = "images/arc.gif")
self.drawImage = PhotoImage(file = "images/freedraw.gif")
self.blackImage = PhotoImage(file = "images/black.gif")
self.redImage = PhotoImage(file = "images/red.gif")
self.blueImage = PhotoImage(file = "images/blue.gif")
self.greenImage = PhotoImage(file = "images/green.gif")
self.yellowImage = PhotoImage(file = "images/yellow.gif")
self.orangeImage = PhotoImage(file = "images/orange.gif")
self.purpleImage = PhotoImage(file = "images/purple.gif")
#Create the controls for the tool bars
circleButton = Button(self.toolFrame, image = self.circleImage, command = self.drawCircle)
squareButton = Button(self.toolFrame, image = self.squareImage, command = self.drawSquare)
lineButton = Button(self.toolFrame, image = self.lineImage, command = self.drawLine)
arcButton = Button(self.toolFrame, image = self.arcImage, command = self.drawArc)
drawButton = Button(self.toolFrame, image = self.drawImage, command = self.freeDraw)
circleButton.grid(row = 1, column = 1)
squareButton.grid(row = 1, column = 2)
lineButton.grid(row = 1, column = 3)
arcButton.grid(row = 1, column = 4)
drawButton.grid(row = 1, column = 5)
#Create the color buttons
self.blackButton = Button(self.toolFrame, image = self.blackImage, command = self.setBlack)
self.redButton = Button(self.toolFrame, image = self.redImage, command = self.setRed)
self.blueButton = Button(self.toolFrame, image = self.blueImage, command = self.setBlue)
self.greenButton = Button(self.toolFrame, image = self.greenImage, command = self.setGreen)
self.yellowButton = Button(self.toolFrame, image = self.yellowImage, command = self.setYellow)
self.orangeButton = Button(self.toolFrame, image = self.orangeImage, command = self.setOrange)
self.purpleButton = Button(self.toolFrame, image = self.purpleImage, command = self.setPurple)
self.blackButton.grid(row = 1, column = 12)
self.redButton.grid(row = 1, column = 13)
self.blueButton.grid(row = 1, column = 14)
self.greenButton.grid(row = 1, column = 15)
self.yellowButton.grid(row = 1, column = 16)
self.orangeButton.grid(row = 1, column = 17)
self.purpleButton.grid(row = 1, column = 18)
#Create undo/redo buttons
self.undoButton = Button(self.toolFrame, text = "Undo", command = self.actionList.undo)
self.redoButton = Button(self.toolFrame, text = "Redo", command = self.actionList.redo)
self.removeAllButton = Button(self.toolFrame, text = "Clear", command = self.actionList.removeAll)
self.undoButton.grid(row = 1, column = 19)
self.removeAllButton.grid(row = 1, column = 21)
#create context-sensitive controls
#Create width button
self.widthLabel = Label(self.toolFrame, text = "Width: ")
self.widthInput = StringVar()
self.widthEntry = Entry(self.toolFrame, textvariable = self.widthInput, width = 3)
self.widthButton = Button(self.toolFrame, text = "Set", command = self.setWidth)
#create start button for arcs
self.startLabel = Label(self.toolFrame, text = "Start: ")
self.startInput = StringVar()
self.startEntry = Entry(self.toolFrame, textvariable = self.startInput, width = 3)
self.startButton = Button(self.toolFrame, text = "Set", command = self.setStart)
#create extent button for arcs
self.extentLabel = Label(self.toolFrame, text = "Extent: ")
self.extentInput = StringVar()
self.extentEntry = Entry(self.toolFrame, textvariable = self.extentInput, width = 3)
self.extentButton = Button(self.toolFrame, text = "Set", comman = self.setExtent)
self.toolFrame.pack(fill = X)
#Create the canvas
canvas = Canvas(window, width = 750, height = 500)
canvas.pack()
#Setup the events on canvas
canvas.bind("<Button-1>", self.drawRoutine)
canvas.bind("<B1-Motion>", self.midDraw)
canvas.bind("<ButtonRelease-1>", self.endDraw)
self.canvas = canvas
#Start the main loop
window.mainloop()
def setStart(self):
#send the start to the arc drawer
if self.startInput.get():
start = eval(self.startInput.get())
self.arcDrawer.setStart(start)
def setExtent(self):
#send the extent to the arc drawer
if self.extentInput.get():
extent = eval(self.extentInput.get())
self.arcDrawer.setExtent(extent)
def setWidth(self):
#check to see what mode we are in to send to correct class
if self.shapeMode == "line":
if self.widthInput.get():
self.lineDrawer.setWidth(eval(self.widthInput.get()))
#Set the shape modes
def drawCircle(self):
#remove other context controls
self.removeContextControls()
#set the mode to circle
self.shapeMode = "circle"
def drawSquare(self):
#remove other mode's buttons
self.removeContextControls()
#set the mode to square
self.shapeMode = "square"
def drawLine(self):
#remove other context controls
self.removeContextControls()
#set the mode to line
self.shapeMode = "line"
#add correct buttons
self.widthLabel.grid(row = 1, column = 6)
self.widthEntry.grid(row = 1, column = 7)
self.widthButton.grid(row = 1, column = 8)
def drawArc(self):
#remove other buttons
self.removeContextControls()
#set the mode
self.shapeMode = "arc"
#now set the arc buttons
self.startLabel.grid(row = 1, column = 6)
self.startEntry.grid(row = 1, column = 7)
self.startButton.grid(row = 1, column = 8)
self.extentLabel.grid(row = 1, column = 9)
self.extentEntry.grid(row = 1, column = 10)
self.extentButton.grid(row = 1, column = 11)
def freeDraw(self):
#remove other buttons
self.removeContextControls()
#set the mode
self.shapeMode = "free"
#Set the drawing color
def setPurple(self):
self.color = "purple"
def setBlack(self):
self.color = "black"
def setBlue(self):
self.color = "blue"
def setRed(self):
self.color = "red"
def setYellow(self):
self.color = "yellow"
def setOrange(self):
self.color = "orange"
def setGreen(self):
self.color = "green"
def lastBlack(self):
self.actionList.undo()
self.actionList.redo("black")
#Methods for changing the color of the last object entered
def lastRed(self):
self.actionList.undo()
self.actionList.redo("red")
def lastBlue(self):
self.actionList.undo()
self.actionList.redo("blue")
def lastGreen(self):
self.actionList.undo()
self.actionList.redo("green")
def lastPurple(self):
self.actionList.undo()
self.actionList.redo("purple")
def lastYellow(self):
self.actionList.undo()
self.actionList.redo("yellow")
def lastOrange(self):
self.actionList.undo()
self.actionList.redo("orange")
def removeContextControls(self):
#remove other mode's buttons
if self.shapeMode == 'arc':
self.startLabel.grid_forget()
self.startEntry.grid_forget()
self.startButton.grid_forget()
self.extentLabel.grid_forget()
self.extentEntry.grid_forget()
self.extentButton.grid_forget()
if self.shapeMode == "line":
self.widthLabel.grid_forget()
self.widthEntry.grid_forget()
self.widthButton.grid_forget()
#the event handler to set the initial points for the objects
def drawRoutine(self, event):
if self.shapeMode == "circle":
x1 = event.x
y1 = event.y
self.circleDrawer.setInitial(x1, y1)
elif self.shapeMode == "square":
x1 = event.x
y1 = event.y
self.squareDrawer.setInitial(x1, y1)
elif self.shapeMode == "arc":
x1 = event.x
y1 = event.y
self.arcDrawer.setInitial(x1, y1)
elif self.shapeMode == "line":
x1 = event.x
y1 = event.y
self.lineDrawer.setInitial(x1, y1)
elif self.shapeMode == "free":
#starting free draw, so make a first point
self.freeDrawer.addPoint(event.x, event.y)
#the event handler to draw the temp objects
def midDraw(self, event):
#remove the temp if exists
self.canvas.delete("temp")
if self.shapeMode == "circle":
x2 = event.x
y2 = event.y
#now draw another temp circle
self.circleDrawer.drawTempCircle(x2, y2)
elif self.shapeMode == "square":
x2 = event.x
y2 = event.y
#now draw another temp
self.squareDrawer.drawTempSquare(x2, y2)
elif self.shapeMode == "arc":
x2 = event.x
y2 = event.y
#now draw another temp
self.arcDrawer.drawTempArc(x2, y2)
elif self.shapeMode == "line":
x2 = event.x
y2 = event.y
#now draw another temp
self.lineDrawer.drawTempLine(x2, y2)
elif self.shapeMode == "free":
#still free drawing, so make another point
self.freeDrawer.addPoint(event.x, event.y)
#the event handler for drawing the final objects
def endDraw(self, event):
#remove a temp if there is one
self.canvas.delete("temp")
if self.shapeMode == "circle":
x2 = event.x
y2 = event.y
#now draw the final circle
self.circleDrawer.drawCircle(x2, y2)
elif self.shapeMode == "square":
x2 = event.x
y2 = event.y
#now draw the final square
self.squareDrawer.drawSquare(x2, y2)
elif self.shapeMode == "arc":
x2 = event.x
y2 = event.y
#now draw the final arc
self.arcDrawer.drawArc(x2, y2)
elif self.shapeMode == "line":
x2 = event.x
y2 = event.y
#now draw the final line
self.lineDrawer.drawLine(x2, y2)
elif self.shapeMode == "free":
self.freeDrawer.endFree()
#save files
def saveFile(self):
#get the filename to save
fileName = tksd.askstring("File Name", "Enter a name for the file")
#make sure that the file extension is added if the user didn't enter it
if fileName[-4:] != ".mpf":
fileName += '.mpf'
#open the file, creating it if needed
with open(fileName, mode = 'w') as fileRef:
self.fileSaveOpen.saveFile(fileRef)
#open files
def openFile(self):
#get the filename to open
fileName = tksd.askstring("File Name", "Enter a name for the file to open")
#make sure that the file extension is added if the user didn't enter it
if fileName[-4:] != ".mpf":
fileName += '.mpf'
#open the file
with open(fileName, mode = 'r') as fileRef:
self.fileSaveOpen.openFile(fileRef)
'''
The classes to handle drawing objects
'''
class CircleDrawer:
def __init__(self, gui, memory):
self.gui = gui
#Counter to help keep track of drawing objects
self.circleCounter = 0
#attributes to set initial point
self.__firstX = 0
self.__firstY = 0
self.__actionList = memory
def setInitial(self, x, y):
self.__firstX = x
self.__firstY = y
def drawTempCircle(self, x2, y2):
coord = self.__firstX, self.__firstY, x2, y2
self.gui.canvas.create_oval(coord, fill = self.gui.color, outline = self.gui.color, tags = "temp")
def drawCircle(self, x2, y2):
coord = self.__firstX, self.__firstY, x2, y2
newTag = "circle" + str(self.circleCounter)
self.gui.canvas.create_oval(coord, fill = self.gui.color, outline = self.gui.color, tags = newTag)
self.circleCounter = self.circleCounter + 1
#Add the object to memory
self.__actionList.addCircle(self.gui.color, self.__firstX, self.__firstY, x2, y2, newTag)
#remove the redo list
self.__actionList.eraseRedo()
def redoCircle(self, color, x1, y1, x2, y2, tag):
coord = x1, y1, x2, y2
self.gui.canvas.create_oval(coord, fill = color, outline = color, tags = tag)
class SquareDrawer:
def __init__(self, gui, memory):
self.gui = gui
self.__firstX = 0
self.__firstY = 0
self.__actionList = memory
#Counter to help keep track of drawing objects
self.squareCounter = 0
def setInitial(self, x, y):
self.__firstX = x
self.__firstY = y
def drawTempSquare(self, x2, y2):
coord = self.__firstX, self.__firstY, x2, y2
self.gui.canvas.create_rectangle(coord, fill = self.gui.color, outline = self.gui.color, tags = "temp")
def drawSquare(self, x2, y2):
coord = self.__firstX, self.__firstY, x2, y2
newTag = "square" + str(self.squareCounter)
self.gui.canvas.create_rectangle(coord, fill = self.gui.color, outline = self.gui.color, tags = newTag)
self.squareCounter = self.squareCounter + 1
#Add the object to memory
self.__actionList.addSquare(self.gui.color, self.__firstX, self.__firstY, x2, y2, newTag)
#remove the redo list
self.__actionList.eraseRedo()
def redoSquare(self, color, x1, y1, x2, y2, tag):
coord = x1, y1, x2, y2
self.gui.canvas.create_rectangle(coord, fill = color, outline = color, tags = tag)
class LineDrawer:
def __init__(self, gui, memory):
#default width is 4
self.__width = 4
#save the canvas object
self.gui = gui
#hold the values of the first click
self.__firstX = 0
self.__firstY = 0
self.__actionList = memory
self.__lineCounter = 0
def setInitial(self, x, y):
self.__firstX = x
self.__firstY = y
def setWidth(self, width):
self.__width = width
def getWidth(self):
return self.__width
def drawTempLine(self, x2, y2):
coords = self.__firstX, self.__firstY, x2, y2
self.gui.canvas.create_line(coords, fill = self.gui.color, width = self.__width, tags = "temp")
def drawLine(self, x2, y2):
coords = self.__firstX, self.__firstY, x2, y2
newTag = "line" + str(self.__lineCounter)
self.gui.canvas.create_line(coords, fill = self.gui.color, width = self.__width, tags = newTag)
self.__lineCounter = self.__lineCounter + 1
#Add the line to memory
self.__actionList.addLine(self.__width, self.gui.color, self.__firstX, self.__firstY, x2, y2, newTag)
#remove the redo list
self.__actionList.eraseRedo()
def redoLine(self, width, color, x1, y1, x2, y2, tag):
coords = x1, y1, x2, y2
self.gui.canvas.create_line(coords, fill = color, width = width, tags = tag)
class ArcDrawer:
def __init__(self, gui, memory):
self.__start = 0
self.__extent = 90
self.__firstX = 0
self.__firstY = 0
self.__actionList = memory
self.gui = gui
#counter to help keep track of drawing objects
self.arcCounter = 0
def setInitial(self, x, y):
self.__firstX = x
self.__firstY = y
def setStart(self, start):
self.__start = start
def getStart(self):
return self.__start
def setExtent(self, extent):
self.__extent = extent
def getExtent(self):
return self.__extent
def drawTempArc(self, x2, y2):
coord = self.__firstX, self.__firstY, x2, y2
self.gui.canvas.create_arc(coord, start = self.__start, extent = self.__extent, fill = self.gui.color, outline = self.gui.color, style = ARC, tags = "temp")
def drawArc(self, x2, y2):
coord = self.__firstX, self.__firstY, x2, y2
newTag = "arc" + str(self.arcCounter)
self.gui.canvas.create_arc(coord, start = self.__start, extent = self.__extent, fill = self.gui.color, outline = self.gui.color, style = ARC, tags = newTag)
#Add object to memory
self.__actionList.addArc(self.__start, self.__extent, self.gui.color, self.__firstX, self.__firstY, x2, y2, newTag)
self.arcCounter = self.arcCounter + 1
#remove the redo list
self.__actionList.eraseRedo()
def redoArc(self, start, extent, color, x1, y1, x2, y2, tag):
coord = x1, y1, x2, y2
self.gui.canvas.create_arc(coord, start = start, extent = extent, fill = color, outline = color, style = ARC, tags = tag)
#class for free-drawing
class FreeDrawer:
def __init__(self, gui, memory):
self.__gui = gui
self.__memory = memory
self.__freeCount = 0
self.__tempPoints = []
def getTempPoints(self):
return self.__tempPoints
def getFreeCount(self):
return self.__freeCount
def addPoint(self, x, y):
x1 = x - 5
y1 = y - 5
x2 = x + 5
y2 = y + 5
#add a new point
self.__gui.canvas.create_oval(x1, y1, x2, y2, fill = self.__gui.color, outline = self.__gui.color, tags = "free" + str(self.__freeCount))
#add the new point to the tempPoints list
self.__tempPoints.append([x1, y1, x2, y2, self.__gui.color])
#this is the method to end the free drawing object. Add it to memory, reset memory, and increment the freeCount
def endFree(self):
#Erase any redo memory, since this is a new object, and redo would not make sense
self.__memory.eraseRedo()
self.__memory.addFreeDraw()
self.__tempPoints = []
self.__freeCount += 1
'''
Memory object to hold each change to the canvas
'''
class ActionList:
def __init__(self, gui):
self.__memory = []
self.__memCount = 0
self.__removed = []
self.__remCount = 0
self.__gui = gui
self.__freeDrawMemory = dict(initial = ["something"])
self.__freeDMemoryCount = 0
#get memory objects (for file writing)
def getMemory(self):
return self.__memory
def getFreeDrawMemory(self):
return self.__freeDrawMemory
#Take in references to all of the drawers
def drawingObject(self, circle, square, line, arc, free):
self.__circleDrawer = circle
self.__squareDrawer = square
self.__lineDrawer = line
self.__arcDrawer = arc
self.__freeDrawer = free
#Methods for adding graphic objects into memory for undo and redo
def addCircle(self, color, x1, y1, x2, y2, tag):
self.__memory.append(["circle", color, x1, y1, x2, y2, tag])
self.__memCount = self.__memCount + 1
def addSquare(self, color, x1, y1, x2, y2, tag):
self.__memory.append(["square", color, x1, y1, x2, y2, tag])
self.__memCount = self.__memCount + 1
def addLine(self, width, color, x1, y1, x2, y2, tag):
self.__memory.append(["line", width, color, x1, y1, x2, y2, tag])
self.__memCount = self.__memCount + 1
def addArc(self, start, extent, color, x1, y1, x2, y2, tag):
self.__memory.append(["arc", start, extent, color, x1, y1, x2, y2, tag])
self.__memCount = self.__memCount + 1
#Free draw memory is a bit more complex than the other shapes
def addFreeDraw(self):
#put the free draw points into the free draw memory
label = "free" + str(self.__freeDMemoryCount)
self.__freeDrawMemory[label] = self.__freeDrawer.getTempPoints()
#put a record of the free draw into the main object memory
self.__memory.append(["free", label, "free" + str(self.__freeDrawer.getFreeCount())])
#update the 2 counts
self.__freeDMemoryCount += 1
self.__memCount += 1
def undo(self):
#only perform if there is something to remove
if self.__memCount > 0:
lastObject = self.__memory.pop(len(self.__memory) - 1)
lastTag = lastObject[len(lastObject) - 1]
self.__gui.canvas.delete(lastTag)
#Object deleted. Now add to delete list for redo
self.__removed.append(lastObject)
#now adjust counts
self.__memCount = self.__memCount - 1
self.__remCount = self.__remCount + 1
#now show the redo button
self.__gui.redoButton.grid(row = 1, column = 20)
def redo(self, newColor = None):
#only perform if there is something to redo
if self.__remCount > 0:
lastRemoved = self.__removed.pop(len(self.__removed) - 1)
shape = lastRemoved[0]
shapeFound = False
if shape == "circle":
#if newColor is something besides None, then a color was passed in and the method call is from the last color options
if newColor != None:
self.__circleDrawer.redoCircle(newColor, lastRemoved[2], lastRemoved[3], lastRemoved[4], lastRemoved[5], lastRemoved[6])
#actually change the last color in memory
lastRemoved[1] = newColor
else:
self.__circleDrawer.redoCircle(lastRemoved[1], lastRemoved[2], lastRemoved[3], lastRemoved[4], lastRemoved[5], lastRemoved[6])
shapeFound = True
elif shape == "square":
if newColor != None:
self.__squareDrawer.redoSquare(newColor, lastRemoved[2], lastRemoved[3], lastRemoved[4], lastRemoved[5], lastRemoved[6])
lastRemoved[1] = newColor
else:
self.__squareDrawer.redoSquare(lastRemoved[1], lastRemoved[2], lastRemoved[3], lastRemoved[4], lastRemoved[5], lastRemoved[6])
shapeFound = True
elif shape == "line":
if newColor != None:
self.__lineDrawer.redoLine(lastRemoved[1], newColor, lastRemoved[3], lastRemoved[4], lastRemoved[5], lastRemoved[6], lastRemoved[7])
lastRemoved[2] = newColor
else:
self.__lineDrawer.redoLine(lastRemoved[1], lastRemoved[2], lastRemoved[3], lastRemoved[4], lastRemoved[5], lastRemoved[6], lastRemoved[7])
shapeFound = True
elif shape == "arc":
if newColor != None:
self.__arcDrawer.redoArc(lastRemoved[1], lastRemoved[2], newColor, lastRemoved[4], lastRemoved[5], lastRemoved[6], lastRemoved[7], lastRemoved[8])
lastRemoved[3] = newColor
else:
self.__arcDrawer.redoArc(lastRemoved[1], lastRemoved[2], lastRemoved[3], lastRemoved[4], lastRemoved[5], lastRemoved[6], lastRemoved[7], lastRemoved[8])
shapeFound = True
elif shape == "free":
#The label that the points are stored under is in the 2nd field of the last removed for "free" objects
#.. __freeDrawMemory stores the actual points under the label.
freeDrawMem = self.__freeDrawMemory[lastRemoved[1]]
#now loop through the points memory. If a color was passed in, change the color in the point memory
if newColor != None:
for pt in freeDrawMem:
self.__gui.canvas.create_oval(pt[0], pt[1], pt[2], pt[3], fill = newColor, outline = newColor, tags = lastRemoved[2])
pt[4] = newColor
else:
for pt in freeDrawMem:
self.__gui.canvas.create_oval(pt[0], pt[1], pt[2], pt[3], fill = pt[4], outline = pt[4], tags = lastRemoved[2])
shapeFound = True
if shapeFound:
#add the object back to the memory
self.__memory.append(lastRemoved)
self.__memCount = self.__memCount + 1
#removed from the removed list, so decrement
self.__remCount = self.__remCount - 1
if self.__remCount == 0:
self.__gui.redoButton.grid_forget()
def eraseRedo(self):
#this is for when the user creates a new object. The redo list is emptied at that point since it no longer makes sense
self.__removed = []
self.__remCount = 0
self.__gui.redoButton.grid_forget()
#method for erasing all objects
def removeAll(self):
if self.__memCount > 0:
for x in range(self.__memCount - 1, -1, -1):
lastObject = self.__memory.pop(x)
lastTag = lastObject[len(lastObject) - 1]
self.__gui.canvas.delete(lastTag)
#Object deleted. Now add to delete list for redo
self.__removed.append(lastObject)
#now adjust counts
self.__memCount = self.__memCount - 1
self.__remCount = self.__remCount + 1
#now show the redo button
self.__gui.redoButton.grid(row = 1, column = 20)
'''
Class for saving and opening files
'''
class FileSaveOpen:
def __init__(self, memory, circleDrawer, squareDrawer, lineDrawer, arcDrawer):
self.__memory = memory
self.__circleDrawer = circleDrawer
self.__squareDrawer = squareDrawer
self.__lineDrawer = lineDrawer
self.__arcDrawer = arcDrawer
def saveFile(self, fileRef):
#get the memory
memory = self.__memory.getMemory()
freeDrawMemory = self.__memory.getFreeDrawMemory()
#iterate through memory
for m in memory:
if m[0] != "free":
#if it isn't a free draw object, the memory object itself is sufficient
#convert the list to a string
stringList = self.convertMemToString(m)
#now write to a file
fileRef.write(stringList + "\n")
else:
#get the listing of temp points
points = freeDrawMemory[m[1]]
#iterate through the points and add them all
for p in points:
pointString = self.convertPointsToString(p)
fileRef.write(pointString + "\n")
tkmb.showinfo("Done", "File saved!")
def openFile(self, fileRef):
#Clear the canvas for the file contents
self.__memory.removeAll()
content = ""
totalList = []
while True:
content = fileRef.readline()
if not content:
break
#assemble the list from the string
obj = []
parts = content[2:-2].split(",")
for p in parts:
obj.append(p)
#now convert number strings to numbers
if obj[0] == "circle" or obj[0] == "square":
obj[1] = obj[1].strip()
obj[2] = eval(obj[2])
obj[3] = eval(obj[3])
obj[4] = eval(obj[4])
obj[5] = eval(obj[5])
obj[6] = obj[6].strip()
#now actually recreate the object
if obj[0] == "circle":
self.__circleDrawer.redoCircle(obj[1], obj[2], obj[3], obj[4], obj[5], obj[6])
else:
self.__squareDrawer.redoSquare(obj[1], obj[2], obj[3], obj[4], obj[5], obj[6])
elif obj[0] == "line":
obj[1] = eval(obj[1])
obj[2] = obj[2].strip()
obj[3] = eval(obj[3])
obj[4] = eval(obj[4])
obj[5] = eval(obj[5])
obj[6] = eval(obj[6])
obj[7] = obj[7].strip()
#redraw the line
self.__lineDrawer.redoLine(obj[1], obj[2], obj[3], obj[4], obj[5], obj[6], obj[7])
elif obj[0] == "arc":
obj[1] = eval(obj[1])
obj[2] = eval(obj[2])
obj[3] = obj[3].strip()
obj[4] = eval(obj[4])
obj[5] = eval(obj[5])
obj[6] = eval(obj[6])
obj[7] = eval(obj[7])
obj[8] = obj[8].strip()
self.__arcDrawer.redoArc(obj[1], obj[2], obj[3], obj[4], obj[5], obj[6], obj[7], obj[8])
else:
obj[0] = eval(obj[0])
obj[1] = eval(obj[1])
obj[2] = eval(obj[2])
obj[3] = eval(obj[3])
obj[4] = obj[4].strip()
self.__circleDrawer.redoCircle(obj[4], obj[0], obj[1], obj[2], obj[3], "free")
def convertMemToString(self, memory):
output = "["
count = 0
if memory[0] == "circle":
count = 7
elif memory[0] == "square":
count = 7
elif memory[0] == "line":
count = 8
elif memory[0] == "arc":
count = 9
for x in range(0, count):
output += " " + str(memory[x])
if x != count - 1:
output += ","
output += "]"
return output
def convertPointsToString(self, points):
output = "["
for x in range(0, 5):
output += " " + str(points[x])
if x != 4:
output += ","
output += "]"
return output
#Start the application
PaintGui()
The indelible lord of tl;dr
Re: Paint
Thought I would just add some features:
Version: 1.2
-Save Image
-View Saved Image
http://script47.tk/Paint/
Enjoy.
Version: 1.2
-Save Image
-View Saved Image
http://script47.tk/Paint/
Enjoy.
- Jackolantern
- Posts: 10893
- Joined: Wed Jul 01, 2009 11:00 pm
Re: Paint
That is why I thought you may want to see itScript47 wrote:@Jack that is a lot more advanced than mine.
You had the same idea as I had to freehand draw on a canvas.
The indelible lord of tl;dr
Re: Paint
I have now made the source available on http://www.github.com/Script47/Paint have fun!
- a_bertrand
- Posts: 1537
- Joined: Mon Feb 25, 2013 1:46 pm
Re: Paint
You know right that your sources were anyhow available?
Creator of Dot World Maker
Mad programmer and annoying composer
Mad programmer and annoying composer