In: Computer Science
Sketch! This assignment is to write a Python program that makes use of the OpenGL graphics library to make an interactive sketching program that will allow the user to do line drawings. The user should be able to choose from a palette of colors displayed on the screen. When the user clicks the mouse in the color palette area, the drawing tool will switch to using the color selected, much like dipping a paint brush into a new color of paint.
Here are two starter codes. I'm trying to combine them basically but end up with a mess. It's supposed to be mimicking Microsoft Paint. Pick a color and then draw a line with it. There are 3 boxes on the left side, red, green, and blue. When the user clicks the box the line color matches the color of the box. Then the user can click in the space and free draw a line of that color, similar to Microsoft paint.
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
# global variables
width = 400 # window dimensions
height = 300
menuwidth = 100 # menu dimensions
ncolors = 3 # number of colors
boxheight = height//ncolors # height of each color box
colormenu = [[1.0,0.0,0.0], [0.0,1.0,0.0], [0.0,0.0,1.0]]
menuindex = -1
###
# Returns true if point (x, y) is in the color menu
###
def incolormenu(x, y):
return x >= 0 and x <= menuwidth and y >= 0 and y <= height
###
# Returns index of point (x, y) in the color menu
###
def colormenuindex(x, y):
if not incolormenu(x, y):
return -1;
else:
return y//boxheight
###
# Watch mouse button presses and handle them
###
def handleButton(button, state, x, y):
global menuindex
y = height - y # reverse y, so zero at bottom, and max at top
if button != GLUT_LEFT_BUTTON: # ignore all but left button
return
# if button pressed and released in same menu box, then update
# the color of the large square
if state == GLUT_DOWN:
if incolormenu(x, y):
menuindex = colormenuindex(x, y)
else:
if incolormenu(x, y) and colormenuindex(x, y) == menuindex:
glColor3f(colormenu[menuindex][0], colormenu[menuindex][1], colormenu[menuindex][2])
glRecti(menuwidth, 0, width, height)
glFlush()
###
# Draw the colored box and the color menu
###
def drawMenu():
# clear window
glClear(GL_COLOR_BUFFER_BIT)
# draw the color menu
for i in range(ncolors):
glColor3f(colormenu[i][0], colormenu[i][1], colormenu[i][2])
glRecti(1, boxheight * i + 1, menuwidth - 1, boxheight * (i + 1) - 1)
glFlush()
###
# Main program
###
def main():
glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA)
glutInitWindowSize(width, height)
window = glutCreateWindow("Color Menu")
# callback routine
glutDisplayFunc(drawMenu)
glutMouseFunc(handleButton)
# lower left of window is (0, 0), upper right is (width, height)
gluOrtho2D(0, width, 0, height)
# specify window clear (background) color to be black
glClearColor(0, 0, 0, 0)
glutMainLoop()
if __name__ == "__main__":
main()
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
# global variables
width = 600 # window dimensions
height = 600
wleft = 0
wright = width
wbottom = 0
wtop = height
tracking = False
###
# Returns true if point (x, y) is in the window
###
def inwindow(x, y):
return x > wleft and x < wright and y > wbottom and y < wtop
###
# Draw a line to new mouse position
###
def m_Motion(x, y):
y = wtop - y
if tracking and inwindow(x, y):
glBegin(GL_LINES)
glVertex2i(width//2, height//2)
glVertex2i(x, y)
glEnd()
glFlush()
###
# Watch mouse button presses and handle them
###
def handleButton(button, state, x, y):
global tracking
y = wtop - y
if button != GLUT_LEFT_BUTTON:
return
if state == GLUT_DOWN:
if inwindow(x, y):
tracking = True
else:
tracking = False
###
# Clear the window
###
def drawMouse():
glClear(GL_COLOR_BUFFER_BIT) # clear the window
glColor3f(0, 0, 0) # set mouse line color
glFlush()
###
# Main program
###
def main():
glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA)
glutInitWindowSize(width, height)
window = glutCreateWindow("Mouse Exam")
# callback routine
glutDisplayFunc(drawMouse)
glutMouseFunc(handleButton)
glutMotionFunc(m_Motion)
# lower left of window is (0, 0), upper right is (width, height)
gluOrtho2D(0, width, 0, height)
# specify window clear (background) color to be dark grey
glClearColor(0.7, 0.7, 0.7, 1)
glutMainLoop()
if __name__ == "__main__":
main()
from tkinter import *
from tkinter.colorchooser import askcolor
class Paint(object):
DEFAULT_PEN_SIZE = 5.0
DEFAULT_COLOR = 'black'
def __init__(self):
self.root = Tk()
self.pen_button = Button(self.root, text='pen',
command=self.use_pen)
self.pen_button.grid(row=0, column=0)
self.brush_button = Button(self.root, text='brush',
command=self.use_brush)
self.brush_button.grid(row=0, column=1)
self.color_button = Button(self.root, text='color',
command=self.choose_color)
self.color_button.grid(row=0, column=2)
self.eraser_button = Button(self.root, text='eraser',
command=self.use_eraser)
self.eraser_button.grid(row=0, column=3)
self.choose_size_button = Scale(self.root, from_=1, to=10,
orient=HORIZONTAL)
self.choose_size_button.grid(row=0, column=4)
self.c = Canvas(self.root, bg='white', width=600,
height=600)
self.c.grid(row=1, columnspan=5)
self.setup()
self.root.mainloop()
def setup(self):
self.old_x = None
self.old_y = None
self.line_width = self.choose_size_button.get()
self.color = self.DEFAULT_COLOR
self.eraser_on = False
self.active_button = self.pen_button
self.c.bind('<B1-Motion>', self.paint)
self.c.bind('<ButtonRelease-1>', self.reset)
def use_pen(self):
self.activate_button(self.pen_button)
def use_brush(self):
self.activate_button(self.brush_button)
def choose_color(self):
self.eraser_on = False
self.color = askcolor(color=self.color)[1]
def use_eraser(self):
self.activate_button(self.eraser_button, eraser_mode=True)
def activate_button(self, some_button, eraser_mode=False):
self.active_button.config(relief=RAISED)
some_button.config(relief=SUNKEN)
self.active_button = some_button
self.eraser_on = eraser_mode
def paint(self, event):
self.line_width = self.choose_size_button.get()
paint_color = 'white' if self.eraser_on else self.color
if self.old_x and self.old_y:
self.c.create_line(self.old_x, self.old_y, event.x, event.y,
width=self.line_width, fill=paint_color,
capstyle=ROUND, smooth=TRUE, splinesteps=36)
self.old_x = event.x
self.old_y = event.y
def reset(self, event):
self.old_x, self.old_y = None, None
if __name__ == '__main__':
Paint()