NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

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