newFeatureNotifyWnd.py (14174B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\newFeatureNotifyWnd.py 2 import math 3 import trinity 4 import uthread2 5 from carbonui import uiconst, TextColor 6 from carbonui.primitives.container import Container 7 from carbonui.primitives.frame import Frame 8 from carbonui.primitives.sprite import Sprite, StreamingVideoSprite 9 from carbonui.primitives.stretchspritehorizontal import StretchSpriteHorizontal 10 from carbonui.uianimations import animations 11 from carbon.client.script.environment.AudioUtil import PlaySound 12 from eve.client.script.ui.control.eveLabel import Label 13 from carbonui.control.window import Window 14 from eveui import ButtonIcon 15 from localization import GetByLabel 16 from eve.client.script.ui.shared.message_bus.newsCarouselMessenger import NewsCarouselMessenger 17 SPRITE_OPACITY = 0.2 18 IMG_HEIGHT = 400 19 DURATION = 0.3 20 SECOND_DURATION = 0.3 21 OUT_DURATION = 0.2 22 OUT_SECOND_DURATION = 0.2 23 MAIN_SPRITE_WIDTH = 946 24 MAIN_SPRITE_HEIGHT = 416 25 26 class OverlayButton(Container): 27 FRAME_OPACITY_IDLE = 0.2 28 FRAME_OPACITY_HOVER = 0.7 29 FRAME_GLOW_BRIGHTNESS_IDLE = 0.0 30 FRAME_GLOW_BRIGHTNESS_HOVER = 0.7 31 _hovered = False 32 33 def __init__(self, callback, state = uiconst.UI_NORMAL, **kwargs): 34 self._callback = callback 35 super(OverlayButton, self).__init__(state=state, **kwargs) 36 self._frame = Frame(parent=self, align=uiconst.TOALL, opacity=self._get_frame_opacity(), outputMode=uiconst.OUTPUT_COLOR_AND_GLOW, glowBrightness=self._get_frame_glow_brightness(), texturePath='res:/UI/Texture/classes/NewFeatureNotify/frame_Window.png', cornerSize=10, idx=0) 37 38 def _get_frame_opacity(self): 39 if self._hovered: 40 return self.FRAME_OPACITY_HOVER 41 else: 42 return self.FRAME_OPACITY_IDLE 43 44 def _get_frame_glow_brightness(self): 45 if self._hovered: 46 return self.FRAME_GLOW_BRIGHTNESS_HOVER 47 else: 48 return self.FRAME_GLOW_BRIGHTNESS_IDLE 49 50 def _update_frame_opacity(self, duration = 0.0): 51 if duration > 0.0: 52 animations.FadeTo(self._frame, startVal=self._frame.opacity, endVal=self._get_frame_opacity(), duration=duration) 53 else: 54 self._frame.opacity = self._get_frame_opacity() 55 56 def _update_frame_glow_brightness(self, duration = 0.0): 57 if duration > 0.0: 58 animations.MorphScalar(self._frame, 'glowBrightness', startVal=self._frame.glowBrightness, endVal=self._get_frame_glow_brightness(), duration=duration) 59 else: 60 self._frame.glowBrightness = self._get_frame_glow_brightness() 61 62 def OnMouseEnter(self, *args): 63 self._hovered = True 64 PlaySound(uiconst.SOUND_BUTTON_HOVER) 65 self._update_frame_opacity(duration=uiconst.TIME_ENTRY) 66 self._update_frame_glow_brightness(duration=uiconst.TIME_ENTRY) 67 68 def OnMouseExit(self, *args): 69 self._hovered = False 70 self._update_frame_opacity(duration=uiconst.TIME_EXIT) 71 self._update_frame_glow_brightness(duration=uiconst.TIME_EXIT) 72 73 def OnClick(self, *args): 74 self._callback() 75 76 77 class NewFeatureNotifyWnd(Window): 78 default_name = 'NewFeatureNotifyWnd' 79 default_windowID = 'NewFeatureNotifyWnd' 80 default_fixedWidth = 1043 81 default_fixedHeight = 550 82 default_isLightBackgroundConfigurable = False 83 default_isMinimizable = False 84 default_isCollapseable = False 85 default_isStackable = False 86 default_isKillable = False 87 default_isLockable = False 88 default_isOverlayable = False 89 hasAnimated = False 90 91 def ApplyAttributes(self, attributes): 92 Window.ApplyAttributes(self, attributes) 93 self.features = attributes.newFeatures 94 self.currentFeature = None 95 self.sr.headerParent.Hide() 96 self.mainCont = Container(name='mainCont', parent=self.sr.main, state=uiconst.UI_PICKCHILDREN, opacity=1.0, padding=2, clipChildren=True) 97 self.contentCont = Container(name='contentCont', parent=self.mainCont, align=uiconst.CENTERTOP, opacity=0.0, top=42, width=MAIN_SPRITE_WIDTH, height=MAIN_SPRITE_HEIGHT) 98 self.underlayCont = Container(name='underlayCont', parent=self.mainCont, align=uiconst.CENTERTOP, opacity=0, top=42, width=MAIN_SPRITE_WIDTH, height=MAIN_SPRITE_HEIGHT) 99 self.backgroundCont = Container(name='backgroundCont', parent=self.mainCont, align=uiconst.CENTERTOP, bgColor=(0, 0, 0, 0.3), opacity=0.0, width=self.width - 30, height=500) 100 self.bannerSprite = Sprite(name='bannerSprite', parent=self.underlayCont, align=uiconst.CENTERTOP, width=MAIN_SPRITE_WIDTH, height=MAIN_SPRITE_HEIGHT, textureSecondaryPath='res:/UI/Texture/classes/newFeatureNotify/mask_Window.png', spriteEffect=trinity.TR2_SFX_MODULATE) 101 self.bannerVideoSprite = StreamingVideoSprite(name='bannerVideoSprite', parent=self.underlayCont, align=uiconst.CENTERTOP, width=MAIN_SPRITE_WIDTH, height=MAIN_SPRITE_HEIGHT, textureSecondaryPath='res:/UI/Texture/classes/newFeatureNotify/mask_Window.png', spriteEffect=trinity.TR2_SFX_MODULATE) 102 self.SetUpBracketSprites() 103 backgroundWhite = (0.9, 0.9, 0.9, 1.0) 104 self.SetUpTopLeftCorner(backgroundWhite) 105 self.ConstructButtons(MAIN_SPRITE_WIDTH, MAIN_SPRITE_HEIGHT) 106 self.LoadFeature() 107 108 def SetUpTexts(self, myWidth): 109 bulletContHeight = len(self.bulletPoints) * 20 + 20 110 self.bulletCont = Container(parent=self.contentCont, name='bulletCont', align=uiconst.TOBOTTOM, width=myWidth - 4, height=bulletContHeight, bgColor=(0, 0, 0, 0.3), padLeft=2, padRight=2, padBottom=12) 111 self.descriptionContainer = Container(parent=self.contentCont, name='descriptionCont', align=uiconst.TOBOTTOM, height=25, width=MAIN_SPRITE_WIDTH) 112 self.titleContainer = Container(parent=self.contentCont, name='titleCont', align=uiconst.TOBOTTOM, height=45, width=MAIN_SPRITE_WIDTH) 113 self.bulletPointCont = Container(parent=self.bulletCont, align=uiconst.TOALL) 114 self.titleCaption = Label(parent=self.titleContainer, align=uiconst.CENTERLEFT, color=TextColor.HIGHLIGHT, fontsize=36, left=20) 115 self.descriptionLabel = Label(parent=self.descriptionContainer, align=uiconst.TOPLEFT, fontsize=16, color=(1.0, 1.0, 1.0, 1.0), maxHeight=10, left=20, shadowSpriteEffect=None, bold=True) 116 117 def PopulateBulletPoints(self): 118 bulletContainerParentHeight = 20 119 for i, bulletPoint in enumerate(self.bulletPoints): 120 bulletContainer = Container(parent=self.bulletPointCont, align=uiconst.TOTOP, width=MAIN_SPRITE_WIDTH, height=20, top=0 if i else 10) 121 Sprite(parent=bulletContainer, align=uiconst.CENTERLEFT, texturePath='res:/UI/Texture/classes/NewFeatureNotify/bulletpoint.png', width=8, height=8, color=(0.75, 0.51, 0.08, 1.0), left=20, top=0) 122 bulletLabel = Label(parent=bulletContainer, align=uiconst.CENTERLEFT, text=bulletPoint, fontsize=16, bold=True, color=TextColor.HIGHLIGHT, left=35, wrapMode=uiconst.WRAPMODE_FORCEWORD, maxWidth=900) 123 w, h = bulletLabel.GetAbsoluteSize() 124 bulletContainerParentHeight += h * 1.1 125 bulletContainer.height = h * 1.1 126 127 self.bulletCont.height = bulletContainerParentHeight 128 129 def SetUpTopLeftCorner(self, backgroundWhite): 130 self.newTextContainer = Container(parent=self.contentCont, align=uiconst.TOPLEFT, width=42, height=41, left=42, top=1) 131 Label(parent=self.newTextContainer, text=GetByLabel('UI/NewFeatureNotify/New'), align=uiconst.CENTERLEFT, fontsize=18, padLeft=4, uppercase=True, color=(0.9, 0.9, 0.9, 1.0)) 132 Sprite(name='newsIcon', parent=self.contentCont, align=uiconst.TOPLEFT, width=30, height=30, top=6, left=6, color=(0, 0, 0, 1), texturePath='res:/UI/Texture/classes/NewFeatureNotify/news_Icon.png') 133 Sprite(name='typeHighlight', parent=self.contentCont, align=uiconst.TOPLEFT, width=42, height=42, color=backgroundWhite, texturePath='res:/UI/Texture/classes/NewFeatureNotify/type_Highlight.png') 134 135 def SetUpBracketSprites(self): 136 self.topBracketContainer = Container(name='topBracketCont', parent=self.mainCont, align=uiconst.CENTERTOP, width=1030, height=7, opacity=0) 137 self.topBracketTail = StretchSpriteHorizontal(name='topSpriteBracket', parent=self.topBracketContainer, align=uiconst.CENTERTOP, width=1030, height=7, leftEdgeSize=16, rightEdgeSize=16, texturePath='res:/UI/Texture/classes/NewFeatureNotify/bracketTails_Window.png') 138 self.topBracketHead = Sprite(name='topSpriteHead', parent=self.topBracketContainer, align=uiconst.CENTERTOP, width=270, height=5, top=1, texturePath='res:/UI/Texture/classes/NewFeatureNotify/bracketHead_Window.png') 139 self.bottomBracketContainer = Container(name='bottomBracketCont', parent=self.mainCont, align=uiconst.CENTERBOTTOM, width=1030, height=7, top=46, opacity=0) 140 self.bottomBracketTail = StretchSpriteHorizontal(name='bottomSpriteBracket', parent=self.bottomBracketContainer, align=uiconst.CENTERBOTTOM, width=1030, height=7, leftEdgeSize=16, rightEdgeSize=16, texturePath='res:/UI/Texture/classes/NewFeatureNotify/bracketTails_Window.png', rotation=math.pi) 141 self.bottomBracketHead = Sprite(name='bottomSpriteHead', parent=self.bottomBracketContainer, align=uiconst.CENTERBOTTOM, width=270, height=5, top=1, texturePath='res:/UI/Texture/classes/NewFeatureNotify/bracketHead_Window.png', rotation=math.pi) 142 143 def ConstructButtons(self, mainSpriteWidth, mainSpriteHeight): 144 self.closeButton = ButtonIcon(name='closeButton', parent=self.mainCont, align=uiconst.TOPRIGHT, size=16, left=12, top=12, color=(1, 1, 1), on_click=self.CloseByUser, hint=GetByLabel('UI/Common/Buttons/Close'), texture_path='res:/UI/Texture/Shared/DarkStyle/windowClose.png') 145 OverlayButton(name='callToActionButton', parent=self.contentCont, align=uiconst.CENTERTOP, width=mainSpriteWidth, height=mainSpriteHeight, callback=self.ExecuteAction) 146 147 def LoadFeature(self): 148 uthread2.start_tasklet(self._DisplayFeature) 149 150 def _DisplayFeature(self): 151 self.GetCurrentFeature() 152 self.bulletPoints = self.currentFeature.GetBulletPoints() 153 self.SetUpTexts(MAIN_SPRITE_WIDTH) 154 self._UpdateSpriteAndVideoSprite(self.currentFeature) 155 self.titleCaption.text = self.currentFeature.GetName() 156 self.descriptionLabel.text = self.currentFeature.GetDescription() 157 if self.currentFeature.GetNeocomBtnID(): 158 sm.GetService('neocom').Blink(self.currentFeature.GetNeocomBtnID()) 159 self.currentFeature.MarkAsSeen() 160 self.PopulateBulletPoints() 161 self._AnimEnter() 162 self.LogFeatureDisplayed() 163 164 def LogFeatureDisplayed(self): 165 if not self.currentFeature or not self.currentFeature.featureID: 166 return 167 message_bus = NewsCarouselMessenger(sm.GetService('publicGatewaySvc')) 168 message_bus.displayed(self.currentFeature.featureID) 169 170 def GetCurrentFeature(self): 171 self.currentFeature = self.features[0] 172 173 def ExecuteAction(self, *args): 174 uthread2.start_tasklet(self.currentFeature.ExecuteCallToAction) 175 if self.currentFeature.GetCallToActionMethod(): 176 self.LogFeatureAcknowledged() 177 self._AnimExit() 178 self.CloseByUser() 179 180 def LogFeatureAcknowledged(self): 181 if not self.currentFeature or not self.currentFeature.featureID: 182 return 183 message_bus = NewsCarouselMessenger(sm.GetService('publicGatewaySvc')) 184 message_bus.acknowledged(self.currentFeature.featureID) 185 186 def _UpdateSpriteAndVideoSprite(self, feature): 187 if feature.IsVideo(): 188 self.bannerVideoSprite.SetVideoPath(feature.GetTexturePath(), videoLoop=True) 189 else: 190 self.bannerSprite.texturePath = feature.GetTexturePath() 191 self.bannerSprite.display = not feature.IsVideo() 192 self.bannerVideoSprite.display = feature.IsVideo() 193 194 def _AnimExit(self, shouldExecuteAction = False): 195 animations.FadeOut(self.contentCont, duration=OUT_DURATION) 196 animations.FadeOut(self.underlayCont, duration=OUT_DURATION) 197 animations.FadeOut(self.backgroundCont, duration=OUT_DURATION) 198 animations.FadeOut(self.mainCont, duration=OUT_DURATION + OUT_SECOND_DURATION + 0.1) 199 animations.MoveTo(self.topBracketContainer, None, (0, 267), OUT_SECOND_DURATION, timeOffset=OUT_DURATION) 200 animations.MoveTo(self.bottomBracketContainer, (0, 46), (0, 267), OUT_SECOND_DURATION, timeOffset=OUT_DURATION) 201 animations.FadeOut(self.topBracketContainer, duration=0.1, timeOffset=OUT_DURATION + OUT_SECOND_DURATION, callback=self.FinalizeAnimation) 202 203 def FinalizeAnimation(self): 204 self.hasAnimated = True 205 206 def _AnimEnter(self): 207 openingOffset = 0.3 208 animations.FadeIn(self.topBracketContainer, endVal=SPRITE_OPACITY, duration=openingOffset) 209 animations.FadeIn(self.bottomBracketContainer, endVal=SPRITE_OPACITY, duration=openingOffset) 210 animations.MoveTo(self.topBracketContainer, (0, 267), None, SECOND_DURATION, timeOffset=openingOffset) 211 animations.MoveTo(self.bottomBracketContainer, (0, 267), (0, 46), SECOND_DURATION, timeOffset=openingOffset) 212 animations.FadeIn(self.contentCont, duration=DURATION, timeOffset=SECOND_DURATION + openingOffset) 213 animations.FadeIn(self.underlayCont, duration=DURATION, timeOffset=SECOND_DURATION + openingOffset) 214 animations.FadeIn(self.backgroundCont, duration=DURATION, timeOffset=SECOND_DURATION + openingOffset) 215 animations.FadeTo(self.descriptionLabel, 0.0, 1.0, duration=0.1, timeOffset=0.2 + DURATION + openingOffset) 216 217 @classmethod 218 def Open(cls, *args, **kwargs): 219 PlaySound('news_window_open_play') 220 return super(NewFeatureNotifyWnd, cls).Open(*args, **kwargs) 221 222 def Close(self, *args, **kwargs): 223 PlaySound('news_window_close_play') 224 super(NewFeatureNotifyWnd, self).Close(*args, **kwargs) 225 226 def CloseByUser(self, *args): 227 if not self.hasAnimated: 228 self._AnimExit() 229 uthread2.Sleep(OUT_DURATION + OUT_SECOND_DURATION) 230 self.killable = True 231 super(NewFeatureNotifyWnd, self).CloseByUser(*args)