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

careerPortalWnd.py (11632B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\careerPortal\careerPortalWnd.py
      2 import math
      3 import telemetry
      4 import uthread2
      5 from carbon.client.script.environment.AudioUtil import PlaySound
      6 from carbonui import Align, uiconst
      7 from carbonui.control.scrollContainer import ScrollContainer
      8 from carbonui.primitives.container import Container
      9 from carbonui.primitives.gradientSprite import GradientSprite
     10 from carbonui.uianimations import animations
     11 from careergoals.client.career_goal_svc import get_career_goals_svc
     12 from careergoals.client.feature_flag import is_air_career_program_enabled
     13 from careergoals.client.signal import on_states_loaded, on_air_career_program_availability_changed
     14 from eve.client.script.ui.control.eveLoadingWheel import LoadingWheel
     15 from player_messaging.client.ui_message import message_player
     16 from eve.client.script.ui.shared.careerPortal import careerConst, cpSignals
     17 from eve.client.script.ui.shared.careerPortal.careerControllerUI import get_career_portal_controller_svc
     18 from eve.client.script.ui.shared.careerPortal.careerPortalBackground import CareerPortalBackground
     19 from eve.client.script.ui.shared.careerPortal.careerPortalTitle import CareerPortalTitle
     20 from eve.client.script.ui.shared.careerPortal.circleView.activityView import ActivityView
     21 from eve.client.script.ui.shared.careerPortal.circleView.careerView import CareerView
     22 from eve.client.script.ui.shared.careerPortal.circleView.goalView import GoalView
     23 from eve.client.script.ui.shared.careerPortal.failStates.noGoalsScreen import NoGoalsScreen
     24 from eve.client.script.ui.shared.careerPortal.panels.panelConts import ActivityViewPanels, GoalViewPanels, GoalDetailPanels, CareerViewPanels
     25 from eve.client.script.ui.shared.careerPortal.globalProgress import GlobalProgress
     26 from eve.client.script.ui.shared.careerPortal.rewards.rewardsCont import RewardsCont
     27 from eve.client.script.ui.shared.mapView.dockPanel import DockablePanel
     28 from eve.client.script.ui.view.viewStateConst import ViewState
     29 from localization import GetByLabel
     30 from stackless_response_router.exceptions import TimeoutException
     31 PANEL_MIN_WIDTH = 421
     32 PANEL_WIDTH_RATIO = 0.25
     33 SIDE_PADDING_WINDOWED = 24
     34 SIDE_PADDING_FULLSCREEN = 48
     35 SOUND_OPEN_PLAY = 'career_portal_open_play'
     36 SOUND_BACKGROUND_LOOP_PLAY = 'career_portal_background_loop_play'
     37 SOUND_BACKGROUND_LOOP_STOP = 'career_portal_background_loop_stop'
     38 
     39 class CareerPortalDockablePanel(DockablePanel):
     40     default_windowID = 'careerPortal'
     41     default_analyticID = 'air_career_portal'
     42     default_captionLabelPath = 'UI/CareerPortal/CareerPortalWnd'
     43     default_descriptionLabelPath = 'UI/CareerPortal/CareerPortalWndDescription'
     44     default_iconNum = 'res:/ui/texture/windowIcons/airCareerProgram.png'
     45     default_width = 900
     46     default_height = 750
     47     default_minSize = (default_width, default_height)
     48     default_clipChildren = True
     49     panelID = default_windowID
     50     viewState = ViewState.CareerPortal
     51     hasImmersiveAudioOverlay = True
     52 
     53     def __init__(self, *args, **kwargs):
     54         super(CareerPortalDockablePanel, self).__init__(*args, **kwargs)
     55         self.infoPanelContainer.topCont.display = False
     56         self._load_data_thread = None
     57         self.construct_loading_wheel()
     58         self.load_data()
     59         PlaySound(SOUND_OPEN_PLAY)
     60         PlaySound(SOUND_BACKGROUND_LOOP_PLAY)
     61         self.on_end_scale.connect(self._on_end_scale)
     62 
     63     def OnDockModeChanged(self, *args, **kwds):
     64         cpSignals.on_cp_window_size_changed(self)
     65 
     66     def _on_end_scale(self, *args):
     67         cpSignals.on_cp_window_size_changed(self)
     68 
     69     @classmethod
     70     def Open(cls, *args, **kwds):
     71         if not is_air_career_program_enabled():
     72             message_player(GetByLabel('UI/CareerPortal/FeatureUnavailable'))
     73             return
     74         return super(CareerPortalDockablePanel, cls).Open(*args, **kwds)
     75 
     76     def Close(self, setClosed = False, *args, **kwds):
     77         try:
     78             PlaySound(SOUND_BACKGROUND_LOOP_STOP)
     79             self.kill_load_data_thread()
     80             self.disconnect_signals()
     81             get_career_goals_svc().get_goal_data_controller().clear_local_completed_goals()
     82         finally:
     83             super(CareerPortalDockablePanel, self).Close(setClosed, *args, **kwds)
     84 
     85     def kill_load_data_thread(self):
     86         if self._load_data_thread is not None:
     87             self._load_data_thread.kill()
     88             self._load_data_thread = None
     89 
     90     def connect_signals(self):
     91         on_states_loaded.connect(self.on_states_loaded)
     92         on_air_career_program_availability_changed.connect(self.on_air_career_program_availability_changed)
     93 
     94     def disconnect_signals(self):
     95         on_states_loaded.disconnect(self.on_states_loaded)
     96         on_air_career_program_availability_changed.disconnect(self.on_air_career_program_availability_changed)
     97 
     98     def construct_loading_wheel(self):
     99         self.loading_wheel = LoadingWheel(name='loading_wheel', parent=self, align=Align.CENTER, idx=0)
    100 
    101     def load_data(self):
    102         self.content.Flush()
    103         self.loading_wheel.Show()
    104         self.kill_load_data_thread()
    105         self._load_data_thread = uthread2.start_tasklet(self.load_data_async)
    106 
    107     def load_data_async(self):
    108         try:
    109             get_career_goals_svc().get_goal_data_controller().prime_definitions_and_states()
    110             self.on_data_load_success()
    111         except TimeoutException:
    112             self.on_data_load_fail()
    113         finally:
    114             self.loading_wheel.Hide()
    115 
    116     def on_data_load_success(self):
    117         self.construct_career_portal()
    118         self.update()
    119         self.connect_signals()
    120 
    121     def on_data_load_fail(self):
    122         no_goals_screen = NoGoalsScreen(name='no_goals_screen', parent=self.content)
    123         no_goals_screen.on_retry.connect(self.on_retry)
    124 
    125     def on_retry(self, no_goals_screen):
    126         try:
    127             no_goals_screen.on_retry.disconnect(self.on_retry)
    128         finally:
    129             self.load_data()
    130 
    131     def construct_career_portal(self):
    132         self.career_portal = CareerPortal(name='career_portal', parent=self.content, padTop=self.toolbarContainer.height)
    133 
    134     def update(self):
    135         is_fullscreen = self.IsFullscreen()
    136         self.career_portal.is_fullscreen = is_fullscreen
    137         self.career_portal.padTop = 0 if is_fullscreen else self.toolbarContainer.height
    138 
    139     def on_states_loaded(self, *args):
    140         self.reload_window()
    141 
    142     def on_air_career_program_availability_changed(self, *args):
    143         if not is_air_career_program_enabled():
    144             message_player(GetByLabel('UI/CareerPortal/FeatureUnavailable'))
    145             self.Close()
    146 
    147     def on_reload_button(self, *args):
    148         self.reload_window()
    149 
    150     def reload_window(self, *args):
    151         self.Reload(self)
    152 
    153     def navigate_to_node(self, career_id = None, activity_id = None, goal_id = None):
    154         self.career_portal.navigate_to_node(career_id, activity_id, goal_id)
    155 
    156     def OnBack(self):
    157         current_state = careerConst.CAREER_WINDOW_STATE_SETTING.get()
    158         if current_state == careerConst.CareerWindowState.GOALS_VIEW:
    159             new_state = careerConst.CareerWindowState.ACTIVITIES_VIEW
    160         else:
    161             new_state = careerConst.CareerWindowState.CAREERS_VIEW
    162         careerConst.CAREER_WINDOW_STATE_SETTING.set(new_state)
    163 
    164 
    165 class CareerPortal(Container):
    166     default_state = uiconst.UI_NORMAL
    167     default_opacity = 0
    168 
    169     def __init__(self, *args, **kwargs):
    170         super(CareerPortal, self).__init__(*args, **kwargs)
    171         self._is_fullscreen = True
    172         self.construct_layout()
    173 
    174     @telemetry.ZONE_METHOD
    175     def construct_layout(self):
    176         self.content = Container(name='content', parent=self)
    177         self.clip_container = Container(name='clip_container', parent=self.content, clipChildren=True)
    178         initialState = careerConst.CAREER_WINDOW_STATE_SETTING.get()
    179         self.construct_central_container(initialState)
    180         self.construct_header()
    181         self.construct_footer()
    182         self.construct_left_side_panels()
    183         self.construct_right_side_panels(initialState)
    184         self.backgroundContainer = CareerPortalBackground(parent=self, name='background', align=Align.TOALL)
    185         self.backgroundContainer.OnCareerWindowStateChanged(initialState)
    186         self.update()
    187         animations.FadeIn(self, duration=careerConst.CONTENT_FADE_IN_DURATION)
    188 
    189     def construct_header(self):
    190         CareerPortalTitle(name='career_portal_title', parent=self.clip_container, align=Align.TOTOP_PROP, height=0.1)
    191 
    192     def construct_footer(self):
    193         footer = Container(name='footer', parent=self.clip_container, align=Align.TOBOTTOM_NOPUSH, height=144, top=8)
    194         GlobalProgress(name='global_progress', parent=footer, align=Align.TOTOP, padding=(32, 0, 32, 0))
    195         GradientSprite(name='progress_bar_gradient', parent=self.clip_container, align=Align.TOBOTTOM, state=uiconst.UI_DISABLED, rgbData=((0, (0.0, 0.0, 0.0)), (0.55, (0.0, 0.0, 0.0)), (1.0, (0.0, 0.0, 0.0))), alphaData=((0.0, 1.0), (0.55, 1.0), (1.0, 0.0)), rotation=math.pi / 2, height=144)
    196 
    197     def construct_central_container(self, initialState):
    198         central_container = Container(name='central_container', parent=self, align=Align.TOALL, padBottom=120)
    199         CareerView(parent=central_container, initialState=initialState)
    200         ActivityView(parent=central_container, initialState=initialState)
    201         GoalView(parent=central_container, initialState=initialState)
    202 
    203     def construct_right_side_panels(self, initialState):
    204         self.right_side_panel = ScrollContainer(name='right_side_panel', parent=self.clip_container, align=Align.TORIGHT_PROP, width=PANEL_WIDTH_RATIO, minWidth=PANEL_MIN_WIDTH)
    205         GoalDetailPanels(parent=self.right_side_panel, initialState=initialState)
    206         ActivityViewPanels(parent=self.right_side_panel, initialState=initialState)
    207         CareerViewPanels(parent=self.right_side_panel, initialState=initialState)
    208         GoalViewPanels(parent=self.right_side_panel, initialState=initialState)
    209 
    210     def construct_left_side_panels(self):
    211         self.left_side_panel = Container(name='left_side_panel', parent=self.clip_container, align=Align.TOLEFT_PROP, width=PANEL_WIDTH_RATIO, minWidth=PANEL_MIN_WIDTH)
    212         self.rewards = RewardsCont(name='rewards', parent=self.left_side_panel, align=Align.TOTOP)
    213 
    214     def update(self):
    215         if self._is_fullscreen:
    216             self.content.padLeft = SIDE_PADDING_FULLSCREEN
    217             self.content.padRight = SIDE_PADDING_FULLSCREEN
    218         else:
    219             self.content.padLeft = SIDE_PADDING_WINDOWED
    220             self.content.padRight = SIDE_PADDING_WINDOWED
    221 
    222     def navigate_to_node(self, career_id = None, activity_id = None, goal_id = None):
    223         animations.FadeOut(obj=self.clip_container, duration=0.2, callback=lambda : self.make_selection(career_id, activity_id, goal_id))
    224 
    225     def make_selection(self, career_id = None, activity_id = None, goal_id = None):
    226         if career_id:
    227             get_career_portal_controller_svc().select_career(career_id, goal_id)
    228         if activity_id:
    229             activity_name = careerConst.GetCareerPathGroupName(career_id, activity_id)
    230             get_career_portal_controller_svc().select_activity(activity_id, activity_name, career_id)
    231         if goal_id:
    232             get_career_portal_controller_svc().select_goal(goal_id)
    233 
    234     @property
    235     def is_fullscreen(self):
    236         return self._is_fullscreen
    237 
    238     @is_fullscreen.setter
    239     def is_fullscreen(self, value):
    240         self._is_fullscreen = value
    241         self.update()
    242 
    243     def OnClick(self, *args):
    244         cpSignals.on_clicked_outside()
    245         self.right_side_panel.Disable()