oldschool-toontown/otp/login/GuiScreen.py
2019-11-02 18:27:54 -04:00

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'}])