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()