00001 import BigWorld, GUI
00002 import weakref
00003 from bwdebug import *
00004
00005 from functools import partial
00006
00007 from Helpers.Listener import Listenable
00008
00009
00010
00011
00012
00013 """
00014 This is the base class for all python gui classes.
00015 There is a simple interface.
00016
00017 active(bool) //must use this entry point to show the gui
00018 setEventHandler(ev) //this function gets called back on an event
00019 self.component //the underlying component. Must be set by derived classes/
00020 """
00021 class PyGUIBase(object, Listenable):
00022
00023 def __init__( self, component = None ):
00024 Listenable.__init__( self )
00025
00026 self.component = component
00027 self.eventHandler = None
00028 self._parent = None
00029 self.isActive = False
00030
00031 def active( self, state ):
00032 if state == self.isActive:
00033 return
00034
00035 if not self.component:
00036 return
00037
00038 self.isActive = state
00039 if state:
00040 if not self._parent:
00041 GUI.addRoot( self.component )
00042 else:
00043 self._parent.addChild( self.component )
00044
00045 self.component.focus = True
00046 self.component.moveFocus = True
00047 self.component.crossFocus = True
00048 else:
00049 if not self._parent:
00050 GUI.delRoot( self.component )
00051 else:
00052 self._parent.delChild( self.component )
00053
00054 self.component.focus = False
00055 self.component.moveFocus = False
00056 self.component.crossFocus = False
00057
00058 self.listeners.activated( state )
00059
00060 def _setparent( self, parent ):
00061 if self.isActive:
00062 if not self._parent:
00063 GUI.delRoot( self.component )
00064 else:
00065 self._parent.delChild( self.component )
00066
00067 if parent:
00068 self._parent = weakref.proxy(parent)
00069 else:
00070 self._parent = parent
00071
00072 if self.isActive:
00073 if not self._parent:
00074 GUI.addRoot( self.component )
00075 else:
00076 self._parent.addChild( self.component )
00077
00078
00079 def _getparent( self ):
00080 return self._parent
00081
00082 parent = property(_getparent, _setparent)
00083
00084 def getWindow( self ):
00085 import Window
00086 if isinstance( self, Window.Window ):
00087 return self
00088 elif self.component.parent and self.component.parent.script:
00089 return self.component.parent.script.getWindow()
00090 else:
00091 return None
00092
00093 def toggleActive( self ):
00094 self.active( not self.isActive )
00095
00096 def setEventHandler( self, eh ):
00097 self.eventHandler = eh
00098
00099 def doLayout( self, parent ):
00100 for name, child in self.component.children:
00101 child.script.doLayout( self )
00102
00103
00104 def setToolTipInfo( self, toolTipInfo ):
00105 self.toolTipInfo = toolTipInfo
00106
00107
00108 def removeToolTipInfo( self ):
00109 if hasattr( self, toolTipInfo ):
00110 del self.toolTipInfo
00111
00112
00113
00114 def focus( self, state ):
00115 pass
00116
00117 def handleKeyEvent( self, down, key, modifiers ):
00118 return False
00119
00120 def handleMouseEvent( self, comp, dx, dy, dz ):
00121 return False
00122
00123 def handleMouseButtonEvent( self, comp, key, down, modifiers ):
00124 window = self.getWindow()
00125 if window:
00126 window.listeners.windowClicked()
00127 return False
00128
00129
00130 def handleMouseClickEvent( self, component ):
00131 return False
00132
00133
00134 def handleMouseEnterEvent( self, comp ):
00135 if getattr( self, 'toolTipInfo', None ):
00136 import ToolTip
00137 ToolTip.ToolTipManager.instance.setupToolTip( self.component, self.toolTipInfo )
00138
00139 return False
00140
00141
00142 def handleMouseLeaveEvent( self, comp ):
00143 return False
00144
00145
00146 def handleAxisEvent( self, axis, value, dTime ):
00147 return False
00148
00149
00150 def handleDragStartEvent( self, comp ):
00151 return False
00152
00153
00154 def handleDragStopEvent( self, comp ):
00155 return False
00156
00157
00158 def handleDragEnterEvent( self, comp, dragged ):
00159 return False
00160
00161
00162 def handleDragLeaveEvent( self, comp, dragged ):
00163 return False
00164
00165
00166 def handleDropEvent( self, comp, dropped ):
00167 return False
00168
00169
00170 def onLoad( self, dataSection ):
00171 if dataSection.has_key( "toolTipInfo" ):
00172 import ToolTip
00173 self.toolTipInfo = ToolTip.ToolTipInfo()
00174 self.toolTipInfo.onLoad( dataSection._toolTipInfo )
00175
00176 def onSave( self, dataSection ):
00177 if hasattr( self, "toolTipInfo" ) and self.toolTipInfo is not None:
00178 toolTipInfoSection = dataSection.createSection( "toolTipInfo" )
00179 self.toolTipInfo.onSave( toolTipInfoSection )
00180
00181 def onBound( self ):
00182 for name, child in self.component.children:
00183 if not child.script:
00184 child.script = PyGUIBase( child )
00185
00186
00187
00188
00189 self._bindEvents( self.__class__ )
00190
00191
00192 def _bindEvents( self, cls ):
00193 for name, function in cls.__dict__.iteritems():
00194 if hasattr( function, "_PyGUIEventHandler" ):
00195 for componentName, eventName, args, kargs in function._PyGUIEventHandler:
00196 assert( callable( function ) )
00197
00198 component = self.component
00199 for name in componentName.split("."):
00200 component = getattr( component, name, None )
00201 if component is None:
00202 break
00203
00204 if component is None:
00205 ERROR_MSG( "PyGUIEvent: '%s' has no component named '%s'." % (str(self), componentName,) )
00206 continue
00207
00208 function = getattr( self, function.__name__ )
00209 setattr( component.script, eventName, partial( function, *args, **kargs ) )
00210
00211 for base in cls.__bases__:
00212 self._bindEvents( base )