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

infoPanelWorldEvents.py (12199B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\infoPanels\infoPanelWorldEvents.py
      2 import blue
      3 import eveicon
      4 import eveui
      5 from carbonui import Align, TextColor
      6 from eve.client.script.ui.shared.infoPanels.InfoPanelBase import InfoPanelBase
      7 from eve.client.script.ui.shared.infoPanels.const.infoPanelConst import PANEL_WORLD_EVENTS
      8 from objectives.client.ui.objective_chain import ObjectiveChainEntry
      9 import eveformat
     10 import localization
     11 from clientsettings.setting import SessionSettingNumeric
     12 from eve.client.script.ui import eveColor, eveThemeColor
     13 from metadata.common.content_tags import get_content_tag_as_object, ContentTags
     14 from carbonui.control.buttonIcon import ButtonIcon
     15 from jobboard.client import get_job_board_service, get_world_event_job, open_world_event
     16 SCROLL_CONTAINER_HEIGHT_MAX = 450
     17 HEADER_BG_COLOR = (0, 0, 0, 0.35)
     18 
     19 class InfoPanelWorldEvents(InfoPanelBase):
     20     default_name = 'InfoPanelWorldEvents'
     21     panelTypeID = PANEL_WORLD_EVENTS
     22     hasSettings = False
     23     label = 'UI/Metadata/ContentTags/WorldEvents'
     24     _scroll_fraction = SessionSettingNumeric(0, 0.0, 1.0)
     25 
     26     @staticmethod
     27     def IsAvailable():
     28         return bool(sm.GetService('tale').get_active_world_event_tales_in_system())
     29 
     30     @classmethod
     31     def GetTexturePath(cls):
     32         return get_content_tag_as_object(ContentTags.feature_world_events).icon
     33 
     34     def __init__(self, **kwargs):
     35         self._entries = {}
     36         self._scroll_initialized = False
     37         self._constructing = True
     38         super(InfoPanelWorldEvents, self).__init__(**kwargs)
     39         self._layout()
     40         self._refresh_entries()
     41         self._update_content_container_scroll_position()
     42 
     43     def ConstructNormal(self):
     44         if self._constructing or self.destroyed:
     45             return
     46         self._refresh_entries()
     47 
     48     @property
     49     def service(self):
     50         return sm.GetService('tale')
     51 
     52     @eveui.skip_if_destroyed
     53     def _refresh_entries(self):
     54         tales = self.service.get_active_world_event_tales_in_system()
     55         tale_ids = set([ tale.tale_id for tale in tales ])
     56         previous_entry_ids = self._entries.keys()
     57         obsolete_entry_ids = list(set(previous_entry_ids) - tale_ids)
     58         for entry_id in obsolete_entry_ids:
     59             if entry_id not in self._entries:
     60                 continue
     61             entry = self._entries[entry_id]
     62             entry.Close()
     63             self._entries[entry_id] = None
     64             self._entries.pop(entry_id)
     65 
     66         for index, tale in enumerate(tales):
     67             if tale.tale_id not in previous_entry_ids:
     68                 self._construct_tale_entry(tale, index)
     69             else:
     70                 self._entries[tale.tale_id].SetOrder(index)
     71 
     72         self._update_content_container_height()
     73 
     74     @eveui.skip_if_destroyed
     75     def _construct_tale_entry(self, tale, index):
     76         entry = TaleInfoPanelEntry(parent=self._content_container, tale=tale, padBottom=4, padTop=4, idx=index, callback=self._update_content_container_height)
     77         self._entries[tale.tale_id] = entry
     78 
     79     def _layout(self):
     80         self._constructing = True
     81         self._title = eveui.EveCaptionSmall(name='title', parent=self.headerCont, align=eveui.Align.center_left, text=localization.GetByLabel(self.label))
     82         self._content_container = eveui.ScrollContainer(name='content_scroll_container', parent=self.mainCont, align=Align.TOTOP, height=0)
     83         self._content_container.OnScrolledVertical = self._on_scroll
     84         self._constructing = False
     85 
     86     def ConstructHeaderButton(self):
     87         container = eveui.Container(parent=self.headerBtnCont, align=eveui.Align.center_right, width=28, height=28)
     88         return ButtonIcon(parent=container, align=eveui.Align.center, iconSize=18, width=18, height=18, texturePath=self.GetTexturePath(), func=self._open_job_board)
     89 
     90     def _open_job_board(self, *args, **kwargs):
     91         get_job_board_service().open_browse_page(content_tag_id=ContentTags.feature_world_events)
     92 
     93     def _update_content_container_height(self):
     94         if not self._content_container or self._content_container.destroyed:
     95             return
     96         totalHeight = self._content_container.mainCont.height
     97         self._content_container.height = min(totalHeight, SCROLL_CONTAINER_HEIGHT_MAX)
     98         self._content_container.clipCont.clipChildren = totalHeight > SCROLL_CONTAINER_HEIGHT_MAX
     99 
    100     def _update_content_container_scroll_position(self):
    101         blue.synchro.Yield()
    102         if not self._content_container or self._content_container.destroyed:
    103             return
    104         self._scroll_initialized = True
    105         self._content_container.ScrollToVertical(self._scroll_fraction.get())
    106 
    107     def _on_scroll(self, pos_fraction):
    108         if self._scroll_initialized:
    109             self._scroll_fraction.set(self._content_container.GetPositionVertical())
    110 
    111 
    112 class TaleInfoPanelEntry(eveui.ContainerAutoSize):
    113     default_align = Align.TOTOP
    114     default_alignMode = Align.TOTOP
    115     default_clipChildren = True
    116 
    117     def __init__(self, tale, *args, **kwargs):
    118         kwargs.setdefault('name', str(tale.tale_id))
    119         super(TaleInfoPanelEntry, self).__init__(*args, **kwargs)
    120         self._tale = tale
    121         self._is_hovered = False
    122         self._objective_chain_entry = None
    123         self._layout()
    124         if self._expanded:
    125             self._expand()
    126         self._update_hover_state()
    127         self._register()
    128         self._on_progress()
    129 
    130     def Close(self):
    131         self._unregister()
    132         if self._objective_chain_entry:
    133             self._objective_chain_entry.Close()
    134             self._objective_chain_entry = None
    135         super(TaleInfoPanelEntry, self).Close()
    136         self.callback = None
    137         self._tale = None
    138 
    139     def _register(self):
    140         self._tale.context.subscribe_to_value('current_progress', self._on_progress)
    141 
    142     def _unregister(self):
    143         self._tale.context.unsubscribe_from_value('current_progress', self._on_progress)
    144 
    145     @property
    146     def _expanded(self):
    147         return self._tale.context.get_value('is_expanded')
    148 
    149     @_expanded.setter
    150     def _expanded(self, value):
    151         self._tale.context.update_value('is_expanded', value)
    152 
    153     @property
    154     def _current_progress(self):
    155         return self._tale.context.get_value('current_progress', 0)
    156 
    157     @property
    158     def _target_progress(self):
    159         return self._tale.context.get_value('target_progress', 0)
    160 
    161     @property
    162     def _progress_percentage(self):
    163         target = self._target_progress
    164         if not target:
    165             return 0
    166         return float(self._current_progress) / target
    167 
    168     @property
    169     def _has_progress(self):
    170         return bool(self._target_progress)
    171 
    172     @property
    173     def _progress_text(self):
    174         target_progress = self._target_progress
    175         if not target_progress:
    176             return ''
    177         elif target_progress >= 100:
    178             return u'{value}%'.format(value=int(self._progress_percentage * 100))
    179         else:
    180             return u'{}/{}'.format(eveformat.number(self._current_progress, 0), eveformat.number(self._target_progress, 0))
    181 
    182     def _on_progress(self, *args, **kwargs):
    183         if not self._tale:
    184             return
    185         text = self._progress_text
    186         if not text:
    187             return
    188         self._progress_label.text = text
    189         eveui.animate(self._progress_fill, 'width', end_value=self._progress_percentage, duration=1)
    190         self._update_progress_color()
    191 
    192     def _layout(self):
    193         self._construct_header()
    194         self._content_container = eveui.ContainerAutoSize(name='content_container', parent=self, align=Align.TOTOP, alignMode=Align.TOTOP)
    195 
    196     def _construct_header(self):
    197         self._header_container = header_container = eveui.ContainerAutoSize(name='header_container', parent=self, state=eveui.State.normal, align=Align.TOTOP, alignMode=Align.TOTOP_NOPUSH, bgColor=HEADER_BG_COLOR)
    198         header_container.OnClick = self.OnClick
    199         header_container.GetMenu = self.GetMenu
    200         wrapper = eveui.ContainerAutoSize(parent=header_container, align=Align.TOTOP_NOPUSH, alignMode=Align.TOTOP, padding=8)
    201         job = get_world_event_job(self._tale.tale_id)
    202         if job:
    203             icon_container = eveui.ContainerAutoSize(parent=wrapper, align=eveui.Align.to_left, padRight=8, width=16)
    204             view_details_button = ButtonIcon(name='view_details_button', parent=icon_container, align=eveui.Align.center, texturePath=job.feature_tag.icon, iconSize=16, width=16, height=16, color=TextColor.NORMAL, func=self._open_tale_details, hint=localization.GetByLabel('UI/Opportunities/ViewOpportunity'))
    205             view_details_button.isDragObject = True
    206             view_details_button.GetDragData = job.get_drag_data
    207         progress_text_container = eveui.ContainerAutoSize(parent=wrapper, state=eveui.State.disabled, align=eveui.Align.to_right, clipChildren=True)
    208         self._progress_label = eveui.EveLabelLarge(parent=progress_text_container, align=eveui.Align.center_right, text=self._progress_text, maxLines=1, padLeft=4)
    209         title_container = eveui.ContainerAutoSize(parent=wrapper, state=eveui.State.disabled, align=Align.TOTOP, clipChildren=True)
    210         self._title = eveui.EveLabelLarge(parent=title_container, align=Align.TOTOP, text=self._tale.title, maxLines=1, showEllipsis=True, color=TextColor.HIGHLIGHT)
    211         progress_fill_container = eveui.Container(name='progress_fill_container', parent=header_container, align=eveui.Align.to_all, clipChildren=True, opacity=0.15)
    212         self._progress_fill = eveui.StretchSpriteHorizontal(parent=progress_fill_container, align=eveui.Align.to_left_prop, texturePath='res:/UI/Texture/classes/InfoPanels/progress_bar_solid.png', color=self._get_progress_color(), leftEdgeSize=2, rightEdgeSize=10, padLeft=-2, padRight=-10, width=self._progress_percentage)
    213 
    214     @eveui.skip_if_destroyed
    215     def _construct_body(self):
    216         if self._objective_chain_entry:
    217             self._objective_chain_entry.Close()
    218             self._objective_chain_entry = None
    219         objective_chain = self._tale.objective_chain
    220         if objective_chain:
    221             self._objective_chain_entry = ObjectiveChainEntry(parent=self._content_container, objective_chain=objective_chain)
    222 
    223     def _reconstruct_body(self):
    224         self._content_container.Flush()
    225         self._construct_body()
    226 
    227     def _expand(self):
    228         self._expanded = True
    229         self._reconstruct_body()
    230         self._update_hover_state()
    231 
    232     def _collapse(self):
    233         self._expanded = False
    234         self._content_container.Flush()
    235         self._update_hover_state()
    236 
    237     def OnClick(self):
    238         if self._expanded:
    239             eveui.Sound.collapse.play()
    240         else:
    241             eveui.Sound.expand.play()
    242         if self._expanded:
    243             self._collapse()
    244         else:
    245             self._expand()
    246 
    247     def GetMenu(self):
    248         return self._tale.get_menu()
    249 
    250     def OnMouseEnter(self, *args):
    251         super(TaleInfoPanelEntry, self).OnMouseEnter(*args)
    252         self._is_hovered = True
    253         self._update_hover_state()
    254 
    255     def OnMouseExit(self, *args):
    256         super(TaleInfoPanelEntry, self).OnMouseEnter(*args)
    257         self._is_hovered = False
    258         self._update_hover_state()
    259 
    260     def _update_hover_state(self):
    261         has_progress = self._has_progress
    262         self._progress_fill.display = has_progress and not self._expanded
    263         self._progress_label.display = has_progress and not self._expanded and not self._is_hovered
    264         if self._expanded or self._is_hovered:
    265             eveui.fade(self._header_container.bgFill, end_value=0.5, duration=0.2)
    266         else:
    267             eveui.fade(self._header_container.bgFill, end_value=HEADER_BG_COLOR[3], duration=0.2)
    268 
    269     def _get_progress_color(self):
    270         if self._progress_percentage < 1:
    271             return eveThemeColor.THEME_FOCUS
    272         else:
    273             return eveColor.SUCCESS_GREEN
    274 
    275     def _update_progress_color(self):
    276         self._progress_fill.color = self._get_progress_color()
    277 
    278     def OnColorThemeChanged(self):
    279         super(TaleInfoPanelEntry, self).OnColorThemeChanged()
    280         self._update_progress_color()
    281 
    282     def _open_tale_details(self, *args, **kwargs):
    283         open_world_event(self._tale.tale_id)