Files @ f1f8a2421f92
Branch filter:

Location: OneEye/src/gui/__init__.py

Laman
updated readme
import logging
import threading
import tkinter as tk

import config
from analyzer import ImageAnalyzer
from .mainwindow import MainWindow
from .boardview import BoardView
from .settings import Settings

log=logging.getLogger(__name__)


class GUI:
	SETUP=PREVIEW=0
	RECORDING=REAL=1

	def __init__(self):
		self.root = tk.Tk()
		self.root.title("OneEye {0}.{1}.{2}".format(*config.misc.version))
		self.root.option_add('*tearOff',False) # for menu

		self.detector=ImageAnalyzer()
		self._frame=None
		self._frameKey=0

		self._ownMessages=None
		self._coreMessages=None

		self._state=GUI.RECORDING

		self.mainWindow = MainWindow(self)
		self.settings=None
		self.root.columnconfigure(0,weight=1)
		self.root.rowconfigure(0,weight=1)

		self.root.bind("<<redrawImgView>>", lambda e: self.mainWindow.redrawImgView())
		self.root.bind("<<setUp>>", lambda e: self.setUp())
		self.root.bind("<<setRecording>>", lambda e: self.setRecording())
		self.root.bind("<F12>",lambda e: Settings(self))
		self.mainWindow.bind("<Destroy>",lambda e: self._shutDown())

		self.setRecording()

	def __call__(self,ownMessages,coreMessages):
		self._ownMessages=ownMessages
		self._coreMessages=coreMessages

		self._listenerThread=threading.Thread(target=lambda: ownMessages.listen(self._handleEvent))
		self._listenerThread.start()

		self.mainWindow.mainloop()

	def sendMsg(self,actionName,args=tuple(),kwargs=None):
		self._coreMessages.send(actionName,args,kwargs)

	def setUp(self):
		self.mainWindow.setUp()
		self.root.bind("<Left>",lambda e: self.sendMsg("prevFrame"))
		self.root.bind("<Right>",lambda e: self.sendMsg("nextFrame"))
		self._state=GUI.SETUP

	def setRecording(self):
		self.mainWindow.setRecording()
		self.root.bind("<Left>",lambda e: None)
		self.root.bind("<Right>",lambda e: None)
		if self.settings:
			self.settings.destroy()
			self.settings=None
		if self._coreMessages: self.sendParams()
		self._state=GUI.RECORDING

	def sendParams(self):
		self.sendMsg("setParams",(self.detector.params.copy(),))

	def preview(self):
		if self.detector.analyze(self._frame):
			self.mainWindow.boardView.redrawState(self.detector.board)

	def _shutDown(self):
		log.info("GUI proc exiting.")
		self._ownMessages.send("!kill",("gui",))
		self._listenerThread.join()

	def _handleEvent(self,e):
		actions={
			"setFrame": self._frameHandler,
			"setGameState": self._stateHandler,
			"setParams": self._paramsHandler
		}
		(actionName,args,kwargs)=e

		return actions[actionName](*args,**kwargs)

	def _frameHandler(self,frame,type,key):
		if self._state!=type and self.mainWindow.imgView.isSet():
			log.info("ignored setFrame event, wrong type")
			return
		self._frame=frame
		self._frameKey=key
		self.mainWindow.setFrame(frame)
		self.root.event_generate("<<redrawImgView>>")

	def _stateHandler(self,gameState,moves):
		if self._state==GUI.SETUP:
			log.info("ignored incoming gameState")
			return
		labels={(row,col):(i+1) for (i,(c,row,col)) in enumerate(moves)}
		self.mainWindow.boardView.redrawState(gameState,labels)

	def _paramsHandler(self,params):
		if not self.settings:
			log.warning("received 'setParams' message while settings is '%s'",str(self.settings))
			return
		self.detector.setParams(params)
		self.settings.setParams(params)


gui=GUI()

"""
# setup #
* we can click around the ImgView
* we can walk through the frames back and forth
* BoardView is showing what the reading of ImgView _would_ be
* core is reading and analyzing frames, pushing results to StateBag, but not showing them

# recording #
* ImgView is showing the current picture, is not clickable
* BoardView is showing last detected position
* on switch to recording (if parameters have changed):
	* feed analyzer new parameters and start using them
	* in the background reanalyze cached frames with the new parameters and merge them into StateBag
"""