Files @ 52d1a214c032
Branch filter:

Location: OneEye/src/gui/__init__.py

Laman
refactoring and documenting API
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._frameKey=0

		self._ownMessages=None
		self._coreMessages=None

		self._state=GUI.SETUP

		self.mainWindow = MainWindow(self, master=self.root)
		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._ownMessages.send("!kill",("gui",)))

		self.setUp()

	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"))

	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
		self.sendParams()

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

	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._frameKey=key
		self.mainWindow.setFrame(frame)
		self.root.event_generate("<<redrawImgView>>")

	def _stateHandler(self,gameState,moves):
		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
"""