# L-11 MCS 275 Fri 8 Feb 2008 : mousedraw.py

# To illustrate the binding of mouse events
# to canvas, we consider filling squares on
# a grid on canvas via the mouse.

from Tkinter import *
from numpy import *
from random import randint

class FillSquares():
   """
   filling squares on canvas with mouse clicks
   """
   def BindMouseEvents(self):
      """
      binds mouse events to the canvas
      """
      self.c.bind("<Button-1>", self.ButtonPressed)
      self.c.bind("<ButtonRelease-1>", self.ButtonReleased)
      self.c.bind("<Enter>", self.EnteredWindow)
      self.c.bind("<Leave>", self.ExitedWindow)
      self.c.bind("<B1-Motion>", self.MouseDragged)

   def __init__(self,wdw,r,c):
      """
      the mouse is bound to the canvas
      a label displays mouse position
      """
      wdw.title("mark with mouse")
      self.mag = 10   # magnification factor
      self.rows = r   # number of rows on canvas
      self.cols = c   # number of columns on canvas
      self.c = Canvas(wdw,\
         width=self.mag*self.cols+2*self.mag,\
         height = self.mag*self.rows+2*self.mag,\
         bg='white')
      self.c.grid(row=1,column=0,columnspan=3)
      # to display mouse position :
      self.MousePosition = StringVar()
      self.MousePosition.set("put mouse inside box to draw")
      self.PositionLabel = Label(wdw, \
         textvariable = self.MousePosition)
      self.PositionLabel.grid(row=2,column=0,columnspan=3)
      # bind mouse events
      self.BindMouseEvents()
      self.filled = zeros((r,c),bool)

   def DrawRectangle(self,x,y):
      """
      draws a green rectangle on canvas,
      with coordinates given at (x,y) by mouse
      """
      x0 = y - y % self.mag
      y0 = x - x % self.mag
      x1 = x0 + self.mag
      y1 = y0 + self.mag
      i = x0/self.mag - 1
      j = y0/self.mag - 1
      name = '('+str(i)+','+str(j)+')'
      if not self.filled[i,j]:
         self.c.create_rectangle(y0,x0,y1,x1,fill="green",tags=name)
         self.filled[i,j] = True
      else:
         self.c.delete(name)
         self.filled[i,j] = False

   def ButtonPressed(self,event):
      """
      display coordinates of button press
      """
      self.MousePosition.set("currently at [ " + \
         str(event.x) + ", " + str(event.y) + " ]" +\
         " release to fill, or drag")

   def ButtonReleased(self,event):
      """
      display coordinates of button release
      """
      self.MousePosition.set("drawn at [ " + \
         str(event.x) + ", " + str(event.y) + " ]" + \
         " redo to clear")
      self.DrawRectangle(event.x,event.y)

   def EnteredWindow(self,event):
      """
      display message that mouse entered window
      """
      self.MousePosition.set("press mouse to give coordinates")

   def ExitedWindow(self,event):
      """
      display message that mouse exited window
      """
      self.MousePosition.set("put mouse inside box to draw")

   def MouseDragged(self,event):
      """
      display coordinaes of moving mouse
      """
      self.MousePosition.set("dragging at [ " + \
         str(event.x) + ", " + str(event.y) + " ]" + \
         " release to draw")

def main():
   top = Tk()
   # r = input('Give #rows : ')
   # c = input('Give #columns : ')
   r = 20; c = 30
   show = FillSquares(top,r,c)
   top.mainloop()

if __name__ == "__main__": main()
