eveIcon.py (22096B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\control\eveIcon.py 2 import eve.common.lib.appConst as const 3 import eveicon 4 import log 5 import trinity 6 import uthread 7 from carbon.client.script.environment.AudioUtil import PlaySound 8 from carbonui import uiconst 9 from carbonui.primitives.container import Container 10 from carbonui.primitives.containerAutoSize import ContainerAutoSize 11 from carbonui.primitives.frame import Frame 12 from carbonui.primitives.sprite import Sprite 13 from carbonui.uianimations import animations 14 from carbonui.util.bunch import Bunch 15 from eve.client.script.ui.const.eveIconConst import IN_ICONS, IN_CORP_ICONS, IN_SMALL_ICONS, CORP_ICONS, RACE_ICONS 16 from eve.client.script.ui.control.eveLabel import EveLabelMedium 17 from eve.common.lib import appConst 18 from eve.common.script.sys import idCheckers 19 from fsdBuiltData.common.iconIDs import GetIconFile 20 import logging 21 logger = logging.getLogger(__name__) 22 23 class Icon(Sprite): 24 __guid__ = 'uicontrols.Icon' 25 size_doc = 'Optional icon pixel size. Will override width and height with size.' 26 typeID_doc = 'Optional param to override the icon path. Will get a type based icon instead.' 27 itemID_doc = "Optional param for char portraits or 'location' icons. Used with typeID." 28 graphicID_doc = 'Optional param to get icon based on standard graphic record.' 29 default_size = None 30 default_typeID = None 31 default_graphicID = None 32 default_itemID = None 33 default_icon = None 34 default_ignoreSize = 0 35 default_rect = None 36 default_name = 'icon' 37 default_left = 0 38 default_top = 0 39 default_width = 0 40 default_height = 0 41 42 def ApplyAttributes(self, attributes): 43 if attributes.__gotShape__ and len(attributes.keys()) == 1: 44 return 45 for each in ('iconID', 'path'): 46 if each in attributes: 47 log.LogInfo('Someone creating icon with', each, 'as keyword', attributes.Get(each, 'None')) 48 49 size = attributes.get('size', self.default_size) 50 if attributes.get('align', self.default_align) != uiconst.TOALL: 51 if size: 52 attributes.width = attributes.height = size 53 else: 54 attributes.pos = (0, 0, 0, 0) 55 attributes.width = attributes.height = 0 56 icon = attributes.get('icon', self.default_icon) 57 if 'icon' in attributes: 58 del attributes['icon'] 59 Sprite.ApplyAttributes(self, attributes) 60 ignoreSize = attributes.get('ignoreSize', self.default_ignoreSize) 61 self.typeID = attributes.get('typeID', self.default_typeID) 62 self.itemID = attributes.get('itemID', self.default_itemID) 63 graphicID = attributes.get('graphicID', self.default_graphicID) 64 isCopy = attributes.get('isCopy', False) 65 if icon: 66 self.LoadIcon(icon, ignoreSize=ignoreSize) 67 elif self.typeID: 68 self.LoadIconByTypeID(self.typeID, itemID=self.itemID, size=size, ignoreSize=ignoreSize, isCopy=isCopy) 69 elif graphicID: 70 self.LoadIconByIconID(graphicID, ignoreSize=ignoreSize) 71 else: 72 self.LoadTexture('res:/UI/Texture/None.dds') 73 onClick = attributes.get('OnClick', None) 74 if onClick: 75 self.OnClick = onClick 76 77 def LoadIconByIconID(self, graphicID, ignoreSize = False): 78 iconFile = GetIconFile(graphicID) 79 if iconFile: 80 self.LoadIcon(iconFile, ignoreSize) 81 82 def LoadIcon(self, icon, ignoreSize = False): 83 if not icon: 84 return 85 if isinstance(icon, eveicon.IconData): 86 self.SetTexturePath(icon) 87 return 88 if isinstance(icon, int): 89 return self.LoadIconByIconID(icon, ignoreSize=ignoreSize) 90 icon = Sprite.LoadIcon(self, icon, ignoreSize) 91 if icon is not None: 92 fullPathData = self.ConvertIconNoToResPath(icon) 93 if fullPathData: 94 resPath, iconSize = fullPathData 95 self.LoadTexture(resPath) 96 if not ignoreSize and self.GetAlign() != uiconst.TOALL and self.texture.atlasTexture: 97 self.width = iconSize 98 self.height = iconSize 99 100 def LoadIconByTypeID(self, typeID, itemID = None, size = None, ignoreSize = False, isCopy = False): 101 self.typeID = typeID 102 sm.GetService('photo').GetIconByType(self, typeID, itemID=itemID, size=size, ignoreSize=ignoreSize, isCopy=isCopy) 103 104 @staticmethod 105 def ConvertIconNoToResPath(iconNo): 106 resPath = None 107 if iconNo.startswith('res:'): 108 return (iconNo, 0) 109 parts = iconNo.split('_') 110 if len(parts) == 2: 111 sheet, iconNum = parts 112 iconSize = GetIconSize(sheet) 113 resPath = 'res:/ui/texture/icons/%s_%s_%s.png' % (int(sheet), int(iconSize), int(iconNum)) 114 elif iconNo.startswith('ui_'): 115 u, sheet, iconSize, iconNum = parts 116 iconSize = int(iconSize) 117 resPath = 'res:/ui/texture/icons/%s_%s_%s.png' % (int(sheet), int(iconSize), int(iconNum)) 118 elif iconNo.startswith('corps_'): 119 resPath = 'res:/ui/texture/corps/' + iconNo[6:] + '.png' 120 iconSize = 128 121 elif iconNo.startswith('alliance_'): 122 resPath = 'res:/ui/texture/alliance/' + iconNo[9:] + '.png' 123 iconSize = 128 124 elif iconNo.startswith('c_'): 125 c, sheet, iconNum = parts 126 resPath = 'res:/ui/texture/corps/%s_128_%s.png' % (int(sheet), int(iconNum)) 127 iconSize = 128 128 elif iconNo.startswith('a_'): 129 a, sheet, iconNum = parts 130 resPath = 'res:/ui/texture/alliance/%s_128_%s.png' % (int(sheet), int(iconNum)) 131 iconSize = 128 132 if resPath: 133 return (resPath, iconSize) 134 log.LogWarn('Icon: MISSING CONVERSION HANDLING FOR', iconNo) 135 136 137 class DraggableIcon(Container): 138 __guid__ = 'uicls.DraggableIcon' 139 default_name = 'draggableIcon' 140 default_opacity = 1.0 141 default_location_icon = False 142 143 def ApplyAttributes(self, attributes): 144 Container.ApplyAttributes(self, attributes) 145 self.location_icon = attributes.get('location_icon', self.default_location_icon) 146 if self.location_icon: 147 self.sr.icon = Container(parent=self, name='icont', align=uiconst.TOALL, clipChildren=True) 148 else: 149 self.sr.icon = Icon(parent=self, name='icon', align=uiconst.TOALL) 150 self.ChangeIcon(**attributes) 151 152 def ChangeIcon(self, typeID = None, itemID = None, icon = None, isCopy = False, **kw): 153 if self.location_icon and typeID is not None: 154 self.typeID = typeID 155 sm.GetService('photo').GetIconByType(self.sr.icon, typeID, itemID=itemID) 156 elif icon: 157 self.sr.icon.LoadIcon(icon, ignoreSize=True) 158 elif typeID: 159 self.sr.icon.LoadIconByTypeID(typeID, itemID=itemID, ignoreSize=True, isCopy=isCopy) 160 from eve.client.script.ui.util.uix import GetTechLevelIcon 161 techIcon = GetTechLevelIcon(None, typeID=typeID) 162 if techIcon: 163 techIcon.SetParent(self, 0) 164 165 def LoadIcon(self, icon, *args, **kwds): 166 self.ChangeIcon(icon=icon) 167 168 def LoadIconByTypeID(self, typeID, itemID = None, isCopy = False, *args, **kwds): 169 self.ChangeIcon(typeID=typeID, itemID=itemID, isCopy=isCopy) 170 171 172 class LogoIcon(Icon): 173 __guid__ = 'uicls.LogoIcon' 174 default_isSmall = None 175 default_isSmall_doc = 'Should we use the small version for faction icons.' 176 default_align = uiconst.RELATIVE 177 178 def ApplyAttributes(self, attributes): 179 itemID = attributes.get('itemID', None) 180 icon = None 181 if itemID is not None: 182 if idCheckers.IsCorporation(itemID): 183 if CheckCorpID(itemID): 184 icon = CORP_ICONS[itemID] 185 else: 186 raise ValueError('LogoIcon class does not support custom corp icons. Use CorpIcon for that') 187 elif idCheckers.IsAlliance(itemID): 188 raise ValueError('LogoIcon class does not support Alliance Logos. Use GetLogoIcon or GetOwnerIcon') 189 elif idCheckers.IsFaction(itemID): 190 isSmall = attributes.get('isSmall', self.default_isSmall) 191 icon = self.GetFactionIconID(itemID, isSmall) 192 elif itemID in RACE_ICONS: 193 icon = RACE_ICONS[itemID] 194 if icon is None: 195 icon = 'ui_1_16_256' 196 attributes['icon'] = icon 197 Icon.ApplyAttributes(self, attributes) 198 199 @staticmethod 200 def GetFactionIconID(factionID, isSmall = default_isSmall): 201 if isSmall and factionID in IN_SMALL_ICONS: 202 return IN_SMALL_ICONS.get(factionID) 203 elif factionID in IN_ICONS: 204 return IN_ICONS.get(factionID) 205 elif factionID in IN_CORP_ICONS: 206 return IN_CORP_ICONS.get(factionID) 207 else: 208 return None 209 210 @staticmethod 211 def GetFactionIconTexturePath(factionID, isSmall = True): 212 iconNo = LogoIcon.GetFactionIconID(factionID, isSmall) 213 texturePath, _ = Icon.ConvertIconNoToResPath(iconNo) 214 return texturePath 215 216 217 class CorpIcon(Container): 218 __guid__ = 'uicls.CorpIcon' 219 isDragObject = True 220 default_left = 0 221 default_top = 0 222 default_width = 128 223 default_height = 128 224 default_size = None 225 size_doc = 'Optional icon pixel size. Will override width and height with size.' 226 default_name = 'corplogo' 227 default_state = uiconst.UI_DISABLED 228 default_align = uiconst.TOPLEFT 229 230 def ApplyAttributes(self, attributes): 231 if attributes.get('align', self.default_align) != uiconst.TOALL: 232 size = attributes.get('size', self.default_size) 233 if size: 234 attributes.width = attributes.height = size 235 else: 236 attributes.pos = (0, 0, 0, 0) 237 attributes.width = attributes.height = 0 238 Container.ApplyAttributes(self, attributes) 239 self.colorIDs = [None, None, None] 240 self.shapeIDs = [None, None, None] 241 specified_size = 'icon_size' in attributes 242 sprite_size = attributes.get('icon_size') 243 for sprite_num in range(3): 244 try: 245 new_sprite = Sprite(parent=self, name='layerTopSample', align=uiconst.CENTER if specified_size else uiconst.TOALL, state=uiconst.UI_DISABLED, color=(1.0, 1.0, 1.0, 0.0), ignoreColorBlindMode=True) 246 if specified_size: 247 new_sprite.width = sprite_size[2] 248 new_sprite.height = sprite_size[3] 249 except Exception as e: 250 logger.exception('CorpIcon failed to create sprite - %s', e) 251 252 self.corpID = attributes.get('corpID', None) 253 if attributes.dontUseThread: 254 self.DoLayout(self.corpID, attributes) 255 else: 256 uthread.new(self.DoLayout, self.corpID, attributes) 257 258 def Load(self, corpID, **kwargs): 259 self.corpID = corpID 260 attributes = Bunch(**kwargs) 261 if attributes.dontUseThread: 262 self.DoLayout(self.corpID, attributes) 263 else: 264 uthread.new(self.DoLayout, self.corpID, attributes) 265 266 def DoLayout(self, corpID, attributes): 267 big = attributes.get('big', False) 268 onlyValid = attributes.get('onlyValid', False) 269 logoData = attributes.get('logoData', None) 270 if corpID in CORP_ICONS: 271 logger.exception('Invalid corpID for CorpIcon, use LogoIcon instead. corpID %s' % corpID) 272 return 273 if logoData is None: 274 if not corpID: 275 return 276 logoData = cfg.corptickernames.Get(corpID) 277 if logoData: 278 log.LogInfo('LogoIcon.GetCorpIconID', 'corpID:', corpID, 'shape1:', logoData.shape1, 'shape2:', logoData.shape2, 'shape3:', logoData.shape3, 'color1:', logoData.color1, 'color2:', logoData.color2, 'color3:', logoData.color3) 279 shapeIDs = (logoData.shape1, logoData.shape2, logoData.shape3) 280 colorIDs = (logoData.color1, logoData.color2, logoData.color3) 281 for i in xrange(3): 282 shapeID = shapeIDs[i] 283 colorID = colorIDs[i] 284 if shapeID is not None and shapeID == int(shapeID): 285 self.SetLayerShapeAndColor(i, shapeID, colorID, big) 286 287 elif onlyValid: 288 raise RuntimeError('not valid corpID') 289 290 def SetLayerShapeAndColor(self, layerNum, shapeID = None, colorID = None, isBig = False): 291 if self.destroyed: 292 return 293 layer = self.children[layerNum] 294 if shapeID is None: 295 shapeID = self.shapeIDs[layerNum] 296 else: 297 self.shapeIDs[layerNum] = shapeID 298 if colorID is None: 299 colorID = self.colorIDs[layerNum] 300 else: 301 self.colorIDs[layerNum] = colorID 302 texturePath = const.graphicCorpLogoLibShapes.get(shapeID, const.graphicCorpLogoLibShapes[const.graphicCorpLogoLibNoShape]) 303 if isBig: 304 texturePath = '%s/large/%s' % tuple(texturePath.rsplit('/', 1)) 305 if colorID is not None and colorID == int(colorID): 306 color, blendMode = const.graphicCorpLogoLibColors.get(colorID, const.CORPLOGO_DEFAULT_COLOR) 307 else: 308 color, blendMode = const.CORPLOGO_DEFAULT_COLOR 309 if blendMode == const.CORPLOGO_BLEND: 310 layer.SetTexturePath(texturePath) 311 layer.SetSecondaryTexturePath(None) 312 layer.spriteEffect = trinity.TR2_SFX_COPY 313 layer.SetRGBA(*color) 314 elif blendMode == const.CORPLOGO_SOLID: 315 layer.SetTexturePath('res:/UI/Texture/fill.dds') 316 layer.SetSecondaryTexturePath(texturePath) 317 layer.spriteEffect = trinity.TR2_SFX_MASK 318 layer.SetRGBA(*color) 319 elif blendMode == const.CORPLOGO_GRADIENT: 320 layer.SetTexturePath('res:/UI/Texture/corpLogoLibs/%s.png' % colorID) 321 layer.SetSecondaryTexturePath(texturePath) 322 layer.spriteEffect = trinity.TR2_SFX_MASK 323 layer.SetRGBA(1.0, 1.0, 1.0, 1.0) 324 325 def OnClick(self, *args): 326 PlaySound(uiconst.SOUND_BUTTON_CLICK) 327 sm.GetService('info').ShowInfo(typeID=const.typeCorporation, itemID=self.corpID) 328 329 def OnMouseEnter(self, *args): 330 PlaySound(uiconst.SOUND_BUTTON_HOVER) 331 332 333 def CheckCorpID(corpID): 334 return corpID in CORP_ICONS 335 336 337 def GetLogoIcon(itemID = None, **kw): 338 if idCheckers.IsAlliance(itemID): 339 logo = Icon(icon=None, **kw) 340 sm.GetService('photo').GetAllianceLogo(itemID, 128, logo) 341 return logo 342 elif not idCheckers.IsCorporation(itemID) or CheckCorpID(itemID): 343 return LogoIcon(itemID=itemID, **kw) 344 else: 345 return CorpIcon(corpID=itemID, **kw) 346 347 348 def GetOwnerLogo(parent, ownerID, size = 64, noServerCall = False, callback = False, orderIfMissing = True, **kwargs): 349 if idCheckers.IsCharacter(ownerID) or idCheckers.IsAlliance(ownerID): 350 logo = Icon(icon=None, parent=parent, width=size, height=size, ignoreSize=True, **kwargs) 351 if idCheckers.IsAlliance(ownerID): 352 path = sm.GetService('photo').GetAllianceLogo(ownerID, 128, logo, callback=callback, orderIfMissing=orderIfMissing) 353 else: 354 path = sm.GetService('photo').GetPortrait(ownerID, size, logo, callback=callback, orderIfMissing=orderIfMissing) 355 return path is not None 356 if idCheckers.IsCorporation(ownerID) or idCheckers.IsFaction(ownerID): 357 GetLogoIcon(itemID=ownerID, parent=parent, width=size, height=size, ignoreSize=True, **kwargs) 358 else: 359 raise RuntimeError('ownerID %d is not of an owner type!!' % ownerID) 360 return True 361 362 363 class OwnerIcon(Container): 364 default_name = 'OwnerIcon' 365 default_align = uiconst.TOPLEFT 366 default_state = uiconst.UI_NORMAL 367 default_size = 128 368 default_isSmall = False 369 default_spriteEffect = None 370 default_textureSecondaryPath = None 371 isDragObject = True 372 373 def ApplyAttributes(self, attributes): 374 Container.ApplyAttributes(self, attributes) 375 self.ownerID = attributes.ownerID 376 self.size = attributes.get('size', self.default_size) 377 self.isSmall = attributes.get('isSmall', self.default_isSmall) 378 self.spriteEffect = attributes.get('spriteEffect', self.default_spriteEffect) 379 self.textureSecondaryPath = attributes.get('textureSecondaryPath', self.default_textureSecondaryPath) 380 if self.ownerID: 381 self.icon = self.ConstructIcon() 382 383 def ConstructIcon(self): 384 self.Flush() 385 icon = self._ConstructIcon() 386 icon.align = uiconst.TOALL 387 icon.width = icon.height = 0 388 icon.state = uiconst.UI_DISABLED 389 if self.textureSecondaryPath: 390 icon.SetSecondaryTexturePath(self.textureSecondaryPath) 391 if self.spriteEffect: 392 icon.spriteEffect = self.spriteEffect 393 return icon 394 395 def _ConstructIcon(self): 396 if idCheckers.IsCharacter(self.ownerID) or idCheckers.IsAlliance(self.ownerID): 397 icon = Icon(icon=None, parent=self, ignoreSize=True) 398 if idCheckers.IsAlliance(self.ownerID): 399 sm.GetService('photo').GetAllianceLogo(self.ownerID, 128, icon, orderIfMissing=True) 400 else: 401 sm.GetService('photo').GetPortrait(self.ownerID, self.size, icon, orderIfMissing=True) 402 elif idCheckers.IsCorporation(self.ownerID) or idCheckers.IsFaction(self.ownerID): 403 icon = GetLogoIcon(itemID=self.ownerID, parent=self, ignoreSize=True, isSmall=self.isSmall) 404 else: 405 raise RuntimeError('ownerID %d is not of an owner type!!' % self.ownerID) 406 return icon 407 408 def GetMenu(self): 409 return sm.GetService('menu').GetMenuForOwner(self.ownerID) 410 411 def SetOwnerID(self, ownerID): 412 self.ownerID = ownerID 413 self.icon = self.ConstructIcon() 414 415 def OnClick(self): 416 PlaySound(uiconst.SOUND_BUTTON_CLICK) 417 typeID = cfg.eveowners.Get(self.ownerID).typeID 418 sm.GetService('info').ShowInfo(typeID, self.ownerID) 419 420 def GetHint(self): 421 if self.hint: 422 return self.hint 423 if self.ownerID: 424 return cfg.eveowners.Get(self.ownerID).ownerName 425 426 def OnMouseEnter(self, *args): 427 PlaySound(uiconst.SOUND_BUTTON_HOVER) 428 animations.FadeTo(self, self.opacity, 1.5, duration=0.3) 429 430 def OnMouseExit(self, *args): 431 animations.FadeTo(self, self.opacity, 1.0, duration=0.3) 432 433 def GetDragData(self): 434 dragData = Bunch() 435 dragData.__guid__ = 'listentry.User' 436 dragData.itemID = self.ownerID 437 dragData.charID = self.ownerID 438 dragData.info = Bunch(typeID=self.GetTypeID(), name=cfg.eveowners.Get(self.ownerID).name) 439 return [dragData] 440 441 def GetTypeID(self): 442 if idCheckers.IsCharacter(self.ownerID): 443 return appConst.typeCharacter 444 if idCheckers.IsAlliance(self.ownerID): 445 return appConst.typeAlliance 446 if idCheckers.IsCorporation(self.ownerID): 447 return appConst.typeCorporation 448 if idCheckers.IsFaction(self.ownerID): 449 return appConst.typeFaction 450 451 452 class PreviewIcon(Icon): 453 __guid__ = 'uicls.PreviewIcon' 454 default_size = 16 455 default_typeID = None 456 457 def ApplyAttributes(self, attributes): 458 typeID = attributes.get('typeID', self.default_typeID) 459 icon = 'ui_38_16_89' 460 attributes['icon'] = icon 461 Icon.ApplyAttributes(self, attributes) 462 self.OnClick = (self.Preview, typeID) 463 464 def Preview(self, typeID, *args): 465 sm.GetService('preview').PreviewType(typeID) 466 467 468 class MenuIcon(Icon): 469 __guid__ = 'uicontrols.MenuIcon' 470 default_size = 16 471 472 def ApplyAttributes(self, attributes): 473 size = attributes.get('size', self.default_size) 474 if size <= 16: 475 icon = 'ui_73_16_50' 476 else: 477 icon = 'ui_77_32_49' 478 attributes['icon'] = icon 479 Icon.ApplyAttributes(self, attributes) 480 self.SetAlpha(0.8) 481 self.expandOnLeft = 1 482 483 def OnMouseEnter(self, *args): 484 PlaySound(uiconst.SOUND_BUTTON_HOVER) 485 self.SetAlpha(1.0) 486 487 def OnMouseExit(self, *args): 488 self.SetAlpha(0.8) 489 490 491 def GetIconSize(sheetNum): 492 sheetNum = int(sheetNum) 493 one = [90, 494 91, 495 92, 496 93] 497 two = [17, 498 18, 499 19, 500 28, 501 29, 502 32, 503 33, 504 59, 505 60, 506 61, 507 65, 508 66, 509 67, 510 80, 511 85, 512 86, 513 87, 514 88, 515 89, 516 102, 517 103, 518 104] 519 eight = [22, 520 44, 521 75, 522 77, 523 105, 524 112] 525 sixteen = [38, 73] 526 if sheetNum in one: 527 return 256 528 if sheetNum in two: 529 return 128 530 if sheetNum in eight: 531 return 32 532 if sheetNum in sixteen: 533 return 16 534 return 64 535 536 537 class OwnerIconAndLabel(ContainerAutoSize): 538 default_name = 'OwnerIconAndLabel' 539 default_state = uiconst.UI_NORMAL 540 541 def ApplyAttributes(self, attributes): 542 ContainerAutoSize.ApplyAttributes(self, attributes) 543 ownerID = attributes.ownerID 544 iconSize = attributes.iconSize 545 iconAlign = attributes.iconAlign 546 text = attributes.get('text', cfg.eveowners.Get(ownerID).ownerName) 547 iconCont = Container(parent=self, align=iconAlign, pos=(0, 548 0, 549 iconSize, 550 iconSize)) 551 self.ownerIcon = OwnerIcon(parent=iconCont, state=uiconst.UI_DISABLED, ownerID=ownerID, size=iconSize, align=uiconst.TOALL) 552 labelContainer = ContainerAutoSize(parent=self, align=iconAlign, left=5) 553 EveLabelMedium(name='fromStandingOwnerLabel', parent=labelContainer, align=uiconst.CENTERLEFT, text=text) 554 555 def GetHint(self): 556 return self.ownerIcon.GetHint() 557 558 def OnClick(self, *args): 559 self.ownerIcon.OnClick() 560 561 def GetMenu(self): 562 return self.ownerIcon.GetMenu() 563 564 def OnMouseEnter(self, *args): 565 animations.FadeTo(self, self.opacity, 1.5, duration=0.3) 566 567 def OnMouseExit(self, *args): 568 animations.FadeTo(self, self.opacity, 1.0, duration=0.3)