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

overview_panel.py (21452B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\theatersOfWar\campaigns\panels\overview_panel.py
      2 import eve.client.script.ui.shared.theatersOfWar.campaigns.panels.panel_const as panel_const
      3 import logging
      4 import uthread2
      5 from achievement_system.client.api.signal import on_achievement_progressed
      6 from campaigns.client.errors import CampaignRequestError
      7 from campaigns.client.settings import campaign_animate_background
      8 from campaigns.client.v1.signals import on_campaign_completed
      9 from carbonui import Align, PickState, TextColor
     10 from carbonui.primitives.container import Container
     11 from carbonui.primitives.containerAutoSize import ContainerAutoSize
     12 from carbonui.primitives.layoutGrid import LayoutGrid
     13 from carbonui.primitives.sprite import Sprite, StreamingVideoSprite
     14 from carbonui.text.custom import TextCustom
     15 from carbonui.text.styles import TextDetail, TextBody, TextHeader
     16 from carbonui.uianimations import animations
     17 from carbonui.uiconst import OUTPUT_COLOR_AND_GLOW, SpriteEffect
     18 from eve.client.script.ui import eveColor
     19 from eve.client.script.ui.shared.theatersOfWar.campaigns.panels.achievement_banner import AchievementBanner
     20 from eve.client.script.ui.shared.theatersOfWar.campaigns.panels.base_scrolling_page import BaseScrollingPage
     21 from eve.client.script.ui.shared.theatersOfWar.campaigns.panels.outcome_panel import OutcomePanel
     22 from eve.client.script.ui.shared.theatersOfWar.campaigns.panels.overview_job_provider_panel import CampaignJobProviderSectionPanel
     23 from eve.client.script.ui.shared.theatersOfWar.campaigns.panels.progress_cont import ProgressCont
     24 from eve.client.script.ui.shared.theatersOfWar.campaigns.panels.segmentedVideo import SegmentedVideoCont
     25 from eve.client.script.ui.shared.theatersOfWar.campaigns.panels.static_background import StaticBackground
     26 from eve.client.script.ui.shared.theatersOfWar.campaigns.panels.stats_cont import StatsContainer
     27 from eveexceptions import ExceptionEater
     28 from jobboard.client.features.campaigns.recommended_card_section import RecommendedCont
     29 from localization.formatters.timeIntervalFormatters import GetByLabel
     30 logger = logging.getLogger(__name__)
     31 
     32 class CampaignOverview(BaseScrollingPage):
     33     default_name = 'campaignOverview'
     34     default_align = Align.TOTOP
     35     default_display = True
     36 
     37     def ApplyAttributes(self, attributes):
     38         self.achievement_cont = None
     39         super(CampaignOverview, self).ApplyAttributes(attributes)
     40         self.campaignPanelController = attributes.campaignPanelController
     41         self._campaign_id = self.campaignPanelController.selected_campaign_id
     42         self._construct_ui()
     43         self.connect_signals()
     44 
     45     def _construct_ui(self):
     46         self.Flush()
     47         self.outcome_cont = Container(name='outcome_cont', parent=self, align=Align.TOALL, display=False)
     48         self.overview_cont = Container(name='overview_cont', parent=self, align=Align.TOALL, display=False)
     49         self.objective_cont = Container(name='objective_cont', parent=self, align=Align.TOALL, top=700, display=False)
     50         self._objective_right_side = Container(parent=self.objective_cont, name='_objective_right_side', align=Align.TORIGHT, width=500)
     51         self._objective_left_side = Container(parent=self.objective_cont, name='_objective_left_side', align=Align.TOALL, left=panel_const.PANEL_LEFT_PADDING)
     52         self._overview_right_side = Container(parent=self.overview_cont, name='_overview_right_side', align=Align.TORIGHT, width=620)
     53         self._overview_left_side = Container(parent=self.overview_cont, name='_overview_left_side', align=Align.TOALL, left=panel_const.PANEL_LEFT_PADDING, minWidth=300)
     54         self._construct_outcome_panel()
     55         self._construct_campaign_bg()
     56         self._construct_campaign_info_section()
     57         self._construct_progress_section()
     58         self._construct_stats()
     59         self._construct_achievement()
     60         self._construct_recommended()
     61         self._construct_all_objectives()
     62         self.change_page(self.campaignPanelController.selected_campaign_page_id, None, False)
     63 
     64     def connect_signals(self):
     65         on_campaign_completed.connect(self.on_campaign_competed)
     66         campaign_animate_background.on_change.connect(self.on_animation_setting_changed)
     67         self.campaignPanelController.on_contribution_completed_objective.connect(self.on_objective_completed_by_contribution)
     68         on_achievement_progressed.connect(self.on_achievement_progressed)
     69 
     70     def disconnect_signals(self):
     71         on_campaign_completed.disconnect(self.on_campaign_competed)
     72         campaign_animate_background.on_change.disconnect(self.on_animation_setting_changed)
     73         self.campaignPanelController.on_contribution_completed_objective.disconnect(self.on_objective_completed_by_contribution)
     74         on_achievement_progressed.disconnect(self.on_achievement_progressed)
     75 
     76     def _construct_outcome_panel(self):
     77         self.outcome_cont.Flush()
     78         self.outcome_panel = OutcomePanel(parent=self.outcome_cont)
     79 
     80     def _construct_campaign_bg(self):
     81         self.bg_cont = Container(name='bg_cont', parent=self)
     82         self.static_background_cont = StaticBackgroundWithParallax(name='static_background_cont', parent=self.bg_cont, display=False)
     83         self.video_background_cont = VideoBackground(name='video_background_cont', parent=self.bg_cont, display=False)
     84         self.campaign_ambient_bg = Sprite(parent=self, align=Align.TOALL, pickState=PickState.OFF)
     85         self._update_bg_states()
     86 
     87     def on_animation_setting_changed(self, newValue):
     88         self._update_bg_states()
     89         self._load_campaign_bg()
     90 
     91     def _update_bg_states(self):
     92         if campaign_animate_background.get():
     93             self.static_background_cont.Hide()
     94             self.video_background_cont.Show()
     95         else:
     96             self.static_background_cont.Show()
     97             self.video_background_cont.Hide()
     98             self.video_background_cont.pause_videos()
     99 
    100     def on_achievement_progressed(self, achievement_id, achievement_state):
    101         if self.achievement_cont:
    102             self.achievement_cont.on_achievement_progressed(achievement_id, achievement_state)
    103 
    104     def _construct_campaign_info_section(self):
    105         top = 48
    106         self.info_cont = ContainerAutoSize(name='info_cont', parent=self._overview_left_side, align=Align.TOTOP, top=top)
    107         self.info_cont.orignal_top = self.info_cont.top
    108         self.date_label = TextDetail(parent=self.info_cont, align=Align.TOTOP, color=TextColor.SECONDARY)
    109         cont = ContainerAutoSize(parent=self.info_cont, align=Align.TOTOP, alignMode=Align.CENTERLEFT, top=8)
    110         self.campaign_icon = Sprite(parent=cont, align=Align.CENTERLEFT, pos=(0, 0, 16, 16))
    111         self.issuer_label = TextBody(parent=cont, align=Align.CENTERLEFT, left=self.campaign_icon.width + 8)
    112         self.title_label = TextCustom(parent=self.info_cont, align=Align.TOTOP, fontsize=96, lineSpacing=-0.2, color=TextColor.HIGHLIGHT, maxLines=2)
    113         self.subtitle_label = TextBody(parent=self.info_cont, align=Align.TOTOP, color=TextColor.SECONDARY, pickState=PickState.ON)
    114 
    115     def _construct_progress_section(self):
    116         progress_cont = ContainerAutoSize(name='progress_cont', parent=self._overview_left_side, align=Align.TOTOP, top=32)
    117         text_cont = ContainerAutoSize(name='text_cont', parent=progress_cont, align=Align.TOTOP, alignMode=Align.TOTOP)
    118         right_text_cont = ContainerAutoSize(parent=text_cont, align=Align.TORIGHT)
    119         TextDetail(name='objectives_completed', parent=text_cont, text=GetByLabel('UI/Campaigns/ObjectivesCompleted'), align=Align.TOTOP, color=TextColor.SECONDARY)
    120         self.num_objectives = TextDetail(name='num_objectives', parent=right_text_cont, align=Align.TORIGHT, color=TextColor.SECONDARY)
    121         completed_label_cont = ContainerAutoSize(parent=right_text_cont, align=Align.TORIGHT)
    122         self.completed_label = TextBody(name='completed_label', parent=completed_label_cont, align=Align.BOTTOMRIGHT, color=eveColor.SUCCESS_GREEN, bold=True, upperCase=True, text=GetByLabel('UI/Campaigns/CampaignCompleted'), left=8, outputMode=OUTPUT_COLOR_AND_GLOW, glowBrightness=0.4, display=False)
    123         self.progress_grid = ProgressCont(parent=progress_cont, top=8)
    124 
    125     def _construct_stats(self):
    126         self.stats_cont = ContainerAutoSize(name='stats_cont', parent=self._overview_left_side, align=Align.TOTOP, top=64)
    127         grid = LayoutGrid(parent=self.stats_cont, columns=3, cellSpacing=64)
    128         self.stat_completed = StatsContainer(parent=grid, stat_name=GetByLabel('UI/Campaigns/ObjectivesCompleted'))
    129         self.stat_days_left = StatsContainer(parent=grid, stat_name=GetByLabel('UI/Campaigns/DaysToComplete'))
    130         self.stat_contributors = StatsContainer(parent=grid, stat_name=GetByLabel('UI/Campaigns/NumContributors'))
    131 
    132     def _construct_achievement(self):
    133         self.achievement_cont = AchievementBanner(parent=self._objective_right_side, align=Align.TORIGHT, pos=(144, 0, 320, 0), campaignPanelController=self.campaignPanelController)
    134 
    135     def _construct_recommended(self):
    136         self.recommended_section = RecommendedCont(parent=self._objective_left_side, padBottom=24, title=GetByLabel('UI/Campaigns/RecommendedObjectives'), campaign_id=self._campaign_id, padTop=24)
    137 
    138     def _construct_all_objectives(self):
    139         all_objectives_cont = Container(name='all_objectives_cont', parent=self._objective_left_side, align=Align.TOALL)
    140         TextHeader(parent=all_objectives_cont, text=GetByLabel('UI/Campaigns/AllObjectives'), align=Align.TOTOP, top=24)
    141         self.job_panel = CampaignJobProviderSectionPanel(parent=all_objectives_cont, campaignPanelController=self.campaignPanelController)
    142 
    143     def load_ui(self):
    144         campaign_controller = self.campaignPanelController.selected_campaign_controller
    145         self._load_campaign_bg()
    146         if campaign_controller.is_expired:
    147             self.outcome_cont.Show()
    148             self.overview_cont.Hide()
    149             self.objective_cont.Hide()
    150             self._load_outcome(campaign_controller)
    151         else:
    152             self.outcome_cont.Hide()
    153             self.overview_cont.Show()
    154             self.objective_cont.Show()
    155             self._load_info_section(campaign_controller)
    156             self.job_panel.AutoSelect()
    157             uthread2.StartTasklet(self._load_progress_ui)
    158         self.animate_in()
    159 
    160     def _load_progress_ui(self):
    161         campaign_controller = self.campaignPanelController.selected_campaign_controller
    162         self._load_progress_section(campaign_controller)
    163         self._load_stats(campaign_controller)
    164         self.completed_label.display = campaign_controller.is_completed
    165 
    166     def _load_campaign_bg(self):
    167         campaign_controller = self.campaignPanelController.selected_campaign_controller
    168         if campaign_animate_background.get():
    169             selected_page_id = self.campaignPanelController.selected_campaign_page_id
    170             self.video_background_cont.load_ui(campaign_controller, selected_page_id == panel_const.PANEL_ID_OVERVIEW)
    171         else:
    172             self.static_background_cont.load_ui(campaign_controller)
    173         self.campaign_ambient_bg.texturePath = campaign_controller.textures.ambient_background
    174 
    175     def _load_info_section(self, campaign_controller):
    176         self.date_label.text = campaign_controller.get_duration_text()
    177         self.campaign_icon.texturePath = campaign_controller.textures.icon_path
    178         self.issuer_label.text = campaign_controller.issuer_name
    179         fontFamily = campaign_controller.font_family
    180         self.title_label.fontFamily = fontFamily
    181         self.title_label.text = campaign_controller.title_text.upper()
    182         self.subtitle_label.text = campaign_controller.subtitle_text
    183 
    184     def _load_progress_section(self, campaign_controller):
    185         current_progress = campaign_controller.current_progress
    186         current = min(current_progress, campaign_controller.target_progress)
    187         text = '%s/%s' % (current, campaign_controller.target_progress)
    188         self.num_objectives.text = text
    189         self.progress_grid.load_progress(current_progress, campaign_controller.target_progress, progress_color=campaign_controller.theme_pack.accent)
    190 
    191     def _load_stats(self, campaign_controller):
    192         try:
    193             progress = campaign_controller.current_progress
    194             completed = progress or 0
    195             contributors = campaign_controller.total_contributors or 0
    196         except CampaignRequestError:
    197             logger.exception('Failed to load campaign stats')
    198             completed = ' '
    199             contributors = ' '
    200 
    201         color = campaign_controller.theme_pack.focus
    202         self.stat_completed.load_stats(completed, color=color)
    203         self.stat_days_left.load_stats(campaign_controller.num_days_left, color=color)
    204         self.stat_contributors.load_stats(contributors, color=color)
    205 
    206     def _load_outcome(self, campaign_controller):
    207         victory = campaign_controller.is_expired and campaign_controller.is_completed
    208         if victory:
    209             resolution_state_text = campaign_controller.text.finished_success_resolution_state_text
    210             resolution_desc = campaign_controller.text.finished_success_description_text
    211         else:
    212             resolution_state_text = campaign_controller.text.finished_failure_resolution_state_text
    213             resolution_desc = campaign_controller.text.finished_failure_description_text
    214         self.outcome_panel.load_ui(campaign_controller.text.finished_campaign_ended_text, campaign_controller.title_text, resolution_state_text, resolution_desc, campaign_controller.theme_pack)
    215 
    216     def animate_in(self):
    217         selected_page_id = self.campaignPanelController.selected_campaign_page_id
    218         if selected_page_id != panel_const.PANEL_ID_OVERVIEW:
    219             return
    220         morph_duration = 1.0
    221         self.static_background_cont.do_parallax_animation(morph_duration)
    222         morph(self._overview_left_side, 'top', 0, morph_duration, 100)
    223 
    224     def change_page(self, new_page_id, old_page_id, animate = True):
    225         new_page_id = new_page_id or panel_const.PANEL_ID_OVERVIEW
    226         duration = 1.0
    227         morph_duration = duration if animate else 0
    228         if new_page_id in (panel_const.PANEL_ID_OVERVIEW, panel_const.PANEL_ID_OBJECTIVES):
    229             self._change_opacity(new_page_id, duration, animate)
    230             if new_page_id == panel_const.PANEL_ID_OBJECTIVES:
    231                 self.animate_go_to_objectives_panel(morph_duration, old_page_id)
    232             elif new_page_id == panel_const.PANEL_ID_OVERVIEW:
    233                 self.animate_go_to_overview_panel(morph_duration, old_page_id)
    234         else:
    235             morph(self.objective_cont, 'top', 0, morph_duration)
    236         self._update_video_playing(new_page_id, old_page_id)
    237 
    238     def _update_video_playing(self, new_page_id, old_page_id):
    239         if not campaign_animate_background.get():
    240             return
    241         if new_page_id == old_page_id:
    242             return
    243         if new_page_id == panel_const.PANEL_ID_OVERVIEW:
    244             self.video_background_cont.play_videos()
    245         elif new_page_id == panel_const.PANEL_ID_OBJECTIVES:
    246             self.video_background_cont.pause_videos()
    247         else:
    248             self.video_background_cont.pause_videos()
    249             self.video_background_cont.hide_videos()
    250 
    251     def animate_go_to_objectives_panel(self, morph_duration, old_page_id):
    252         if old_page_id is None:
    253             morph_duration = 0
    254         info_panel_to_value = min(-200, -self.info_cont.height)
    255         morph(self.info_cont, 'top', info_panel_to_value, morph_duration)
    256         morph(self.objective_cont, 'top', 75, morph_duration)
    257         morph(self._overview_right_side, 'width', 520, morph_duration)
    258         if campaign_animate_background.get() and old_page_id == panel_const.PANEL_ID_OVERVIEW:
    259             self.video_background_cont.animate_out()
    260 
    261     def animate_go_to_overview_panel(self, morph_duration, old_page_id):
    262         morph(self.info_cont, 'top', self.info_cont.orignal_top, morph_duration)
    263         morph(self.objective_cont, 'top', self.height - 150, morph_duration)
    264         morph(self._overview_right_side, 'width', 620, morph_duration)
    265 
    266     def _change_opacity(self, current_page_id, duration, animate):
    267         fade_elements = {panel_const.PANEL_ID_OVERVIEW: [self.info_cont, self.bg_cont, self.stats_cont],
    268          panel_const.PANEL_ID_OBJECTIVES: [self.achievement_cont]}
    269         for page_id, element_list in fade_elements.iteritems():
    270             for element in element_list:
    271                 if element is None:
    272                     return
    273                 if current_page_id != page_id:
    274                     if animate:
    275                         animations.FadeOut(element, duration=duration, callback=element.Hide)
    276                     else:
    277                         element.opacity = 0.0
    278                         element.Hide()
    279                 else:
    280                     element.Show()
    281                     if animate:
    282                         animations.FadeIn(element, duration=duration)
    283                     else:
    284                         element.opacity = 1.0
    285 
    286     def _on_size_changed(self, width, height):
    287         current_page_id = self.campaignPanelController.selected_campaign_page_id or 0
    288         if current_page_id == panel_const.PANEL_ID_OVERVIEW:
    289             self.objective_cont.top = self.height - 150
    290 
    291     def on_campaign_competed(self, campaign_id):
    292         self._load_progress_ui()
    293 
    294     def on_objective_completed_by_contribution(self, objective_id, campaign_id):
    295         self._load_progress_ui()
    296 
    297     def Close(self):
    298         super(CampaignOverview, self).Close()
    299         with ExceptionEater('Closing CampaignOverview'):
    300             self.disconnect_signals()
    301 
    302 
    303 class StaticBackgroundWithParallax(StaticBackground):
    304 
    305     def do_parallax_animation(self, morph_duration):
    306         morph(self.campaign_bg, 'top', self.campaign_bg.top, morph_duration, self.campaign_bg.top - 120)
    307         morph(self.campaign_bg, 'left', self.campaign_bg.left, morph_duration, self.campaign_bg.left + 40)
    308         morph(self.campaign_middleground, 'top', self.campaign_middleground.top, morph_duration, self.campaign_middleground.top - 60)
    309         morph(self.campaign_middleground, 'left', self.campaign_middleground.left, morph_duration, self.campaign_middleground.left + 60)
    310         morph(self.campaign_middleground, 'width', self.campaign_middleground.width, morph_duration, self.campaign_middleground.width + 80)
    311         morph(self.campaign_middleground, 'height', self.campaign_middleground.height, morph_duration, self.campaign_middleground.height + 142)
    312         morph(self.campaign_foreground, 'top', self.campaign_foreground.top, morph_duration, self.campaign_foreground.top - 80)
    313         morph(self.campaign_foreground, 'left', self.campaign_foreground.left, morph_duration, self.campaign_foreground.left - 160)
    314 
    315 
    316 class VideoBackground(Container):
    317 
    318     def ApplyAttributes(self, attributes):
    319         self._videos_loaded = False
    320         super(VideoBackground, self).ApplyAttributes(attributes)
    321         self.campaign_foreground_video = SegmentedVideoCont(name='campaign_foreground_video', parent=self, align=Align.TOPRIGHT, pos=(-280, 320, 1152, 648), pickState=PickState.OFF)
    322         self.campaign_middleground_video = SegmentedVideoCont(name='campaign_middleground_video', parent=self, align=Align.TOPRIGHT, pos=(0, -30, 648, 1152), pickState=PickState.OFF)
    323         self.campaign_bg_video = StreamingVideoSprite(name='campaign_bg_video', parent=self, align=Align.TOPRIGHT, pos=(-15, -100, 648, 1152), pickState=PickState.OFF, spriteEffect=SpriteEffect.COPY, videoLoop=True)
    324 
    325     def load_ui(self, campaign_controller, start_videos = False):
    326         return uthread2.StartTasklet(self._load_ui, campaign_controller, start_videos)
    327 
    328     def _load_ui(self, campaign_controller, start_videos):
    329         self.campaign_foreground_video.load_videos(*campaign_controller.textures.dashboard_foreground_videos)
    330         self.campaign_middleground_video.load_videos(*campaign_controller.textures.dashboard_middleground_videos)
    331         try:
    332             background_path = campaign_controller.textures.dashboard_background_video
    333             if self.campaign_bg_video.path == background_path:
    334                 self.campaign_bg_video.Play()
    335             else:
    336                 self.campaign_bg_video.SetVideoPath(background_path, videoLoop=True)
    337         except RuntimeError:
    338             logger.exception('failed to play video')
    339 
    340         self._videos_loaded = True
    341         if start_videos:
    342             self.play_videos()
    343 
    344     def animate_out(self):
    345         self.campaign_foreground_video.skip_loop()
    346 
    347     def pause_videos(self):
    348         self.campaign_foreground_video.pause_videos()
    349         self.campaign_middleground_video.pause_videos()
    350         self.campaign_bg_video.Pause()
    351 
    352     def play_videos(self):
    353         self.campaign_foreground_video.play()
    354         self.campaign_middleground_video.play()
    355         self.campaign_bg_video.Play()
    356         self.campaign_bg_video.Show()
    357 
    358     def hide_videos(self):
    359         self.campaign_foreground_video.hide_videos()
    360         self.campaign_middleground_video.hide_videos()
    361         self.campaign_bg_video.Hide()
    362 
    363 
    364 def morph(obj, attributeName, to_value, duration, startValue = None):
    365     if duration == 0:
    366         setattr(obj, attributeName, to_value)
    367     else:
    368         if startValue is None:
    369             startValue = getattr(obj, attributeName)
    370         animations.MorphScalar(obj, attributeName, startValue, to_value, duration=duration)