Files @ f6b3d570893c
Branch filter:

Location: OneEye/src/gui.py

Laman
basic logging, basic configuration, little refactoring
import tkinter as tk
from PIL import ImageTk
import PIL

import config
from corners import *
from grid import *
from image_analyzer import *
from go import *


class Application(tk.Frame):
	def __init__(self, master=None):
		self.corners=Corners()
		self.boardGrid=None

		tk.Frame.__init__(self, master)
		self.grid(column=0,row=0)
		self.createWidgets()

	def createWidgets(self):
		# a captured frame with overlay graphics
		self.imgView=tk.Canvas(self)
		self.imgView.configure(width=480,height=360)
		self.imgOrig=PIL.Image.open("../images/7.jpg")

		self.img=ImageTk.PhotoImage(self.imgOrig.resize((int(self.imgView['width']),int(self.imgView['height'])),resample=PIL.Image.BILINEAR))

		self.imgView.bind('<1>',lambda e: self.addCorner(e.x,e.y))

		self.imgView.grid(column=0,row=0)

		# board with detected stones
		self.boardView=BoardView(self)
		self.boardView.grid(column=1,row=0)

		# more controls below the board
		def _refreshTresholds(_):
			self.refreshTresholds()
			self.redrawImgView()
		self.scaleTresB=tk.Scale(self, orient=tk.HORIZONTAL, length=200, from_=0.0, to=100.0, command=_refreshTresholds)
		self.scaleTresW=tk.Scale(self, orient=tk.HORIZONTAL, length=200, from_=0.0, to=100.0, command=_refreshTresholds)
		self.scaleTresB.set(30.0)
		self.scaleTresW.set(60.0)
		self.scaleTresB.grid(column=0,row=1,columnspan=2)
		self.scaleTresW.grid(column=0,row=2,columnspan=2)

		# render everything
		self.redrawImgView()

	## Stores a grid corner located at x,y coordinates.
	def addCorner(self,x,y):
		self.corners.add(x,y)
		if self.corners.canonizeOrder():
			self.boardGrid=Grid(self.corners)
			self.boardView.setBoardGrid(self.boardGrid)

		self.redrawImgView()

	## Redraws the current image and its overlay.
	def redrawImgView(self):
		self.imgView.create_image(2,2,anchor="nw",image=self.img)

		origWidth,origHeight=self.imgOrig.size
		widthRatio=origWidth/self.img.width()
		heightRatio=origHeight/self.img.height()
		sizeCoef=max(widthRatio,heightRatio)
		tresB=self.scaleTresB.get()
		tresW=self.scaleTresW.get()

		for corner in self.corners.corners:
			self.markPoint(corner.x,corner.y)

		if self.boardGrid!=None and config.gui.showGrid:
			for r in range(19):
				a=self.boardGrid.intersections[r][0]
				b=self.boardGrid.intersections[r][-1]
				self.imgView.create_line(a.x,a.y,b.x,b.y,fill='#00ff00')
			for c in range(19):
				a=self.boardGrid.intersections[0][c]
				b=self.boardGrid.intersections[-1][c]
				self.imgView.create_line(a.x,a.y,b.x,b.y,fill='#00ff00')

		if self.boardGrid!=None and config.gui.showBigPoints:
			for r in range(19):
				for c in range(19):
					((r1,c1),(r2,c2))=self.boardView.detector.relevantRect(self.boardGrid.intersections[r][c],*(self.boardGrid.stoneSizeAt(r,c,sizeCoef)))
					self.imgView.create_rectangle(r1,c1,r2,c2,outline="#00ffff")

		self.imgView.grid()

		shift=EPoint(origWidth-self.img.width()*sizeCoef,origHeight-self.img.height()*sizeCoef)/2

		self.boardView.redrawState(self.imgOrig,sizeCoef,shift)

	## Marks a point at the image with a green cross. Used for corners.
	def markPoint(self,x,y):
		self.imgView.create_line(x-3,y-3,x+4,y+4,fill="#00ff00")
		self.imgView.create_line(x-3,y+3,x+4,y-4,fill="#00ff00")

		self.imgView.grid()

	def refreshTresholds(self):
			self.boardView.detector.tresB=self.scaleTresB.get()
			self.boardView.detector.tresW=self.scaleTresW.get()


## Handles and presents the game state as detected by the program.
class BoardView(tk.Canvas):
	def __init__(self, master=None):
		self.detector=ImageAnalyzer()
		self.boardGrid=None

		tk.Canvas.__init__(self, master)
		self.configure(width=360,height=360,background="#ffcc00")

		self.drawGrid()

		self.grid()

	## Redraws and reananalyzes the board view.
	def redrawState(self,img,sizeCoef,shift):
		self.create_rectangle(0,0,360,360,fill="#ffcc00")
		self.drawGrid()

		self.detector.analyze(img,sizeCoef,shift)

		for r,row in enumerate(self.detector.board):
			for c,point in enumerate(row):
				self.drawStone(r,c,point)

		self.grid()

	def drawGrid(self):
		for i in range(19):
			self.create_line(18,18*(i+1),360-18,18*(i+1),fill="#000000") # rows
			self.create_line(18*(i+1),18,18*(i+1),360-18,fill="#000000") # cols

		self.drawStars()

	def drawStars(self):
		for r in range(4,19,6):
			for c in range(4,19,6):
				self.create_oval(r*18-2,c*18-2,r*18+2,c*18+2,fill='#000000')

	## Draws a stone at provided coordinates.
	#
	#  For an unknown color draws nothing and returns False.
	#
	#  @param r row coordinate, [0-18], counted from top
	#  @param c column coordinate, [0-18], counted from left
	#  @param color color indicator, Go.BLACK or Go.WHITE
	def drawStone(self,r,c,color):
		if color==Go.BLACK: hexCode='#000000'
		elif color==Go.WHITE: hexCode='#ffffff'
		else: return False
		r+=1
		c+=1
		self.create_oval(c*18-9,r*18-9,c*18+9,r*18+9,fill=hexCode)

	def setBoardGrid(self,boardGrid):
		self.boardGrid=boardGrid
		self.detector.setGrid(boardGrid)


root = tk.Tk()
root.title("OneEye {0}.{1}".format(*config.misc.version))
app = Application(master=root)
app.mainloop()