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()