skinsPanel.py (9931B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\neocom\charsheet\skinsPanel.py 2 from functools import partial 3 from collections import Counter 4 import eveicon 5 import localization 6 from carbonui import const as uiconst 7 from carbonui.primitives.container import Container 8 from carbonui.primitives.containerAutoSize import ContainerAutoSize 9 from carbonui.primitives.layoutGrid import LayoutGrid 10 from carbonui.control.buttonIcon import ButtonIcon 11 from eve.client.script.ui.control.entries.item import Item 12 from eve.client.script.ui.control.entries.util import GetFromClass 13 from eve.client.script.ui.control.eveLabel import EveLabelMedium 14 from eve.client.script.ui.control.eveScroll import Scroll 15 from eve.client.script.ui.control.listgroup import ListGroup 16 from eve.client.script.ui.control.utilMenu import UtilMenu 17 from eve.client.script.ui.quickFilter import QuickFilterEdit 18 from eve.client.script.ui.services.menuSvcExtras import menuFunctions 19 from eve.client.script.ui.shared.skins.skinPanel import SkinDurationLabel 20 from cosmetics.client.cosmeticsSvc import FirstPartySkin 21 from inventorycommon.const import typeCapsuleGolden 22 from itertoolsext import bucket, count 23 from menucheckers import ItemChecker 24 from menucheckers.sessionChecker import SessionChecker 25 from shipskins.uiUtil import GroupAndFilterByShip, GetDataForSkinEntry, GetSkinsAndTexturePathsByByMaterialName 26 SETTING_SHOW_SKINS = 'charsheet_skins_showSkins' 27 SHOW_ALL_SKINS = 'all_skins' 28 SHOW_ACTIVE_SKINS = 'active_skins' 29 SHOW_INACTIVE_SKINS = 'inactive_skins' 30 SETTING_DEFAULTS = {SETTING_SHOW_SKINS: SHOW_ALL_SKINS} 31 32 class SkinsPanel(Container): 33 __notifyevents__ = ['OnSkinLicenseActivated', 'OnSkinLicenseRemoved'] 34 default_name = 'SkinsPanel' 35 36 def ApplyAttributes(self, attributes): 37 super(SkinsPanel, self).ApplyAttributes(attributes) 38 sm.RegisterNotify(self) 39 self.isConstructed = False 40 41 def ConstructLayout(self): 42 if self.isConstructed: 43 return 44 self.isConstructed = True 45 menuBar = ContainerAutoSize(parent=self, align=uiconst.TOTOP, padBottom=16, alignMode=uiconst.CENTERLEFT) 46 UtilMenu(parent=menuBar, align=uiconst.CENTERLEFT, GetUtilMenu=self.GetSettingsMenu, texturePath=eveicon.settings, width=24, height=24, iconSize=16) 47 self.filter = QuickFilterEdit(parent=menuBar, align=uiconst.CENTERRIGHT, left=2, width=150, hintText=localization.GetByLabel('UI/Inventory/Filter')) 48 spacer = Container(parent=menuBar, align=uiconst.CENTERLEFT, pos=(0, 49 0, 50 1, 51 self.filter.height)) 52 self.counterText = EveLabelMedium(parent=ContainerAutoSize(parent=menuBar, align=uiconst.TOLEFT, left=30), align=uiconst.CENTERLEFT, text='') 53 self.filter.ReloadFunction = self.LoadPanel 54 self.scroll = Scroll(parent=self, align=uiconst.TOALL) 55 self.scroll.sr.content.OnDropData = self.OnDropData 56 57 @property 58 def filterText(self): 59 return self.filter.GetValue().strip().lower() 60 61 def LoadPanel(self, *args): 62 self.ConstructLayout() 63 self.scroll.Clear() 64 skinsByMaterialID, numLicensedSkinsForShip = self._GetFilteredSkinsByMaterialID() 65 skinsByByMaterialName, texturePathsByName = GetSkinsAndTexturePathsByByMaterialName(skinsByMaterialID, sm.GetService('cosmeticsSvc')) 66 entries = [] 67 for eachName, skins in skinsByByMaterialName.iteritems(): 68 texturePaths = texturePathsByName.get(eachName, []) 69 entry = self._CreateGroupEntryForMaterials(eachName, skins, texturePaths) 70 if entry is not None: 71 entries.append(entry) 72 73 self.counterText.text = localization.GetByLabel('UI/Skins/YouHaveNumShipSkins', numSkins=numLicensedSkinsForShip) 74 self.scroll.Load(contentList=sorted(entries, key=lambda e: e.label), noContentHint=localization.GetByLabel('UI/SkillQueue/NoResultsForFilters')) 75 76 def _GetFilteredSkinsByMaterialID(self): 77 cosmeticsSvc = sm.GetService('cosmeticsSvc') 78 licensedSkinsByID = {s.skinID:s for s in cosmeticsSvc.GetLicensedSkins()} 79 skins = [] 80 for staticSkin in cosmeticsSvc.static.GetAllShipSkins(): 81 licensedSkin = licensedSkinsByID.get(staticSkin.skinID, None) 82 skins.append(self._CreateSkinObject(staticSkin, licensedSkin)) 83 84 allLicensedSkins = filter(lambda s: s.licensed, skins) 85 show = GetSetting(SETTING_SHOW_SKINS) 86 if show == SHOW_ACTIVE_SKINS: 87 skins = allLicensedSkins 88 elif show == SHOW_INACTIVE_SKINS: 89 skins = filter(lambda s: not s.licensed, skins) 90 numLicensedSkinsForShip = 0 91 for skin in allLicensedSkins: 92 numLicensedSkinsForShip += len(skin.types) 93 94 return (bucket(skins, keyprojection=lambda s: s.materialID), numLicensedSkinsForShip) 95 96 def _CreateSkinObject(self, staticSkin, licensedSkin = None): 97 material = sm.GetService('cosmeticsSvc').static.GetMaterialByID(staticSkin.skinMaterialID) 98 licensed = licensedSkin is not None 99 expires = licensedSkin.expires if licensedSkin else None 100 isSingleUse = licensedSkin.isSingleUse if licensedSkin else None 101 return FirstPartySkin(material, skin=staticSkin, licensed=licensed, expires=expires, isSingleUse=isSingleUse) 102 103 def _CreateGroupEntryForMaterials(self, materialName, skins, texturePaths): 104 skinsByShipID = GroupAndFilterByShip(skins, self.filterText) 105 if not skinsByShipID: 106 return 107 skinsByShipID.pop(typeCapsuleGolden, None) 108 textureToUse = None 109 if texturePaths: 110 textureToUse, _ = Counter(texturePaths).most_common()[0] 111 owned = count((ship for ship, skins in skinsByShipID.iteritems() if any((s.licensed for s in skins)))) 112 return GetFromClass(ListGroup, {'label': localization.GetByLabel('UI/CharacterSheet/CharacterSheetWindow/SkinsGroupWithCount', groupName=materialName, skinsOwned=owned, skinsTotal=len(skinsByShipID)), 113 'id': ('SkinMaterials', materialName), 114 'showicon': textureToUse, 115 'groupItems': skinsByShipID, 116 'GetSubContent': self._GetSkinsSubContent, 117 'showlen': False, 118 'BlockOpenWindow': True, 119 'state': 'locked', 120 'DropData': self.OnDropData}) 121 122 def _GetSkinsSubContent(self, nodedata, *args): 123 skinsByShipID = nodedata.groupItems 124 nodes = [] 125 for shipTypeID, skins in skinsByShipID.iteritems(): 126 data = GetDataForSkinEntry(shipTypeID, skins) 127 data['OnDropData'] = self.OnDropData 128 entry = GetFromClass(ShipSkinEntry, data) 129 nodes.append(entry) 130 131 nodes = sorted(nodes, key=lambda x: x.label) 132 return nodes 133 134 def GetSettingsMenu(self, menuParent): 135 menuParent.AddRadioButton(text=localization.GetByLabel('UI/CharacterSheet/CharacterSheetWindow/Skins/ShowAllSkins'), checked=GetSetting(SETTING_SHOW_SKINS) == SHOW_ALL_SKINS, callback=partial(self.SetSettingAndReload, SETTING_SHOW_SKINS, SHOW_ALL_SKINS)) 136 menuParent.AddRadioButton(text=localization.GetByLabel('UI/CharacterSheet/CharacterSheetWindow/Skins/ShowActiveSkins'), checked=GetSetting(SETTING_SHOW_SKINS) == SHOW_ACTIVE_SKINS, callback=partial(self.SetSettingAndReload, SETTING_SHOW_SKINS, SHOW_ACTIVE_SKINS)) 137 menuParent.AddRadioButton(text=localization.GetByLabel('UI/CharacterSheet/CharacterSheetWindow/Skins/ShowInactiveSkins'), checked=GetSetting(SETTING_SHOW_SKINS) == SHOW_INACTIVE_SKINS, callback=partial(self.SetSettingAndReload, SETTING_SHOW_SKINS, SHOW_INACTIVE_SKINS)) 138 139 def SetSettingAndReload(self, key, value): 140 SetSetting(key, value) 141 self.LoadPanel() 142 143 def OnSkinLicenseActivated(self, skinID, licenseeID): 144 if self.display: 145 self.LoadPanel() 146 147 def OnSkinLicenseRemoved(self, skinID, itemID, typeID): 148 if self.display: 149 self.LoadPanel() 150 151 def OnDropData(self, dragObj, nodes): 152 sessionChecker = SessionChecker(session, sm) 153 itemAndTypeIDs = [] 154 for eachNode in nodes: 155 if eachNode.__guid__ not in ('xtriui.InvItem', 'listentry.InvItem', 'listentry.InvAssetItem'): 156 continue 157 rec = eachNode.rec 158 item = ItemChecker(rec, sessionChecker) 159 if item.OfferActivateShipSkinLicense(): 160 itemAndTypeIDs.append((rec.itemID, rec.typeID)) 161 162 if itemAndTypeIDs: 163 menuFunctions.ActivateShipSkinLicense(itemAndTypeIDs) 164 165 166 class ShipSkinEntry(Item): 167 168 def Startup(self, *args): 169 super(ShipSkinEntry, self).Startup(*args) 170 self.previewIcon = ButtonIcon(name='previewIcon', parent=self, align=uiconst.CENTERRIGHT, texturePath='res:/UI/Texture/classes/skins/preview.png', func=self.PreviewSkin) 171 172 def Load(self, node): 173 super(ShipSkinEntry, self).Load(node) 174 self.sr.infoicon.display = False 175 if node.skin.licensed: 176 self.sr.label.opacity = 1 177 else: 178 self.sr.label.opacity = 0.5 179 self.sr.icon.opacity = 0.5 180 if node.skin.licensed: 181 grid = LayoutGrid(parent=self, align=uiconst.CENTERRIGHT, columns=2, left=26) 182 EveLabelMedium(parent=grid, text=localization.GetByLabel('UI/CharacterSheet/CharacterSheetWindow/Skins/Active')) 183 SkinDurationLabel(parent=grid, skin=node.skin) 184 185 def PreviewSkin(self): 186 node = self.sr.node 187 materialID = node.skin.materialID 188 licenses = sm.GetService('cosmeticsSvc').GetLicencesForTypeWithMaterial(node.typeID, materialID) 189 if licenses: 190 typeID = licenses[0] 191 shipTypeID = node.typeID 192 sm.GetService('preview').PreviewType(typeID, otherTypeID=shipTypeID) 193 194 195 def GetSetting(key): 196 return settings.user.ui.Get(key, SETTING_DEFAULTS[key]) 197 198 199 def SetSetting(key, value): 200 settings.user.ui.Set(key, value)