charCreationNavigation.py (13244B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\login\charcreation\charCreationNavigation.py 2 import localization 3 import telemetry 4 from carbon.common.script.sys.serviceConst import ROLE_PROGRAMMER 5 from carbonui import uiconst 6 from carbonui.primitives.container import Container 7 from carbonui.primitives.sprite import Sprite 8 from carbonui.uianimations import animations 9 from charactercreator import const as ccConst 10 from charactercreator.client.characterCreationSteps import GetStepOrder 11 from eve.client.script.ui import eveColor 12 from eve.client.script.ui.login.charcreation.label import CCLabel 13 from eve.client.script.ui.util.uix import GetTextWidth 14 15 class CharCreationNavigationElement(Container): 16 SHAPE_INACTIVE = 1 17 SHAPE_ACTIVE = 2 18 SHAPE_LOCKED = 3 19 SHAPE_COMPLETED = 4 20 SHAPE_INACTIVE_FURTHEST = 5 21 SHAPE_ACTIVE_FURTHEST = 6 22 default_shape = 1 23 24 def ApplyAttributes(self, attributes): 25 Container.ApplyAttributes(self, attributes) 26 activeShape = attributes.get('shape', self.default_shape) 27 self.shapeSprites = {self.SHAPE_ACTIVE: self._CreateSprite('activeSprite', 'res:/UI/Texture/classes/EmpireSelection/navdotFull.png', color=eveColor.PRIMARY_BLUE), 28 self.SHAPE_ACTIVE_FURTHEST: self._CreateSprite('activeFurthestSprite', 'res:/UI/Texture/classes/EmpireSelection/navdotFurthest.png', color=eveColor.PRIMARY_BLUE), 29 self.SHAPE_COMPLETED: self._CreateSprite('completedSprite', 'res:/UI/Texture/classes/EmpireSelection/navdotFull.png'), 30 self.SHAPE_INACTIVE: self._CreateSprite('inactiveSprite', 'res:/UI/Texture/classes/EmpireSelection/navdotFull.png'), 31 self.SHAPE_INACTIVE_FURTHEST: self._CreateSprite('inactiveFurthestSprite', 'res:/UI/Texture/classes/EmpireSelection/navdotFurthest.png'), 32 self.SHAPE_LOCKED: self._CreateSprite('lockedSprite', 'res:/UI/Texture/classes/EmpireSelection/navdotEmpty.png')} 33 self._SetShape(activeShape) 34 35 def _SetShape(self, shape): 36 self.activeShape = shape 37 for k in self.shapeSprites: 38 if k == shape: 39 self.shapeSprites[k].state = uiconst.UI_DISABLED 40 else: 41 self.shapeSprites[k].state = uiconst.UI_HIDDEN 42 43 def Activate(self, furthest = True): 44 self._SetShape(self.SHAPE_ACTIVE_FURTHEST if furthest else self.SHAPE_ACTIVE) 45 46 def Complete(self): 47 self._SetShape(self.SHAPE_COMPLETED) 48 49 def Deactivate(self, furthest = False): 50 self._SetShape(self.SHAPE_INACTIVE_FURTHEST if furthest else self.SHAPE_INACTIVE) 51 52 def Lock(self): 53 self._SetShape(self.SHAPE_LOCKED) 54 55 def _CreateSprite(self, name, texturePath, color = None): 56 return Sprite(name=name, parent=self, align=uiconst.TOPLEFT, pos=(2, 2, 32, 32), state=uiconst.UI_DISABLED, texturePath=texturePath, color=color) 57 58 59 class CharCreationNavigation(Container): 60 default_align = uiconst.TOPLEFT 61 default_height = 110 62 default_state = uiconst.UI_NORMAL 63 ANIMATIONTIME = 500.0 64 MOUSEOVEROPACITY = 0.8 65 NORMALOPACITY = 0.3 66 ACTIVEOPACITY = 1.0 67 FONTSIZE = 16 68 STEPSIZE = 36 69 stepLabelDict = {ccConst.CUSTOMIZATIONSTEP: 'UI/CharacterCreation/Step3', 70 ccConst.PORTRAITSTEP: 'UI/CharacterCreation/Step4', 71 ccConst.NAMINGSTEP: 'UI/CharacterCreation/Step5', 72 ccConst.EMPIRESTEP: 'UI/CharacterCreation/Step7', 73 ccConst.TECHNOLOGYSTEP: 'UI/CharacterCreation/Step8', 74 ccConst.BLOODLINESTEP: 'UI/CharacterCreation/Step2'} 75 76 @telemetry.ZONE_METHOD 77 def ApplyAttributes(self, attributes): 78 Container.ApplyAttributes(self, attributes) 79 self.stepID = attributes.stepID 80 self.furthestStepID = self.stepID 81 self.stepsUsed = attributes.stepsUsed 82 self.availableSteps = attributes.availableSteps 83 self.stepIndex = {} 84 self.navigationElements = {} 85 stepIndex = 0 86 for stepID in self.availableSteps: 87 self.stepIndex[stepIndex] = stepID 88 stepIndex += 1 89 90 self.attributesApplied = 0 91 self.callbackFunc = attributes.func 92 width = len(self.availableSteps) * self.STEPSIZE 93 self.width = width 94 self.stepCont = Container(name='stepCont', parent=self, align=uiconst.CENTERTOP, pos=(0, 95 0, 96 width, 97 self.STEPSIZE)) 98 headerContainer = Container(name='headerContainer', parent=self, align=uiconst.TOTOP, top=26, width=width, height=26) 99 self.header = CCLabel(name='header', parent=headerContainer, align=uiconst.CENTER, top=0, uppercase=1, letterspace=2, color=(0.9, 0.9, 0.9, 0.8), fontsize=self.FONTSIZE, bold=False, opacity=0.0) 100 self.ResetToStep(self.stepID, set(self.stepsUsed)) 101 102 def StepIndexToStepId(self, stepindex): 103 return self.stepIndex[stepindex] 104 105 def GetNextStepIDForStepID(self, stepID): 106 nextStepUpcoming = False 107 for i in range(0, len(self.availableSteps)): 108 currentStep = self.availableSteps[i] 109 if nextStepUpcoming: 110 return currentStep 111 if currentStep is stepID: 112 nextStepUpcoming = True 113 114 def makeConnectors(self): 115 left = 20 116 connectorFile = 'res:/UI/Texture/classes/EmpireSelection/navdotConnector.png' 117 for stepID in self.availableSteps[1:]: 118 connectorWidth = 0 119 if stepID in self.stepsUsed: 120 connectorWidth = 32 121 cont = Container(name='space%s' % stepID, parent=self.stepCont, align=uiconst.TOPLEFT, pos=(left, 122 10, 123 connectorWidth, 124 16), state=uiconst.UI_DISABLED, clipChildren=1) 125 setattr(self, 'connector%s' % stepID, cont) 126 sprite = Sprite(name='connector%s' % stepID, parent=cont, align=uiconst.TOPLEFT, pos=(0, 0, 32, 16), state=uiconst.UI_DISABLED, texturePath=connectorFile) 127 sprite.SetAlpha(self.NORMALOPACITY) 128 left += self.STEPSIZE 129 130 @telemetry.ZONE_METHOD 131 def CreateSteps(self, *args): 132 self.stepCont.Flush() 133 left = 0 134 currentStepOrder = GetStepOrder(self.stepID) 135 for stepID in self.availableSteps: 136 step = Container(name='step%s' % stepID, parent=self.stepCont, align=uiconst.TOPLEFT, pos=(left, 137 0, 138 self.STEPSIZE, 139 self.STEPSIZE), state=uiconst.UI_DISABLED) 140 stepOrder = GetStepOrder(stepID) 141 if stepOrder > currentStepOrder: 142 shape = CharCreationNavigationElement.SHAPE_LOCKED 143 elif stepOrder < currentStepOrder: 144 shape = CharCreationNavigationElement.SHAPE_INACTIVE 145 else: 146 shape = CharCreationNavigationElement.SHAPE_ACTIVE 147 self.navigationElements[stepID] = CharCreationNavigationElement(parent=step, shape=shape) 148 step.SetOpacity(self.NORMALOPACITY) 149 left += self.STEPSIZE 150 step.id = stepID 151 step.OnMouseEnter = (self.OnStepMouseOver, step) 152 step.OnMouseExit = (self.OnStepMouseExit, step) 153 step.OnClick = (self.OnStepClicked, step) 154 setattr(self, 'step%s' % stepID, step) 155 156 self.stepCont.width = left 157 self.makeConnectors() 158 self.attributesApplied = 1 159 160 @telemetry.ZONE_METHOD 161 def ResetToStep(self, resetToStep, stepsUsed, *args): 162 self.stepID = resetToStep 163 self.stepsUsed = stepsUsed 164 self.CreateSteps() 165 firstCont = self.GetStepContainer(self.availableSteps[0]) 166 firstCont.state = uiconst.UI_NORMAL 167 if max(stepsUsed) < 1: 168 firstCont.SetOpacity(self.ACTIVEOPACITY) 169 secondCont = self.GetStepContainer(self.availableSteps[1]) 170 secondCont.state = uiconst.UI_NORMAL 171 else: 172 for stepID in xrange(self.availableSteps[0], resetToStep + 1): 173 self.PerformStepChange(stepID, stepsUsed, forceOpen=1, time=0) 174 175 self.stepsUsed.add(resetToStep) 176 177 def GetStepContainer(self, stepID): 178 return getattr(self, 'step%s' % stepID, None) 179 180 def GetStepContainerViaGetAttr(self, stepID): 181 return getattr(self, 'step%s' % stepID, None) 182 183 def GetConnectorForStep(self, stepID): 184 return getattr(self, 'connector%s' % stepID, None) 185 186 def UpdateHeader(self, stepID, opacity): 187 labelPath = self.stepLabelDict.get(stepID) 188 headerText = localization.GetByLabel(labelPath) 189 headerWidth = GetTextWidth(strng=headerText, fontsize=self.FONTSIZE, hspace=2, uppercase=1) 190 if headerWidth > self.width: 191 self.header.SetAlign(uiconst.CENTERLEFT) 192 else: 193 self.header.SetAlign(uiconst.CENTER) 194 self.header.text = headerText 195 self.header.SetAlpha(opacity) 196 197 def _UpdateActiveNavigationElement(self, *args): 198 if self.stepID in self.navigationElements: 199 stepOrder = GetStepOrder(self.stepID) 200 furthestOrder = GetStepOrder(self.furthestStepID) 201 self.navigationElements[self.stepID].Activate(furthest=stepOrder >= furthestOrder) 202 203 @telemetry.ZONE_METHOD 204 def PerformStepChange(self, stepID, stepsUsed, forceOpen = 0, time = None): 205 if not self.attributesApplied: 206 return 207 if time is None: 208 time = self.ANIMATIONTIME 209 self.stepID = stepID 210 self.stepsUsed = stepsUsed 211 furthestOrder = GetStepOrder(self.furthestStepID) 212 currentOrder = GetStepOrder(self.stepID) 213 if currentOrder > furthestOrder: 214 self.furthestStepID = self.stepID 215 furthestOrder = GetStepOrder(self.furthestStepID) 216 container = self.GetStepContainerViaGetAttr(stepID) 217 currentContainerStepID = None 218 if container: 219 currentContainerStepID = container.id 220 stepsUsed = self.stepsUsed.copy() 221 try: 222 for availableStepID in self.availableSteps: 223 connectorFromPreviousStep = self.GetConnectorForStep(availableStepID) 224 if availableStepID == stepID: 225 pass 226 elif availableStepID in stepsUsed: 227 if connectorFromPreviousStep: 228 connectorFromPreviousStep.width = 32 229 stepOrder = GetStepOrder(availableStepID) 230 if stepOrder > currentOrder: 231 self.navigationElements[availableStepID].Deactivate(furthest=stepOrder == furthestOrder) 232 elif stepOrder < currentOrder: 233 self.navigationElements[availableStepID].Complete() 234 else: 235 self.navigationElements[availableStepID].Lock() 236 if connectorFromPreviousStep: 237 connectorFromPreviousStep.width = 0 238 cont = self.GetStepContainerViaGetAttr(availableStepID) 239 if cont and availableStepID != currentContainerStepID: 240 cont.SetOpacity(self.NORMALOPACITY) 241 242 cont = self.GetStepContainerViaGetAttr(currentContainerStepID) 243 if currentContainerStepID not in stepsUsed or forceOpen: 244 connector = self.GetConnectorForStep(currentContainerStepID) 245 if connector: 246 if time: 247 animations.MorphScalar(connector, 'width', endVal=32, duration=time / 1000.0, sleep=True, callback=self._UpdateActiveNavigationElement) 248 else: 249 self._UpdateActiveNavigationElement() 250 connector.width = 32 251 cont.SetOpacity(self.ACTIVEOPACITY) 252 else: 253 self._UpdateActiveNavigationElement() 254 nextStepID = self.GetNextStepIDForStepID(currentContainerStepID) 255 nextStep = self.GetStepContainer(nextStepID) 256 if nextStep: 257 nextStep.state = uiconst.UI_NORMAL 258 else: 259 self._UpdateActiveNavigationElement() 260 if container and not container.destroyed and container.id == self.stepID: 261 container.SetOpacity(self.ACTIVEOPACITY) 262 except AttributeError as e: 263 if self is None or self.destroyed or e.message == 'SetOpacity': 264 sm.GetService('cc').LogWarn('Attibute error ignored when performing step change') 265 else: 266 raise 267 268 @telemetry.ZONE_METHOD 269 def OnStepClicked(self, stepClicked, *args): 270 if self.callbackFunc: 271 if self.stepID == stepClicked.id: 272 if not session.role & ROLE_PROGRAMMER: 273 return 274 self.callbackFunc(stepClicked.id) 275 276 @telemetry.ZONE_METHOD 277 def OnStepMouseOver(self, container, *args): 278 mousedStep = container.id 279 sm.StartService('audio').SendUIEvent(unicode('ui_icc_button_mouse_over_play')) 280 if container.id != self.stepID: 281 container.SetOpacity(self.MOUSEOVEROPACITY) 282 self.UpdateHeader(stepID=mousedStep, opacity=self.ACTIVEOPACITY) 283 284 @telemetry.ZONE_METHOD 285 def OnStepMouseExit(self, container, *args): 286 if container.id != self.stepID: 287 container.SetOpacity(self.NORMALOPACITY) 288 self.UpdateHeader(stepID=self.stepID, opacity=0.0)