NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

charCreation.py (25878B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\login\charcreation\charCreation.py
      2 import carbonui.const as uiconst
      3 import uthread
      4 import log
      5 import localization
      6 import charactercreator.const as ccConst
      7 import blue
      8 import trinity
      9 import eve.common.lib.appConst as const
     10 from carbon.common.script.util import timerstuff
     11 from carbonui.primitives.container import Container
     12 from carbonui.primitives.gradientSprite import GradientConst, GradientSprite
     13 from carbonui.primitives.sprite import Sprite
     14 from carbonui.uianimations import animations
     15 from carbonui.uicore import uicore
     16 from eve.client.script.ui.login.charcreation.hexes import CCHexButtonBody, CCHexButtonHead
     17 FILL_SELECTION = 0.2
     18 TEXT_NORMAL = 0.8
     19 MINSIDESIZE = 280
     20 MAXMENUSIZE = 380
     21 CC_LEFT_SIZE = 180
     22 ZONEMAP = {-1: uiconst.UICURSOR_DEFAULT,
     23  0: uiconst.UICURSOR_CCALLDIRECTIONS,
     24  1: uiconst.UICURSOR_CCALLDIRECTIONS,
     25  2: uiconst.UICURSOR_CCALLDIRECTIONS,
     26  3: uiconst.UICURSOR_CCALLDIRECTIONS,
     27  4: uiconst.UICURSOR_CCALLDIRECTIONS,
     28  5: uiconst.UICURSOR_CCALLDIRECTIONS,
     29  6: uiconst.UICURSOR_CCALLDIRECTIONS,
     30  7: uiconst.UICURSOR_CCALLDIRECTIONS,
     31  8: uiconst.UICURSOR_CCALLDIRECTIONS,
     32  9: uiconst.UICURSOR_CCALLDIRECTIONS,
     33  10: uiconst.UICURSOR_CCALLDIRECTIONS,
     34  11: uiconst.UICURSOR_CCALLDIRECTIONS,
     35  12: uiconst.UICURSOR_CCALLDIRECTIONS,
     36  13: uiconst.UICURSOR_CCALLDIRECTIONS,
     37  14: uiconst.UICURSOR_CCUPDOWN,
     38  15: uiconst.UICURSOR_CCALLDIRECTIONS,
     39  16: uiconst.UICURSOR_CCALLDIRECTIONS,
     40  17: uiconst.UICURSOR_CCLEFTRIGHT}
     41 ZONEMAP_SIDE = {-1: uiconst.UICURSOR_DEFAULT,
     42  0: uiconst.UICURSOR_CCALLDIRECTIONS,
     43  1: uiconst.UICURSOR_CCALLDIRECTIONS,
     44  2: uiconst.UICURSOR_CCALLDIRECTIONS,
     45  3: uiconst.UICURSOR_CCALLDIRECTIONS,
     46  4: uiconst.UICURSOR_CCALLDIRECTIONS,
     47  5: uiconst.UICURSOR_CCALLDIRECTIONS,
     48  6: uiconst.UICURSOR_CCALLDIRECTIONS,
     49  7: uiconst.UICURSOR_CCALLDIRECTIONS,
     50  8: uiconst.UICURSOR_CCALLDIRECTIONS,
     51  9: uiconst.UICURSOR_CCALLDIRECTIONS,
     52  10: uiconst.UICURSOR_CCALLDIRECTIONS,
     53  11: uiconst.UICURSOR_CCALLDIRECTIONS,
     54  12: uiconst.UICURSOR_CCALLDIRECTIONS,
     55  13: uiconst.UICURSOR_CCALLDIRECTIONS,
     56  14: uiconst.UICURSOR_CCUPDOWN,
     57  15: uiconst.UICURSOR_CCALLDIRECTIONS,
     58  16: uiconst.UICURSOR_CCALLDIRECTIONS,
     59  17: uiconst.UICURSOR_DEFAULT}
     60 ZONEMAP_ANIM = {-1: uiconst.UICURSOR_DEFAULT,
     61  0: uiconst.UICURSOR_CCHEADALL,
     62  1: uiconst.UICURSOR_CCHEADALL,
     63  2: uiconst.UICURSOR_CCHEADALL,
     64  3: uiconst.UICURSOR_CCALLDIRECTIONS,
     65  4: uiconst.UICURSOR_CCHEADTILT,
     66  5: uiconst.UICURSOR_CCALLDIRECTIONS,
     67  6: uiconst.UICURSOR_CCALLDIRECTIONS,
     68  7: uiconst.UICURSOR_CCHEADALL,
     69  8: uiconst.UICURSOR_CCHEADALL,
     70  9: uiconst.UICURSOR_CCALLDIRECTIONS,
     71  10: uiconst.UICURSOR_CCALLDIRECTIONS,
     72  11: uiconst.UICURSOR_CCHEADTILT,
     73  12: uiconst.UICURSOR_CCHEADALL,
     74  13: uiconst.UICURSOR_CCHEADALL,
     75  14: uiconst.UICURSOR_CCHEADALL,
     76  15: uiconst.UICURSOR_CCALLDIRECTIONS,
     77  16: uiconst.UICURSOR_CCALLDIRECTIONS,
     78  17: uiconst.UICURSOR_CCALLDIRECTIONS}
     79 ZONEMAP_ANIMBODY = {-1: uiconst.UICURSOR_DEFAULT,
     80  3: uiconst.UICURSOR_CCSHOULDERTWIST,
     81  4: uiconst.UICURSOR_CCSHOULDERTWIST,
     82  5: uiconst.UICURSOR_CCSHOULDERTWIST,
     83  6: uiconst.UICURSOR_CCSHOULDERTWIST}
     84 GHOST_TEXTURE_PATH = 'res:/UI/Texture/CharacterCreation/silhuette_ghost.dds'
     85 
     86 class BaseCharacterCreationStep(Container):
     87     __notifyevents__ = ['OnHideUI', 'OnShowUI', 'OnUIScalingChange']
     88     default_align = uiconst.TOALL
     89     default_state = uiconst.UI_NORMAL
     90     racialHeader = {const.raceCaldari: 384,
     91      const.raceMinmatar: 128,
     92      const.raceAmarr: 256,
     93      const.raceGallente: 0}
     94     raceHeaderPath = 'res:/UI/Texture/CharacterCreation/RACE_Titletext.dds'
     95     raceFontColor = {const.raceCaldari: (0.93, 0.94, 0.99, 1.0),
     96      const.raceMinmatar: (0.99, 0.95, 0.95, 1.0),
     97      const.raceAmarr: (0.99, 0.95, 0.92, 1.0),
     98      const.raceGallente: (0.99, 0.99, 0.92, 1.0)}
     99 
    100     def ApplyAttributes(self, attributes):
    101         sm.RegisterNotify(self)
    102         Container.ApplyAttributes(self, attributes)
    103         self.charSvc = sm.GetService('character')
    104         self._cameraActive = False
    105         self._activeSculptZone = None
    106         self._didSculptMotion = False
    107         self._latestPickTime = None
    108         self.uiContainer = Container(name='uiContainer', parent=self, align=uiconst.TOALL)
    109         self.leftSide = Container(name='leftSide', parent=self.uiContainer, align=uiconst.TOLEFT_PROP, width=0.5)
    110         self.rightSide = Container(name='rightSide', parent=self.uiContainer, align=uiconst.TORIGHT_PROP, width=0.5)
    111         settings.user.ui.Get('assetMenuState', {ccConst.BODYGROUP: True})
    112 
    113     def GetInfo(self):
    114         return uicore.layer.charactercreation.controller.GetInfo()
    115 
    116     def ValidateStepComplete(self):
    117         return True
    118 
    119     def GetPickInfo(self, pos):
    120         layer = uicore.layer.charactercreation.controller
    121         layer.StartEditMode(mode='makeup', skipPickSceneReset=True, useThread=0)
    122         pickedMakeup = layer.PassMouseEventToSculpt('LeftDown', *pos)
    123         layer.StartEditMode(mode='hair', skipPickSceneReset=True, useThread=0)
    124         pickedHair = layer.PassMouseEventToSculpt('LeftDown', *pos)
    125         layer.StartEditMode(mode='bodyselect', skipPickSceneReset=True, useThread=0)
    126         pickedBody = layer.PassMouseEventToSculpt('LeftDown', *pos)
    127         layer.StartEditMode(mode='sculpt', skipPickSceneReset=True, useThread=0)
    128         pickedSculpt = layer.PassMouseEventToSculpt('LeftDown', *pos)
    129         reset = layer.PassMouseEventToSculpt('LeftUp', *pos)
    130         return (pickedMakeup,
    131          pickedHair,
    132          pickedBody,
    133          pickedSculpt)
    134 
    135     def OnMouseDown(self, btn, *args):
    136         if self.stepID not in (ccConst.CUSTOMIZATIONSTEP, ccConst.PORTRAITSTEP):
    137             return
    138         self.storedMousePos = None
    139         pos = (int(uicore.uilib.x * uicore.desktop.dpiScaling), int(uicore.uilib.y * uicore.desktop.dpiScaling))
    140         layer = uicore.layer.charactercreation.controller
    141         if btn == uiconst.MOUSERIGHT:
    142             self._cameraActive = True
    143             self._SetActiveSculptZone(None)
    144         elif btn == uiconst.MOUSELEFT and not self._cameraActive and self.charSvc.IsSculptingReady():
    145             self._didSculptMotion = False
    146             self._latestPickTime = blue.os.GetWallclockTime()
    147             if self.CanSculpt():
    148                 layer.StartEditMode(mode='sculpt', callback=self.ChangeSculptingCursor)
    149                 pickedSculpt = layer.PassMouseEventToSculpt('LeftDown', *pos)
    150                 if pickedSculpt >= 0:
    151                     uicore.layer.charactercreation.controller.TryFreezeAnimation()
    152                     self.storedMousePos = (uicore.uilib.x, uicore.uilib.y)
    153                     self.cursor = uiconst.UICURSOR_NONE
    154                     self._cameraActive = False
    155                     self._SetActiveSculptZone(pickedSculpt)
    156                 else:
    157                     self._cameraActive = True
    158                     self._SetActiveSculptZone(None)
    159             elif self.stepID == ccConst.PORTRAITSTEP:
    160                 info = self.GetInfo()
    161                 self.charSvc.StartPosing(info.charID, callback=self.ChangeSculptingCursor)
    162                 pickedSculpt = layer.PassMouseEventToSculpt('LeftDown', *pos)
    163                 if pickedSculpt >= 0:
    164                     self._cameraActive = False
    165                     self._SetActiveSculptZone(pickedSculpt)
    166                 else:
    167                     self._cameraActive = True
    168                     self._SetActiveSculptZone(None)
    169             else:
    170                 self._cameraActive = True
    171                 self._SetActiveSculptZone(None)
    172         elif btn == uiconst.MOUSELEFT and self.stepID == ccConst.CUSTOMIZATIONSTEP and not layer.CanChangeBaseAppearance():
    173             self._cameraActive = True
    174         else:
    175             return
    176         uicore.uilib.ClipCursor(0, 0, uicore.desktop.width, uicore.desktop.height)
    177         uicore.uilib.SetCapture(self)
    178 
    179     def OnMouseUp(self, btn, *args):
    180         if self.stepID not in (ccConst.CUSTOMIZATIONSTEP, ccConst.PORTRAITSTEP):
    181             return
    182         uicore.layer.charactercreation.controller.UnfreezeAnimationIfNeeded()
    183         if getattr(self, 'storedMousePos', None) is not None:
    184             uicore.uilib.SetCursorPos(*self.storedMousePos)
    185             self.storedMousePos = None
    186         if btn == uiconst.MOUSELEFT:
    187             uicore.layer.charactercreation.controller.PassMouseEventToSculpt('LeftUp', uicore.uilib.x, uicore.uilib.y)
    188             if self.CanSculpt():
    189                 if self._activeSculptZone is not None and self._didSculptMotion:
    190                     uicore.layer.charactercreation.controller.TryStoreDna(False, 'Sculpting', sculpting=True)
    191                     charID = uicore.layer.charactercreation.controller.GetInfo().charID
    192                     sm.ScatterEvent('OnDollUpdated', charID, False, 'sculpting')
    193                     self.charSvc.UpdateTattoos(charID)
    194                 elif self._latestPickTime:
    195                     if blue.os.TimeDiffInMs(self._latestPickTime, blue.os.GetWallclockTime()) < 250.0:
    196                         pickedMakeup, pickedHair, pickedBody, pickedSculpt = self.GetPickInfo((uicore.uilib.x, uicore.uilib.y))
    197                         log.LogInfo('Pickinfo: makeup, hair, bodyselect, sculpt = ', pickedMakeup, pickedHair, pickedBody, pickedSculpt)
    198                         for each in (('hair', pickedHair),
    199                          ('makeup', pickedMakeup),
    200                          ('clothes', pickedBody),
    201                          ('sculpt', pickedSculpt)):
    202                             if each in ccConst.PICKMAPPING:
    203                                 pickedModifier = ccConst.PICKMAPPING[each]
    204                                 self.ExpandMenuByModifier(pickedModifier)
    205                                 break
    206 
    207             self._SetActiveSculptZone(None)
    208         if not uicore.uilib.rightbtn and not uicore.uilib.leftbtn:
    209             uicore.layer.charactercreation.controller.PassMouseEventToSculpt('Motion', uicore.uilib.x, uicore.uilib.y)
    210             self._cameraActive = False
    211             self._SetActiveSculptZone(None)
    212             self.cursor = uiconst.UICURSOR_DEFAULT
    213             uicore.uilib.UnclipCursor()
    214             if uicore.uilib.GetCapture() is self:
    215                 uicore.uilib.ReleaseCapture()
    216 
    217     def OnMouseMove(self, *args):
    218         if self.stepID not in (ccConst.CUSTOMIZATIONSTEP, ccConst.PORTRAITSTEP):
    219             return
    220         pos = (int(uicore.uilib.x * uicore.desktop.dpiScaling), int(uicore.uilib.y * uicore.desktop.dpiScaling))
    221         if self._cameraActive:
    222             if uicore.uilib.leftbtn and uicore.uilib.rightbtn:
    223                 modifier = uicore.mouseInputHandler.GetCameraZoomModifier()
    224                 uicore.layer.charactercreation.controller.camera.Dolly(modifier * uicore.uilib.dy)
    225             if uicore.uilib.leftbtn:
    226                 uicore.layer.charactercreation.controller.camera.AdjustYaw(uicore.uilib.dx)
    227                 if not uicore.uilib.rightbtn:
    228                     uicore.layer.charactercreation.controller.camera.AdjustPitch(uicore.uilib.dy)
    229             elif uicore.uilib.rightbtn:
    230                 uicore.layer.charactercreation.controller.camera.Pan(uicore.uilib.dx, uicore.uilib.dy)
    231         else:
    232             if self._activeSculptZone is not None and self.stepID == ccConst.CUSTOMIZATIONSTEP:
    233                 uicore.layer.charactercreation.controller.CheckDnaLog('OnMouseMove')
    234                 self._didSculptMotion = True
    235             uicore.layer.charactercreation.controller.PassMouseEventToSculpt('Motion', *pos)
    236 
    237     def OnMouseWheel(self, *args):
    238         if not uicore.layer.charactercreation.controller.camera:
    239             return
    240         modifier = uicore.mouseInputHandler.GetCameraZoomModifier()
    241         uicore.layer.charactercreation.controller.camera.Dolly(modifier * -uicore.uilib.dz)
    242 
    243     def ChangeSculptingCursor(self, zone, isFront, isHead):
    244         if self.destroyed:
    245             return
    246         if self.stepID == ccConst.CUSTOMIZATIONSTEP:
    247             if isFront:
    248                 cursor = ZONEMAP.get(zone, uiconst.UICURSOR_DEFAULT)
    249             else:
    250                 cursor = ZONEMAP_SIDE.get(zone, uiconst.UICURSOR_DEFAULT)
    251             self.cursor = cursor
    252         elif self.stepID == ccConst.PORTRAITSTEP:
    253             if isHead:
    254                 cursor = ZONEMAP_ANIM.get(zone, uiconst.UICURSOR_DEFAULT)
    255             else:
    256                 cursor = ZONEMAP_ANIMBODY.get(zone, uiconst.UICURSOR_DEFAULT)
    257             self.cursor = cursor
    258         lastZone = getattr(self, '_lastZone', None)
    259         if lastZone != zone:
    260             sm.StartService('audio').SendUIEvent(unicode('ui_icc_sculpting_mouse_over_loop_play'))
    261             self._lastZone = zone
    262             if self._lastZone == -1:
    263                 sm.StartService('audio').SendUIEvent(unicode('ui_icc_sculpting_mouse_over_loop_stop'))
    264 
    265     def ExpandMenuByModifier(self, modifier):
    266         from eve.client.script.ui.login.charcreation.assetMenu import CharCreationAssetPicker
    267         if not self.assetMenu:
    268             return
    269         lastParentGroup = None
    270         allMenus = [ each for each in self.assetMenu.mainContainter.children if isinstance(each, CharCreationAssetPicker) ]
    271         for menu in allMenus:
    272             if not menu.isSubmenu:
    273                 lastParentGroup = menu
    274             if getattr(menu, 'modifier', None) == modifier:
    275                 if lastParentGroup and not lastParentGroup.IsExpanded():
    276                     uthread.new(lastParentGroup.Expand)
    277                 uthread.new(menu.Expand)
    278 
    279     def OnHideUI(self, *args):
    280         self.uiContainer.state = uiconst.UI_HIDDEN
    281 
    282     def OnShowUI(self, *args):
    283         self.uiContainer.state = uiconst.UI_PICKCHILDREN
    284 
    285     def CanSculpt(self, *args):
    286         return self.stepID == ccConst.CUSTOMIZATIONSTEP and uicore.layer.charactercreation.controller.CanChangeBaseAppearance() and getattr(self, 'menuMode', None) != getattr(self, 'TATTOOMENU', None)
    287 
    288     def IsDollReady(self, *args):
    289         if uicore.layer.charactercreation.controller.doll is None:
    290             return False
    291         return not uicore.layer.charactercreation.controller.doll.busyUpdating
    292 
    293     def GetViewportForPicking(self):
    294         return trinity.device.viewport
    295 
    296     def _SetActiveSculptZone(self, sculptZone):
    297         self._activeSculptZone = sculptZone
    298 
    299 
    300 class CCHeadBodyPicker(Container):
    301     default_name = 'CCHeadBodyPicker'
    302     default_opacity = 0
    303     default_width = 130
    304     default_height = 130
    305 
    306     def ApplyAttributes(self, attributes):
    307         super(CCHeadBodyPicker, self).ApplyAttributes(attributes)
    308         self.headCallback = attributes.headCallback
    309         self.bodyCallback = attributes.bodyCallback
    310         self.ConstructLayout()
    311         self.updateTimer = timerstuff.AutoTimer(33, self.UpdatePosition)
    312         animations.FadeIn(self, duration=0.25)
    313 
    314     def ConstructLayout(self, *args):
    315         self.headHex = CCHexButtonHead(name='headHex', parent=self, align=uiconst.CENTERTOP, state=uiconst.UI_NORMAL, pos=(0, 0, 64, 64), pickRadius=21, info=None, id=0, hexName=localization.GetByLabel('UI/CharacterCreation/ZoomIn'), func=self.HeadClicked, iconNum=0, showIcon=False)
    316         self.headSolid = self.headHex.selection
    317         self.headSolid.SetState(uiconst.UI_DISABLED)
    318         self.headFrame = self.headHex.frame
    319         self.bodyHex = CCHexButtonBody(name='bodyHex', parent=self, align=uiconst.CENTERTOP, state=uiconst.UI_NORMAL, pos=(0, 16, 128, 128), pickRadius=42, info=None, id=0, hexName=localization.GetByLabel('UI/CharacterCreation/ZoomOut'), func=self.BodyClicked, iconNum=0, showIcon=False)
    320         self.bodySolid = self.bodyHex.selection
    321         self.bodySolid.SetState(uiconst.UI_DISABLED)
    322         self.bodyFrame = self.bodyHex.frame
    323         sprite = Sprite(name='ghostSprite', parent=self, align=uiconst.CENTERTOP, state=uiconst.UI_DISABLED, pos=(0, 7, 128, 128), idx=0, texturePath=GHOST_TEXTURE_PATH)
    324         sprite.SetRect(0, 0, 0, 0)
    325 
    326     def UpdatePosition(self, *args):
    327         if self.destroyed:
    328             return
    329         camera = getattr(uicore.layer.charactercreation.controller, 'camera', None)
    330         if camera is not None:
    331             portion = camera.GetPortionFromDistance()
    332             self.headSolid.SetOpacity(max(0.2, 1.0 - portion))
    333             self.bodySolid.SetOpacity(max(0.2, portion))
    334             for hex in (self.headHex, self.bodyHex):
    335                 if hex.selection.opacity >= 0.5 and len(self.children) and hex == self.children[-1]:
    336                     toSwap = self.children[-2]
    337                     self.children.remove(toSwap)
    338                     self.children.append(toSwap)
    339                     break
    340 
    341     def MouseOverPart(self, frameName, *args):
    342         sm.StartService('audio').SendUIEvent(unicode('ui_icc_button_mouse_over_play'))
    343         frame = self.get(frameName, None)
    344         if frame:
    345             frame.state = uiconst.UI_DISABLED
    346 
    347     def MouseExitPart(self, frameName, *args):
    348         frame = self.get(frameName, None)
    349         if frame:
    350             frame.state = uiconst.UI_HIDDEN
    351 
    352     def HeadClicked(self, *args):
    353         sm.StartService('audio').SendUIEvent(unicode('ui_icc_button_mouse_down_play'))
    354         self.headFrame.state = uiconst.UI_HIDDEN
    355         self.bodyFrame.state = uiconst.UI_HIDDEN
    356         if self.headCallback:
    357             self.headCallback()
    358 
    359     def BodyClicked(self, *args):
    360         sm.StartService('audio').SendUIEvent(unicode('ui_icc_button_mouse_down_play'))
    361         self.headFrame.state = uiconst.UI_HIDDEN
    362         self.bodyFrame.state = uiconst.UI_HIDDEN
    363         if self.bodyCallback:
    364             self.bodyCallback()
    365 
    366 
    367 class BitSlider(Container):
    368     default_name = 'BitSlider'
    369     default_align = uiconst.RELATIVE
    370     default_bitWidth = 3
    371     default_bitHeight = 8
    372     default_bitGap = 1
    373     default_state = uiconst.UI_NORMAL
    374     default_left = 0
    375     default_top = 0
    376     default_width = 128
    377     default_height = 12
    378     cursor = uiconst.UICURSOR_SELECT
    379 
    380     def ApplyAttributes(self, attributes):
    381         Container.ApplyAttributes(self, attributes)
    382         self.onSetValueCallback = None
    383         targetWidth = attributes.get('sliderWidth', 100)
    384         bitGap = attributes.get('bitGap', self.default_bitGap)
    385         bitAmount = attributes.bitAmount
    386         self.bitHeight = attributes.bitHeight or self.default_bitHeight
    387         self.height = self.bitHeight + 4
    388         if bitAmount:
    389             self.bitWidth = int(targetWidth / float(bitAmount))
    390         else:
    391             self.bitWidth = attributes.bitWidth or self.default_bitWidth
    392         self._value = 0.0
    393         self.bitParent = Container(parent=self, pos=(0,
    394          0,
    395          targetWidth,
    396          self.height), align=uiconst.TOPLEFT)
    397         self.handle = Container(parent=self.bitParent, align=uiconst.RELATIVE, state=uiconst.UI_DISABLED, pos=(0,
    398          0,
    399          3,
    400          self.height), bgColor=ccConst.COLOR + (1.0,))
    401         i = 0
    402         while True:
    403             if bitAmount is None and i >= 3 and i * (self.bitWidth + bitGap) + self.bitWidth > targetWidth:
    404                 break
    405             bit = Container(parent=self.bitParent, pos=(i * (self.bitWidth + bitGap),
    406              2,
    407              self.bitWidth,
    408              self.bitHeight), align=uiconst.RELATIVE, state=uiconst.UI_DISABLED, bgColor=ccConst.COLOR + (1.0,))
    409             bit.isBit = True
    410             i += 1
    411             if bitAmount is not None and i == bitAmount:
    412                 break
    413 
    414         self._numBits = i
    415         if targetWidth != bit.left + bit.width:
    416             diff = targetWidth - (bit.left + bit.width)
    417             bit.width += diff
    418         self.bitParent.width = targetWidth
    419         self.width = targetWidth
    420         if attributes.setvalue is not None:
    421             self.SetValue(attributes.setvalue)
    422         self.onSetValueCallback = attributes.OnSetValue
    423 
    424     def OnMouseDown(self, mouseBtn, *args):
    425         if mouseBtn != uiconst.MOUSELEFT:
    426             return
    427         self.softSlideTimer = None
    428         self.slideTimer = timerstuff.AutoTimer(33, self.UpdateSliderPortion)
    429 
    430     def OnMouseEnter(self, *args):
    431         self.softSlideTimer = timerstuff.AutoTimer(33, self.UpdateSoftSliderPortion)
    432 
    433     def OnMouseExit(self, *args):
    434         pass
    435 
    436     def OnMouseWheel(self, *args):
    437         if uicore.uilib.dz > 0:
    438             self.SetValue(self.GetValue() + 1.0 / self._numBits)
    439         else:
    440             self.SetValue(self.GetValue() - 1.0 / self._numBits)
    441 
    442     def UpdateSoftSliderPortion(self, *args):
    443         if uicore.uilib.mouseOver is self or uicore.uilib.mouseOver.IsUnder(self):
    444             l, t, w, h = self.bitParent.GetAbsolute()
    445             portion = max(0.0, min(1.0, (uicore.uilib.x - l) / float(w)))
    446             self.ShowSoftLit(portion)
    447         else:
    448             self.softSlideTimer = None
    449             self.ShowSoftLit(0.0)
    450 
    451     def UpdateSliderPortion(self, *args):
    452         l, t, w, h = self.bitParent.GetAbsolute()
    453         portion = max(0.0, min(1.0, (uicore.uilib.x - l) / float(w)))
    454         self.handle.left = int((w - self.bitWidth) * portion)
    455         self.ShowLit(portion)
    456 
    457     def OnMouseUp(self, mouseBtn, *args):
    458         if mouseBtn != uiconst.MOUSELEFT:
    459             return
    460         self.slideTimer = None
    461         l, t, w, h = self.bitParent.GetAbsolute()
    462         portion = max(0.0, min(1.0, (uicore.uilib.x - l) / float(w)))
    463         self.handle.left = int((w - self.handle.width) * portion)
    464         self.SetValue(portion)
    465 
    466     def ShowLit(self, portion):
    467         l, t, w, h = self.bitParent.GetAbsolute()
    468         if not w:
    469             return
    470         self.handle.left = int((w - self.handle.width) * portion)
    471         for each in self.bitParent.children:
    472             if not hasattr(each, 'isBit'):
    473                 continue
    474             mportion = max(0.0, min(1.0, (each.left + each.width / 2) / float(w)))
    475             if portion > mportion:
    476                 each.SetOpacity(1.0)
    477             else:
    478                 each.SetOpacity(0.333)
    479 
    480     def ShowSoftLit(self, portion):
    481         l, t, w, h = self.bitParent.GetAbsolute()
    482         for each in self.bitParent.children:
    483             if not hasattr(each, 'isBit'):
    484                 continue
    485             if each.opacity == 1.0:
    486                 continue
    487             mportion = max(0.0, min(1.0, (each.left + each.width / 2) / float(w)))
    488             if portion > mportion:
    489                 each.SetOpacity(0.5)
    490             else:
    491                 each.SetOpacity(0.333)
    492 
    493     def SetValue(self, value, doCallback = True):
    494         callback = value != self._value
    495         self._value = max(0.0, min(1.0, value))
    496         self.ShowLit(self._value)
    497         if callback and doCallback and self.onSetValueCallback:
    498             self.onSetValueCallback(self)
    499 
    500     def GetValue(self):
    501         return self._value
    502 
    503 
    504 class GradientSlider(Container):
    505     default_name = 'GradientSlider'
    506     default_align = uiconst.RELATIVE
    507     default_bitWidth = 3
    508     default_bitHeight = 8
    509     default_bitGap = 1
    510     default_state = uiconst.UI_NORMAL
    511     default_left = 0
    512     default_top = 0
    513     default_width = 128
    514     default_height = 12
    515     cursor = uiconst.UICURSOR_SELECT
    516 
    517     def ApplyAttributes(self, attributes):
    518         Container.ApplyAttributes(self, attributes)
    519         self.onSetValueCallback = None
    520         targetWidth = attributes.get('sliderWidth', 100)
    521         bitHeight = attributes.bitHeight or self.default_bitHeight
    522         self.height = bitHeight + 4
    523         self._value = 0.0
    524         self.handle = Container(parent=self, align=uiconst.RELATIVE, state=uiconst.UI_DISABLED, pos=(0,
    525          -2,
    526          3,
    527          self.height + 4), bgColor=ccConst.COLOR + (1.0,))
    528         if attributes.get('alphaValues'):
    529             alphaValues = attributes.get('alphaValues')
    530             rgbValues = [(0, (0, 0, 0))]
    531         else:
    532             alphaValues = (1, 1)
    533             rgbValues = [(0, (0, 0, 0)), (1.0, (1, 1, 1))]
    534         self.gradientSprite = GradientSprite(parent=self, pos=(0,
    535          0,
    536          targetWidth,
    537          self.height), rgbData=rgbValues, alphaData=[alphaValues, (1.0, 1.0)], alphaInterp=GradientConst.INTERP_LINEAR, colorInterp=GradientConst.INTERP_LINEAR, state=uiconst.UI_DISABLED)
    538         self.gradientSprite.width = targetWidth
    539         if attributes.setvalue is not None:
    540             self.SetValue(attributes.setvalue)
    541         self.onSetValueCallback = attributes.OnSetValue
    542         self.ChangeGradientColor(secondColor=(1.0, (1, 1, 0)))
    543 
    544     def OnMouseDown(self, mouseBtn, *args):
    545         if mouseBtn != uiconst.MOUSELEFT:
    546             return
    547         self.slideTimer = timerstuff.AutoTimer(33, self.UpdateSliderPortion)
    548 
    549     def UpdateSliderPortion(self, *args):
    550         l, t, w, h = self.gradientSprite.GetAbsolute()
    551         portion = max(0.0, min(1.0, (uicore.uilib.x - l) / float(w)))
    552         self.handle.left = int(w * portion)
    553 
    554     def OnMouseUp(self, mouseBtn, *args):
    555         if mouseBtn != uiconst.MOUSELEFT:
    556             return
    557         self.slideTimer = None
    558         l, t, w, h = self.gradientSprite.GetAbsolute()
    559         portion = max(0.0, min(1.0, (uicore.uilib.x - l) / float(w)))
    560         self.handle.left = int(w * portion)
    561         self.SetValue(portion)
    562 
    563     def SetValue(self, value, doCallback = True):
    564         callback = value != self._value
    565         self._value = max(0.0, min(1.0, value))
    566         self.SetHandle(self._value)
    567         if callback and doCallback and self.onSetValueCallback:
    568             self.onSetValueCallback(self)
    569 
    570     def SetHandle(self, portion):
    571         l, t, w, h = self.gradientSprite.GetAbsolute()
    572         if not w:
    573             return
    574         self.handle.left = int((w - self.handle.width) * portion)
    575 
    576     def GetValue(self):
    577         return self._value
    578 
    579     def ChangeGradientColor(self, firstColor = None, secondColor = None):
    580         colorData = self.gradientSprite.colorData
    581         if len(colorData) < 2:
    582             firstColor = secondColor
    583         if firstColor is not None:
    584             colorData[0] = firstColor
    585         if secondColor is not None and len(colorData) > 1:
    586             colorData[1] = secondColor
    587         self.gradientSprite.SetGradient()