baseSkinCard.py (15047B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\cosmetics\ship\pages\cards\baseSkinCard.py 2 import uthread2 3 from carbon.client.script.environment.AudioUtil import PlaySound 4 from carbonui import Align, TextAlign, TextColor, uiconst, SpriteEffect, PickState 5 from carbonui.text.styles import TextBody 6 from carbonui.primitives.container import Container 7 from carbonui.primitives.containerAutoSize import ContainerAutoSize 8 from carbonui.primitives.fill import Fill 9 from carbonui.primitives.sprite import Sprite 10 from carbonui.primitives.stretchspritehorizontal import StretchSpriteHorizontal 11 from carbonui.uianimations import animations 12 from cosmetics.client.liveIconRenderer import LiveIconSprite 13 from eve.client.script.ui import eveColor 14 from eve.client.script.ui.control.eveLoadingWheel import LoadingWheel 15 from eve.client.script.ui.cosmetics.ship.pages.cards import cardConst 16 from eve.client.script.ui.cosmetics.ship.pages.cards.cardConst import CardOutline 17 from signals import Signal 18 19 class SkinCard(Container): 20 default_state = uiconst.UI_NORMAL 21 default_width = cardConst.card_width 22 default_height = cardConst.card_height 23 ship_glow = True 24 ANIM_DURATION = 0.2 25 GLOW_AMOUNT = 0.4 26 ICON_SIZE = 128 27 28 def __init__(self, *args, **kwargs): 29 super(SkinCard, self).__init__(*args, **kwargs) 30 self._is_selected = False 31 self.is_hovered = False 32 self.live_rendered_icon = None 33 self.finished_loading = False 34 self.on_click = Signal('on_click') 35 self._update_live_icon_thread = None 36 self._update_thread = None 37 self.construct_layout() 38 self.update_live_icon_threaded() 39 self.update_threaded() 40 self.name_label.text = self.get_skin_name() 41 42 def Close(self): 43 try: 44 self.kill_threads() 45 finally: 46 super(SkinCard, self).Close() 47 48 def kill_threads(self): 49 self.kill_update_live_icon_thread() 50 self.kill_update_thread() 51 52 def kill_update_live_icon_thread(self): 53 if self._update_live_icon_thread is not None: 54 self._update_live_icon_thread.kill() 55 self._update_live_icon_thread = None 56 57 def kill_update_thread(self): 58 if self._update_thread is not None: 59 self._update_thread.kill() 60 self._update_thread = None 61 62 def construct_layout(self): 63 self.construct_content_container() 64 self.construct_outline() 65 self.construct_stack_lines() 66 self.construct_stack_number() 67 self.construct_label() 68 self.construct_highlight() 69 self.construct_top_line() 70 self.construct_tier_indicator() 71 self.construct_loading_indicator() 72 self.construct_live_rendered_icon_container() 73 self.construct_live_rendered_icon_sprite() 74 75 def construct_loading_indicator(self): 76 self.loading_indicator = LoadingWheel(parent=self, align=uiconst.CENTER, display=True, idx=0) 77 78 def on_live_rendered_icon_initialized(self): 79 self.finished_loading = True 80 self.loading_indicator.Hide() 81 animations.FadeIn(self.live_rendered_icon) 82 self.live_rendered_icon.on_rendered.disconnect(self.on_live_rendered_icon_initialized) 83 84 def on_loading_sprite_fadeout_complete(self): 85 self.loading_indicator.display = False 86 87 def get_live_rendered_icon_skin_design(self): 88 return None 89 90 def construct_stack_lines(self): 91 self.stack_lines_container = Container(name='stack_lines_container', parent=self, align=Align.TOTOP, opacity=0.5, height=6, display=False, padTop=-6) 92 Fill(parent=self.stack_lines_container, align=Align.CENTERBOTTOM, color=self.stack_lines_color, opacity=0.5, pos=(0, 2, 150, 1)) 93 Fill(parent=self.stack_lines_container, align=Align.CENTERBOTTOM, color=self.stack_lines_color, opacity=0.3, pos=(0, 5, 134, 1)) 94 95 @property 96 def stack_lines_color(self): 97 return eveColor.WHITE 98 99 def construct_content_container(self): 100 self.content = Container(name='content', parent=self, align=Align.TOALL) 101 102 def construct_stack_number(self): 103 self.stack_numbers_container = ContainerAutoSize(name='stack_numbers_container', parent=self.content, align=Align.BOTTOMRIGHT, alignMode=Align.CENTER, display=False, top=36, minHeight=34, minWidth=38) 104 self.stack_numbers_label = TextBody(name='stack_numbers_label', parent=self.stack_numbers_container, align=Align.CENTER, textAlign=Align.CENTER, padding=(16, 0, 8, 0)) 105 StretchSpriteHorizontal(name='stack_numbers_line', parent=self.stack_numbers_container, align=Align.TOALL, texturePath='res:/UI/Texture/classes/Cosmetics/Ship/cards/stack/corner_line.png', color=eveColor.WHITE, opacity=0.02, leftEdgeSize=8, rightEdgeSize=20) 106 StretchSpriteHorizontal(name='stack_numbers_background', parent=self.stack_numbers_container, align=Align.TOALL, texturePath='res:/UI/Texture/classes/Cosmetics/Ship/cards/stack/corner_fill.png', color=eveColor.COAL_BLACK, leftEdgeSize=27, rightEdgeSize=11) 107 108 def get_background_texture(self): 109 return 'res:/UI/Texture/classes/Cosmetics/Ship/cards/skin_design/background.png' 110 111 def get_mask_texture(self): 112 return 'res:/UI/Texture/classes/Cosmetics/Ship/cards/skin_design/mask.png' 113 114 def construct_live_rendered_icon_container(self): 115 self.icon_container = Container(name='icon_container', parent=self.content, align=Align.CENTERTOP, width=168, height=198) 116 Sprite(bgParent=self.icon_container, spriteEffect=SpriteEffect.MODULATE, textureSecondaryPath=self.get_background_texture(), texturePath=self.get_mask_texture()) 117 118 def construct_live_rendered_icon_sprite(self): 119 self.live_rendered_icon = LiveIconSprite(name='live_rendered_icon', parent=self.icon_container, align=Align.TOALL, opacity=0.0, pickState=PickState.OFF, viewportWidth=self.icon_container.width, viewportHeight=self.icon_container.height, bg_texture_path=self.get_background_texture(), mask_texture_path=self.get_mask_texture(), glow=self.ship_glow) 120 self.finished_loading = False 121 self.live_rendered_icon.on_rendered.connect(self.on_live_rendered_icon_initialized) 122 123 def construct_tier_indicator(self): 124 self.tier_label = TextBody(name='tier_label', parent=self.content, align=Align.TOTOP_NOPUSH, textAlign=TextAlign.CENTER, text=self.get_skin_tier_text(), color=self.get_skin_tier_text_color(), shadowOffset=(0, 0), bold=True, padTop=6) 125 if not self.show_tier_background(): 126 return 127 self.tier_container = Container(name='tier_container', parent=self.content, align=Align.TOTOP_NOPUSH, opacity=0.5, width=self.default_width, height=29) 128 self.tier_background = Sprite(name='tier_background', parent=self.tier_container, align=Align.TOTOP_NOPUSH, state=uiconst.UI_DISABLED, texturePath=self.get_skin_tier_texture(), outputMode=uiconst.OutputMode.COLOR_AND_GLOW, glowBrightness=self.GLOW_AMOUNT, width=self.default_width, height=29) 129 130 def show_tier_background(self): 131 return True 132 133 def get_skin_tier_level(self): 134 return 1 135 136 def get_skin_tier_text(self): 137 return '{tier}'.format(tier=self.get_skin_tier_level()) 138 139 def get_skin_tier_text_color(self): 140 return eveColor.BLACK 141 142 def get_skin_tier_texture(self): 143 tier_level = self.get_skin_tier_level() 144 return 'res:/UI/Texture/classes/Cosmetics/Ship/cards/tier/tier_{level}.png'.format(level=tier_level) 145 146 def construct_top_line(self): 147 self.top_left_corner = Sprite(name='top_left_corner', parent=self.content, align=Align.TOPLEFT, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/Cosmetics/Ship/cards/skin_design/top_corner.png', outputMode=uiconst.OutputMode.COLOR_AND_GLOW, glowBrightness=self.GLOW_AMOUNT, width=8, height=1) 148 self.top_right_corner = Sprite(name='top_right_corner', parent=self.content, align=Align.TOPRIGHT, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/Cosmetics/Ship/cards/skin_design/top_corner.png', outputMode=uiconst.OutputMode.COLOR_AND_GLOW, glowBrightness=self.GLOW_AMOUNT, width=8, height=1) 149 self.top_line_container = Container(name='top_line_container', parent=self.content, align=Align.TOTOP_NOPUSH, opacity=0.5, width=self.default_width, height=1) 150 self.top_line = Sprite(name='top_line', parent=self.top_line_container, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/Cosmetics/Ship/cards/skin_design/top_line.png', outputMode=uiconst.OutputMode.COLOR_AND_GLOW, glowBrightness=self.GLOW_AMOUNT, width=self.default_width, height=1) 151 152 def construct_outline(self): 153 self.outline = Sprite(name='outline', parent=self.content, state=uiconst.UI_DISABLED, texturePath=self.get_outline_texture(), color=self.get_outline_color(), outputMode=uiconst.OutputMode.COLOR_AND_GLOW, glowBrightness=self.GLOW_AMOUNT, width=168, height=197, opacity=0.0) 154 155 def get_outline_color(self): 156 return eveColor.FOCUS_BLUE 157 158 def get_outline_texture(self): 159 return CardOutline.DEFAULT 160 161 def construct_highlight(self): 162 self.highlight_container = Container(name='highlight_container', parent=self.content, align=Align.TOBOTTOM_NOPUSH, opacity=0.0, height=4) 163 self.highlight_bottom = Sprite(name='highlight_bottom', parent=self.highlight_container, align=Align.CENTER, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/Cosmetics/Ship/cards/skin_design/highlight_bottom.png', outputMode=uiconst.OutputMode.COLOR_AND_GLOW, glowBrightness=self.GLOW_AMOUNT, width=48, height=4) 164 165 @property 166 def highlight_offset(self): 167 return 13 168 169 def construct_label(self): 170 self.name_label_container = Container(name='name_label_container', parent=self.content, align=Align.TOBOTTOM, width=self.default_width, height=18, padLeft=10, padRight=10, top=6) 171 self.name_label = TextBody(name='name_label', parent=self.name_label_container, align=Align.CENTERLEFT, color=TextColor.SECONDARY, maxLines=1, autoFadeSides=16) 172 173 def get_skin_name(self): 174 return '' 175 176 def update_live_icon_threaded(self): 177 self.kill_update_live_icon_thread() 178 self._update_live_icon_thread = uthread2.start_tasklet(self.update_live_icon) 179 180 def update_live_icon(self): 181 if self.destroyed: 182 return 183 self.live_rendered_icon.apply_skin_design(self.get_live_rendered_icon_skin_design()) 184 185 def update_threaded(self): 186 self.kill_update_thread() 187 self._update_thread = uthread2.start_tasklet(self.update) 188 189 def update(self): 190 if self.destroyed: 191 return 192 self.state = uiconst.UI_DISABLED 193 self.update_stack_lines() 194 self.update_stack_numbers() 195 self.update_top_line() 196 self.update_outline() 197 self.update_highlight() 198 self.update_tier_indicator() 199 self.update_label() 200 self.state = uiconst.UI_NORMAL 201 202 def update_stack_lines(self): 203 self.stack_lines_container.display = False 204 205 def update_stack_numbers(self): 206 self.stack_numbers_container.display = False 207 208 def update_top_line(self): 209 target_color = self.get_top_line_color() 210 animations.SpColorMorphTo(self.top_line, self.top_line.GetRGBA(), target_color, self.ANIM_DURATION) 211 self.update_line_corners() 212 animations.FadeTo(self.top_line_container, self.top_line_container.opacity, self.get_top_line_opacity(), self.ANIM_DURATION) 213 214 def get_top_line_opacity(self): 215 if self.is_hovered or self.is_selected: 216 return 1.0 217 return 0.5 218 219 def update_outline(self): 220 if self.is_selected: 221 target_opacity = 0.6 222 elif self.is_hovered: 223 target_opacity = 0.2 224 else: 225 target_opacity = 0.0 226 animations.FadeTo(self.outline, self.outline.opacity, target_opacity, self.ANIM_DURATION) 227 228 def update_line_corners(self): 229 target_color = self.get_top_line_corner_color() 230 animations.SpColorMorphTo(self.top_left_corner, self.top_left_corner.GetRGBA(), target_color, self.ANIM_DURATION) 231 animations.SpColorMorphTo(self.top_right_corner, self.top_right_corner.GetRGBA(), target_color, self.ANIM_DURATION) 232 233 def get_top_line_color(self): 234 if self.is_selected: 235 return eveColor.CRYO_BLUE 236 return eveColor.WHITE 237 238 def get_top_line_corner_color(self): 239 if self.is_selected: 240 return eveColor.CRYO_BLUE 241 return eveColor.WHITE 242 243 def get_highlight_color(self): 244 return eveColor.WHITE 245 246 def update_highlight(self): 247 self.highlight_container.top = self.highlight_offset 248 self.highlight_bottom.color = self.get_highlight_color() 249 animations.FadeTo(self.highlight_container, self.highlight_container.opacity, self.get_highlight_opacity(), self.ANIM_DURATION) 250 251 def get_highlight_opacity(self): 252 if self.is_selected: 253 return 1.0 254 return 0.0 255 256 def update_tier_indicator(self): 257 if not self.show_tier_background(): 258 return 259 if hasattr(self, 'tier_container'): 260 target_opacity = 1.0 if self.is_hovered or self.is_selected else 0.5 261 animations.FadeTo(self.tier_container, self.tier_container.opacity, target_opacity, self.ANIM_DURATION) 262 263 def update_label(self): 264 color = self.get_label_color() 265 animations.SpColorMorphTo(self.name_label, self.name_label.GetRGBA(), color, self.ANIM_DURATION) 266 267 def get_label_color(self): 268 color = TextColor.HIGHLIGHT if self.is_selected or self.is_hovered else TextColor.SECONDARY 269 return color 270 271 @property 272 def is_selected(self): 273 return self._is_selected 274 275 @is_selected.setter 276 def is_selected(self, value): 277 if self._is_selected == value: 278 return 279 self._is_selected = value 280 if value: 281 self._on_selected() 282 else: 283 self._on_deselected() 284 self.update_threaded() 285 286 def _on_selected(self): 287 pass 288 289 def _on_deselected(self): 290 pass 291 292 def OnMouseEnter(self, *args): 293 self.is_hovered = True 294 PlaySound('nanocoating_button_hover_play') 295 self.update_threaded() 296 297 def OnMouseExit(self, *args): 298 self.is_hovered = False 299 self.update_threaded() 300 301 def OnClick(self, *args): 302 self.is_selected = not self.is_selected 303 self.on_click(self) 304 305 306 class BlankSkinCard(Container): 307 default_width = cardConst.card_width 308 default_height = cardConst.card_height 309 310 def __init__(self, *args, **kwargs): 311 super(BlankSkinCard, self).__init__(*args, **kwargs) 312 self.construct_layout() 313 314 def construct_layout(self): 315 self.bg_sprite = Sprite(name='bg_sprite', parent=self, align=Align.CENTERTOP, texturePath=self.get_background_texture(), width=self.default_width, height=self.default_height) 316 317 def get_background_texture(self): 318 return 'res:/UI/Texture/classes/Cosmetics/Ship/cards/skin_design/blank.png'