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

sequenceBinderPanel.py (13035B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\cosmetics\ship\pages\sequence\sequenceBinderPanel.py
      2 import logging
      3 from carbonui import Align, PickState, uiconst
      4 from carbonui.primitives.container import Container
      5 from carbonui.primitives.containerAutoSize import ContainerAutoSize
      6 from carbonui.primitives.sprite import Sprite
      7 from carbonui.uianimations import animations
      8 from carbonui.uiconst import OutputMode
      9 from cosmetics.client.shipSkinComponentSvc import get_ship_skin_component_svc
     10 from cosmetics.client.shipSkinSequencingSvc import get_ship_skin_sequencing_svc
     11 from cosmetics.client.ships import ship_skin_signals
     12 from cosmetics.client.ships.skins.live_data import current_skin_design, current_skin_design_signals
     13 from cosmetics.common.cosmeticsConst import SEQUENCE_BINDER_TYPES
     14 from cosmetics.common.ships.skins.static_data.slot import SlotsDataLoader
     15 from cosmetics.common.ships.skins.static_data.slot_configuration import SlotConfigurationsDataLoader
     16 from cosmetics.common.ships.skins.static_data.slot_name import SlotID, PATTERN_RELATED_SLOT_IDS
     17 from eve.client.script.ui import eveThemeColor
     18 from player_messaging.client.ui_message import message_player
     19 from eve.client.script.ui.cosmetics.ship.pages.sequence import sequence_ui_signals
     20 from eve.client.script.ui.cosmetics.ship.pages.sequence.sequenceBinderEntries import SequenceBinderCostEntryCompact
     21 from eve.client.script.ui.cosmetics.ship.pages.studio.cosmeticSlot import CosmeticSlot
     22 from eve.client.script.ui.cosmetics.ship.pages.studio.licenseSelector import LicenseSelector
     23 from eve.common.lib import appConst
     24 from localization import GetByLabel
     25 from publicGateway.grpc.exceptions import GenericException
     26 from stackless_response_router.exceptions import TimeoutException
     27 log = logging.getLogger(__name__)
     28 LINE_TEXTURES_BY_SLOT_ID_TYPE_ID = {SlotID.PRIMARY_NANOCOATING: {appConst.typeFermionic: ('res:/UI/Texture/classes/Cosmetics/Ship/sequencing/lines/left_1_ferm.png', (-20, 63, 45, 72)),
     29                               appConst.typeKerr: ('res:/UI/Texture/classes/Cosmetics/Ship/sequencing/lines/left_1_kerr.png', (-20, 60, 45, 170))},
     30  SlotID.SECONDARY_NANOCOATING: {appConst.typeFermionic: ('res:/UI/Texture/classes/Cosmetics/Ship/sequencing/lines/left_2_ferm.png', (-20, 21, 45, 44)),
     31                                 appConst.typeKerr: ('res:/UI/Texture/classes/Cosmetics/Ship/sequencing/lines/left_2_kerr.png', (-20, 60, 45, 58))},
     32  SlotID.TERTIARY_NANOCOATING: {appConst.typeFermionic: ('res:/UI/Texture/classes/Cosmetics/Ship/sequencing/lines/left_3_ferm.png', (-20, -91, 45, 156)),
     33                                appConst.typeKerr: ('res:/UI/Texture/classes/Cosmetics/Ship/sequencing/lines/left_3_kerr.png', (-20, 4, 45, 58))},
     34  SlotID.TECH_AREA: {appConst.typeFermionic: ('res:/UI/Texture/classes/Cosmetics/Ship/sequencing/lines/left_4_ferm.png', (-20, -203, 45, 268)),
     35                     appConst.typeKerr: ('res:/UI/Texture/classes/Cosmetics/Ship/sequencing/lines/left_4_kerr.png', (-20, -108, 45, 170))},
     36  SlotID.PATTERN_MATERIAL: {appConst.typeFermionic: ('res:/UI/Texture/classes/Cosmetics/Ship/sequencing/lines/right_1_ferm.png', (-20, 90, 57, 17)),
     37                            appConst.typeKerr: ('res:/UI/Texture/classes/Cosmetics/Ship/sequencing/lines/right_1_kerr.png', (-20, 65, 45, 140))},
     38  SlotID.SECONDARY_PATTERN_MATERIAL: {appConst.typeFermionic: ('res:/UI/Texture/classes/Cosmetics/Ship/sequencing/lines/right_2_ferm.png', (-20, 19, 53, 28)),
     39                                      appConst.typeKerr: ('res:/UI/Texture/classes/Cosmetics/Ship/sequencing/lines/right_2_kerr.png', (-20, 90, 57, 31))},
     40  SlotID.PATTERN: {appConst.typeAlignment: ('res:/UI/Texture/classes/Cosmetics/Ship/sequencing/lines/right_3_align.png', (-20, 87, 56, 26))},
     41  SlotID.SECONDARY_PATTERN: {appConst.typeAlignment: ('res:/UI/Texture/classes/Cosmetics/Ship/sequencing/lines/right_4_align.png', (-20, 24, 55, 20))}}
     42 
     43 class SequenceBinderPanel(ContainerAutoSize):
     44     is_loaded = False
     45 
     46     def __init__(self, **kw):
     47         super(SequenceBinderPanel, self).__init__(**kw)
     48         self.cost_entries = []
     49 
     50     def load_panel(self):
     51         if not self.is_loaded:
     52             self.is_loaded = True
     53             self.construct_layout()
     54             self.connect_signals()
     55         self.reconstruct_slots()
     56         self.update_values()
     57         self.anim_entry()
     58 
     59     def anim_entry(self):
     60         self.opacity = 0.0
     61         animations.MorphScalar(self, 'left', -200, 0, duration=0.6)
     62         animations.FadeTo(self, 0.0, 1.0, duration=0.3, timeOffset=0.6)
     63 
     64     def connect_signals(self):
     65         sequence_ui_signals.on_num_skins_changed.connect(self.on_num_skins_changed)
     66         current_skin_design_signals.on_component_instance_license_to_use_changed.connect(self.on_component_instance_license_to_use_changed)
     67         current_skin_design_signals.on_slot_fitting_changed.connect(self.on_slot_fitting_changed)
     68         ship_skin_signals.on_component_license_granted.connect(self.on_component_license_granted)
     69 
     70     def disconnect_signals(self):
     71         sequence_ui_signals.on_num_skins_changed.disconnect(self.on_num_skins_changed)
     72         current_skin_design_signals.on_component_instance_license_to_use_changed.disconnect(self.on_component_instance_license_to_use_changed)
     73         current_skin_design_signals.on_slot_fitting_changed.disconnect(self.on_slot_fitting_changed)
     74         ship_skin_signals.on_component_license_granted.disconnect(self.on_component_license_granted)
     75 
     76     def on_slot_fitting_changed(self, *args):
     77         self.reconstruct_slots()
     78         self.update_values()
     79 
     80     def on_component_instance_license_to_use_changed(self, component_id, license):
     81         self.update_values()
     82 
     83     def on_component_license_granted(self, *args):
     84         self.reconstruct_slots()
     85         self.update_values()
     86 
     87     def Close(self):
     88         try:
     89             self.disconnect_signals()
     90         finally:
     91             super(SequenceBinderPanel, self).Close()
     92 
     93     def on_num_skins_changed(self, num_skins):
     94         self.update_values()
     95 
     96     def update_values(self):
     97         num_runs = get_ship_skin_sequencing_svc().get_num_runs()
     98         amount_by_type = current_skin_design.get().get_sequence_binder_amounts_required(num_runs)
     99         for entry in self.cost_entries:
    100             entry.update(amount_by_type[entry.type_id])
    101 
    102     def construct_layout(self):
    103         self.content = ContainerAutoSize(name='content', parent=self, align=Align.CENTERLEFT, height=512, top=64)
    104         self.left_cont = ContainerAutoSize(name='left_cont', parent=self.content, align=Align.TOLEFT)
    105         self.center_cont = Container(name='center_cont', parent=self.content, align=Align.TOLEFT, pickState=PickState.ON, width=100, top=64)
    106         self.right_cont = ContainerAutoSize(name='right_cont', parent=self.content, align=Align.TOLEFT)
    107         self.construct_center_cont()
    108 
    109     def reconstruct_slots(self):
    110         self.left_cont.Flush()
    111         self.right_cont.Flush()
    112         slot_config = SlotConfigurationsDataLoader.get_for_ship(current_skin_design.get().ship_type_id)
    113         y_offset_left = 118
    114         k_offset_right = 34
    115         y_offset_right = 94
    116         for slot_id in slot_config.slots:
    117             if slot_id == SlotID.PRIMARY_NANOCOATING:
    118                 SlotCostEntry(parent=self.left_cont, slot_id=slot_id, top=0, align=Align.TOPRIGHT, alignMode=Align.CENTERRIGHT)
    119             elif slot_id == SlotID.SECONDARY_NANOCOATING:
    120                 SlotCostEntry(parent=self.left_cont, slot_id=slot_id, top=y_offset_left, align=Align.TOPRIGHT, alignMode=Align.CENTERRIGHT)
    121             elif slot_id == SlotID.TERTIARY_NANOCOATING:
    122                 SlotCostEntry(parent=self.left_cont, slot_id=slot_id, align=Align.TOPRIGHT, top=2 * y_offset_left, alignMode=Align.CENTERRIGHT)
    123             elif slot_id == SlotID.TECH_AREA:
    124                 SlotCostEntry(parent=self.left_cont, slot_id=slot_id, align=Align.TOPRIGHT, top=3 * y_offset_left, alignMode=Align.CENTERRIGHT)
    125             elif slot_id == SlotID.PATTERN_MATERIAL:
    126                 SlotCostEntry(parent=self.right_cont, slot_id=slot_id, align=Align.TOPLEFT, top=k_offset_right, alignMode=Align.CENTERLEFT)
    127             elif slot_id == SlotID.SECONDARY_PATTERN_MATERIAL:
    128                 SlotCostEntry(parent=self.right_cont, slot_id=slot_id, align=Align.TOPLEFT, top=k_offset_right + y_offset_right, alignMode=Align.CENTERLEFT)
    129             elif slot_id == SlotID.PATTERN:
    130                 SlotCostEntry(parent=self.right_cont, slot_id=slot_id, align=Align.TOPLEFT, top=k_offset_right + 2 * y_offset_right, alignMode=Align.CENTERLEFT)
    131             elif slot_id == SlotID.SECONDARY_PATTERN:
    132                 SlotCostEntry(parent=self.right_cont, slot_id=slot_id, align=Align.TOPLEFT, top=k_offset_right + 3 * y_offset_right, alignMode=Align.CENTERLEFT)
    133 
    134     def construct_center_cont(self):
    135         for i, type_id in enumerate(SEQUENCE_BINDER_TYPES):
    136             cost_entry = SequenceBinderCostEntryCompact(parent=self.center_cont, type_id=type_id, align=Align.CENTERTOP, pickState=PickState.ON, top=45 + i * 97)
    137             self.cost_entries.append(cost_entry)
    138 
    139 
    140 class SlotCostEntry(ContainerAutoSize):
    141     default_state = uiconst.UI_PICKCHILDREN
    142 
    143     def __init__(self, slot_id, **kw):
    144         super(SlotCostEntry, self).__init__(**kw)
    145         self.slot_id = slot_id
    146         self.line = None
    147         self.component = current_skin_design.get().slot_layout.get_component(self.slot_id)
    148         if self.component:
    149             svc = get_ship_skin_component_svc()
    150             component_data = self.component.get_component_data()
    151             try:
    152                 self.bound_license = svc.get_bound_license(self.component.component_id, component_data.category)
    153                 self.unbound_license = svc.get_unbound_license(self.component.component_id, component_data.category)
    154             except (GenericException, TimeoutException):
    155                 message_player(GetByLabel('UI/Common/CannotConnectToServer'))
    156                 self.bound_license = self.unbound_license = None
    157 
    158         else:
    159             self.opacity = 0.35
    160             self.bound_license = self.unbound_license = None
    161         self.construct_layout()
    162         self.connect_signals()
    163 
    164     def Close(self):
    165         try:
    166             self.disconnect_signals()
    167         finally:
    168             super(SlotCostEntry, self).Close()
    169 
    170     def connect_signals(self):
    171         current_skin_design_signals.on_component_instance_license_to_use_changed.connect(self.on_component_instance_license_to_use_changed)
    172         sequence_ui_signals.on_component_license_selection_changed.connect(self.on_component_license_selection_changed)
    173 
    174     def disconnect_signals(self):
    175         current_skin_design_signals.on_component_instance_license_to_use_changed.disconnect(self.on_component_instance_license_to_use_changed)
    176         sequence_ui_signals.on_component_license_selection_changed.disconnect(self.on_component_license_selection_changed)
    177 
    178     def on_component_license_selection_changed(self):
    179         self.reconstruct_line()
    180 
    181     def on_component_instance_license_to_use_changed(self, component_id, license):
    182         if self.component and self.component.component_id == component_id:
    183             self.reconstruct_line()
    184 
    185     def construct_layout(self):
    186         slot_data = SlotsDataLoader.get_slot_data(self.slot_id)
    187         self.slot = SequenceStepCosmeticSlot(name='slot_{name}'.format(name=slot_data.internal_name), parent=self, slot_data=slot_data, component=self.component, align=self.alignMode, selectable=False)
    188         LicenseSelector(name='license_selector', parent=self, align=self.alignMode, component_instance=self.component, left=108)
    189         if self.component:
    190             self.reconstruct_line()
    191 
    192     def reconstruct_line(self):
    193         if self.line:
    194             self.line.Close()
    195         if not self.component or not self.component.sequence_binder_amount_required:
    196             return
    197         pos, texturePath = self._get_line_texture_path_and_position()
    198         align = Align.TOPLEFT if self.slot_id in PATTERN_RELATED_SLOT_IDS else Align.TOPRIGHT
    199         self.line = Sprite(name='line', parent=self, align=align, pos=pos, texturePath=texturePath, outputMode=OutputMode.COLOR_AND_GLOW, glowBrightness=0.75, color=eveThemeColor.THEME_ACCENT, pickState=PickState.ON)
    200 
    201     def _get_line_texture_path_and_position(self):
    202         try:
    203             texturePath, pos = LINE_TEXTURES_BY_SLOT_ID_TYPE_ID[self.slot_id][self.component.sequence_binder_type_id]
    204         except KeyError:
    205             log.exception('Line texture not found: slot_id: {}, component_id: {}, sequence_binder_type_id: {}'.format(self.slot_id, self.component.component_id, self.component.sequence_binder_type_id))
    206             texturePath = None
    207             pos = (0, 0, 0, 0)
    208 
    209         return (pos, texturePath)
    210 
    211 
    212 class SequenceStepCosmeticSlot(CosmeticSlot):
    213     default_height = 128
    214     default_width = 128
    215 
    216     def _update_state_side_frame(self, animate):
    217         self.side_frame.display = False
    218 
    219     def construct_license_selector(self):
    220         self.license_selector = None