import logging as log import tkinter as tk from tkinter import N,S,E,W from PIL import ImageTk import config import imageanalyzer from corners import Corners from epoint import EPoint from grid import Grid from .boardview import BoardView class MainWindow(tk.Frame): def __init__(self,parent,master=None): self.parent=parent self.corners=Corners() self.currentFrame=None self._boardGrid=None self.img=None self._imgSizeCoef=1 self._imgShift=EPoint(0,0) tk.Frame.__init__(self, master) self.grid(column=0,row=0,sticky=(N,S,E,W)) self._createWidgets() def setCurrentFrame(self,frame): self.currentFrame=frame w=int(self.imgView['width']) h=int(self.imgView['height']) wo,ho=frame.size # o for original widthRatio=wo/w heightRatio=ho/h self._imgSizeCoef=max(widthRatio,heightRatio) # shift compensates possible horizontal or vertical empty margins from unmatching aspect ratios self._imgShift=EPoint(wo-w*self._imgSizeCoef,ho-h*self._imgSizeCoef)/2 frame.thumbnail((w,h)) # resize self.img=ImageTk.PhotoImage(frame) def _createWidgets(self): # a captured frame with overlay graphics self.imgView=tk.Canvas(self) self.imgView.configure(width=480,height=360,background="#ff00ff") self.imgView.bind('<1>',lambda e: self.addCorner(e.x,e.y)) self.imgView.grid(column=0,row=0,sticky=(N,S,E,W)) # board with detected stones self._boardWrapper=tk.Frame(self,width=360,height=360) self.boardView=BoardView(self._boardWrapper) self._boardWrapper.grid(column=1,row=0,sticky=(N,S,E,W)) # more controls below the board self.scaleTresB=tk.Scale(self, orient=tk.HORIZONTAL, length=200, from_=0.0, to=100.0, command=self.refreshTresholds) self.scaleTresW=tk.Scale(self, orient=tk.HORIZONTAL, length=200, from_=0.0, to=100.0, command=self.refreshTresholds) self.scaleTresB.set(30.0) # !! proper defaults self.scaleTresW.set(60.0) self.scaleTresB.grid(column=0,row=1,columnspan=2) self.scaleTresW.grid(column=0,row=2,columnspan=2) self.columnconfigure(0,weight=1) self.columnconfigure(1,weight=1) self.rowconfigure(0,weight=1) # render everything self.redrawImgView() ## Stores a grid corner located at x,y coordinates. def addCorner(self,x,y): self.corners.add(x,y) log.debug("click on %d,%d",x,y) log.debug("sizeCoef: %f, shift: %d,%d",self._imgSizeCoef,self._imgShift.x,self._imgShift.y) if self.corners.canonizeOrder(): # transform corners from show coordinates to real coordinates log.debug(self.corners.corners) self._boardGrid=Grid(self.corners.corners) corners=[(c*self._imgSizeCoef+self._imgShift) for c in self.corners.corners] self.parent.sendMsg("setCorners",(corners,)) self.redrawImgView() ## Redraws the current image and its overlay. def redrawImgView(self): if self.currentFrame and self.img: self.imgView.create_image(240,180,anchor="center",image=self.img) 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))=imageanalyzer.relevantRect(self._boardGrid.intersections[r][c], *(self._boardGrid.stoneSizeAt(r, c))) self.imgView.create_rectangle(r1,c1,r2,c2,outline="#00ffff") self.imgView.grid() ## 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.parent.sendMsg("setTresholds",tuple(),{"tresB":self.scaleTresB.get(), "tresW":self.scaleTresW.get()})