characterSlots.py (73127B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\login\charSelection\characterSlots.py 2 import math 3 import blue 4 import carbonui.const as uiconst 5 import carbonui.fontconst 6 import eve.client.script.ui.login.charSelection.characterSelectionColors as csColors 7 import eve.client.script.ui.login.charSelection.characterSelectionUtils as csUtil 8 import evetypes 9 import inventorycommon.typeHelpers 10 import localization 11 import log 12 import trinity 13 import uthread 14 from achievement_system.client.ui.chip.achievement_info import AchievementInfoChips 15 from caching.memoize import Memoize 16 from carbon.client.script.environment.AudioUtil import PlaySound 17 from carbon.common.script.util import timerstuff 18 from carbon.common.script.util.format import IntToRoman 19 from carbonui.primitives.container import Container 20 from carbonui.primitives.containerAutoSize import ContainerAutoSize 21 from carbonui.primitives.fill import Fill 22 from carbonui.primitives.frame import Frame 23 from carbonui.primitives.line import Line 24 from carbonui.primitives.sprite import Sprite 25 from carbonui.primitives.transform import Transform 26 from carbonui.uicore import uicore 27 from carbonui.util.color import Color 28 from eve.client.script.ui.control import eveIcon, eveLabel 29 from eve.client.script.ui.control.eveIcon import CorpIcon 30 from eve.client.script.ui.login.charSelection.characterSelectionUtils import SetColor, MakeTransparent, SetEffectOpacity, SetSaturation 31 from eve.client.script.ui.shared.neocom.corporation.war.atWarTooltip import LoadAtWarTooltipPanel 32 from eve.client.script.ui.shared.radialMenu.radialMenu import ThreePartContainer 33 from eve.common.script.sys.idCheckers import IsAbyssalSpaceSystem, IsHiddenSpaceSystem, IsVoidSpaceSystem 34 from eve.common.script.util import eveFormat 35 from player_messaging.client.ui_message import prompt_player_fsd_dialog 36 from security.client.fonticons import get_font_icon_text 37 SHIP_BOUNDING_BOXES = {} 38 39 class SmallSlot(Container): 40 __notifyevents__ = ['OnExternalDragInitiated', 'OnExternalDragEnded', 'OnTokensRedeemed'] 41 default_align = uiconst.TOLEFT 42 default_width = 200 43 default_state = uiconst.UI_NORMAL 44 maxImageSize = 256 45 paddingName = 20 46 outerFrameWidth = 2 47 innerFrameWidth = 1 48 distanceFromOuterToInnerFrame_side = 4 49 distanceFromOuterToInnerFrame_bottom = 4 50 distanceFromInnerFrameToContent_sides = 6 51 distanceFromInnerFrameToContent_bottom = 6 52 isEmptySlot = False 53 54 def ApplyAttributes(self, attributes): 55 Container.ApplyAttributes(self, attributes) 56 self.callback = attributes.get('callback', None) 57 self.doubleClickCallback = attributes.get('doubleClickCallback', None) 58 self.slotIdx = attributes.get('slotIdx') 59 self.charID = None 60 self.mouseOverState = False 61 self.enteringGameWithSlot = False 62 innerslotPadding = self.outerFrameWidth + self.distanceFromOuterToInnerFrame_side 63 self.innerSlotCont = Container(parent=self, name='innerSlotCont', padding=innerslotPadding) 64 self.slotBackground = Fill(bgParent=self.innerSlotCont, color=csColors.SLOT_BACKGROUND, padding=0) 65 frameCornerSize = 2 + self.innerFrameWidth 66 glowFrameTexturePath = 'res:/UI/Texture/classes/CharacterSelection/glowDotFrame.png' 67 self.normalGlowFrame = Frame(parent=self.innerSlotCont, name='glowFrame', color=csColors.FRAME_GLOW_ACTIVE, frameConst=(glowFrameTexturePath, 68 5, 69 -2, 70 0), padding=0) 71 self.normalFrame = Frame(parent=self.innerSlotCont, name='normalFrame', padding=0, color=csColors.INNER_FRAME_INACTIVE, frameConst=('ui_1_16_161', 72 frameCornerSize, 73 -2, 74 0)) 75 self.drawLineLeft = ThreePartContainer(parent=self.innerSlotCont, name='endDots', align=uiconst.TOLEFT_NOPUSH, state=uiconst.UI_DISABLED, pos=(0, 0, 2, 0), idx=0, leftTexturePath='res:/UI/Texture/classes/CharacterSelection/topDot.png', rightTexturePath='res:/UI/Texture/classes/CharacterSelection/bottomDots.png', sideSize=20, color=csColors.FRAME_GLOW_ACTIVE, orientation='vertical') 76 self.drawLineLeft.opacity = 0 77 self.drawLineRight = ThreePartContainer(parent=self.innerSlotCont, name='endDots', align=uiconst.TORIGHT_NOPUSH, state=uiconst.UI_DISABLED, pos=(0, 0, 2, 0), idx=0, leftTexturePath='res:/UI/Texture/classes/CharacterSelection/topDot.png', rightTexturePath='res:/UI/Texture/classes/CharacterSelection/bottomDots.png', sideSize=20, color=csColors.FRAME_GLOW_ACTIVE, orientation='vertical') 78 self.drawLineRight.opacity = 0 79 offSetBottom = self.outerFrameWidth + self.distanceFromOuterToInnerFrame_bottom 80 texturePath = 'res:/UI/Texture/classes/CharacterSelection/selectFrame.png' 81 self.selectionFrameGlow = Frame(parent=self.innerSlotCont, name='selectionFrame', color=csColors.FRAME_GLOW_ACTIVE, frameConst=(texturePath, 82 22, 83 0, 84 0), padding=(-innerslotPadding, 85 -innerslotPadding, 86 -innerslotPadding, 87 -offSetBottom)) 88 self.selectionFrameGlow.opacity = 0 89 frameCornerSize = 2 + self.outerFrameWidth 90 self.selectionFrame = Frame(parent=self.innerSlotCont, name='selectionFrame', color=csColors.OUTER_FRAME, frameConst=('ui_1_16_161', 91 frameCornerSize, 92 -2, 93 0), padding=(-innerslotPadding, 94 -innerslotPadding, 95 -innerslotPadding, 96 -offSetBottom)) 97 self.selectionFrame.opacity = 0 98 infoContPadding = self.distanceFromInnerFrameToContent_sides + self.innerFrameWidth 99 self.infoCont = ContainerAutoSize(parent=self.innerSlotCont, name='infoCont', padding=infoContPadding, align=uiconst.TOTOP, alignMode=uiconst.TOTOP) 100 self.nameCont = Container(parent=self, name='nameCont', align=uiconst.TOTOP, height=28, padLeft=0, padRight=0, idx=0) 101 inactivePadding = (innerslotPadding, 102 0, 103 innerslotPadding, 104 4) 105 self.nameSelectionFillActive = Fill(bgParent=self.nameCont, padding=(0, 0, 0, 4), color=csColors.NAME_CONT_FILL_ACTIVE) 106 self.nameSelectionFillInactive = Fill(bgParent=self.nameCont, padding=inactivePadding, color=csColors.NAME_CONT_FILL_INACTIVE) 107 self.nameSelectionFillRedeemMode = Fill(bgParent=self.nameCont, padding=inactivePadding, color=csColors.NAME_CONT_FILL_ACTIVE) 108 self.innerNameCont = Container(parent=self.nameCont, padRight=innerslotPadding, clipChildren=True) 109 self.characterNameLabel = eveLabel.EveLabelLargeBold(parent=self.innerNameCont, name='characterNameLabel', align=uiconst.CENTERLEFT, text='', padLeft=8 + innerslotPadding, top=-2) 110 self.characterNameLabel.letterspace = 1 111 self.characterNameLabel.SetTextColor(csColors.NAME_LABEL_ACTIVE) 112 extraPadding = self.GetExtraWidth() 113 self.portraitCont = Container(parent=self.infoCont, name='portraitCont', align=uiconst.TOTOP, height=self.width - extraPadding, clipChildren=True) 114 self.portraitInnerCont = Container(parent=self.portraitCont, name='portraitInnerCont', align=uiconst.TOALL, pos=(0, 0, 0, 0), clipChildren=True, state=uiconst.UI_PICKCHILDREN) 115 chip_container = Container(name='chip_container', parent=self.portraitInnerCont, align=uiconst.TOTOP_NOPUSH, height=AchievementInfoChips.default_height, padding=(4, 4, 0, 0)) 116 self.titleAndAchievementChips = AchievementInfoChips(parent=chip_container, name='titleAndAchievementChips', align=uiconst.TOLEFT, character_id=self.charID, display_score=False) 117 self.portraitSprite = Sprite(parent=self.portraitInnerCont, name='portraitSprite', align=uiconst.TOALL, texturePath='res:/UI/Texture/classes/CharacterSelection/silhuette.png', pos=(0, 0, 0, 0), state=uiconst.UI_PICKCHILDREN, color=(0.5, 0.5, 0.5, 1.0), saturation=csColors.PORTRAIT_INACTIVE_SATURATION, spriteEffect=trinity.TR2_SFX_SOFTLIGHT) 118 self.portraitGrid = Sprite(parent=self.portraitInnerCont, texturePath='res:/UI/Texture/classes/CharacterSelection/Grid_ships_plus2.png', align=uiconst.TOALL, pos=(0, 0, 0, 0), color=csColors.GRID_ACTIVE, state=uiconst.UI_DISABLED, tileX=True, tileY=True) 119 offset = self.distanceFromInnerFrameToContent_bottom + self.innerFrameWidth 120 self.shipAndLocationCont = CharacterDetailsLocation(parent=self.innerSlotCont, padding=(infoContPadding, 121 infoContPadding, 122 infoContPadding, 123 offset), callback=self.OnClick, isEmptySlot=self.isEmptySlot, clipChildren=True) 124 self.skillQueueCont = SkillQueueCont(parent=self.infoCont, padTop=self.distanceFromInnerFrameToContent_sides) 125 self.AddCharacterDetailsLines() 126 sm.RegisterNotify(self) 127 128 def AddCharacterDetailsLines(self): 129 self.skillContainer = CharacterDetailsLine(parent=self.infoCont, iconPath='res:/UI/Texture/classes/CharacterSelection/skills.png', text='') 130 self.walletContainer = CharacterDetailsLine(parent=self.infoCont, iconPath='res:/UI/Texture/classes/CharacterSelection/isk.png', text='') 131 self.mailContainer = CharacterDetailsLine(parent=self.infoCont, iconPath='res:/UI/Texture/classes/CharacterSelection/mail.png', text='', addLine=False) 132 133 def SetMouseExitState(self, animate = False): 134 if self.enteringGameWithSlot: 135 return 136 self.mouseOverState = False 137 self.SetDisabled(animate=animate) 138 139 def SetMouseOverState(self, animate = False): 140 self.mouseOverState = True 141 self.SetEnabled(animate=animate) 142 SetColor(self.selectionFrame, csColors.OUTER_FRAME, animate=animate) 143 SetColor(self.selectionFrameGlow, csColors.FRAME_GLOW_ACTIVE, animate=animate) 144 SetColor(self.normalGlowFrame, csColors.FRAME_GLOW_ACTIVE, animate=animate) 145 SetColor(self.normalFrame, csColors.INNER_FRAME_ACTIVE, animate=animate) 146 147 def SetEnabled(self, redeemMode = False, animate = False): 148 if redeemMode: 149 MakeTransparent(self.nameSelectionFillActive, animate=animate) 150 SetColor(self.nameSelectionFillRedeemMode, csColors.NAME_CONT_FILL_ACTIVE, animate=animate) 151 else: 152 SetColor(self.nameSelectionFillActive, csColors.NAME_CONT_FILL_ACTIVE, animate=animate) 153 MakeTransparent(self.nameSelectionFillRedeemMode, animate=animate) 154 MakeTransparent(self.nameSelectionFillInactive, animate=animate) 155 self.shipAndLocationCont.SetSelected(animate=animate) 156 self.SetInfoLineActiveState(isActive=True, animate=animate) 157 self.shipAndLocationCont.SetActiveState(isActive=True, animate=animate) 158 if not csUtil.IsMonochromeStyleEnabled(): 159 SetColor(self.portraitSprite, (1, 1, 1, 1), animate=animate) 160 SetEffectOpacity(self.portraitSprite, newOpacity=0, animate=animate) 161 SetSaturation(self.portraitSprite, newSaturation=1.0, animate=animate) 162 self.skillQueueCont.SetSelected(animate=animate) 163 164 def SetDisabled(self, animate = False): 165 SetColor(self.normalFrame, csColors.INNER_FRAME_INACTIVE, animate=animate) 166 SetColor(self.normalGlowFrame, csColors.FRAME_GLOW_INACTIVE, animate=animate) 167 MakeTransparent(self.selectionFrame, animate=animate) 168 MakeTransparent(self.selectionFrameGlow, animate=animate) 169 MakeTransparent(self.nameSelectionFillActive, animate=animate) 170 MakeTransparent(self.nameSelectionFillRedeemMode, animate=animate) 171 SetColor(self.nameSelectionFillInactive, csColors.NAME_CONT_FILL_INACTIVE, animate=animate) 172 self.shipAndLocationCont.SetDeselected(animate=animate) 173 self.SetInfoLineActiveState(isActive=False, animate=animate) 174 self.shipAndLocationCont.SetActiveState(isActive=False, animate=animate) 175 SetColor(self.portraitSprite, csColors.PORTRAIT_INACTIVE, animate=animate) 176 SetEffectOpacity(self.portraitSprite, newOpacity=csColors.PORTRAIT_INACTIVE_EFFECT_OPACITY, animate=animate) 177 SetSaturation(self.portraitSprite, newSaturation=csColors.PORTRAIT_INACTIVE_SATURATION, animate=animate) 178 self.skillQueueCont.SetDeselected(animate=animate) 179 180 def SetInfoLineActiveState(self, isActive = True, animate = False): 181 for eachCont in (self.skillContainer, self.walletContainer, self.mailContainer): 182 eachCont.SetActiveState(isActive=isActive, animate=animate) 183 184 def GetShipAndLocationContHeight(self): 185 return self.shipAndLocationCont.GetHeight() 186 187 def SetShipContHeight(self, height): 188 self.shipAndLocationCont.SetShipContHeight(height) 189 190 def OnClick(self, *_): 191 if self.callback: 192 self.callback(self) 193 194 def OnDblClick(self, *_): 195 if self.doubleClickCallback: 196 self.doubleClickCallback(self) 197 198 @classmethod 199 def GetExtraWidth(cls): 200 outerFrameToInnerFrame = cls.outerFrameWidth + cls.distanceFromOuterToInnerFrame_side 201 innerFrameToConent = cls.innerFrameWidth + cls.distanceFromInnerFrameToContent_sides 202 totalPadding = outerFrameToInnerFrame + innerFrameToConent 203 return 2 * totalPadding 204 205 def GetSlotHeight(self, shipVisible = True): 206 w, infoContHeight = self.infoCont.GetAbsoluteSize() 207 shipContHeight = self.shipAndLocationCont.GetHeight(shipVisible=shipVisible) 208 nameContHeight = self.nameCont.height 209 innerContPadding = self.innerSlotCont.padTop + self.innerSlotCont.padBottom 210 infoContPadding = self.infoCont.padTop + self.infoCont.padBottom 211 shipContPadding = self.shipAndLocationCont.padBottom 212 totalPadding = innerContPadding + infoContPadding + shipContPadding 213 contentHeight = infoContHeight + shipContHeight + nameContHeight + totalPadding 214 return contentHeight 215 216 def ExpandSlot(self, animate = True): 217 if animate: 218 uicore.animations.MorphScalar(self, 'opacity', startVal=self.opacity, endVal=1.0, duration=csUtil.COLLAPSE_TIME) 219 else: 220 self.opacity = 1.0 221 self.shipAndLocationCont.ExpandShipSection(animate=animate) 222 223 def SetActiveInRedeeemMode(self): 224 pass 225 226 def CollapseSlot(self, animate = True): 227 self.shipAndLocationCont.CollapseShipSection(animate=animate) 228 229 def OnIconMouseEnter(self, icon, buttonIconOnMouseEnter): 230 preparingForDelete = self.characterDetails and bool(self.characterDetails.GetDeletePrepareTime()) 231 if not preparingForDelete: 232 self.SetMouseOverState(animate=False) 233 buttonIconOnMouseEnter() 234 235 def OnExternalDragInitiated(self, dragSource, dragData): 236 self.SetActiveInRedeeemMode() 237 238 def OnExternalDragEnded(self, *args): 239 if uicore.uilib.mouseOver == self or uicore.uilib.mouseOver.IsUnder(self): 240 self.SetMouseOverState(animate=True) 241 else: 242 self.SetMouseExitState(animate=True) 243 244 def OnTokensRedeemed(self, charID, stationID, tokensRedeemed, numItemsCreated): 245 if charID != self.charID: 246 return 247 uicore.animations.BlinkOut(self, startVal=1.0, endVal=0.5, duration=0.3, loops=1, curveType=uiconst.ANIM_BOUNCE) 248 249 def AnimateSlotIn(self, animationOffset = 0.0, soundFunction = None, charContHeight = 100): 250 self.enteringGameWithSlot = False 251 minBlinkValue = 0.2 252 blinkDuration = 0.1 253 lineAnimationOffset = animationOffset 254 lineAnimationDuration = 0.4 255 lineFadeOutOffset = lineAnimationOffset + lineAnimationDuration 256 lineFadeOutDuration = 0.2 257 uicore.animations.MorphScalar(self.drawLineLeft, 'padTop', startVal=(charContHeight - 30) / 2.0, endVal=0.0, duration=lineAnimationDuration, timeOffset=lineAnimationOffset) 258 uicore.animations.MorphScalar(self.drawLineLeft, 'padBottom', startVal=(charContHeight - 30) / 2.0, endVal=0.0, duration=lineAnimationDuration, timeOffset=lineAnimationOffset) 259 uicore.animations.MorphScalar(self.drawLineLeft, 'opacity', startVal=0.8, endVal=0, duration=lineFadeOutDuration, timeOffset=lineFadeOutOffset) 260 uicore.animations.MorphScalar(self.drawLineRight, 'padTop', startVal=(charContHeight - 30) / 2.0, endVal=0.0, duration=lineAnimationDuration, timeOffset=lineAnimationOffset) 261 uicore.animations.MorphScalar(self.drawLineRight, 'padBottom', startVal=(charContHeight - 30) / 2.0, endVal=0.0, duration=lineAnimationDuration, timeOffset=lineAnimationOffset) 262 uicore.animations.MorphScalar(self.drawLineRight, 'opacity', startVal=0.8, endVal=0, duration=lineFadeOutDuration, timeOffset=lineFadeOutOffset) 263 normalFrameFadeOffset = lineFadeOutDuration + lineFadeOutOffset - 0.2 264 normalFrameFadeDuration = 0.4 265 uthread.new(soundFunction, event='character_selection_animobject', sleepTime=normalFrameFadeOffset) 266 uicore.animations.MorphScalar(self.normalFrame, 'opacity', startVal=0, endVal=csColors.INNER_FRAME_INACTIVE[3], duration=normalFrameFadeDuration, timeOffset=normalFrameFadeOffset) 267 nameContDuration = 0.2 268 uicore.animations.MorphScalar(self.nameCont, 'opacity', startVal=0.0, endVal=1.0, duration=nameContDuration, timeOffset=normalFrameFadeOffset) 269 uicore.animations.BlinkIn(self.nameSelectionFillActive, startVal=0.0, endVal=1.0, duration=blinkDuration, loops=2, curveType=uiconst.ANIM_BOUNCE, callback=None, sleep=False, timeOffset=normalFrameFadeOffset) 270 portraitOffset = normalFrameFadeOffset + normalFrameFadeDuration - 0.2 271 portraitDuration = 0.2 272 uicore.animations.MorphScalar(self.portraitInnerCont, 'padTop', startVal=self.portraitCont.height / 2.0, endVal=0, duration=portraitDuration, timeOffset=portraitOffset) 273 uicore.animations.MorphScalar(self.portraitInnerCont, 'padBottom', startVal=self.portraitCont.height / 2.0, endVal=0, duration=portraitDuration, timeOffset=portraitOffset) 274 uicore.animations.BlinkIn(self.portraitInnerCont, startVal=1.0, endVal=minBlinkValue, duration=blinkDuration, curveType=uiconst.ANIM_BOUNCE, timeOffset=portraitOffset + portraitDuration) 275 uicore.animations.SpColorMorphTo(self.slotBackground, startColor=(0, 0, 0, 0), endColor=csColors.SLOT_BACKGROUND, duration=1.0, timeOffset=portraitOffset) 276 skillQueueOffset = portraitOffset + portraitDuration 277 skillQueueDuration = 0.1 278 uicore.animations.MorphScalar(self.skillQueueCont, 'opacity', startVal=0.0, endVal=1.0, duration=skillQueueDuration, timeOffset=skillQueueOffset) 279 uthread.new(soundFunction, event='character_selection_animobject', sleepTime=skillQueueOffset) 280 contOffset = skillQueueOffset + skillQueueDuration 281 contDuration = 0.03 282 for contIdx, eachCont in enumerate([self.skillContainer, self.walletContainer, self.mailContainer]): 283 contOffset += contIdx * contDuration 284 uicore.animations.BlinkIn(eachCont.icon, startVal=csColors.LINES_ICON_INACTIVE[3], endVal=minBlinkValue, duration=blinkDuration, loops=2, curveType=uiconst.ANIM_BOUNCE, timeOffset=contOffset) 285 uicore.animations.BlinkIn(eachCont.textLabel, startVal=1.0, endVal=minBlinkValue, duration=blinkDuration, loops=2, curveType=uiconst.ANIM_BOUNCE, timeOffset=contOffset) 286 uicore.animations.MorphScalar(eachCont, 'opacity', startVal=0.0, endVal=1.0, duration=contDuration, loops=2, timeOffset=contOffset) 287 bigTextLabel = getattr(eachCont, 'bigTextLabel', None) 288 if bigTextLabel: 289 uicore.animations.BlinkIn(bigTextLabel, startVal=1.0, endVal=minBlinkValue, duration=blinkDuration, loops=2, curveType=uiconst.ANIM_BOUNCE, timeOffset=contOffset) 290 291 shipLocationOffset = contOffset + contDuration 292 shipLocationBlinkOffset = shipLocationOffset + 0.05 293 shipLocationDuration = 0.2 294 uicore.animations.MorphScalar(self.shipAndLocationCont, 'opacity', startVal=0.0, endVal=1.0, duration=shipLocationDuration, loops=1, timeOffset=shipLocationBlinkOffset) 295 uicore.animations.BlinkIn(self.shipAndLocationCont.locationCont, startVal=1.0, endVal=minBlinkValue, duration=blinkDuration, loops=2, curveType=uiconst.ANIM_BOUNCE, timeOffset=shipLocationBlinkOffset) 296 uicore.animations.BlinkIn(self.shipAndLocationCont.shipParentCont, startVal=1.0, endVal=minBlinkValue, duration=blinkDuration, loops=2, curveType=uiconst.ANIM_BOUNCE, timeOffset=shipLocationOffset) 297 298 def AnimateSlotOut(self, animationOffset = 0.0, soundFunction = None, charContHeight = 100): 299 minBlinkValue = 0.2 300 blinkDuration = 0.1 301 uthread.new(soundFunction, event='character_selection_animobject', sleepTime=animationOffset) 302 shipLocationOffset = animationOffset 303 shipLocationBlinkOffset = shipLocationOffset + 0.05 304 shipLocationDuration = 0.2 305 uicore.animations.MorphScalar(self.shipAndLocationCont, 'opacity', startVal=1.0, endVal=0.0, duration=shipLocationDuration, loops=1, timeOffset=shipLocationBlinkOffset) 306 uicore.animations.BlinkOut(self.shipAndLocationCont.locationCont, startVal=1.0, endVal=minBlinkValue, duration=blinkDuration, loops=2, curveType=uiconst.ANIM_BOUNCE, timeOffset=shipLocationBlinkOffset) 307 uicore.animations.BlinkOut(self.shipAndLocationCont.shipParentCont, startVal=1.0, endVal=minBlinkValue, duration=blinkDuration, loops=2, curveType=uiconst.ANIM_BOUNCE, timeOffset=shipLocationOffset) 308 contOffset = shipLocationOffset + shipLocationDuration 309 contDuration = 0.03 310 for contIdx, eachCont in enumerate([self.mailContainer, self.walletContainer, self.skillContainer]): 311 contOffset += contIdx * contDuration 312 uicore.animations.BlinkOut(eachCont.icon, startVal=eachCont.icon.opacity, endVal=minBlinkValue, duration=blinkDuration, loops=2, curveType=uiconst.ANIM_BOUNCE, timeOffset=contOffset) 313 uicore.animations.BlinkOut(eachCont.textLabel, startVal=eachCont.icon.opacity, endVal=minBlinkValue, duration=blinkDuration, loops=2, curveType=uiconst.ANIM_BOUNCE, timeOffset=contOffset) 314 uicore.animations.MorphScalar(eachCont, 'opacity', startVal=1.0, endVal=0.0, duration=contDuration, loops=2, timeOffset=contOffset) 315 bigTextLabel = getattr(eachCont, 'bigTextLabel', None) 316 if bigTextLabel: 317 uicore.animations.BlinkOut(bigTextLabel, startVal=1.0, endVal=minBlinkValue, duration=blinkDuration, loops=2, curveType=uiconst.ANIM_BOUNCE, timeOffset=contOffset) 318 319 skillQueueOffset = contOffset + contDuration 320 skillQueueDuration = 0.1 321 uicore.animations.MorphScalar(self.skillQueueCont, 'opacity', startVal=1.0, endVal=0.0, duration=skillQueueDuration, timeOffset=skillQueueOffset) 322 uthread.new(soundFunction, event='character_selection_animobject', sleepTime=skillQueueOffset) 323 portraitOffset = skillQueueOffset + skillQueueDuration 324 portraitDuration = 0.2 325 uicore.animations.MorphScalar(self.portraitInnerCont, 'padTop', startVal=0, endVal=self.portraitCont.height / 2.0, duration=portraitDuration, timeOffset=portraitOffset) 326 uicore.animations.MorphScalar(self.portraitInnerCont, 'padBottom', startVal=0, endVal=self.portraitCont.height / 2.0, duration=portraitDuration, timeOffset=portraitOffset) 327 uicore.animations.BlinkOut(self.portraitInnerCont, startVal=1.0, endVal=minBlinkValue, duration=blinkDuration, curveType=uiconst.ANIM_BOUNCE, timeOffset=portraitOffset + portraitDuration) 328 uicore.animations.SpColorMorphTo(self.slotBackground, startColor=csColors.SLOT_BACKGROUND, endColor=(0, 0, 0, 0), duration=0.5, timeOffset=portraitOffset) 329 normalFrameFadeOffset = portraitOffset + portraitDuration 330 normalFrameFadeDuration = 0.4 331 uicore.animations.MorphScalar(self.normalFrame, 'opacity', startVal=csColors.INNER_FRAME_INACTIVE[3], endVal=0, duration=normalFrameFadeDuration, timeOffset=normalFrameFadeOffset) 332 nameContDuration = 0.2 333 uicore.animations.MorphScalar(self.nameCont, 'opacity', startVal=1.0, endVal=0.0, duration=nameContDuration, timeOffset=normalFrameFadeOffset) 334 uicore.animations.BlinkOut(self.nameSelectionFillActive, startVal=0.0, endVal=1.0, duration=blinkDuration, loops=2, curveType=uiconst.ANIM_BOUNCE, callback=None, sleep=False, timeOffset=normalFrameFadeOffset) 335 lineAnimationOffset = normalFrameFadeOffset + nameContDuration 336 lineAnimationDuration = 0.4 337 lineFadeOutOffset = lineAnimationOffset + lineAnimationDuration 338 lineFadeOutDuration = 0.2 339 uicore.animations.MorphScalar(self.drawLineLeft, 'padTop', startVal=0, endVal=(charContHeight - 30) / 2.0, duration=lineAnimationDuration, timeOffset=lineAnimationOffset) 340 uicore.animations.MorphScalar(self.drawLineLeft, 'padBottom', startVal=0, endVal=(charContHeight - 30) / 2.0, duration=lineAnimationDuration, timeOffset=lineAnimationOffset) 341 uicore.animations.MorphScalar(self.drawLineLeft, 'opacity', startVal=0.8, endVal=0.0, duration=lineFadeOutDuration, timeOffset=lineFadeOutOffset) 342 uicore.animations.MorphScalar(self.drawLineRight, 'padTop', startVal=0, endVal=(charContHeight - 30) / 2.0, duration=lineAnimationDuration, timeOffset=lineAnimationOffset) 343 uicore.animations.MorphScalar(self.drawLineRight, 'padBottom', startVal=0, endVal=(charContHeight - 30) / 2.0, duration=lineAnimationDuration, timeOffset=lineAnimationOffset) 344 uicore.animations.MorphScalar(self.drawLineRight, 'opacity', startVal=0.8, endVal=0, duration=lineFadeOutDuration, timeOffset=lineFadeOutOffset, curveType=uiconst.ANIM_BOUNCE) 345 346 def PlaySelectedAnimation(self): 347 self.enteringGameWithSlot = True 348 uicore.animations.BlinkIn(self.selectionFrame, startVal=csColors.OUTER_FRAME[3], endVal=0.0, duration=0.1, loops=2, curveType=uiconst.ANIM_BOUNCE, timeOffset=0.2) 349 uicore.animations.BlinkIn(self.nameSelectionFillActive, startVal=csColors.NAME_CONT_FILL_ACTIVE[3], endVal=0.0, duration=0.1, loops=2, curveType=uiconst.ANIM_BOUNCE, timeOffset=0.2) 350 uicore.animations.BlinkIn(self.shipAndLocationCont.locationBg, startVal=csColors.LOCATION_FILL_ACTIVE[3], endVal=0.0, duration=0.1, loops=2, curveType=uiconst.ANIM_BOUNCE, timeOffset=0.2) 351 uicore.animations.BlinkIn(self.skillQueueCont.fill, startVal=csColors.SKILLQUEUE_FILL_ACTIVE[3], endVal=0.0, duration=0.1, loops=2, curveType=uiconst.ANIM_BOUNCE, timeOffset=0.2) 352 sm.GetService('audio').SendUIEvent('character_select_character') 353 354 355 class SmallCharacterSlot(SmallSlot): 356 default_name = 'smallCharacterSlot' 357 __notifyevents__ = ['OnExternalDragInitiated', 'OnExternalDragEnded', 'OnTokensRedeemed'] 358 359 def ApplyAttributes(self, attributes): 360 SmallSlot.ApplyAttributes(self, attributes) 361 self.slotLoaded = False 362 self.characterDetails = None 363 self.deleteCallback = attributes.get('deleteCallback', None) 364 self.undoDeleteCallback = attributes.get('undoDeleteCallback', None) 365 self.terminateCallback = attributes.get('terminateCallback', None) 366 self.corpCont = Container(parent=self.portraitInnerCont, name='corpLabel', align=uiconst.BOTTOMLEFT, pos=(0, 0, 48, 48), idx=0) 367 self.allianceLogo = Sprite(parent=self.portraitInnerCont, name='allianceLogo', align=uiconst.BOTTOMRIGHT, state=uiconst.UI_NORMAL, pos=(0, 0, 48, 48), idx=0, spriteEffect=trinity.TR2_SFX_SOFTLIGHT) 368 self.allianceLogo.OnClick = self.OnClick 369 atWarLeft = self.corpCont.left + self.corpCont.width 370 atWarTop = self.corpCont.top + self.corpCont.height - 20 371 self.atWarSprite = Sprite(parent=self.portraitInnerCont, name='characterIsAtWar', align=uiconst.BOTTOMLEFT, state=uiconst.UI_NORMAL, texturePath='res:/UI/Texture/classes/war/atWar_24.png', pos=(atWarLeft, 372 atWarTop, 373 20, 374 20), spriteEffect=trinity.TR2_SFX_SOFTLIGHT, idx=0) 375 self.atWarSprite.SetRGBA(1.0, 0.0, 0.0, 1.0) 376 self.deleteCont = ContainerAutoSize(parent=self.nameCont, name='deleteCont', align=uiconst.TORIGHT, alignMode=uiconst.TORIGHT, pos=(12, -2, 32, 16), state=uiconst.UI_PICKCHILDREN, idx=0) 377 self.deleteCont.display = False 378 self.deleteButton1 = DeleteButton(parent=self.deleteCont, name='deleteButton', texturePath='res:/UI/Texture/Icons/Plus_Small.png', state=uiconst.UI_NORMAL, color=(1.0, 0.0, 0.0, 1.0), callback=self.DeleteButton1Clicked, hint=localization.GetByLabel('UI/CharacterSelection/CompleteTermination'), rotation=math.pi / 4.0, onMouseEnterCallback=self.OnMouseEnter, onMouseExitCallback=self.OnMouseExit) 379 iconOnMouseEnter = self.deleteButton1.OnMouseEnter 380 self.deleteButton1.OnMouseEnter = (self.OnIconMouseEnter, self.deleteButton1, iconOnMouseEnter) 381 self.deleteButton2 = DeleteButton(parent=self.deleteCont, name='cancelDeteleButton', texturePath='res:/UI/Texture/Icons/Plus_Small.png', state=uiconst.UI_NORMAL, callback=self.DeleteButton2Clicked, color=(1.0, 1.0, 1.0, 1.0), hint=localization.GetByLabel('UI/CharacterSelection/RemoveFromBiomass')) 382 iconOnMouseEnter = self.deleteButton2.OnMouseEnter 383 self.deleteButton2.OnMouseEnter = (self.OnIconMouseEnter, self.deleteButton2, iconOnMouseEnter) 384 self.timeCont = Container(parent=self.deleteCont, name='timeCont', align=uiconst.TORIGHT, width=20) 385 self.timeLabel = eveLabel.EveLabelLargeBold(parent=self.timeCont, name='textLabel', align=uiconst.CENTERLEFT, text='00:00:00', state=uiconst.UI_DISABLED) 386 self.timeCont.width = self.timeLabel.textwidth + 6 387 sm.RegisterNotify(self) 388 389 def LoadSlot(self, charID, characterDetails): 390 self.charID = charID 391 self.characterDetails = characterDetails 392 sm.GetService('photo').GetPortrait(charID, 512, self.portraitSprite) 393 self.portraitGrid.display = False 394 self.characterNameLabel.text = cfg.eveowners.Get(charID).name 395 corpID, allianceID = characterDetails.GetCorporationInfo() 396 self.corpCont.Flush() 397 self.corpLogo = eveIcon.GetLogoIcon(itemID=corpID, parent=self.corpCont, align=uiconst.TOPLEFT, name='corpLogo', state=uiconst.UI_NORMAL, size=48, ignoreSize=True, dontUseThread=True) 398 self.corpLogo.OnClick = self.OnClick 399 self.corpLogo.OnMouseEnter = lambda *args: PlaySound(uiconst.SOUND_BUTTON_HOVER) 400 if isinstance(self.corpLogo, CorpIcon): 401 for eachLogo in self.corpLogo.children: 402 eachLogo.originalColor = eachLogo.GetRGBA() 403 if eachLogo.spriteEffect == trinity.TR2_SFX_MASK: 404 newColor = self.FindPlayerCorpLogoColor(eachLogo) 405 SetColor(eachLogo, newColor, animate=False) 406 else: 407 eachLogo.spriteEffect = trinity.TR2_SFX_SOFTLIGHT 408 SetColor(eachLogo, csColors.PORTRAIT_INACTIVE, animate=False) 409 SetEffectOpacity(eachLogo, csColors.PORTRAIT_INACTIVE_EFFECT_OPACITY, animate=False) 410 SetSaturation(eachLogo, 0.0, animate=False) 411 412 else: 413 self.corpLogo.spriteEffect = trinity.TR2_SFX_SOFTLIGHT 414 SetColor(self.corpLogo, csColors.PORTRAIT_INACTIVE, animate=False) 415 SetEffectOpacity(self.corpLogo, csColors.PORTRAIT_INACTIVE_EFFECT_OPACITY, animate=False) 416 SetSaturation(self.corpLogo, 0.0, animate=False) 417 self.corpLogo.hint = cfg.eveowners.Get(corpID).name 418 if csUtil.IsMonochromeStyleEnabled(): 419 if isinstance(self.corpLogo, CorpIcon): 420 for eachLogo in self.corpLogo.children: 421 csUtil.SetMonochromeStyle(eachLogo, True) 422 423 else: 424 csUtil.SetMonochromeStyle(self.corpLogo, True) 425 self.allianceLogo.SetTexturePath('') 426 if allianceID is not None: 427 uthread.new(self.LoadAllianceLogo, self.allianceLogo, allianceID) 428 self.shipAndLocationCont.LoadInfo(characterDetails) 429 newlyFinishedSkills = characterDetails.GetFinishedSkills() 430 if newlyFinishedSkills: 431 skillText = localization.GetByLabel('UI/CharacterSelection/NumSkillsCompleted', skillCount=newlyFinishedSkills) 432 else: 433 sp = characterDetails.GetSkillInfo() or 0 434 skillText = localization.formatters.FormatNumeric(sp, useGrouping=True) 435 self.skillContainer.SetTextAndEnableContainer(skillText) 436 balance = characterDetails.GetWalletBalance() 437 balance = eveFormat.FmtISK(balance, showFractionsAlways=0) 438 walletChange = characterDetails.GetWalletChanged() 439 if walletChange > 0: 440 iconPath2 = 'res:/UI/Texture/classes/CharacterSelection/up.png' 441 elif walletChange < 0: 442 iconPath2 = 'res:/UI/Texture/classes/CharacterSelection/down.png' 443 else: 444 iconPath2 = None 445 self.walletContainer.SetTextAndEnableContainer(balance) 446 if walletChange: 447 value = eveFormat.FmtISK(walletChange, showFractionsAlways=bool(abs(walletChange) < 1)) 448 prefix = '<color=#FFFF1919>' if walletChange < 0 else '<color=#FF19FF19>+' 449 walletHint = '%s<br>%s%s</color>' % (localization.GetByLabel('UI/Neocom/Blink/ISKBalanceChanged'), prefix, value) 450 else: 451 walletHint = '' 452 self.walletContainer.SetSecondIcon(iconPath2, walletHint) 453 unreadMails = characterDetails.GetUnreaddMailCount() 454 if unreadMails: 455 unreadMailsText = localization.GetByLabel('UI/CharacterSelection/NumUnreadMails', mailCount=unreadMails) 456 else: 457 unreadMailsText = localization.GetByLabel('UI/CharacterSelection/NoUnreadMails') 458 self.mailContainer.SetTextAndEnableContainer(unreadMailsText) 459 characterIsAtWar = characterDetails.IsCharacterAtWar() 460 self.atWarSprite.display = characterIsAtWar 461 self.atWarSprite.LoadTooltipPanel = lambda tooltipPanel, *args: self.LoadAtWarTooltipPanel(tooltipPanel, characterDetails) 462 trainingInfo = characterDetails.GetSkillInTrainingInfo() 463 currentSkill = trainingInfo.get('currentSkill', None) 464 if currentSkill is not None: 465 level = trainingInfo.get('level', 1) 466 romanNumber = IntToRoman(min(5, int(level))) 467 startTime = trainingInfo.get('trainingStartTime') 468 finishTime = trainingInfo.get('trainingEndTime') 469 now = blue.os.GetWallclockTime() 470 timeLeft = max(0, finishTime - now) 471 fromSP = trainingInfo.get('fromSP') 472 finishSP = trainingInfo.get('finishSP') 473 trainedSP = trainingInfo.get('trainedSP') 474 currentTimeProgress = min(1.0, float(now - startTime) / (finishTime - startTime)) 475 currentTrained = currentTimeProgress * (finishSP - fromSP) + (trainedSP - fromSP) 476 progress = currentTrained / finishSP 477 progress = min([progress, 1.0]) 478 progress = max([progress, 0.0]) 479 skillText = localization.GetByLabel('UI/CharacterSelection/SkillAndLevel', skill=currentSkill, levelInRoman=romanNumber) 480 timeText = localization.formatters.FormatTimeIntervalShortWritten(long(timeLeft), showFrom='day', showTo='minute') 481 queueEndTime = trainingInfo.get('queueEndTime', 0) 482 if queueEndTime != finishTime: 483 queueTimeLeft = max(0, queueEndTime - now) 484 queueTimeText = localization.formatters.FormatTimeIntervalShortWritten(long(queueTimeLeft), showFrom='day', showTo='minute') 485 timeText = '%s +' % timeText 486 hint = '%s<br>%s' % (localization.GetByLabel('UI/SkillQueue/TrainingQueue'), queueTimeText) 487 else: 488 hint = '' 489 self.skillQueueCont.SetProgress(progress=progress) 490 self.skillQueueCont.SetText(skillText, timeText, hint) 491 self.skillQueueCont.SetSkillQueueActivityState(bool(currentSkill)) 492 self.SetDeleteUI(animate=False) 493 self.titleAndAchievementChips.character_id = charID 494 self.slotLoaded = True 495 496 def CountDown_thread(self): 497 deletePrepareTime = self.characterDetails.GetDeletePrepareTime() 498 if deletePrepareTime is None: 499 self.countDownThread = None 500 self.deleteButton1.display = False 501 return 502 now = blue.os.GetWallclockTime() 503 timeLeft = deletePrepareTime - now 504 timeLeftText = localization.formatters.FormatTimeIntervalShort(long(max(0, timeLeft)), showFrom='hour', showTo='second') 505 self.timeLabel.text = timeLeftText 506 if timeLeft < 0: 507 self.countDownThread = None 508 self.deleteButton1.display = True 509 self.deleteButton1.ExpandButton() 510 uicore.animations.BlinkOut(self.timeLabel, startVal=1.0, endVal=0.0, duration=0.3, loops=3, curveType=uiconst.ANIM_WAVE) 511 512 def LoadAllianceLogo(self, logo, allianceID): 513 sm.GetService('photo').GetAllianceLogo(allianceID, 64, logo, orderIfMissing=True) 514 logo.hint = cfg.eveowners.Get(allianceID).ownerName 515 logo.OnMouseEnter = lambda *args: PlaySound(uiconst.SOUND_BUTTON_HOVER) 516 517 def SetMouseExitState(self, animate = False): 518 if self.enteringGameWithSlot or not self.slotLoaded: 519 return 520 preparingForDelete = self.characterDetails and bool(self.characterDetails.GetDeletePrepareTime()) 521 if not preparingForDelete: 522 self.deleteCont.display = False 523 SmallSlot.SetMouseExitState(self, animate=animate) 524 self.SetIconsColorInactive(animate=animate) 525 self.AdjustNameLabel() 526 527 def SetMouseOverState(self, animate = False): 528 if not self.slotLoaded: 529 return 530 SmallSlot.SetMouseOverState(self, animate=animate) 531 if not csUtil.IsMonochromeStyleEnabled(): 532 self.SetIconsColorActive(animate=animate) 533 self.deleteCont.display = True 534 self.AdjustNameLabel() 535 536 def AdjustNameLabel(self): 537 if self.characterNameLabel.textwidth > self.width - 100: 538 slotWidth, h = self.innerNameCont.GetAbsoluteSize() 539 fadeEnd = slotWidth - 20 - self.characterNameLabel.left 540 self.characterNameLabel.SetRightAlphaFade(fadeEnd, maxFadeWidth=20) 541 542 def SetDisabled(self, animate = False): 543 SmallSlot.SetDisabled(self, animate) 544 if self.characterDetails.IsPreparingForDeletion(): 545 SetColor(self.portraitSprite, csColors.BIOMASS_PORTRAIT, animate=animate) 546 SetEffectOpacity(self.portraitSprite, newOpacity=csColors.PORTRAIT_INACTIVE_EFFECT_OPACITY, animate=animate) 547 SetSaturation(self.portraitSprite, newSaturation=csColors.PORTRAIT_INACTIVE_SATURATION, animate=animate) 548 self.shipAndLocationCont.SetDeselected(animate=animate) 549 550 def SetIconsColorActive(self, animate = False): 551 SetEffectOpacity(self.allianceLogo, 0, animate=animate) 552 SetSaturation(self.allianceLogo, 1.0, animate=animate) 553 if isinstance(self.corpLogo, CorpIcon): 554 self.SetPlayerCorpLogoColor(self.corpLogo, isActive=True, animate=animate) 555 else: 556 SetEffectOpacity(self.corpLogo, 0, animate=animate) 557 SetColor(self.atWarSprite, csColors.AT_WAR_ACTIVE, animate=animate) 558 559 def SetIconsColorInactive(self, animate = False): 560 SetEffectOpacity(self.allianceLogo, csColors.PORTRAIT_INACTIVE_EFFECT_OPACITY, animate=animate) 561 SetSaturation(self.allianceLogo, 0.0, animate=animate) 562 if isinstance(self.corpLogo, CorpIcon): 563 self.SetPlayerCorpLogoColor(self.corpLogo, isActive=False, animate=animate) 564 else: 565 SetEffectOpacity(self.corpLogo, csColors.PORTRAIT_INACTIVE_EFFECT_OPACITY, animate=animate) 566 SetColor(self.atWarSprite, csColors.AT_WAR_INACTIVE, animate=animate) 567 568 def SetPlayerCorpLogoColor(self, logo, isActive = True, animate = False): 569 for layerNum, eachSprite in enumerate(logo.children): 570 if eachSprite.spriteEffect == trinity.TR2_SFX_MASK: 571 if isActive: 572 newColor = eachSprite.originalColor 573 else: 574 newColor = self.FindPlayerCorpLogoColor(eachSprite) 575 else: 576 if isActive: 577 effectOpacity = 1.0 578 saturation = 1.0 579 newColor = eachSprite.originalColor 580 spriteEffect = trinity.TR2_SFX_COPY 581 else: 582 effectOpacity = csColors.PORTRAIT_INACTIVE_EFFECT_OPACITY 583 saturation = 0.0 584 newColor = csColors.PORTRAIT_INACTIVE 585 spriteEffect = trinity.TR2_SFX_SOFTLIGHT 586 SetEffectOpacity(eachSprite, effectOpacity, animate=animate) 587 SetSaturation(eachSprite, saturation, animate=animate) 588 eachSprite.spriteEffect = spriteEffect 589 SetColor(eachSprite, newColor, animate=animate) 590 591 def FindPlayerCorpLogoColor(self, sprite): 592 currentColor = sprite.originalColor 593 currentColor = [ min(1.0, value) for value in currentColor ] 594 newColor = Color(*currentColor).SetSaturation(0.05).SetAlpha(0.9).GetRGBA() 595 return newColor 596 597 def OnDropData(self, dragSource, dragData): 598 if self.characterDetails.IsPreparingForDeletion(): 599 return 600 tokens = [ {'tokenID': eachData['item'].tokenID, 601 'massTokenID': eachData['item'].massTokenID, 602 'typeID': eachData['item'].typeID} for eachData in dragData ] 603 useHomeStation = True 604 if self.characterDetails and self.characterDetails.GetCurrentStation(): 605 useHomeStation = False 606 if useHomeStation: 607 message = localization.GetByLabel('UI/Redeem/ConfirmRedeemToHomeStation', charID=self.characterDetails.charID) 608 ret = prompt_player_fsd_dialog('AskAreYouSure', {'cons': message}, uiconst.YESNO) 609 if ret != uiconst.ID_YES: 610 return 611 redeemInfo = sm.GetService('redeem').ClaimRedeemTokens(tokens, self.charID, useHomeStation=useHomeStation) 612 if redeemInfo and redeemInfo['isk_balance'] is not None: 613 balanceText = eveFormat.FmtISK(redeemInfo['isk_balance'], showFractionsAlways=0) 614 self.walletContainer.SetTextAndEnableContainer(balanceText) 615 616 def SetActiveInRedeeemMode(self): 617 SmallSlot.SetActiveInRedeeemMode(self) 618 if self.characterDetails and not self.characterDetails.IsPreparingForDeletion(): 619 self.SetEnabled(redeemMode=True) 620 else: 621 self.SetDisabled() 622 623 def RefreshCharacterDetails(self, characterDetails): 624 self.characterDetails = characterDetails 625 626 def SetDeleteUI(self, animate = True): 627 deletePrepareTime = self.characterDetails.GetDeletePrepareTime() 628 if deletePrepareTime: 629 self.SetMouseExitState() 630 self.deleteCont.display = True 631 self.timeCont.display = True 632 self.deleteButton2.hint = localization.GetByLabel('UI/CharacterSelection/RemoveFromBiomass') 633 now = blue.os.GetWallclockTime() 634 timeLeft = deletePrepareTime - now 635 timeLeftText = localization.formatters.FormatTimeIntervalShort(long(max(0, timeLeft)), showFrom='hour', showTo='second') 636 self.timeLabel.text = timeLeftText 637 self.portraitSprite.saturation = csColors.PORTRAIT_INACTIVE_SATURATION 638 self.portraitSprite.effectOpacity = csColors.PORTRAIT_INACTIVE_EFFECT_OPACITY 639 if animate: 640 uicore.animations.MorphScalar(self.deleteButton2.iconCont, 'rotation', startVal=self.deleteButton2.iconCont.rotation, endVal=0, duration=2.0) 641 uicore.animations.SpColorMorphTo(self.deleteButton2.icon, self.deleteButton2.icon.GetRGB(), csColors.BIOMASS_RED, csUtil.COLLAPSE_TIME) 642 uicore.animations.SpColorMorphTo(self.portraitSprite, self.portraitSprite.GetRGB(), csColors.BIOMASS_PORTRAIT, csUtil.COLLAPSE_TIME) 643 else: 644 self.deleteButton2.iconCont.rotation = 0 645 self.deleteButton2.icon.SetRGBA(*csColors.BIOMASS_RED) 646 self.portraitSprite.SetRGBA(*csColors.BIOMASS_PORTRAIT) 647 if timeLeft < 0: 648 self.deleteButton1.ExpandButton(animate=animate) 649 if animate: 650 uicore.animations.SpColorMorphTo(self.deleteButton2.icon, self.deleteButton2.icon.GetRGB(), csColors.BIOMASS_RED, csUtil.COLLAPSE_TIME) 651 else: 652 self.deleteButton2.icon.SetRGBA(*csColors.BIOMASS_RED) 653 else: 654 self.deleteButton1.CollapseButton(animate=animate) 655 self.countDownThread = timerstuff.AutoTimer(1000, self.CountDown_thread) 656 else: 657 self.timeCont.display = False 658 self.deleteButton1.CollapseButton(animate=animate) 659 self.deleteButton2.hint = localization.GetByLabel('UI/CharacterSelection/Terminate') 660 iconRotation = -math.pi / 4.0 661 if animate: 662 uicore.animations.SpColorMorphTo(self.deleteButton2.icon, self.deleteButton2.icon.GetRGB(), csColors.BIOMASS_WHITE, csUtil.COLLAPSE_TIME) 663 uicore.animations.MorphScalar(self.deleteButton2.iconCont, 'rotation', startVal=self.deleteButton1.iconCont.rotation, endVal=iconRotation, duration=2.0) 664 self.SetMouseExitState() 665 else: 666 self.deleteButton2.iconCont.rotation = iconRotation 667 self.deleteButton2.icon.SetRGBA(*csColors.BIOMASS_WHITE) 668 self.AdjustNameLabel() 669 670 def DeleteButton2Clicked(self): 671 deletePrepTime = self.characterDetails.GetDeletePrepareTime() 672 if self.deleteCallback and deletePrepTime is None: 673 self.deleteCallback(self.charID) 674 return 675 if deletePrepTime and self.undoDeleteCallback: 676 self.undoDeleteCallback(self.charID) 677 678 def DeleteButton1Clicked(self): 679 if self.terminateCallback: 680 self.terminateCallback(self.charID) 681 682 def LoadAtWarTooltipPanel(self, tooltipPanel, characterDetails, *args): 683 wars = characterDetails.GetCharacterWars() 684 corpID, allianceID = characterDetails.GetCorporationInfo() 685 ownerID = allianceID or corpID 686 LoadAtWarTooltipPanel(tooltipPanel, ownerID, wars) 687 688 689 class SmallEmptySlot(SmallSlot): 690 default_name = 'smallCharacterSlot' 691 isEmptySlot = True 692 isDropLocation = False 693 694 def InCohort(self): 695 return False 696 697 def ApplyAttributes(self, attributes): 698 SmallSlot.ApplyAttributes(self, attributes) 699 self.nameSelectionFillActive.opacity = 0 700 self.ownSlot = attributes.get('ownSlot', True) 701 if self.ownSlot: 702 text = localization.GetByLabel('UI/CharacterSelection/AddCharacter') 703 texturePath = 'res:/UI/Texture/classes/CharacterSelection/plus2.png' 704 else: 705 text = localization.GetByLabel('UI/CharacterSelection/AddSlot') 706 texturePath = 'res:/UI/Texture/classes/CharacterSelection/padlock.png' 707 self.characterNameLabel.text = text 708 self.characterNameLabel.SetAlign(uiconst.CENTER) 709 self.characterNameLabel.left = -12 710 self.plus = Sprite(parent=self.portraitInnerCont, align=uiconst.CENTER, texturePath=texturePath, idx=0, width=64, height=64, state=uiconst.UI_DISABLED, color=csColors.PLUS_INACTIVE) 711 self.walletContainer.SetBigText(text) 712 self.shipAndLocationCont.SetDisabled() 713 self.skillQueueCont.SetSkillqueueForEmpty() 714 self.SetMouseExitState() 715 716 def SetMouseExitState(self, animate = False): 717 SmallSlot.SetMouseExitState(self, animate=animate) 718 SetColor(self.plus, csColors.PLUS_INACTIVE, animate=animate) 719 720 def SetMouseOverState(self, animate = False): 721 SmallSlot.SetMouseOverState(self, animate=animate) 722 SetColor(self.plus, csColors.PLUS_ACTIVE, animate=animate) 723 724 725 class SkillQueueCont(Container): 726 default_align = uiconst.TOTOP 727 default_height = 30 728 default_padBottom = 8 729 default_clipChildren = True 730 paddingTimeText = 8 731 paddingSkillText = 8 732 733 def ApplyAttributes(self, attributes): 734 Container.ApplyAttributes(self, attributes) 735 self.glowFrame, self.normalFrame, self.fill = csUtil.AddFrameWithFillAndGlow(parent=self, fillColor=csColors.SKILLQUEUE_BACKGROUND_INACTIVE) 736 self.isActive = True 737 textCont = Container(name='textCont', parent=self) 738 self.timeText = eveLabel.EveLabelMedium(parent=ContainerAutoSize(parent=textCont, align=uiconst.TORIGHT), name='textLabel', align=uiconst.CENTERRIGHT, text='', left=self.paddingTimeText, state=uiconst.UI_NORMAL) 739 self.skillText = eveLabel.EveLabelMedium(parent=Container(parent=textCont, padRight=5), name='textLabel', align=uiconst.CENTERLEFT, text='', left=self.paddingSkillText, autoFadeSides=15) 740 self.skillFill = Fill(parent=self, align=uiconst.TOLEFT_PROP, width=0.0, color=csColors.SKILLQUEUE_FILL_ACTIVE) 741 self.skillEdge = Fill(parent=self, align=uiconst.TOLEFT, width=1, color=csColors.SKILLQUEUE_BRIGHT_EDGE) 742 743 def SetText(self, skillText, timeText, hint): 744 self.skillText.SetText('<b>%s</b>' % skillText) 745 self.timeText.SetText(timeText) 746 self.timeText.hint = hint 747 width, h = self.GetAbsoluteSize() 748 availableWidth = width - self.timeText.textwidth - self.paddingSkillText - self.paddingTimeText 749 if self.skillText.textwidth > availableWidth: 750 fadeEnd = availableWidth - 10 751 self.skillText.SetRightAlphaFade(fadeEnd, maxFadeWidth=10) 752 753 def SetSkillQueueActivityState(self, isActive = True): 754 self.isActive = isActive 755 if isActive: 756 self.skillText.display = True 757 self.timeText.display = True 758 self.skillText.SetRGBA(*csColors.SKILLQUEUE_TEXT_TRAINING_INACTIVE) 759 self.timeText.SetRGBA(*csColors.SKILLQUEUE_TEXT2_TRAINING_INACTIVE) 760 self.fill.SetRGBA(*csColors.SKILLQUEUE_BACKGROUND_ACTIVE) 761 self.normalFrame.SetRGBA(*csColors.SKILLQUEUE_FRAME_TRAINING_ACTIVE) 762 self.skillFill.display = True 763 self.skillEdge.display = True 764 else: 765 self.skillText.SetText(localization.GetByLabel('UI/CharacterSelection/NoSkillTraining')) 766 self.skillText.SetRGBA(*csColors.SKILLQUEUE_TEXT_NOT_TRAINING_INACTIVE) 767 self.timeText.SetRGBA(*csColors.SKILLQUEUE_TEXT_NOT_TRAINING_INACTIVE) 768 self.timeText.display = False 769 self.fill.SetRGBA(*csColors.SKILLQUEUE_BACKGROUND_INACTIVE) 770 self.normalFrame.SetRGBA(*csColors.SKILLQUEUE_FRAME_NOT_TRAINING_ACTIVE) 771 self.skillFill.display = False 772 self.skillEdge.display = False 773 774 def SetSkillqueueForEmpty(self): 775 self.fill.SetRGBA(*csColors.SKILLQUEUE_FILL_INACTIVE) 776 self.skillFill.display = False 777 self.skillEdge.display = False 778 self.normalFrame.SetRGBA(*csColors.SKILLQUEUE_FRAME_NOT_TRAINING_INACTIVE) 779 780 def SetProgress(self, progress = 0.0): 781 self.skillFill.width = progress 782 783 def SetSelected(self, animate = False): 784 SetColor(self.glowFrame, csColors.FRAME_GLOW_ACTIVE, animate=animate) 785 SetColor(self.fill, csColors.SKILLQUEUE_BACKGROUND_ACTIVE, animate=animate) 786 if self.isActive: 787 SetColor(self.normalFrame, csColors.SKILLQUEUE_FRAME_TRAINING_ACTIVE, animate=animate) 788 SetColor(self.skillFill, csColors.SKILLQUEUE_FILL_ACTIVE, animate=animate) 789 SetColor(self.skillText, csColors.SKILLQUEUE_TEXT_TRAINING_ACTIVE, animate=animate) 790 SetColor(self.timeText, csColors.SKILLQUEUE_TEXT2_TRAINING_ACTIVE, animate=animate) 791 else: 792 SetColor(self.normalFrame, csColors.SKILLQUEUE_FRAME_NOT_TRAINING_ACTIVE, animate=animate) 793 SetColor(self.skillText, csColors.SKILLQUEUE_TEXT_NOT_TRAINING_ACTIVE, animate=animate) 794 SetColor(self.timeText, csColors.SKILLQUEUE_TEXT_NOT_TRAINING_ACTIVE, animate=animate) 795 796 def SetDeselected(self, animate = False): 797 SetColor(self.glowFrame, csColors.FRAME_GLOW_INACTIVE, animate=animate) 798 SetColor(self.fill, csColors.SKILLQUEUE_BACKGROUND_INACTIVE, animate=animate) 799 if self.isActive: 800 SetColor(self.normalFrame, csColors.SKILLQUEUE_FRAME_TRAINING_INACTIVE, animate=animate) 801 SetColor(self.skillFill, csColors.SKILLQUEUE_FILL_INACTIVE, animate=animate) 802 SetColor(self.skillText, csColors.SKILLQUEUE_TEXT_TRAINING_INACTIVE, animate=animate) 803 SetColor(self.timeText, csColors.SKILLQUEUE_TEXT2_TRAINING_INACTIVE, animate=animate) 804 else: 805 SetColor(self.normalFrame, csColors.SKILLQUEUE_FRAME_NOT_TRAINING_INACTIVE, animate=animate) 806 SetColor(self.skillText, csColors.SKILLQUEUE_TEXT_NOT_TRAINING_INACTIVE, animate=animate) 807 SetColor(self.timeText, csColors.SKILLQUEUE_TEXT_NOT_TRAINING_INACTIVE, animate=animate) 808 809 810 class CharacterDetailsLocation(Container): 811 default_align = uiconst.TOBOTTOM 812 default_alignMode = uiconst.TOTOP 813 paddingShipAlignmentTop = 20 814 paddingShipAlignmentBottom = 40 815 locationContHeight = 60 816 minShipSize = 40 817 topOffset = (paddingShipAlignmentTop - paddingShipAlignmentBottom) / 2 818 819 def ApplyAttributes(self, attributes): 820 Container.ApplyAttributes(self, attributes) 821 self.glowFrame, self.normalFrame, fill = csUtil.AddFrameWithFillAndGlow(parent=self, showFill=False, frameColor=csColors.LOCATION_FRAME_INACTIVE) 822 self.characterDetails = None 823 self.fullHeight = self.height 824 self.isEmptySlot = attributes.get('isEmptySlot', False) 825 self.callback = attributes.get('callback') 826 self.locationCont = Container(parent=self, name='locationCont', height=self.locationContHeight, align=uiconst.TOBOTTOM) 827 self.shipParentCont = Container(parent=self, name='shipParentCont', align=uiconst.TOALL, clipChildren=True) 828 self.shipNameLabel = eveLabel.EveLabelSmall(parent=self.shipParentCont, name='shipText', align=uiconst.CENTERBOTTOM, top=4) 829 self.shipCont = Container(parent=self.shipParentCont, name='shipCont', align=uiconst.TOALL, clipChildren=True) 830 self.locationBg = Fill(bgParent=self.locationCont, color=csColors.LOCATION_FILL_ACTIVE) 831 self.shipbg = Fill(bgParent=self.shipParentCont, color=(0, 0, 0, 0.7)) 832 self.vignette = Sprite(parent=self.shipCont, texturePath='res:/UI/Texture/classes/CharacterSelection/vignette.png', align=uiconst.TOALL, pos=(0, 833 self.topOffset, 834 0, 835 0), padding=10, color=csColors.VIGNETTE_INACTIVE, state=uiconst.UI_DISABLED) 836 self.shipGrid = Sprite(parent=self.shipCont, texturePath='res:/UI/Texture/classes/CharacterSelection/bigGrid.png', align=uiconst.CENTER, pos=(0, 837 self.topOffset, 838 256, 839 256), color=csColors.GRID_ACTIVE, state=uiconst.UI_DISABLED) 840 self.shipScaleXCont = ShipScale(parent=self.shipCont, name='shipScaleXCont', align=uiconst.CENTER, top=self.topOffset) 841 self.shipScaleYCont = ShipScale(parent=self.shipCont, name='shipScaleYCont', align=uiconst.CENTER, isVertical=True, top=self.topOffset) 842 self.shipScaleXCont.display = False 843 self.shipScaleYCont.display = False 844 self.shipIconCont = Container(parent=self.shipCont, name='shipIconCont', align=uiconst.CENTER, idx=0, top=self.topOffset) 845 self.shipIcon = Sprite(parent=self.shipIconCont, name='shipIcon', align=uiconst.CENTER, pos=(0, 0, 128, 128), state=uiconst.UI_DISABLED, blendMode=trinity.TR2_SBM_ADD, spriteEffect=trinity.TR2_SFX_SOFTLIGHT, color=csColors.SHIP_ICON_ACTIVE) 846 locationText = attributes.get('locationText', '') 847 extraText = attributes.get('extraText', '') 848 self.locationTextCont = Container(parent=self.locationCont, name='locationTextCont', align=uiconst.TOALL) 849 self.textLabel = eveLabel.EveLabelLargeBold(parent=self.locationTextCont, name='textLabel', align=uiconst.CENTER, state=uiconst.UI_NORMAL, text=locationText, top=-10) 850 self.textLabel.OnClick = self.OnClick 851 self.extraTextLabel = eveLabel.EveLabelMedium(parent=self.locationTextCont, name='textLabel', align=uiconst.CENTER, text=extraText, top=10) 852 853 def OnClick(self, *args): 854 if self.callback: 855 self.callback() 856 857 def LoadInfo(self, characterDetails): 858 self.characterDetails = characterDetails 859 self.SetLocationText() 860 currentShipTypeID = characterDetails.GetCurrentShip() 861 texturePath = None 862 try: 863 graphicID = evetypes.GetGraphicID(currentShipTypeID) 864 if graphicID is not None: 865 texturePath = inventorycommon.typeHelpers.GetHoloIconPath(currentShipTypeID) 866 except AttributeError as e: 867 log.LogException(e) 868 869 self.shipIcon.SetTexturePath(texturePath) 870 self.shipNameLabel.text = evetypes.GetName(currentShipTypeID) 871 shipBoundingBox = SHIP_BOUNDING_BOXES.get(currentShipTypeID, None) 872 if shipBoundingBox is None: 873 shipBoundingBox = GetShipBoundingBox(texturePath) 874 if shipBoundingBox: 875 SHIP_BOUNDING_BOXES[currentShipTypeID] = shipBoundingBox 876 shipWidth = shipBoundingBox['maxX'] - shipBoundingBox['minX'] 877 shipHeight = shipBoundingBox['maxY'] - shipBoundingBox['minY'] 878 else: 879 shipWidth = 128 880 shipHeight = 128 881 self.shipIconCont.width = shipWidth 882 self.shipIconCont.height = shipHeight 883 if texturePath: 884 self.shipScaleXCont.display = True 885 self.shipScaleYCont.display = True 886 self.shipScaleXCont.width = shipWidth 887 self.shipScaleYCont.height = shipHeight 888 self.shipScaleXCont.top = int(shipHeight / 2.0) + 10 + self.topOffset 889 self.shipScaleYCont.left = -int(shipWidth / 2.0) - 15 890 891 def SetLocationText(self, fontColor = (1.0, 1.0, 1.0, 1.0), secColorAlpha = 1.0): 892 if not self.characterDetails: 893 return 894 stationID = self.characterDetails.GetCurrentStation() 895 locationID, securityStatus = self.characterDetails.GetCurrentLocationInfo() 896 securityText, secColor = eveFormat.FmtSystemSecStatus(securityStatus, 1) 897 if csUtil.IsMonochromeStyleEnabled(): 898 secColor = Color.GRAY5 899 secColor = int(Color.RGBtoHex(secColor[0], secColor[1], secColor[2], secColorAlpha), 16) 900 normalTextColor = int(Color.RGBtoHex(*fontColor), 16) 901 fontPath = None 902 if locationID is None: 903 locationText = '' 904 elif IsAbyssalSpaceSystem(locationID): 905 locationText = sm.GetService('abyss').get_mangled_system_name(locationID, self.characterDetails.charID) 906 locationText = '<color=%s>%s' % (normalTextColor, locationText) 907 fontPath = carbonui.fontconst.TRIGLAVIAN 908 elif IsVoidSpaceSystem(locationID) or IsHiddenSpaceSystem(locationID): 909 locationText = localization.GetByLabel('UI/Common/Unknown') 910 else: 911 locationText = cfg.evelocations.Get(locationID).name 912 securityModifierText = self._GetSecurityModifierText(locationID) 913 locationText = '<color=%s>%s</color>%s <color=%s>%s' % (secColor, 914 securityText, 915 securityModifierText, 916 normalTextColor, 917 locationText) 918 if stationID: 919 stationInfo = self.characterDetails.GetCurrentStationAndStationLocation() 920 stationName = stationInfo.get('stationName', '') 921 orbitName = stationInfo.get('shortOrbitName', '') 922 if orbitName: 923 extraText = '>>> [%s] %s <<<' % (orbitName, stationName) 924 else: 925 extraText = '>>> %s <<<' % (stationName,) 926 else: 927 extraText = localization.GetByLabel('UI/CharacterSelection/NotDocked') 928 self.textLabel.fontPath = fontPath 929 self.textLabel.SetText(locationText) 930 slotWidth, h = self.GetAbsoluteSize() 931 self.extraTextLabel.SetText(extraText) 932 self.extraTextLabel.SetRGBA(*fontColor) 933 if self.extraTextLabel.textwidth > slotWidth: 934 self.extraTextLabel.SetAlign(uiconst.CENTERLEFT) 935 self.extraTextLabel.left = 4 936 fadeEnd = slotWidth - 10 937 self.extraTextLabel.SetRightAlphaFade(fadeEnd, maxFadeWidth=20) 938 else: 939 self.extraTextLabel.left = 0 940 self.extraTextLabel.SetAlign(uiconst.CENTER) 941 self.extraTextLabel.SetRightAlphaFade(0, maxFadeWidth=0) 942 943 @Memoize(1) 944 def _GetSecurityModifierText(self, locationID): 945 mapSvc = sm.RemoteSvc('map') 946 modifiedSecuritySystems = mapSvc.GetSecurityModifiedSystems() 947 indexedSystems = modifiedSecuritySystems.Index('solarSystemID') 948 if locationID in indexedSystems: 949 system = indexedSystems[locationID] 950 return get_font_icon_text(system.security, system.modifiedSecurity) 951 return '' 952 953 def GetHeight(self, shipVisible = True): 954 if not shipVisible: 955 return self.locationContHeight + max(self.shipNameLabel.textheight + 2 * self.shipNameLabel.top, 20) 956 padding = self.paddingShipAlignmentTop + self.paddingShipAlignmentBottom 957 return max(self.shipIconCont.height, self.minShipSize) + self.locationCont.height + padding 958 959 def SetShipContHeight(self, height): 960 self.height = height 961 self.fullHeight = height 962 963 def SetDisabled(self): 964 self.vignette.padLeft = -30 965 self.vignette.padRight = -30 966 self.vignette.padTop = -30 967 self.vignette.padBottom = -30 968 self.normalFrame.SetRGBA(*csColors.LOCATION_FRAME_INACTIVE) 969 self.locationBg.SetRGBA(*csColors.LOCATION_FILL_INACTIVE) 970 self.vignette.SetRGBA(*csColors.VIGNETTE_DISABLED) 971 972 def SetActiveState(self, isActive = True, animate = False): 973 if isActive: 974 uthread.new(self.SetLocationText, fontColor=csColors.LOCATION_TEXT_ACTIVE) 975 SetColor(self.glowFrame, csColors.FRAME_GLOW_ACTIVE, animate=animate) 976 else: 977 uthread.new(self.SetLocationText, fontColor=csColors.LOCATION_TEXT_INACTIVE, secColorAlpha=0.6) 978 SetColor(self.glowFrame, csColors.FRAME_GLOW_INACTIVE, animate=animate) 979 980 def SetSelected(self, animate = False): 981 SetColor(self.shipGrid, csColors.GRID_ACTIVE, animate=animate) 982 SetColor(self.shipIcon, csColors.SHIP_ICON_ACTIVE, animate=animate) 983 SetColor(self.normalFrame, csColors.LOCATION_FRAME_ACTIVE, animate=animate) 984 SetColor(self.locationBg, csColors.LOCATION_FILL_ACTIVE, animate=animate) 985 SetColor(self.shipNameLabel, csColors.SHIP_NAME_ACTIVE, animate=animate) 986 self.SetActiveVignetteColor(animate=animate) 987 988 def SetDeselected(self, animate = False): 989 SetColor(self.shipGrid, csColors.GRID_INACTIVE, animate=animate) 990 SetColor(self.shipIcon, csColors.SHIP_ICON_INACTIVE, animate=animate) 991 SetColor(self.normalFrame, csColors.LOCATION_FRAME_INACTIVE, animate=animate) 992 SetColor(self.locationBg, csColors.LOCATION_FILL_INACTIVE, animate=animate) 993 SetColor(self.shipNameLabel, csColors.SHIP_NAME_INACTIVE, animate=animate) 994 self.SetInactiveVignetteColor(animate=animate) 995 996 def SetActiveVignetteColor(self, animate = False): 997 if self.isEmptySlot: 998 SetColor(self.vignette, csColors.VIGNETTE_DISABLED, animate=animate) 999 else: 1000 SetColor(self.vignette, csColors.VIGNETTE_ACTIVE, animate=animate) 1001 1002 def SetInactiveVignetteColor(self, animate = False): 1003 if self.isEmptySlot: 1004 SetColor(self.vignette, csColors.VIGNETTE_DISABLED, animate=animate) 1005 else: 1006 SetColor(self.vignette, csColors.VIGNETTE_INACTIVE, animate=animate) 1007 1008 def CollapseShipSection(self, animate = True): 1009 newHeight = self.locationContHeight + max(self.shipNameLabel.textheight + 2 * self.shipNameLabel.top, 20) 1010 if animate: 1011 uicore.animations.MorphScalar(self.shipCont, 'opacity', startVal=self.shipCont.opacity, endVal=0, duration=0.2) 1012 uicore.animations.MorphScalar(self, 'height', startVal=self.height, endVal=newHeight, duration=csUtil.COLLAPSE_TIME) 1013 else: 1014 uicore.animations.StopAnimation(self.shipCont, 'opacity') 1015 self.shipCont.opacity = 0 1016 uicore.animations.StopAnimation(self, 'height') 1017 self.height = newHeight 1018 1019 def ExpandShipSection(self, animate = True): 1020 if animate: 1021 uicore.animations.MorphScalar(self.shipCont, 'opacity', startVal=self.shipCont.opacity, endVal=1.0, duration=0.6) 1022 uicore.animations.MorphScalar(self, 'height', startVal=self.height, endVal=self.fullHeight, duration=csUtil.COLLAPSE_TIME) 1023 else: 1024 uicore.animations.StopAnimation(self.shipCont, 'opacity') 1025 self.shipCont.opacity = 1.0 1026 uicore.animations.StopAnimation(self, 'height') 1027 self.height = self.fullHeight 1028 1029 def Close(self): 1030 self._GetSecurityModifierText.clear_memoized() 1031 super(CharacterDetailsLocation, self).Close() 1032 1033 1034 class CharacterDetailsLine(Container): 1035 default_height = 20 1036 default_align = uiconst.TOTOP 1037 paddingText = 6 1038 paddingIcon = 4 1039 1040 def ApplyAttributes(self, attributes): 1041 Container.ApplyAttributes(self, attributes) 1042 iconPath = attributes.iconPath 1043 self.addLine = attributes.get('addLine', True) 1044 self.icon = Sprite(parent=self, name='icon', align=uiconst.CENTERLEFT, state=uiconst.UI_DISABLED, texturePath=iconPath, pos=(self.paddingIcon, 1045 0, 1046 24, 1047 24), spriteEffect=trinity.TR2_SFX_SOFTLIGHT, color=csColors.LINES_ICON_INACTIVE) 1048 iconPath2 = attributes.iconPath2 1049 left = self.icon.left + self.icon.width + 2 1050 self.icon2 = Sprite(parent=self, name='icon2', align=uiconst.CENTERLEFT, state=uiconst.UI_DISABLED, texturePath=iconPath2, pos=(left, 1051 0, 1052 24, 1053 24), spriteEffect=trinity.TR2_SFX_SOFTLIGHT, color=csColors.LINES_ICON_INACTIVE) 1054 self.icon.display = False 1055 self.icon2.display = False 1056 text = attributes.get('text', '') 1057 self.textLabel = eveLabel.EveLabelMedium(parent=self, name='textLabel', align=uiconst.CENTERRIGHT, text=text, left=self.paddingText) 1058 if self.addLine: 1059 self.AddLine() 1060 self.height = max(self.height, self.textLabel.textheight + 4) 1061 if text: 1062 self.SetTextAndEnableContainer(text) 1063 1064 def SetTextAndEnableContainer(self, text): 1065 self.textLabel.SetText(text) 1066 self.EnableContainer() 1067 1068 def EnableContainer(self): 1069 self.icon.display = True 1070 self.icon2.display = True 1071 1072 def SetSecondIcon(self, texturePath, hint = ''): 1073 self.icon2.SetTexturePath(texturePath) 1074 self.icon2.display = True 1075 self.icon2.state = uiconst.UI_NORMAL if texturePath else uiconst.UI_DISABLED 1076 self.icon2.hint = hint 1077 1078 def SetActiveState(self, isActive = True, animate = False): 1079 if isActive: 1080 SetColor(self.textLabel, csColors.LINES_TEXT_ACTIVE, animate=animate) 1081 SetColor(self.icon, csColors.LINES_ICON_ACTIVE, animate=animate) 1082 SetColor(self.icon2, csColors.LINES_ICON_ACTIVE, animate=animate) 1083 if self.addLine: 1084 self.endDots.opacity = csColors.FRAME_GLOW_ACTIVE[3] 1085 SetColor(self.bottomLine, csColors.LINES_ACTIVE, animate=animate) 1086 else: 1087 SetColor(self.textLabel, csColors.LINES_TEXT_INACTIVE, animate=animate) 1088 SetColor(self.icon, csColors.LINES_ICON_INACTIVE, animate=animate) 1089 SetColor(self.icon2, csColors.LINES_ICON_INACTIVE, animate=animate) 1090 if self.addLine: 1091 self.endDots.opacity = csColors.FRAME_GLOW_INACTIVE[3] 1092 SetColor(self.bottomLine, csColors.LINES_INACTIVE, animate=animate) 1093 1094 def SetBigText(self, text): 1095 bigTextLabel = getattr(self, 'bigTextLabel', None) 1096 if bigTextLabel is None or bigTextLabel.destroyed: 1097 self.bigTextLabel = eveLabel.CaptionLabel(parent=self, name='bigTextLabel', align=uiconst.CENTER, text='', fontsize=14, uppercase=False, letterspace=0, bold=False) 1098 self.bigTextLabel.SetTextColor(csColors.ADDCHARACTER_TEXT_ACTIVE) 1099 self.bigTextLabel.SetText(text) 1100 1101 def AddLine(self): 1102 padBottom = 0 1103 weight = 1 1104 self.bottomLine = Line(parent=self, align=uiconst.TOBOTTOM, weight=weight, color=csColors.LINES_ACTIVE, padBottom=padBottom) 1105 self.endDots = ThreePartContainer(parent=self, name='endDots', align=uiconst.TOBOTTOM_NOPUSH, state=uiconst.UI_DISABLED, pos=(0, 1106 0, 1107 0, 1108 weight), idx=0, leftTexturePath='res:/UI/Texture/classes/CharacterSelection/glowLineEndLeft.png', rightTexturePath='res:/UI/Texture/classes/CharacterSelection/glowLineEndRight.png', sideSize=8, color=csColors.FRAME_GLOW_ACTIVE) 1109 1110 1111 class DeleteButton(Container): 1112 default_state = uiconst.UI_NORMAL 1113 default_align = uiconst.TORIGHT 1114 1115 def ApplyAttributes(self, attributes): 1116 Container.ApplyAttributes(self, attributes) 1117 self.width = 14 1118 self.fullWidth = self.width 1119 texturePath = attributes.get('texturePath', None) 1120 self.callback = attributes.get('callback') 1121 color = attributes.get('color', (1, 0, 0, 1)) 1122 rotation = attributes.get('rotation', 0) 1123 self.onMouseEnterCallback = attributes.get('onMouseEnterCallback') 1124 self.onMouseExitCallback = attributes.get('onMouseExitCallback') 1125 self.iconCont = Transform(parent=self, align=uiconst.CENTER, pos=(0, 0, 10, 10), state=uiconst.UI_DISABLED, rotation=rotation) 1126 self.icon = Sprite(parent=self.iconCont, texturePath=texturePath, align=uiconst.TOPLEFT, pos=(0, 0, 10, 10), state=uiconst.UI_DISABLED, color=color) 1127 1128 def OnClick(self, *args): 1129 if self.callback: 1130 self.callback() 1131 self.icon.top = 0 1132 1133 def OnMouseDown(self, *args): 1134 self.icon.top = 2 1135 1136 def OnMouseUp(self, *args): 1137 self.icon.top = 0 1138 1139 def OnMouseEnter(self, *args): 1140 self.icon.SetAlpha(1.5) 1141 1142 def OnMouseExit(self, *args): 1143 self.icon.SetAlpha(1.0) 1144 1145 def ExpandButton(self, animate = True): 1146 if animate: 1147 uicore.animations.MorphScalar(self, 'width', startVal=self.width, endVal=self.fullWidth, duration=csUtil.COLLAPSE_TIME) 1148 else: 1149 self.width = self.fullWidth 1150 1151 def CollapseButton(self, animate = True): 1152 if animate: 1153 uicore.animations.MorphScalar(self, 'width', startVal=self.width, endVal=0, duration=csUtil.COLLAPSE_TIME) 1154 else: 1155 self.width = 0 1156 1157 1158 class ShipScale(Container): 1159 default_state = uiconst.UI_DISABLED 1160 default_clipChildren = True 1161 default_length = 256 1162 default_weight = 5 1163 default_scaleWeight = 3 1164 1165 def ApplyAttributes(self, attributes): 1166 Container.ApplyAttributes(self, attributes) 1167 isVertical = attributes.get('isVertical', False) 1168 length = attributes.get('length', self.default_length) 1169 weight = attributes.get('weight', self.default_weight) 1170 self.scaleWeigth = attributes.get('scaleWeight', self.default_scaleWeight) 1171 scaleColor = attributes.get('scaleColor', csColors.GRID_SCALE) 1172 endColor = attributes.get('endColor', scaleColor) 1173 if isVertical: 1174 self.height = length 1175 self.width = weight 1176 texturePath = 'res:/UI/Texture/classes/CharacterSelection/scaleY.png' 1177 startScaleAlign = uiconst.TOBOTTOM_NOPUSH 1178 endScaleAlign = uiconst.TOTOP_NOPUSH 1179 spriteHeight = self.height 1180 spriteWidth = self.scaleWeigth 1181 else: 1182 self.height = weight 1183 self.width = length 1184 texturePath = 'res:/UI/Texture/classes/CharacterSelection/scaleX.png' 1185 startScaleAlign = uiconst.TOLEFT_NOPUSH 1186 endScaleAlign = uiconst.TORIGHT_NOPUSH 1187 spriteHeight = self.scaleWeigth 1188 spriteWidth = self.width 1189 Line(parent=self, align=startScaleAlign, color=endColor) 1190 Line(parent=self, align=endScaleAlign, color=endColor) 1191 self.scaleSprite = Sprite(parent=self, texturePath=texturePath, align=uiconst.CENTER, pos=(0, 1192 0, 1193 spriteWidth, 1194 spriteHeight), color=scaleColor, state=uiconst.UI_DISABLED) 1195 1196 1197 def GetShipBoundingBox(texturePath, ignoredColors = None): 1198 if texturePath is None: 1199 return 1200 if ignoredColors is None: 1201 ignoredColors = [(0, 0, 0, 1)] 1202 image = blue.resMan.GetResource(texturePath, 'raw') 1203 blue.resMan.Wait() 1204 maxX = None 1205 minX = None 1206 maxY = None 1207 minY = None 1208 if not image.height: 1209 return 1210 for x in xrange(image.width): 1211 for y in xrange(image.height): 1212 color = image.GetPixelColor(x, y) 1213 if color in ignoredColors: 1214 continue 1215 if minX is None: 1216 minX = x 1217 if maxX is None or maxX < x: 1218 maxX = x 1219 if minY is None or minY > y: 1220 minY = y 1221 if maxY is None or maxY < y: 1222 maxY = y 1223 1224 return {'maxX': maxX or image.width, 1225 'minX': minX or 0, 1226 'maxY': maxY or image.height, 1227 'minY': minY or 0}