shipSafetyButton.py (28816B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\inflight\shipSafetyButton.py 2 from math import pi, radians, sqrt 3 import blue 4 import carbonui.const as uiconst 5 import eveicon 6 import localization 7 import trinity 8 import uthread 9 from carbon.client.script.environment.AudioUtil import PlaySound 10 from carbonui import fontconst, PickState, Align, TextColor 11 from carbonui.primitives.container import Container 12 from carbonui.primitives.containerAutoSize import ContainerAutoSize 13 from carbonui.primitives.fill import Fill 14 from carbonui.primitives.frame import Frame 15 from carbonui.primitives.layoutGrid import LayoutGrid 16 from carbonui.primitives.sprite import Sprite 17 from carbonui.primitives.transform import Transform 18 from carbonui.primitives.vectorlinetrace import VectorLineTrace 19 from carbonui.text import styles 20 from carbonui.text.styles import TextBody 21 from carbonui.uicore import uicore 22 from carbonui.util.color import Color 23 from eve.client.script.ui.control import eveLabel 24 from eve.client.script.ui.control.themeColored import FillThemeColored 25 from eve.client.script.ui.crimewatch import crimewatchConst 26 from eve.client.script.ui.inflight import shipSafetyConst 27 from eve.client.script.ui.inflight.shipSafetyConst import OPACITY_BG, DOCK_POINTER_LENGTH, DOCK_MARGIN, DESELECTED_BUTTON_OPACITY, HINT_DELAY, TRANSITION_TOTAL_DURATION, TRANSITION_STAGE2_ROTATION_DEG, TRANSITION_STAGE3_ROTATION_DEG 28 from eve.client.script.ui.shared.mapView.links.utils import get_map_link 29 from eve.client.script.ui.shared.maps.mapcommon import STARMODE_SECURITY 30 from eve.client.script.util.settings import IsShipHudTopAligned 31 from eve.common.lib import appConst as const 32 from localization import GetByLabel 33 from security.client.const import get_range_id_by_security_status, SAFE_SEC 34 from security.client.securityColor import get_security_status_color 35 from signals import Signal 36 37 class LightEmittingDiode(Container): 38 __guid__ = 'shipSafetyButton.LightEmittingDiode' 39 default_color = (1, 0, 0, 1) 40 default_align = uiconst.TOPLEFT 41 default_width = 32 42 default_height = 32 43 44 def ApplyAttributes(self, attributes): 45 Container.ApplyAttributes(self, attributes) 46 self.isAnimating = False 47 self.colorSprite = Sprite(bgParent=self, texturePath='res:/UI/Texture/CharacterCreation/radiobuttonColor.dds') 48 Sprite(bgParent=self, texturePath='res:/UI/Texture/CharacterCreation/radiobuttonBack.dds', opacity=0.4) 49 Sprite(bgParent=self, texturePath='res:/UI/Texture/CharacterCreation/radiobuttonShadow.dds', color=(0.4, 0.4, 0.4, 0.4)) 50 self.SetColor(attributes.get('color', self.default_color)) 51 52 def SetColor(self, color): 53 self._color = color 54 self.colorSprite.SetRGBA(*color) 55 56 def Blink(self, cycles = 2, audioAlert = True): 57 if not self.isAnimating: 58 self.isAnimating = True 59 self.blinkCurve = uicore.animations.SpColorMorphTo(self.colorSprite, Color.BLACK, self._color, duration=0.5, loops=cycles, curveType=uiconst.ANIM_BOUNCE, callback=self._EndBlink, sleep=False) 60 if audioAlert: 61 sm.GetService('audio').SendUIEvent('crimewatch_locked_play') 62 63 def _EndBlink(self): 64 self.isAnimating = False 65 self.blinkCurve.Stop() 66 self.blinkCurve = None 67 self.SetColor(self._color) 68 69 70 class SafetyTransitionEffect(Container): 71 default_align = uiconst.CENTER 72 default_width = 26 73 default_height = 26 74 default_state = uiconst.UI_DISABLED 75 TEXTURE_STAGE1 = 'res:/UI/Texture/classes/ShipUI/secTrans00.png' 76 TEXTURE_STAGE2 = 'res:/UI/Texture/classes/ShipUI/secTrans01.png' 77 TEXTURE_STAGE3 = 'res:/UI/Texture/classes/ShipUI/secTrans02.png' 78 TEXTURE_STAGE4 = 'res:/UI/Texture/classes/ShipUI/secTrans03.png' 79 80 def ApplyAttributes(self, attributes): 81 super(SafetyTransitionEffect, self).ApplyAttributes(attributes) 82 green = crimewatchConst.Colors.Green.GetRGBA() 83 self.transform0 = Transform(parent=self, name='transEffect0', align=uiconst.TOALL, rotationCenter=(0.5, 0.5)) 84 self.sprite0 = Sprite(parent=self.transform0, name='secTrans0', texturePath=self.TEXTURE_STAGE1, align=uiconst.TOALL, state=uiconst.UI_DISABLED, color=green, blendMode=trinity.TR2_SBM_ADD, opacity=0.0) 85 self.transform1 = Transform(parent=self, name='transEffect1', align=uiconst.TOALL, rotationCenter=(0.5, 0.5)) 86 self.sprite1 = Sprite(parent=self.transform1, name='secTrans1', texturePath=self.TEXTURE_STAGE2, align=uiconst.CENTER, width=self.width + 2, height=self.height + 2, state=uiconst.UI_DISABLED, color=green, blendMode=trinity.TR2_SBM_ADD, opacity=0.0) 87 self.transform2 = Transform(parent=self, name='transEffect2', align=uiconst.TOALL, rotationCenter=(0.5, 0.5)) 88 self.sprite2 = Sprite(parent=self.transform2, name='secTrans2', texturePath=self.TEXTURE_STAGE3, align=uiconst.CENTER, width=self.width + 2, height=self.height + 2, state=uiconst.UI_DISABLED, color=green, blendMode=trinity.TR2_SBM_ADD, opacity=0.0) 89 self.transform2_inner = Transform(parent=self, name='transEffect2Inner', align=uiconst.TOALL, rotationCenter=(0.5, 0.5)) 90 self.sprite2_inner = Sprite(parent=self.transform2_inner, name='secTrans2Inner', texturePath=self.TEXTURE_STAGE4, align=uiconst.CENTER, width=self.width + 2, height=self.height + 2, state=uiconst.UI_DISABLED, color=green, blendMode=trinity.TR2_SBM_ADD, opacity=0.0) 91 92 def play_transition(self): 93 uthread.new(self._animate_transition) 94 95 def _animate_transition(self): 96 rot2 = radians(45) 97 rot3 = radians(45) 98 self.transform0.SetRotation(0) 99 self.transform1.SetRotation(0) 100 self.transform2.SetRotation(0) 101 self.sprite0.opacity = 0.0 102 self.sprite1.opacity = 0.0 103 self.sprite2.opacity = 0.0 104 self.sprite2_inner.opacity = 0.0 105 blue.pyos.synchro.SleepSim(200) 106 if self.destroyed: 107 return 108 uicore.animations.FadeTo(self.sprite0, startVal=0.0, endVal=0.6, duration=0.2, sleep=True) 109 if self.destroyed: 110 return 111 blue.pyos.synchro.SleepSim(200) 112 if self.destroyed: 113 return 114 uicore.animations.FadeTo(self.sprite0, startVal=0.6, endVal=0.0, duration=0.2) 115 uicore.animations.Tr2DRotateTo(self.transform1, startAngle=0.0, endAngle=rot2, duration=0.2) 116 uicore.animations.FadeTo(self.sprite1, startVal=0.0, endVal=1.0, duration=0.2, sleep=True) 117 if self.destroyed: 118 return 119 uicore.animations.FadeTo(self.sprite1, startVal=1.0, endVal=0.5, duration=0.1, sleep=True) 120 if self.destroyed: 121 return 122 blue.pyos.synchro.SleepSim(300) 123 if self.destroyed: 124 return 125 uicore.animations.FadeTo(self.sprite2, startVal=0.0, endVal=1.0, duration=0.3) 126 uicore.animations.Tr2DRotateTo(self.transform2, startAngle=rot3, endAngle=0.0, duration=0.3, sleep=True) 127 if self.destroyed: 128 return 129 blue.pyos.synchro.SleepSim(300) 130 if self.destroyed: 131 return 132 uicore.animations.FadeTo(self.sprite2_inner, startVal=0.0, endVal=1.0, duration=0.2, sleep=True) 133 134 def show_static(self): 135 self.sprite0.opacity = 0.0 136 self.sprite1.opacity = 0.5 137 self.transform1.SetRotation(radians(TRANSITION_STAGE2_ROTATION_DEG)) 138 self.sprite2.opacity = 1.0 139 self.transform2.SetRotation(radians(TRANSITION_STAGE3_ROTATION_DEG)) 140 self.sprite2_inner.opacity = 1.0 141 self.transform2_inner.SetRotation(radians(TRANSITION_STAGE3_ROTATION_DEG)) 142 143 def clear(self, animate = True): 144 if animate and (self.sprite0.opacity > 0.0 or self.sprite1.opacity > 0.0 or self.sprite2.opacity > 0.0 or self.sprite2_inner.opacity > 0.0): 145 curveSet = uicore.animations.FadeOut(self.sprite0, duration=0.3) 146 uicore.animations.FadeOut(self.sprite1, duration=0.3, curveSet=curveSet) 147 uicore.animations.FadeOut(self.sprite2, duration=0.3, curveSet=curveSet) 148 uicore.animations.FadeOut(self.sprite2_inner, duration=0.3, curveSet=curveSet) 149 else: 150 self.sprite0.opacity = 0.0 151 self.sprite1.opacity = 0.0 152 self.sprite2.opacity = 0.0 153 self.sprite2_inner.opacity = 0.0 154 155 156 class SafetyButton(Container): 157 default_align = uiconst.TOPLEFT 158 default_width = 24 159 default_height = 24 160 default_state = uiconst.UI_NORMAL 161 default_hintDelay = HINT_DELAY 162 __notifyevents__ = ['OnSafetyLevelChanged', 'OnCrimewatchSafetyCheckFailed', 'OnSessionChanged'] 163 164 def ApplyAttributes(self, attributes): 165 super(SafetyButton, self).ApplyAttributes(attributes) 166 sm.RegisterNotify(self) 167 self.selector = None 168 self.content = Container(parent=self, name='content', align=uiconst.TOPLEFT, state=uiconst.UI_DISABLED, pos=(0, 0, 24, 24)) 169 self.hilite = Sprite(parent=self.content, name='hilite', align=uiconst.TOALL, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/ShipUI/utilBtnBaseAndShadow.png', color=(0.63, 0.63, 0.63, 1.0), blendMode=trinity.TR2_SBM_ADD, scale=(0.75, 0.75), display=False) 170 Sprite(parent=self.content, name='baseButton', align=uiconst.TOALL, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/ShipUI/utilBtnBaseAndShadow.png', scale=(0.75, 0.75)) 171 Sprite(parent=self, name='busy', align=uiconst.TOALL, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/ShipUI/utilBtnGlow.png', color=(0, 0, 0, 0.8)) 172 self.led = LightEmittingDiode(parent=self.content, align=uiconst.CENTER) 173 self.transitionEffect = SafetyTransitionEffect(parent=self) 174 self.update_safety_level() 175 self._update_starter_space_effect(animate=True) 176 177 def can_be_modified(self): 178 return not sm.GetService('crimewatchSvc').IsSafetyLockedToFullLevel() 179 180 def update_safety_level(self): 181 safetyLevel = sm.GetService('crimewatchSvc').GetSafetyLevel() 182 self.SetSafetyLevel(safetyLevel, doAlert=False) 183 184 def SetSafetyLevel(self, safetyLevel, doAlert = True): 185 color = shipSafetyConst.COLOR[safetyLevel] 186 self.led.SetColor(color.GetRGBA()) 187 if doAlert: 188 audioEvent = shipSafetyConst.AUDIO_EVENT[safetyLevel] 189 sm.GetService('audio').SendUIEvent(audioEvent) 190 191 def GetHint(self): 192 if self.selector: 193 return None 194 safety_level = sm.GetService('crimewatchSvc').GetSafetyLevel() 195 color = shipSafetyConst.COLOR[safety_level] 196 hint = GetByLabel(shipSafetyConst.STATE_TEXT[safety_level], color=color.GetHex()) 197 locked_to_full_reason = sm.GetService('crimewatchSvc').IsSafetyLockedToFullLevel() 198 if locked_to_full_reason: 199 hint += '\n\n' + locked_to_full_reason 200 button_hint = shipSafetyConst.STATE_HINT[safety_level] 201 hint += '\n\n' + GetByLabel(button_hint, color=color.GetHex()) 202 return hint 203 204 def OnMouseEnter(self): 205 PlaySound(uiconst.SOUND_BUTTON_HOVER) 206 self.hilite.display = True 207 208 def OnMouseExit(self): 209 self.hilite.display = False 210 211 def OnClick(self): 212 if self.selector: 213 return 214 PlaySound(uiconst.SOUND_EXPAND) 215 self.selector = SafetyLevelSelector(parent=uicore.layer.abovemain, anchor=self, width=280 * fontconst.fontSizeFactor) 216 self.selector.on_closed.connect(self.on_selector_closed) 217 218 def on_selector_closed(self): 219 self.selector = None 220 221 def OnMouseDown(self, btn, *args): 222 self.content.top = 1 223 224 def OnMouseUp(self, *args): 225 self.content.top = 0 226 227 def OnSafetyLevelChanged(self, safetyLevel): 228 self.SetSafetyLevel(safetyLevel) 229 if self.selector is None or self.selector.destroyed: 230 return 231 self.selector.state = uiconst.UI_DISABLED 232 while self.selector.confirmationButton and not self.selector.confirmationButton.destroyed: 233 blue.pyos.synchro.SleepSim(25) 234 235 self.selector.SetSafetyLevel(safetyLevel) 236 blue.pyos.synchro.SleepSim(500) 237 if self.selector: 238 self.selector.CloseSelector() 239 self.led.Blink(audioAlert=False) 240 241 def OnCrimewatchSafetyCheckFailed(self): 242 self.led.Blink() 243 244 def _update_starter_space_effect(self, animate = False): 245 if sm.GetService('crimewatchSvc').IsSafetyLockedToFullLevel(): 246 if animate: 247 self.transitionEffect.play_transition() 248 else: 249 self.transitionEffect.show_static() 250 else: 251 self.transitionEffect.clear(animate=animate) 252 253 def OnSessionChanged(self, isRemote, sess, change): 254 if 'solarsystemid' not in change: 255 return 256 self._update_starter_space_effect(animate=True) 257 258 259 class SafetyLevelSelector(ContainerAutoSize): 260 __guid__ = 'shipSafetyButton.SafetyLevelSelector' 261 default_width = 250 262 default_state = uiconst.UI_NORMAL 263 default_align = uiconst.TOPLEFT 264 default_alignMode = uiconst.TOTOP 265 default_name = 'SafetyLevelSelector' 266 267 def __init__(self, anchor, **kwargs): 268 super(SafetyLevelSelector, self).__init__(**kwargs) 269 currentSafetyLevel = sm.GetService('crimewatchSvc').GetSafetyLevel() 270 self.isTabStop = True 271 self.confirmationButton = None 272 self.anchor = anchor 273 self.on_closed = Signal('on_closed') 274 self.lineTrace = None 275 self.construct_layout(currentSafetyLevel) 276 self.on_size_changed.connect(self._on_size_changed) 277 self.anim_entry() 278 279 def _on_size_changed(self, width, height): 280 align_to_top = IsShipHudTopAligned() 281 self.SetPosition(align_to_top) 282 self.DrawFrame(align_to_top) 283 self.DrawPointer(align_to_top) 284 285 def construct_layout(self, currentSafetyLevel): 286 self.construct_text() 287 self.construct_buttons(currentSafetyLevel) 288 self.construct_bg() 289 290 def construct_bg(self): 291 FillThemeColored(bgParent=self, opacity=OPACITY_BG) 292 293 def anim_entry(self): 294 self.opacity = 0.0 295 uicore.animations.FadeIn(self, duration=0.1, loops=1) 296 uicore.registry.SetFocus(self) 297 298 def update_height(self): 299 height = 0 300 for container in self.children: 301 if container.GetAlign() == uiconst.TOTOP: 302 height += container.height 303 304 self.height = height 305 306 def construct_text(self): 307 textCont = LayoutGrid(parent=self, align=uiconst.TOTOP, name='textCont', columns=1, cellSpacing=8, margin=16) 308 styles.TextHeader(parent=textCont, text=localization.GetByLabel('UI/Crimewatch/SafetyLevel/SafetySettingsCaption')) 309 bodyText = localization.GetByLabel('UI/Crimewatch/SafetyLevel/SafetyLevelSelectionBody', suspectColor=crimewatchConst.Colors.Yellow.GetHex(), criminalColor=crimewatchConst.Colors.Red.GetHex()) 310 styles.TextBody(parent=textCont, text=bodyText, maxWidth=self.width - 32) 311 security_status = sm.GetService('map').GetSystemSecurityValue(session.solarsystemid2) 312 security_level = get_range_id_by_security_status(session.solarsystemid2, security_status) 313 if security_level == SAFE_SEC: 314 Container(parent=textCont, name='safeSecCont', align=uiconst.TOTOP, height=1, bgColor=TextColor.DISABLED) 315 TextBody(parent=textCont, align=uiconst.TOTOP, state=uiconst.UI_NORMAL, pickState=PickState.ON, text=localization.GetByLabel('UI/SecurityStatus/StarterSecSafetyMessage', color=Color.RGBtoHex(*get_security_status_color(security_status)), link=localization.GetByLabel('UI/SecurityStatus/ShowOnMap', link=get_map_link(localization.GetByLabel('UI/SecurityStatus/LinkText'), None, STARMODE_SECURITY, get_range_id_by_security_status(session.solarsystemid2, security_status))))) 316 Container(parent=textCont, name='safeSecCont', align=uiconst.TOTOP, height=1, bgColor=TextColor.DISABLED) 317 318 def construct_buttons(self, currentSafetyLevel): 319 self.securityButtons = [] 320 for safetyLevel in (const.shipSafetyLevelNone, const.shipSafetyLevelPartial, const.shipSafetyLevelFull): 321 cont = ContainerAutoSize(parent=self, name='SecButtonCont', align=uiconst.TOTOP, alignMode=Align.CENTERTOP, padBottom=16) 322 securityButton = SecurityButton(parent=cont, safetyLevel=safetyLevel, align=uiconst.CENTERTOP, width=160 * fontconst.fontSizeFactor) 323 securityButton.SetSelected(safetyLevel == currentSafetyLevel) 324 securityButton.OnClick = (self.OnSecurityButtonClick, securityButton) 325 self.securityButtons.append(securityButton) 326 327 if sm.GetService('crimewatchSvc').IsSafetyLockedToFullLevel(): 328 for button in self.securityButtons: 329 if button.safetyLevel == const.shipSafetyLevelFull: 330 button.text.SetText(GetByLabel('UI/Crimewatch/SafetyLevel/SafetyButtonLocked')) 331 332 def DrawPointer(self, alignToTop): 333 pointerWidth = DOCK_POINTER_LENGTH * 2 334 pointerSideWidth = int(DOCK_POINTER_LENGTH * 2 / sqrt(2)) 335 pointerSideWidthHalf = pointerSideWidth / 2 336 if alignToTop: 337 clipperAlign = uiconst.CENTERTOP 338 transformAlign = uiconst.CENTERBOTTOM 339 else: 340 clipperAlign = uiconst.CENTERBOTTOM 341 transformAlign = uiconst.CENTERTOP 342 clipperCont = Container(name='clipper', parent=self, width=pointerWidth, height=DOCK_POINTER_LENGTH, clipChildren=True, align=clipperAlign, top=-DOCK_POINTER_LENGTH) 343 transform = Transform(name='transform', parent=clipperCont, align=transformAlign, rotation=pi / 4, width=pointerSideWidth, height=pointerSideWidth, top=-pointerSideWidthHalf) 344 FillThemeColored(bgParent=transform, opacity=OPACITY_BG) 345 346 def SetPosition(self, alignToTop): 347 left, top, width, height = self.anchor.GetAbsolute() 348 if alignToTop: 349 self.top = top + (self.anchor.height + DOCK_POINTER_LENGTH + DOCK_MARGIN) 350 else: 351 self.top = top - (self.height + DOCK_POINTER_LENGTH + DOCK_MARGIN) 352 self.left = left + (self.anchor.width - self.width) * 0.5 353 354 def DrawFrame(self, alignToTop): 355 if alignToTop: 356 pointList = ((0, 0), 357 ((self.width - DOCK_POINTER_LENGTH * 2) * 0.5, 0), 358 (self.width * 0.5, -DOCK_POINTER_LENGTH), 359 ((self.width + DOCK_POINTER_LENGTH * 2) * 0.5, 0), 360 (self.width, 0), 361 (self.width, self.height), 362 (0, self.height)) 363 else: 364 pointList = ((0, 0), 365 (self.width, 0), 366 (self.width, self.height), 367 ((self.width + DOCK_POINTER_LENGTH * 2) * 0.5, self.height), 368 (self.width * 0.5, self.height + DOCK_POINTER_LENGTH), 369 ((self.width - DOCK_POINTER_LENGTH * 2) * 0.5, self.height), 370 (0, self.height)) 371 if self.lineTrace is not None: 372 self.lineTrace.Close() 373 self.lineTrace = VectorLineTrace(name='Frame', parent=self, lineWidth=1.0, spriteEffect=trinity.TR2_SFX_FILL) 374 self.lineTrace.isLoop = True 375 for point in pointList: 376 x, y = point 377 color = sm.GetService('uiColor').GetUIColor(uiconst.COLORTYPE_UIHILIGHT) 378 color = color[:3] + (0.25,) 379 self.lineTrace.AddPoint((x, y), color) 380 381 def OnKillFocus(self): 382 if not self.confirmationButton or self.confirmationButton.destroyed: 383 uthread.new(self.Close) 384 385 def CloseSelector(self): 386 uicore.animations.FadeOut(self, sleep=True) 387 self.Close() 388 389 def Close(self): 390 super(SafetyLevelSelector, self).Close() 391 self.on_closed() 392 393 def OnSecurityButtonClick(self, securityButton): 394 if securityButton.IsLocked(): 395 return 396 if self.confirmationButton and not self.confirmationButton.destroyed: 397 return 398 PlaySound(uiconst.SOUND_BUTTON_CLICK) 399 currentSafetyLevel = sm.GetService('crimewatchSvc').GetSafetyLevel() 400 for button in self.securityButtons: 401 if button.safetyLevel == securityButton.safetyLevel: 402 button.Blink() 403 if securityButton.safetyLevel < currentSafetyLevel: 404 self.confirmationButton = SafetyConfirmButton(parent=button.parent, left=8, color=shipSafetyConst.COLOR[securityButton.safetyLevel].GetRGBA(), idx=0, align=uiconst.CENTERRIGHT, safetyButton=button) 405 button.Highlight(False) 406 button.Pin() 407 uicore.registry.SetFocus(self.confirmationButton) 408 else: 409 sm.GetService('crimewatchSvc').SetSafetyLevel(securityButton.safetyLevel) 410 411 def SetSafetyLevel(self, safetyLevel): 412 selected = None 413 for button in self.securityButtons: 414 if button.safetyLevel == safetyLevel: 415 selected = button 416 else: 417 button.SetSelected(False) 418 419 selected.SetSelected(True, sleep=True) 420 421 422 class SecurityButton(Container): 423 default_height = 36 424 default_align = uiconst.TOPLEFT 425 default_state = uiconst.UI_NORMAL 426 default_hintDelay = HINT_DELAY 427 lineWidth = 5.0 428 lineSeperation = 14.0 429 430 def ApplyAttributes(self, attributes): 431 super(SecurityButton, self).ApplyAttributes(attributes) 432 self.pinned = False 433 self.isSelected = False 434 self.safetyLevel = attributes.get('safetyLevel') 435 cont = Container(name='content', parent=self, padding=3) 436 color = shipSafetyConst.COLOR[self.safetyLevel] 437 button_text = GetByLabel(shipSafetyConst.ACTION_LABEL[self.safetyLevel]) 438 self.text = eveLabel.EveHeaderSmall(name='buttonLabel', parent=cont, color=color.GetRGBA(), text=button_text, align=uiconst.CENTER, opacity=DESELECTED_BUTTON_OPACITY) 439 self.defaultSprite = Sprite(parent=self, name='default', texturePath='res:/UI/Texture/Crimewatch/SafetyButton_Default.png', align=uiconst.TOALL, state=uiconst.UI_DISABLED, color=color.GetRGBA(), opacity=DESELECTED_BUTTON_OPACITY) 440 self.highlightSprite = Sprite(parent=self, name='highlight', texturePath='res:/UI/Texture/Crimewatch/SafetyButton_Highlight.png', align=uiconst.TOALL, state=uiconst.UI_DISABLED, color=color.GetRGBA()) 441 self.highlightSprite.Hide() 442 self.leftArrowSprite = Sprite(parent=self, name='leftArrows', texturePath='res:/UI/Texture/Crimewatch/Safety_Selection.png', align=uiconst.CENTERLEFT, pos=(-24, 0, 16, 13), state=uiconst.UI_DISABLED, color=color.GetRGBA(), opacity=0.0) 443 self.rightArrows = Transform(parent=self, name='rightArrowsTranform', align=uiconst.CENTERRIGHT, pos=(-24, 0, 16, 13), state=uiconst.UI_DISABLED, rotation=pi) 444 self.rightArrowSprite = Sprite(parent=self.rightArrows, name='rightArrows', texturePath='res:/UI/Texture/Crimewatch/Safety_Selection.png', align=uiconst.CENTERRIGHT, pos=(0, 0, 16, 13), state=uiconst.UI_DISABLED, color=color.GetRGBA(), opacity=0.0) 445 446 def IsLocked(self): 447 if sm.GetService('crimewatchSvc').IsSafetyLockedToFullLevel(): 448 return self.safetyLevel != const.shipSafetyLevelFull 449 return self.IsAlphaLockedAndRed() 450 451 def IsAlphaLockedAndRed(self): 452 if sm.GetService('crimewatchSvc').IsSafetyAlphaLocked(): 453 return self.safetyLevel == const.shipSafetyLevelNone 454 return False 455 456 def GetHint(self): 457 color = shipSafetyConst.COLOR[self.safetyLevel] 458 parts = [] 459 if self.IsAlphaLockedAndRed(): 460 parts.append(GetByLabel('UI/Crimewatch/SafetyLevel/SafetyButtonNoneOptionHintAlphaLocked')) 461 button_hint = shipSafetyConst.STATE_HINT[self.safetyLevel] 462 parts.append(GetByLabel(button_hint, color=color.GetHex())) 463 return '\n\n'.join(parts) 464 465 def GetTooltipPointer(self): 466 return uiconst.POINT_RIGHT_2 467 468 def Pin(self): 469 self.pinned = True 470 self.text.opacity = 1.0 471 self.defaultSprite.opacity = 1.0 472 473 def Unpin(self): 474 self.pinned = False 475 self.text.opacity = DESELECTED_BUTTON_OPACITY 476 self.defaultSprite.opacity = DESELECTED_BUTTON_OPACITY 477 478 def SetSelected(self, selected, sleep = False): 479 self.isSelected = selected 480 if selected: 481 self.text.opacity = 1.0 482 self.defaultSprite.opacity = 1.0 483 self.leftArrowSprite.opacity = 1.0 484 self.rightArrowSprite.opacity = 1.0 485 curveSet = uicore.animations.MoveInFromLeft(self.leftArrowSprite, loops=1, duration=0.4, amount=20) 486 uicore.animations.MoveInFromRight(self.rightArrowSprite, loops=1, duration=0.4, amount=20, curveSet=curveSet, sleep=sleep) 487 else: 488 self.text.opacity = DESELECTED_BUTTON_OPACITY 489 self.defaultSprite.opacity = DESELECTED_BUTTON_OPACITY 490 if self.leftArrowSprite.opacity > 0.0 or self.rightArrowSprite.opacity > 0.0: 491 curveSet = uicore.animations.FadeOut(self.leftArrowSprite, duration=0.25) 492 uicore.animations.FadeOut(self.rightArrowSprite, duration=0.25, curveSet=curveSet) 493 494 def Highlight(self, enable): 495 if self.IsLocked(): 496 return 497 if enable and not self.IsConfirmButtonActive(): 498 self.defaultSprite.Hide() 499 self.highlightSprite.Show() 500 self.text.opacity = 1.0 501 else: 502 self.defaultSprite.Show() 503 self.highlightSprite.Hide() 504 if self.isSelected or self.pinned: 505 self.text.opacity = 1.0 506 else: 507 self.text.opacity = DESELECTED_BUTTON_OPACITY 508 509 def OnMouseEnter(self): 510 if not self.IsLocked(): 511 PlaySound(uiconst.SOUND_BUTTON_HOVER) 512 self.Highlight(True) 513 514 def OnMouseExit(self): 515 if not self.IsLocked(): 516 self.Highlight(False) 517 518 def IsConfirmButtonActive(self): 519 return not (self.parent.parent.confirmationButton is None or self.parent.parent.confirmationButton.destroyed) 520 521 def Blink(self, sleep = True): 522 color = shipSafetyConst.COLOR[self.safetyLevel] 523 curveSet = uicore.animations.SpGlowFadeTo(self.highlightSprite, startColor=color.GetRGBA(), glowExpand=0.0) 524 uicore.animations.SpGlowFadeTo(self.defaultSprite, startColor=color.GetRGBA(), glowExpand=0.0, curveSet=curveSet) 525 526 527 class SafetyConfirmButton(Container): 528 default_width = 50 529 default_height = 32 530 default_state = uiconst.UI_NORMAL 531 default_align = uiconst.TOPRIGHT 532 default_name = 'SafetyConfirmButton' 533 default_hintDelay = HINT_DELAY 534 535 def ApplyAttributes(self, attributes): 536 super(SafetyConfirmButton, self).ApplyAttributes(attributes) 537 self.isTabStop = True 538 self.canBeModified = attributes.get('canBeModified', True) 539 self.safetyButton = attributes.get('safetyButton') 540 self.color = attributes.get('color', (1, 1, 1, 1)) 541 self.bgColor = (self.color[0] * 0.3, 542 self.color[1] * 0.3, 543 self.color[2] * 0.3, 544 1.0) 545 self.label = eveLabel.EveLabelSmall(parent=self, text=localization.GetByLabel('UI/Common/Confirm'), color=self.color, align=uiconst.CENTER) 546 self.frame = Frame(parent=self, frameConst=('ui_105_32_1', 8, -4), color=self.color, opacity=0.5) 547 self.fill = Fill(parent=self, color=self.bgColor) 548 color = shipSafetyConst.COLOR[self.safetyButton.safetyLevel] 549 self.SetHint(localization.GetByLabel('UI/Crimewatch/SafetyLevel/SafetyConfirmHint', color=color.GetHex())) 550 width, _ = self.label.GetAbsoluteSize() 551 self.width = max(self.width, width + 4) 552 553 def OnMouseEnter(self): 554 if self.canBeModified: 555 PlaySound(uiconst.SOUND_BUTTON_HOVER) 556 self.label.SetTextColor(Color.WHITE) 557 558 def OnMouseExit(self): 559 if self.canBeModified: 560 self.label.SetTextColor(self.color) 561 562 def OnClick(self): 563 if not self.canBeModified: 564 return 565 PlaySound(uiconst.SOUND_BUTTON_CLICK) 566 self.state = uiconst.UI_DISABLED 567 self.safetyButton.Blink() 568 self.Blink() 569 sm.GetService('crimewatchSvc').SetSafetyLevel(self.safetyButton.safetyLevel) 570 uthread.new(self._CloseButton) 571 572 def OnKillFocus(self): 573 uthread.new(self._CloseButton) 574 575 def _CloseButton(self): 576 if not self or self.destroyed: 577 return 578 self.safetyButton.Unpin() 579 uicore.registry.SetFocus(self.parent.parent) 580 uicore.animations.FadeOut(self, duration=0.1, sleep=True) 581 self.Close() 582 583 def Blink(self): 584 curveSet = uicore.animations.SpGlowFadeTo(self.frame, startColor=self.color, glowExpand=0.0) 585 uicore.animations.SpGlowFadeTo(self.fill, glowExpand=0.0, startColor=self.bgColor, curveSet=curveSet, sleep=True) 586 587 def GetTooltipPointer(self): 588 return uiconst.POINT_LEFT_2