276 lines
11 KiB
Python
276 lines
11 KiB
Python
from pandac.PandaModules import *
|
|
from otp.otpbase import OTPGlobals
|
|
from direct.gui.DirectGui import *
|
|
from otp.otpgui import OTPDialog
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
from otp.otpbase import OTPLocalizer
|
|
from direct.task.Task import Task
|
|
|
|
class GuiScreen:
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('GuiScreen')
|
|
DGG.ENTERPRESS_ADVANCE = 0
|
|
DGG.ENTERPRESS_ADVANCE_IFNOTEMPTY = 1
|
|
DGG.ENTERPRESS_DONT_ADVANCE = 2
|
|
DGG.ENTERPRESS_REMOVE_FOCUS = 3
|
|
ENTRY_WIDTH = 20
|
|
|
|
def __init__(self):
|
|
self.waitingForDatabase = None
|
|
self.focusIndex = None
|
|
self.suppressClickSound = 0
|
|
return
|
|
|
|
def startFocusMgmt(self, startFocus = 0, enterPressBehavior = DGG.ENTERPRESS_ADVANCE_IFNOTEMPTY, overrides = {}, globalFocusHandler = None):
|
|
GuiScreen.notify.debug('startFocusMgmt:\nstartFocus=%s,\nenterPressBehavior=%s\noverrides=%s' % (startFocus, enterPressBehavior, overrides))
|
|
self.accept('tab', self.__handleTab)
|
|
self.accept('shift-tab', self.__handleShiftTab)
|
|
self.accept('enter', self.__handleEnter)
|
|
self.__startFrameStartTask()
|
|
self.userGlobalFocusHandler = globalFocusHandler
|
|
self.focusHandlerAbsorbCounts = {}
|
|
for i in xrange(len(self.focusList)):
|
|
item = self.focusList[i]
|
|
if isinstance(item, DirectEntry):
|
|
self.focusHandlerAbsorbCounts[item] = 0
|
|
|
|
self.userFocusHandlers = {}
|
|
self.userCommandHandlers = {}
|
|
for i in xrange(len(self.focusList)):
|
|
item = self.focusList[i]
|
|
if isinstance(item, DirectEntry):
|
|
self.userFocusHandlers[item] = (item['focusInCommand'], item['focusInExtraArgs'])
|
|
item['focusInCommand'] = self.__handleFocusChangeAbsorb
|
|
item['focusInExtraArgs'] = [i]
|
|
self.userCommandHandlers[item] = (item['command'], item['extraArgs'])
|
|
item['command'] = None
|
|
item['extraArgs'] = []
|
|
elif isinstance(item, DirectScrolledList):
|
|
self.userCommandHandlers[item] = (item['command'], item['extraArgs'])
|
|
item['command'] = self.__handleDirectScrolledListCommand
|
|
item['extraArgs'] = [i]
|
|
|
|
self.enterPressHandlers = {}
|
|
for i in xrange(len(self.focusList)):
|
|
item = self.focusList[i]
|
|
behavior = enterPressBehavior
|
|
if overrides.has_key(item):
|
|
behavior = overrides[item]
|
|
if callable(behavior):
|
|
self.enterPressHandlers[item] = behavior
|
|
else:
|
|
if not isinstance(item, DirectEntry) and behavior == GuiScreen_ENTERPRESS_ADVANCE_IFNOTEMPTY:
|
|
behavior = GuiScreen_ENTERPRESS_ADVANCE
|
|
commandHandlers = (self.__alwaysAdvanceFocus,
|
|
self.__advanceFocusIfNotEmpty,
|
|
self.__neverAdvanceFocus,
|
|
self.__ignoreEnterPress)
|
|
self.enterPressHandlers[item] = commandHandlers[behavior]
|
|
|
|
self.setFocus(startFocus)
|
|
return
|
|
|
|
def focusMgmtActive(self):
|
|
return self.focusIndex != None
|
|
|
|
def stopFocusMgmt(self):
|
|
GuiScreen.notify.debug('stopFocusMgmt')
|
|
if not self.focusMgmtActive():
|
|
return
|
|
self.ignore('tab')
|
|
self.ignore('shift-tab')
|
|
self.ignore('enter')
|
|
self.__stopFrameStartTask()
|
|
self.userGlobalFocusHandler = None
|
|
self.focusIndex = None
|
|
self.focusHandlerAbsorbCounts = {}
|
|
for item in self.focusList:
|
|
if isinstance(item, DirectEntry):
|
|
userHandler, userHandlerArgs = self.userFocusHandlers[item]
|
|
item['focusInCommand'] = userHandler
|
|
item['focusInExtraArgs'] = userHandlerArgs
|
|
userHandler, userHandlerArgs = self.userCommandHandlers[item]
|
|
item['command'] = userHandler
|
|
item['extraArgs'] = userHandlerArgs
|
|
elif isinstance(item, DirectScrolledList):
|
|
userHandler, userHandlerArgs = self.userCommandHandlers[item]
|
|
item['command'] = userHandler
|
|
item['extraArgs'] = userHandlerArgs
|
|
|
|
self.userFocusHandlers = {}
|
|
self.userCommandHandlers = {}
|
|
self.enterPressHandlers = {}
|
|
return
|
|
|
|
def setFocus(self, arg, suppressSound = 1):
|
|
if type(arg) == type(0):
|
|
index = arg
|
|
else:
|
|
index = self.focusList.index(arg)
|
|
if suppressSound:
|
|
self.suppressClickSound += 1
|
|
self.__setFocusIndex(index)
|
|
|
|
def advanceFocus(self, condition = 1):
|
|
index = self.getFocusIndex()
|
|
if condition:
|
|
index += 1
|
|
self.setFocus(index, suppressSound=0)
|
|
|
|
def getFocusIndex(self):
|
|
if not self.focusMgmtActive():
|
|
return None
|
|
return self.focusIndex
|
|
|
|
def getFocusItem(self):
|
|
if not self.focusMgmtActive():
|
|
return None
|
|
return self.focusList[self.focusIndex]
|
|
|
|
def removeFocus(self):
|
|
focusItem = self.getFocusItem()
|
|
if isinstance(focusItem, DirectEntry):
|
|
focusItem['focus'] = 0
|
|
if self.userGlobalFocusHandler:
|
|
self.userGlobalFocusHandler(None)
|
|
return
|
|
|
|
def restoreFocus(self):
|
|
self.setFocus(self.getFocusItem())
|
|
|
|
def __setFocusIndex(self, index):
|
|
focusIndex = index % len(self.focusList)
|
|
focusItem = self.focusList[focusIndex]
|
|
if isinstance(focusItem, DirectEntry):
|
|
focusItem['focus'] = 1
|
|
self.focusHandlerAbsorbCounts[focusItem] += 1
|
|
self.__handleFocusChange(focusIndex)
|
|
|
|
def __chainToUserCommandHandler(self, item):
|
|
userHandler, userHandlerArgs = self.userCommandHandlers[item]
|
|
if userHandler:
|
|
if isinstance(item, DirectEntry):
|
|
enteredText = item.get()
|
|
apply(userHandler, [enteredText] + userHandlerArgs)
|
|
elif isinstance(item, DirectScrolledList):
|
|
apply(userHandler, userHandlerArgs)
|
|
|
|
def __chainToUserFocusHandler(self, item):
|
|
if isinstance(item, DirectEntry):
|
|
userHandler, userHandlerArgs = self.userFocusHandlers[item]
|
|
if userHandler:
|
|
apply(userHandler, userHandlerArgs)
|
|
|
|
def __handleTab(self):
|
|
self.tabPressed = 1
|
|
self.focusDirection = 1
|
|
self.__setFocusIndex(self.getFocusIndex() + self.focusDirection)
|
|
|
|
def __handleShiftTab(self):
|
|
self.tabPressed = 1
|
|
self.focusDirection = -1
|
|
self.__setFocusIndex(self.getFocusIndex() + self.focusDirection)
|
|
|
|
def __handleFocusChangeAbsorb(self, index):
|
|
item = self.focusList[index]
|
|
if self.focusHandlerAbsorbCounts[item] > 0:
|
|
self.focusHandlerAbsorbCounts[item] -= 1
|
|
else:
|
|
self.__handleFocusChange(index)
|
|
|
|
def playFocusChangeSound(self):
|
|
base.playSfx(DGG.getDefaultClickSound())
|
|
|
|
def __handleFocusChange(self, index):
|
|
if index != self.focusIndex:
|
|
self.removeFocus()
|
|
self.__focusChangedThisFrame = 1
|
|
if hasattr(self, 'tabPressed'):
|
|
del self.tabPressed
|
|
else:
|
|
self.focusDirection = 1
|
|
self.focusIndex = index
|
|
if self.suppressClickSound > 0:
|
|
self.suppressClickSound -= 1
|
|
else:
|
|
self.playFocusChangeSound()
|
|
focusItem = self.getFocusItem()
|
|
if self.userGlobalFocusHandler:
|
|
self.userGlobalFocusHandler(focusItem)
|
|
if self.getFocusItem() != focusItem:
|
|
GuiScreen.notify.debug('focus changed by global focus handler')
|
|
if self.focusMgmtActive():
|
|
self.__chainToUserFocusHandler(focusItem)
|
|
|
|
def __startFrameStartTask(self):
|
|
self.__focusChangedThisFrame = 0
|
|
self.frameStartTaskName = 'GuiScreenFrameStart'
|
|
taskMgr.add(self.__handleFrameStart, self.frameStartTaskName, -100)
|
|
|
|
def __stopFrameStartTask(self):
|
|
taskMgr.remove(self.frameStartTaskName)
|
|
del self.frameStartTaskName
|
|
del self.__focusChangedThisFrame
|
|
|
|
def __handleFrameStart(self, task):
|
|
self.__focusChangedThisFrame = 0
|
|
return Task.cont
|
|
|
|
def __handleDirectScrolledListCommand(self, index):
|
|
self.__chainToUserCommandHandler(self.focusList[index])
|
|
self.setFocus(index, suppressSound=self.getFocusIndex() == index)
|
|
|
|
def __handleEnter(self):
|
|
if self.__focusChangedThisFrame:
|
|
return
|
|
focusItem = self.getFocusItem()
|
|
if isinstance(focusItem, DirectEntry):
|
|
self.__chainToUserCommandHandler(focusItem)
|
|
if self.focusMgmtActive() and focusItem == self.getFocusItem():
|
|
self.enterPressHandlers[focusItem]()
|
|
|
|
def __alwaysAdvanceFocus(self):
|
|
self.advanceFocus()
|
|
|
|
def __advanceFocusIfNotEmpty(self):
|
|
focusItem = self.getFocusItem()
|
|
enteredText = focusItem.get()
|
|
if enteredText != '':
|
|
self.advanceFocus()
|
|
else:
|
|
self.setFocus(self.getFocusIndex())
|
|
|
|
def __neverAdvanceFocus(self):
|
|
self.setFocus(self.getFocusIndex())
|
|
|
|
def __ignoreEnterPress(self):
|
|
pass
|
|
|
|
def waitForDatabaseTimeout(self, requestName = 'unknown'):
|
|
GuiScreen.notify.debug('waiting for database timeout %s at %s' % (requestName, globalClock.getFrameTime()))
|
|
globalClock.tick()
|
|
taskMgr.doMethodLater(OTPGlobals.DatabaseDialogTimeout, self.__showWaitingForDatabase, 'waitingForDatabase', extraArgs=[requestName])
|
|
|
|
def __showWaitingForDatabase(self, requestName):
|
|
GuiScreen.notify.info('timed out waiting for %s at %s' % (requestName, globalClock.getFrameTime()))
|
|
dialogClass = OTPGlobals.getDialogClass()
|
|
self.waitingForDatabase = dialogClass(text=OTPLocalizer.GuiScreenToontownUnavailable, dialogName='WaitingForDatabase', buttonTextList=[OTPLocalizer.GuiScreenCancel], style=OTPDialog.Acknowledge, command=self.__handleCancelWaiting)
|
|
self.waitingForDatabase.show()
|
|
taskMgr.doMethodLater(OTPGlobals.DatabaseGiveupTimeout, self.__giveUpWaitingForDatabase, 'waitingForDatabase', extraArgs=[requestName])
|
|
return Task.done
|
|
|
|
def __giveUpWaitingForDatabase(self, requestName):
|
|
GuiScreen.notify.info('giving up waiting for %s at %s' % (requestName, globalClock.getFrameTime()))
|
|
self.cleanupWaitingForDatabase()
|
|
messenger.send(self.doneEvent, [{'mode': 'failure'}])
|
|
return Task.done
|
|
|
|
def cleanupWaitingForDatabase(self):
|
|
if self.waitingForDatabase != None:
|
|
self.waitingForDatabase.cleanup()
|
|
self.waitingForDatabase = None
|
|
taskMgr.remove('waitingForDatabase')
|
|
return
|
|
|
|
def __handleCancelWaiting(self, value):
|
|
self.cleanupWaitingForDatabase()
|
|
messenger.send(self.doneEvent, [{'mode': 'quit'}])
|