00001 '''
00002 '''
00003
00004 import BigWorld, GUI
00005 import Keys
00006 import math
00007
00008 from PyGUIBase import PyGUIBase
00009 from DraggableComponent import DraggableComponent
00010 from Utils import clipPosition, clipSize, applyMapping
00011 from VisualStateComponent import VisualState, VisualStateComponent
00012
00013
00014 class SliderVisualState( VisualState ):
00015
00016 def __init__( self ):
00017 VisualState.__init__( self )
00018 self.backgroundTextureName = ""
00019 self.backgroundTextureMapping = None
00020 self.backgroundColour = (255,255,255,255)
00021 self.thumbTextureName = ""
00022 self.thumbTextureMapping = None
00023 self.thumbColour = (255,255,255,255)
00024
00025
00026 def onSave( self, dataSection ):
00027 VisualState.onSave( self, dataSection )
00028
00029 backgroundSection = dataSection.createSection( "background" )
00030 backgroundSection.writeString( "textureName", self.backgroundTextureName )
00031 if self.backgroundTextureMapping:
00032 mappingSection = backgroundSection.createSection( "mapping" )
00033 self._writeMappingSection( mappingSection, self.backgroundTextureMappingType,
00034 self.backgroundTextureMapping )
00035 backgroundSection.writeVector4( "colour", self.backgroundColour )
00036
00037 thumbSection = dataSection.createSection( "thumb" )
00038 thumbSection.writeString( "textureName", self.thumbTextureName )
00039 if self.thumbTextureMapping:
00040 mappingSection = thumbSection.createSection( "mapping" )
00041 self._writeMappingSection( mappingSection, self.thumbTextureMappingType,
00042 self.thumbTextureMapping )
00043 thumbSection.writeVector4( "colour", self.thumbColour )
00044
00045
00046 def onLoad( self, dataSection ):
00047 VisualState.onLoad( self, dataSection )
00048
00049 if dataSection.has_key( "background" ):
00050 backgroundSection = dataSection._background
00051 self.backgroundTextureName = backgroundSection.readString( "textureName", "" )
00052 if backgroundSection.has_key( "mapping" ):
00053 mappingSection = backgroundSection._mapping
00054 mappingType, mapping = self._readMappingSection( mappingSection )
00055 self.backgroundTextureMappingType = mappingType
00056 self.backgroundTextureMapping = mapping
00057 else:
00058 self.backgroundTextureMapping = None
00059 self.backgroundColour = backgroundSection.readVector4( "colour", (255,255,255,255) )
00060
00061 if dataSection.has_key( "thumb" ):
00062 thumbSection = dataSection._thumb
00063 self.thumbTextureName = thumbSection.readString( "textureName", "" )
00064 if thumbSection.has_key( "mapping" ):
00065 mappingSection = thumbSection._mapping
00066 mappingType, mapping = self._readMappingSection( mappingSection )
00067 self.thumbTextureMappingType = mappingType
00068 self.thumbTextureMapping = mapping
00069 else:
00070 self.thumbTextureMapping = None
00071 self.thumbColour = thumbSection.readVector4( "colour", (255,255,255,255) )
00072
00073
00074 def apply( self, componentScript ):
00075 VisualState.apply( self, componentScript )
00076
00077 if hasattr( componentScript, "sliderBackground" ):
00078 componentScript.sliderBackground.textureName = self.backgroundTextureName
00079 if self.thumbTextureMapping:
00080 applyMapping( componentScript.sliderBackground,
00081 self.backgroundTextureMappingType,
00082 self.backgroundTextureMapping )
00083 componentScript.sliderBackground.colour = self.backgroundColour
00084
00085 if hasattr( componentScript, "sliderThumb" ):
00086 componentScript.sliderThumb.textureName = self.thumbTextureName
00087 if self.thumbTextureMapping:
00088 applyMapping( componentScript.sliderThumb,
00089 self.thumbTextureMappingType,
00090 self.thumbTextureMapping )
00091 componentScript.sliderThumb.colour = self.thumbColour
00092
00093
00094 class SliderThumb( PyGUIBase, DraggableComponent ):
00095
00096 factoryString="PyGUI.SliderThumb"
00097
00098 def __init__( self, component, isHorizontal = True ):
00099 PyGUIBase.__init__( self, component )
00100 DraggableComponent.__init__( self, isHorizontal, not isHorizontal, True )
00101
00102 self.component.focus = True
00103 self.component.moveFocus = True
00104 self.component.crossFocus = True
00105
00106 self.onDragging = self._onDragging
00107
00108
00109 def _setValue( self, value ):
00110 sliderWidth, sliderHeight = clipSize( self.component )
00111
00112 slider = self.component.parent.script
00113 thumbPos = (value - slider.minValue) / (slider.maxValue - slider.minValue)
00114 if slider.isHorizontal:
00115 thumbPos = (2.0 - sliderWidth) * thumbPos - 1.0 + sliderWidth / 2
00116 else:
00117 thumbPos = (2.0 - sliderHeight) * thumbPos - 1.0 + sliderHeight / 2
00118 self.component.position = (thumbPos, 0, 1) if slider.isHorizontal else (0, thumbPos, 1)
00119
00120
00121 def _setValueFromMouse( self, pos ):
00122 slider = self.component.parent.script
00123 parent = self.component.parent
00124 position = parent.screenToLocal( pos )
00125 self.component.position = (2 * position[0] / parent.width - 1.0, 0, 1) \
00126 if slider.isHorizontal else (0, 2 * position[1] / parent.height - 1.0, 1)
00127 self._onDragging()
00128
00129
00130 def _onDragging( self ):
00131 position = clipPosition( self.component )
00132 sliderWidth, sliderHeight = clipSize( self.component )
00133 slider = self.component.parent.script
00134 if slider.isHorizontal:
00135 thumbPos = (position[0] + 1.0 - sliderWidth / 2) / (2.0 - sliderWidth)
00136 else:
00137 thumbPos = (position[1] + 1.0 - sliderHeight / 2) / (2.0 - sliderHeight)
00138
00139 thumbPos = min( max( 0.0, thumbPos ), 1.0 )
00140 newValue = thumbPos * (slider.maxValue - slider.minValue) + slider.minValue
00141 newValue += slider.stepSize / 2.0
00142 newValue -= math.fmod( newValue, slider.stepSize )
00143
00144
00145 self._setValue( newValue )
00146
00147 slider.value = newValue
00148 slider.onValueChanged()
00149
00150
00151 def handleMouseButtonEvent( self, comp, key, down, modifiers ):
00152 PyGUIBase.handleMouseButtonEvent( self, comp, key, down, modifiers )
00153
00154 slider = self.component.parent.script
00155 if key == Keys.KEY_LEFTMOUSE:
00156 if down and not slider.thumbPressed:
00157 slider.thumbPressed = True
00158 elif not down and slider.thumbPressed:
00159 slider.thumbPressed = False
00160 slider._updateVisualState( hover=True )
00161
00162 return DraggableComponent.handleMouseButtonEvent( self, comp, key, down, modifiers )
00163
00164
00165 def handleMouseEnterEvent( self, comp ):
00166 PyGUIBase.handleMouseEnterEvent( self, comp )
00167
00168 slider = self.component.parent.script
00169 slider.handleMouseEnterEvent( comp )
00170
00171
00172 slider.thumbPressed = slider.thumbPressed and BigWorld.isKeyDown( Keys.KEY_LEFTMOUSE )
00173 slider._updateVisualState( hover=True )
00174 return True
00175
00176
00177 def handleMouseLeaveEvent( self, comp ):
00178 slider = self.component.parent.script
00179 slider._updateVisualState( hover=False )
00180 return True
00181
00182
00183 @staticmethod
00184 def create( slider, thumbTexture = "", isHorizontal = True ):
00185 c = GUI.Window( thumbTexture )
00186 c.materialFX = "BLEND"
00187 c.widthMode = slider.component.widthMode
00188 c.heightMode = slider.component.heightMode
00189 c.horizontalPositionMode = 'CLIP'
00190 c.verticalPositionMode = 'CLIP'
00191 c.position = (0, 0, 1)
00192
00193 slider.component.addChild( c, "thumb" )
00194
00195 return SliderThumb( c, isHorizontal )
00196
00197
00198 class Slider( PyGUIBase, VisualStateComponent ):
00199
00200 NORMAL_STATE = 'normal'
00201 HOVER_STATE = 'hover'
00202 PRESSED_STATE = 'pressed'
00203 DISABLED_STATE = 'disabled'
00204
00205 factoryString="PyGUI.Slider"
00206 visualStateString="PyGUI.SliderVisualState"
00207
00208 def __init__( self, component ):
00209 PyGUIBase.__init__( self, component )
00210 VisualStateComponent.__init__( self, component, Slider.visualStateString )
00211 component.script = self
00212
00213 self.isHorizontal = True
00214 self.minValue = 0.0
00215 self.maxValue = 1.0
00216 self.stepSize = 0.1
00217 self._value = 0.0
00218
00219 self.thumbPressed = False
00220 self.sliderDisabled = False
00221
00222 self.component.focus = True
00223 self.component.crossFocus = True
00224 self.component.moveFocus = True
00225
00226 self.onValueChanged = lambda:None
00227
00228
00229 def _updateVisualState( self, hover ):
00230 if self.sliderDisabled:
00231 visualStateName = Slider.DISABLED_STATE
00232 elif self.thumbPressed:
00233 visualStateName = Slider.PRESSED_STATE
00234 elif hover:
00235 visualStateName = Slider.HOVER_STATE
00236 else:
00237 visualStateName = Slider.NORMAL_STATE
00238
00239 self.setVisualState( visualStateName )
00240
00241
00242 def _onValueChanged( self ):
00243 self.onValueChanged()
00244
00245
00246 def _getValue( self ):
00247 return self._value
00248
00249 def _setValue( self, value ):
00250 self._value = value
00251 self.component.thumb.script._setValue( value )
00252
00253 value = property( _getValue, _setValue )
00254
00255
00256 def handleMouseButtonEvent( self, comp, key, down, modifiers ):
00257 if down:
00258 self.component.thumb.script._setValueFromMouse( GUI.mcursor().position )
00259
00260 self.component.thumb.script.handleMouseButtonEvent( self.component.thumb, key, down, modifiers )
00261 return True
00262
00263
00264 def onSave( self, dataSection ):
00265 PyGUIBase.onSave( self, dataSection )
00266 dataSection.writeBool( "isHorizontal", self.isHorizontal )
00267 dataSection.writeFloat( "minValue", self.minValue )
00268 dataSection.writeFloat( "maxValue", self.maxValue )
00269 dataSection.writeFloat( "stepSize", self.stepSize )
00270 VisualStateComponent.onSave( self, dataSection )
00271
00272
00273 def onLoad( self, dataSection ):
00274 PyGUIBase.onLoad( self, dataSection )
00275 self.isHorizontal = dataSection.readBool( "isHorizontal", self.isHorizontal )
00276 self.minValue = dataSection.readFloat( "minValue", self.minValue )
00277 self.maxValue = dataSection.readFloat( "maxValue", self.maxValue )
00278 self.stepSize = dataSection.readFloat( "stepSize", self.stepSize )
00279 VisualStateComponent.onLoad( self, dataSection )
00280
00281
00282 def onBound( self ):
00283 self.value = self.minValue
00284 self.sliderBackground = self.component
00285 self.sliderThumb = self.component.thumb
00286 self._updateVisualState( hover=False )
00287
00288
00289 @staticmethod
00290 def create( texture, thumbTexture = "", isHorizontal = True, **kwargs ):
00291 c = GUI.Window( texture )
00292 c.materialFX = "BLEND"
00293 c.widthMode = 'CLIP'
00294 c.heightMode = 'CLIP'
00295 c.horizontalPositionMode = 'CLIP'
00296 c.verticalPositionMode = 'CLIP'
00297
00298 s = Slider( c, **kwargs )
00299 s.isHorizontal = isHorizontal
00300
00301 thumb = SliderThumb.create( s, thumbTexture, isHorizontal )
00302 thumb.width = 0.2 if isHorizontal else 2.0
00303 thumb.height = 2.0 if isHorizontal else 0.2
00304
00305 return s.component
00306