skinListingCard.py (15457B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\cosmetics\ship\pages\cards\skinListingCard.py 2 import eveformat 3 import eveicon 4 import evetypes 5 import uthread2 6 from carbon.common.script.util.format import FmtAmt 7 from carbonui import Align, PickState, TextColor, uiconst 8 from carbonui.text.styles import TextBody, TextDetail 9 from carbonui.control.contextMenu.menuData import MenuData 10 from carbonui.primitives.container import Container 11 from carbonui.primitives.containerAutoSize import ContainerAutoSize 12 from carbonui.primitives.sprite import Sprite 13 from carbonui.uianimations import animations 14 from cosmetics.client.ships.qa.menus import is_qa, get_qa_menu_for_skin_listing_card 15 from cosmetics.client.ships.ship_skin_signals import on_skin_listing_expired 16 from cosmetics.client.shipSkinTradingSvc import get_ship_skin_trading_svc 17 from cosmetics.common.ships.skins.util import Currency 18 from eve.client.script.ui import eveColor 19 from eve.client.script.ui.control.eveIcon import GetLogoIcon 20 from eve.client.script.ui.control.itemIcon import ItemIcon 21 from eve.client.script.ui.cosmetics.ship.pages.cards import cardConst 22 from eve.client.script.ui.cosmetics.ship.pages.cards.cardConst import CardBackground, CardOutline, CardMask 23 from eve.client.script.ui.cosmetics.ship.pages.cards.baseSkinCard import SkinCard 24 from eve.client.script.ui.cosmetics.ship.pages.store import storeSignals 25 from eve.client.script.ui.cosmetics.ship.pages.store.skinListingDragData import SkinListingDragData 26 from eveservices.menu import GetMenuService 27 from inventorycommon.const import typeLoyaltyPointsHeraldry 28 from localization import GetByLabel 29 _EXPIRED_CONTENT_OPACITY = 0.5 30 31 class SkinListingCard(SkinCard): 32 default_height = cardConst.card_height + 16 33 isDragObject = True 34 35 def __init__(self, listing, *args, **kwargs): 36 self.listing = listing 37 self.name = str(self.listing.identifier) 38 self._expired = self.listing.is_expired 39 self._buyer_fee_amount = None 40 self._update_label_thread = None 41 self._update_buyer_fee_amount_thread = None 42 super(SkinListingCard, self).__init__(*args, **kwargs) 43 self._update_label_thread = uthread2.start_tasklet(self.update_remaining_time_label_thread) 44 if self._expired: 45 self._set_expired(animate=False) 46 self.connect_signals() 47 48 def Close(self): 49 try: 50 self.disconnect_signals() 51 self.kill_update_label_thread() 52 self.kill_update_buyer_fee_amount_thread() 53 finally: 54 super(SkinListingCard, self).Close() 55 56 def kill_update_label_thread(self): 57 if self._update_label_thread: 58 self._update_label_thread.kill() 59 60 def kill_update_buyer_fee_amount_thread(self): 61 if self._update_buyer_fee_amount_thread: 62 self._update_buyer_fee_amount_thread.kill() 63 64 def disconnect_signals(self): 65 on_skin_listing_expired.disconnect(self._on_skin_listing_expired) 66 67 def connect_signals(self): 68 on_skin_listing_expired.connect(self._on_skin_listing_expired) 69 70 def construct_layout(self): 71 self.construct_character_targeted_cross() 72 self.construct_cost_container() 73 self.construct_remaining_time_label() 74 self.construct_buyer_fee() 75 self.construct_seller_character_name() 76 if self.listing.is_targeted_at_any_organization and self.listing.branded: 77 self.update_buyer_fee_amount_async() 78 super(SkinListingCard, self).construct_layout() 79 80 def get_live_rendered_icon_skin_design(self): 81 return self.listing.skin_design 82 83 def construct_outline(self): 84 super(SkinListingCard, self).construct_outline() 85 if self.listing.branded: 86 self.construct_branded_logo() 87 88 def construct_branded_logo(self): 89 branded_logo_container = Container(name='branded_logo_container', parent=self.content, align=Align.TOPLEFT, pos=(8, 10, 40, 40)) 90 icon = GetLogoIcon(name='icon', parent=branded_logo_container, align=Align.CENTER, state=uiconst.UI_NORMAL, itemID=self.listing.target.target_id, pos=(0, 0, 32, 32)) 91 icon.OnClick = self.on_icon_click 92 93 def on_icon_click(self, *args): 94 sm.GetService('info').ShowInfo(typeID=cfg.eveowners.Get(self.listing.target.target_id).typeID, itemID=self.listing.target.target_id) 95 96 def construct_character_targeted_cross(self): 97 self.character_targeted_cross = Sprite(name='character_targeted_cross', parent=self, align=Align.CENTER, pickState=PickState.OFF, texturePath='res:/UI/Texture/classes/Cosmetics/Ship/cards/listing/targeted_character_cross.png', color=eveColor.WHITE, opacity=0.1, pos=(0, -29, 162, 136), display=False) 98 99 def construct_cost_container(self): 100 self.cost_cont = ContainerAutoSize(name='const_cont', parent=self, align=Align.CENTERBOTTOM, opacity=0.5, top=58, pickState=PickState.OFF) 101 self.cost_icon = Sprite(parent=self.cost_cont, align=Align.CENTERLEFT, pos=(0, 0, 16, 16)) 102 self.cost_label = TextBody(parent=self.cost_cont, align=Align.CENTERLEFT, left=20) 103 104 def construct_remaining_time_label(self): 105 self.time_remaining_container = Container(name='time_remaining_container', parent=self, align=Align.TOBOTTOM, opacity=0.0, width=self.default_width, height=16, padLeft=10, padRight=10) 106 self.remaining_time_label = TextDetail(name='remaining_time_label', parent=self.time_remaining_container, align=Align.CENTERLEFT, color=TextColor.SECONDARY, maxLines=1, autoFadeSides=16) 107 108 def construct_buyer_fee(self): 109 self.buyer_fee_container = ContainerAutoSize(name='buyer_fee_container', parent=self, align=Align.CENTERBOTTOM, pickState=PickState.OFF, height=20, opacity=0.0, top=58) 110 ItemIcon(name='evermarks_icon', parent=self.buyer_fee_container, align=Align.CENTERLEFT, width=20, height=20, typeID=typeLoyaltyPointsHeraldry) 111 self.buyer_fee_label = TextBody(name='buyer_fee_label', parent=self.buyer_fee_container, align=Align.CENTERLEFT, color=eveColor.SUCCESS_GREEN, left=24) 112 113 def construct_seller_character_name(self): 114 container_width = cardConst.card_width - 60 115 self.seller_character_container = Container(name='seller_character_container', parent=self, align=Align.CENTERBOTTOM, pickState=PickState.OFF, width=container_width, height=20, opacity=0.0, top=58) 116 text = self.seller_character_text 117 text_width, _ = TextBody.MeasureTextSize(text) if text else (0, 0) 118 self.seller_character_label = TextBody(name='seller_character_label', parent=self.seller_character_container, align=Align.CENTER if text_width < container_width else Align.TOLEFT, text=text, maxLines=1, color=eveColor.FOCUS_BLUE, autoFadeSides=10) 119 120 def update(self): 121 super(SkinListingCard, self).update() 122 self.update_character_targeted_cross() 123 self.update_cost() 124 self.update_time_remaining_container() 125 self.update_buyer_fee() 126 self.update_targeted_character_name() 127 128 def update_character_targeted_cross(self): 129 self.character_targeted_cross.display = self.listing.is_targeted_at_any_character 130 target_opacity = 0.5 if self.is_hovered or self.is_selected else 0.1 131 animations.FadeTo(self.character_targeted_cross, self.character_targeted_cross.opacity, target_opacity, self.ANIM_DURATION) 132 133 def update_cost(self): 134 self._update_cost_label() 135 target_opacity = 1.0 if self.is_hovered or self.is_selected else 0.5 136 animations.FadeTo(self.cost_cont, self.cost_cont.opacity, target_opacity, self.ANIM_DURATION) 137 if self._buyer_fee_amount is not None or self.listing.is_targeted_at_any_character: 138 target_top = 78 if self.is_hovered or self.is_selected else 58 139 animations.MorphScalar(self.cost_cont, 'top', self.cost_cont.top, target_top, self.ANIM_DURATION) 140 141 def _update_cost_label(self): 142 if self._expired: 143 self.cost_label.text = GetByLabel('UI/Personalization/ShipSkins/SKINR/Store/ListingExpired') 144 self.cost_label.left = 0 145 self.cost_icon.display = False 146 else: 147 self.cost_label.text = eveformat.number(self.listing.price) 148 self.cost_label.left = 20 149 self.cost_icon.display = True 150 if self.listing.currency == Currency.PLEX: 151 self.cost_icon.texturePath = eveicon.plex 152 self.cost_icon.color = eveColor.PLEX_YELLOW 153 else: 154 self.cost_icon.texturePath = eveicon.isk 155 self.cost_icon.color = eveColor.WHITE 156 157 def update_time_remaining_container(self): 158 target_opacity = 1.0 if self.is_hovered or self.is_selected else 0.0 159 animations.FadeTo(self.time_remaining_container, self.time_remaining_container.opacity, target_opacity, self.ANIM_DURATION) 160 161 def update_buyer_fee(self): 162 if self._buyer_fee_amount is None: 163 self.buyer_fee_label.text = None 164 self.buyer_fee_container.opacity = 0.0 165 else: 166 self.buyer_fee_label.text = FmtAmt(self._buyer_fee_amount) 167 target_opacity = 1.0 if self.is_hovered or self.is_selected else 0.0 168 animations.FadeTo(self.buyer_fee_container, self.buyer_fee_container.opacity, target_opacity, self.ANIM_DURATION) 169 170 def update_targeted_character_name(self): 171 if not self.listing.is_targeted_at_any_character: 172 return 173 target_opacity = 1.0 if self.is_hovered or self.is_selected else 0.0 174 animations.FadeTo(self.seller_character_container, self.seller_character_container.opacity, target_opacity, self.ANIM_DURATION) 175 176 def update_buyer_fee_amount_async(self): 177 self.kill_update_buyer_fee_amount_thread() 178 uthread2.start_tasklet(self.update_buyer_fee_amount) 179 180 def update_buyer_fee_amount(self): 181 self._buyer_fee_amount = self.get_buyer_fee_amount() 182 183 def update_stack_lines(self): 184 if not self.is_stack: 185 return 186 self.stack_lines_container.display = True 187 target_opacity = 1.0 if self.is_hovered or self.is_selected else 0.5 188 animations.FadeTo(self.stack_lines_container, self.stack_lines_container.opacity, target_opacity, self.ANIM_DURATION) 189 190 def update_stack_numbers(self): 191 self.stack_numbers_container.display = self.is_stack 192 self.stack_numbers_label.text = self.listing.quantity if self.is_stack else None 193 194 def get_top_line_color(self): 195 if self.listing.branded: 196 if self.is_selected: 197 return eveColor.SUCCESS_GREEN 198 return eveColor.WHITE 199 return super(SkinListingCard, self).get_top_line_color() 200 201 def get_top_line_corner_color(self): 202 if self.listing.branded: 203 if self.is_selected: 204 return eveColor.SUCCESS_GREEN 205 return eveColor.WHITE 206 return super(SkinListingCard, self).get_top_line_corner_color() 207 208 def get_skin_tier_level(self): 209 return self.listing.skin_design.tier_level 210 211 def get_outline_color(self): 212 if self.listing.branded: 213 return eveColor.SUCCESS_GREEN 214 return eveColor.FOCUS_BLUE 215 216 def get_outline_texture(self): 217 if self.listing.is_targeted_at_any_character: 218 if self.is_stack: 219 return CardOutline.TARGETED_AT_CHARACTER_STACK 220 return CardOutline.TARGETED_AT_CHARACTER 221 if self.listing.is_targeted_at_any_organization: 222 if self.is_stack: 223 return CardOutline.TARGETED_AT_ORGANIZATION_STACK 224 return CardOutline.TARGETED_AT_ORGANIZATION 225 if self.is_stack: 226 return CardOutline.PUBLIC_STACK 227 return CardOutline.PUBLIC 228 229 def get_background_texture(self): 230 if self.listing.is_targeted_at_any_character: 231 if self.is_stack: 232 return CardBackground.TARGETED_AT_CHARACTER_STACK 233 return CardBackground.TARGETED_AT_CHARACTER 234 if self.listing.is_targeted_at_any_organization: 235 if self.listing.branded: 236 if self.is_stack: 237 return CardBackground.TARGETED_AT_ORGANIZATION_BRANDED_STACK 238 return CardBackground.TARGETED_AT_ORGANIZATION_BRANDED 239 elif self.is_stack: 240 return CardBackground.TARGETED_AT_ORGANIZATION_STACK 241 else: 242 return CardBackground.TARGETED_AT_ORGANIZATION 243 if self.is_stack: 244 return CardBackground.PUBLIC_STACK 245 return CardBackground.PUBLIC 246 247 def get_mask_texture(self): 248 if self.listing.is_targeted_at_any_character: 249 if self.is_stack: 250 return CardMask.TARGETED_AT_CHARACTER_STACK 251 return CardMask.TARGETED_AT_CHARACTER 252 if self.listing.is_targeted_at_any_organization: 253 if self.is_stack: 254 return CardMask.TARGETED_AT_ORGANIZATION_STACK 255 return CardMask.TARGETED_AT_ORGANIZATION 256 if self.is_stack: 257 return CardMask.PUBLIC_STACK 258 return CardMask.PUBLIC 259 260 def _on_selected(self): 261 storeSignals.on_skin_listing_selected(self.listing, self) 262 263 def OnClick(self, *args): 264 if self.is_selected: 265 return 266 super(SkinListingCard, self).OnClick(*args) 267 268 def get_skin_name(self): 269 return self.listing.name 270 271 def update_remaining_time_label_thread(self): 272 while not self.destroyed: 273 self.remaining_time_label.text = self.listing.time_remaining_text 274 uthread2.Sleep(0.5) 275 276 def _on_skin_listing_expired(self, listing_id): 277 if self.listing and self.listing.identifier == listing_id and not self._expired: 278 self.kill_update_label_thread() 279 self.remaining_time_label.text = None 280 self._set_expired() 281 282 def _set_expired(self, animate = True): 283 self._expired = True 284 self._update_cost_label() 285 if animate: 286 animations.FadeTo(self.content, self.content.opacity, _EXPIRED_CONTENT_OPACITY, self.ANIM_DURATION) 287 else: 288 self.content.opacity = _EXPIRED_CONTENT_OPACITY 289 290 def get_buyer_fee_amount(self): 291 if self.listing is None or self.listing.target is None: 292 return 293 buyer_fee, error = get_ship_skin_trading_svc().get_buyer_fee_for_listing(self.listing) 294 if error: 295 return 296 elif buyer_fee.lp_amount > 0: 297 return buyer_fee.lp_amount 298 else: 299 return 300 301 def GetMenu(self): 302 menu_data = MenuData() 303 type_id = self.listing.skin_design.ship_type_id 304 menu_data.AddEntry(text=evetypes.GetName(type_id), subMenuData=lambda : GetMenuService().GetMenuFromItemIDTypeID(itemID=None, typeID=type_id, includeMarketDetails=True)) 305 if is_qa(): 306 menu_data.AddEntry('QA:', subMenuData=lambda : get_qa_menu_for_skin_listing_card(self, self.listing.identifier)) 307 return menu_data 308 309 def GetDragData(self): 310 return SkinListingDragData(self.listing) 311 312 @property 313 def is_stack(self): 314 return self.listing.quantity > 1 315 316 @property 317 def seller_character_text(self): 318 if not self.listing.is_targeted_at_any_character: 319 return None 320 elif self.listing.seller_id == session.charid: 321 return cfg.eveowners.Get(self.listing.target.target_id).name 322 else: 323 return cfg.eveowners.Get(self.listing.seller_id).name