bracket.py (47699B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\inflight\bracket.py 2 import math 3 import appConst 4 import weakref 5 from carbon.common.script.util import timerstuff 6 from carbon.common.script.util.format import FmtAmt, FmtDist 7 from carbonui import fontconst 8 from carbonui.control.label import LabelCore 9 from carbonui.primitives.bracket import Bracket as BracketCore 10 from carbonui.primitives.container import Container 11 from carbonui.primitives.base import ScaleDpi 12 from carbonui.primitives.fill import Fill 13 from carbonui.primitives.frame import Frame 14 from carbonui.primitives.sprite import Sprite 15 import overviewPresets.overviewSettingsConst as osConst 16 from carbonui.util.dpi import ReverseScaleDpi 17 from eve.client.script.ui.inflight.bracketsAndTargets import bracketVarious 18 from eve.client.script.ui.inflight.bracketsAndTargets.activeTargetIndicator import ActiveTargetIndicator 19 from eve.client.script.ui.inflight.bracketsAndTargets.activeTargetIndicator import TargetedIndicator 20 from eve.client.script.ui.control.eveLabel import Label 21 from eve.client.script.ui.control.eveIcon import Icon 22 from eve.client.script.ui.control.eveLabel import EveLabelSmall 23 from eve.client.script.ui.control.eveHint import BubbleHint 24 from eve.client.script.ui.inflight.bracketsAndTargets.bracket_attachment_mixin import BracketAttachmentMixin 25 from eve.client.script.ui.shared.fleet.fleetBroadcastConst import iconsByBroadcastType 26 from eve.client.script.ui.shared.stateFlag import FlagIconWithState, GetExtraInfoForSlimItem 27 import evetypes 28 import blue 29 import telemetry 30 import uthread 31 from eve.client.script.parklife import states as state 32 import trinity 33 from eve.client.script.ui.shared.fleet import fleetbroadcastexports as fleetbr 34 import carbonui.const as uiconst 35 from eve.client.script.ui.shared.maps import maputils 36 import localization 37 from eve.client.script.util.bubble import SlimItemFromCharID 38 from eve.common.script.mgt.entityConst import POS_STRUCTURE_STATE 39 from carbonui.uicore import uicore 40 from eve.common.script.sys import idCheckers 41 from eveservices.menu import GetMenuService 42 from spacecomponents.common.helper import HasEntityStandingsComponent 43 SHOWLABELS_NEVER = 0 44 SHOWLABELS_ONMOUSEENTER = 1 45 SHOWLABELS_ALWAYS = 2 46 TARGETTING_UI_UPDATE_RATE = 50 47 LABELMARGIN = 6 48 49 class BracketShadowLabel(BracketAttachmentMixin, Container): 50 displayText = None 51 default_fontsize = fontconst.EVE_SMALL_FONTSIZE 52 default_fontStyle = fontconst.STYLE_SMALLTEXT 53 54 def __init__(self, bracket = None, text = '', fontsize = fontconst.EVE_SMALL_FONTSIZE, fontStyle = fontconst.STYLE_SMALLTEXT, bold = False, **kwargs): 55 super(BracketShadowLabel, self).__init__(bracket=bracket, **kwargs) 56 self.top = -500 57 self.renderObject.displayY = -500.0 58 self.DelegateEvents(bracket) 59 self.construct_label(bold, fontStyle, fontsize, text) 60 self.text = text 61 62 def construct_label(self, bold, fontStyle, fontsize, text): 63 self.mainLabel = LabelCore(parent=self, state=uiconst.UI_DISABLED, align=uiconst.CENTERLEFT, color=(1, 1, 1, 1), fontsize=fontsize, fontStyle=fontStyle, bold=bold, shadowOffset=(1, 1)) 64 65 @property 66 def text(self): 67 return self.mainLabel.text 68 69 @text.setter 70 def text(self, value): 71 self.mainLabel.text = value 72 self.width = self.mainLabel.width 73 self.height = self.mainLabel.height 74 75 @property 76 def textwidth(self): 77 return self.mainLabel.textwidth 78 79 @property 80 def textheight(self): 81 return self.mainLabel.textheight 82 83 84 class BracketLabel(Label): 85 default_fontsize = fontconst.EVE_SMALL_FONTSIZE 86 default_fontStyle = fontconst.STYLE_SMALLTEXT 87 displayText = None 88 89 def ApplyAttributes(self, attributes): 90 Label.ApplyAttributes(self, attributes) 91 bracket = attributes.bracket 92 cs = uicore.uilib.bracketCurveSet 93 xBinding = trinity.CreateBinding(cs, bracket.renderObject, 'displayX', self.renderObject, 'displayX') 94 yBinding = trinity.CreateBinding(cs, bracket.renderObject, 'displayY', self.renderObject, 'displayY') 95 self.bindings = (xBinding, yBinding) 96 self.OnMouseUp = bracket.OnMouseUp 97 self.OnMouseDown = bracket.OnMouseDown 98 self.OnMouseEnter = bracket.OnMouseEnter 99 self.OnMouseExit = bracket.OnMouseExit 100 self.OnMouseHover = bracket.OnMouseHover 101 self.OnClick = bracket.OnClick 102 self.OnDblClick = bracket.OnDblClick 103 self.GetMenu = bracket.GetMenu 104 105 @property 106 def x_offset(self): 107 return ReverseScaleDpi(self.bindings[0].offset[0]) 108 109 @x_offset.setter 110 def x_offset(self, value): 111 self.bindings[0].offset = (ScaleDpi(value), 112 0, 113 0, 114 0) 115 116 @property 117 def y_offset(self): 118 return ReverseScaleDpi(self.bindings[1].offset[0]) 119 120 @y_offset.setter 121 def y_offset(self, value): 122 self.bindings[1].offset = (ScaleDpi(value), 123 0, 124 0, 125 0) 126 127 def Close(self, *args, **kw): 128 if getattr(self, 'bindings', None): 129 cs = uicore.uilib.bracketCurveSet 130 for each in self.bindings: 131 if cs and each in cs.bindings: 132 cs.bindings.remove(each) 133 134 self.OnMouseUp = None 135 self.OnMouseDown = None 136 self.OnMouseEnter = None 137 self.OnMouseExit = None 138 self.OnMouseHover = None 139 self.OnClick = None 140 self.GetMenu = None 141 super(BracketLabel, self).Close() 142 143 @apply 144 def displayX(): 145 fget = Label.displayX.fget 146 147 def fset(self, value): 148 pass 149 150 return property(**locals()) 151 152 @apply 153 def displayY(): 154 fget = Label.displayY.fget 155 156 def fset(self, value): 157 pass 158 159 return property(**locals()) 160 161 @apply 162 def displayRect(): 163 fget = Label.displayRect.fget 164 165 def fset(self, value): 166 displayX, displayY, displayWidth, displayHeight = value 167 self._displayWidth = int(round(displayWidth)) 168 self._displayHeight = int(round(displayHeight)) 169 ro = self.renderObject 170 if ro: 171 ro.displayWidth = self._displayWidth 172 ro.displayHeight = self._displayHeight 173 if self.isAffectedByPushAlignment: 174 ro.textWidth = ro.displayWidth 175 ro.textHeight = ro.displayHeight 176 else: 177 ro.textWidth = ScaleDpi(self.width) 178 ro.textHeight = ScaleDpi(self.height) 179 180 return property(**locals()) 181 182 183 class BracketSubIcon(Icon): 184 185 def ApplyAttributes(self, attributes): 186 Icon.ApplyAttributes(self, attributes) 187 bracket = attributes.bracket 188 cs = uicore.uilib.bracketCurveSet 189 xBinding = trinity.CreateBinding(cs, bracket.renderObject, 'displayX', self.renderObject, 'displayX') 190 yBinding = trinity.CreateBinding(cs, bracket.renderObject, 'displayY', self.renderObject, 'displayY') 191 self.bindings = (xBinding, yBinding) 192 self.OnMouseUp = bracket.OnMouseUp 193 self.OnMouseDown = bracket.OnMouseDown 194 self.OnMouseEnter = bracket.OnMouseEnter 195 self.OnMouseExit = bracket.OnMouseExit 196 self.OnMouseHover = bracket.OnMouseHover 197 self.OnClick = bracket.OnClick 198 self.GetMenu = bracket.GetMenu 199 200 def Close(self, *args, **kw): 201 if getattr(self, 'bindings', None): 202 cs = uicore.uilib.bracketCurveSet 203 for each in self.bindings: 204 if cs and each in cs.bindings: 205 cs.bindings.remove(each) 206 207 self.OnMouseUp = None 208 self.OnMouseDown = None 209 self.OnMouseEnter = None 210 self.OnMouseExit = None 211 self.OnMouseHover = None 212 self.OnClick = None 213 self.GetMenu = None 214 Icon.Close(self, *args, **kw) 215 216 217 class SimpleBracket(BracketCore): 218 default_width = 16 219 default_height = 16 220 targetingPath = None 221 stateItemID = None 222 fleetBroadcastIcon = None 223 fleetTagAndTarget = None 224 _originalIconColor = None 225 _fleetTag = None 226 _fleetTargetNo = None 227 228 def Startup_update(self, *args): 229 self.targeted_indicator = None 230 231 def ApplyAttributes(self, attributes): 232 super(SimpleBracket, self).ApplyAttributes(attributes) 233 self.IsBracket = 1 234 self.invisible = False 235 self.inflight = False 236 self.categoryID = None 237 self.groupID = None 238 self.itemID = None 239 self.displayName = '' 240 self.displaySubLabel = '' 241 self.sr.icon = None 242 self.sr.flag = None 243 self.sr.bgColor = None 244 self.sr.hilite = None 245 self.selection_sprite = None 246 self.sr.posStatus = None 247 self.slimItem = None 248 self.ball = None 249 self.stateItemID = None 250 self.label = None 251 self.subLabel = None 252 self.fadeColor = True 253 self.iconNo = None 254 self.iconXOffset = 0 255 self.lastPosEvent = None 256 self.scanAttributeChangeFlag = False 257 self.iconTop = 0 258 259 def Close(self, *args, **kw): 260 self.subItemsUpdateTimer = None 261 if getattr(self, 'label', None): 262 self.label.Close() 263 self.label = None 264 if getattr(self, 'subLabel', None): 265 self.subLabel.Close() 266 self.subLabel = None 267 if getattr(self, 'fleetBroadcastIcon', None): 268 self.fleetBroadcastIcon.Close() 269 self.fleetBroadcastIcon = None 270 if getattr(self, 'fleetTagAndTarget', None): 271 self.fleetTagAndTarget.Close() 272 self.fleetTagAndTarget = None 273 super(SimpleBracket, self).Close(*args, **kw) 274 275 def Show(self): 276 projectBracket = self.projectBracket 277 if projectBracket: 278 projectBracket.bracket = self.renderObject 279 super(SimpleBracket, self).Show() 280 281 def Hide(self): 282 super(SimpleBracket, self).Hide() 283 self.KillLabel() 284 projectBracket = self.projectBracket 285 if projectBracket: 286 projectBracket.bracket = None 287 288 def Startup(self, itemID, groupID, categoryID, iconNo): 289 self.iconNo = iconNo 290 self.LoadIcon(iconNo) 291 self.itemID = itemID 292 self.stateItemID = itemID 293 self.groupID = groupID 294 self.categoryID = categoryID 295 296 def LoadIcon(self, iconNo): 297 if self.sr.icon is None: 298 icon = Icon(parent=self, name='mainicon', state=uiconst.UI_DISABLED, pos=(0, 0, 16, 16), icon=iconNo, align=uiconst.RELATIVE) 299 if self.fadeColor: 300 self.color = icon.color 301 else: 302 icon.opacity = 0.75 303 self.sr.icon = icon 304 else: 305 self.sr.icon.LoadIcon(iconNo) 306 307 def ShowLabel(self, *args): 308 if not self.destroyed and (self.displayName == '' or not getattr(self, 'showLabel', True)): 309 return 310 if not self.label: 311 self.label = BracketLabel(parent=self.parent, name='labelparent', idx=0, align=uiconst.TOPLEFT, state=uiconst.UI_NORMAL, text=self.displayName, bracket=self) 312 if not self.subLabel and self.displaySubLabel: 313 self.subLabel = BracketLabel(parent=self.parent, name='sublabelparent', align=uiconst.TOPLEFT, state=uiconst.UI_NORMAL, text=self.displaySubLabel, bracket=self) 314 self.update_attached_objects() 315 316 def KillLabel(self, *args, **kwds): 317 if getattr(self, 'label', None): 318 self.label.Close() 319 if getattr(self, 'subLabel', None): 320 self.subLabel.Close() 321 self.label = None 322 self.subLabel = None 323 self.update_attached_objects() 324 325 def GetMenu(self): 326 return None 327 328 def Select(self, status): 329 if status: 330 if not self.selection_sprite: 331 self.selection_sprite = Sprite(parent=self, pos=(0, 0, 30, 30), name='selection', state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/Bracket/selectionCircle.png', align=uiconst.CENTER, color=(1, 1, 1, 0.5)) 332 self.selection_sprite.display = True 333 self.ShowLabel() 334 else: 335 if self.selection_sprite: 336 self.selection_sprite.state = uiconst.UI_HIDDEN 337 if self.projectBracket and self.projectBracket.bracket: 338 self.KillLabel() 339 340 def Hilite(self, status): 341 if status and self.state != uiconst.UI_HIDDEN: 342 uthread.pool('Bracket::Hilite', self._ShowLabel) 343 elif self.projectBracket and self.projectBracket.bracket and sm.GetService('stateSvc').GetExclState(state.selected) != self.itemID: 344 self.KillLabel() 345 346 def _ShowLabel(self): 347 blue.pyos.synchro.SleepWallclock(50) 348 if self.destroyed: 349 return 350 over = uicore.uilib.mouseOver 351 if getattr(over, 'stateItemID', None) == self.itemID: 352 self.ShowLabel() 353 354 def GetDistance(self): 355 ball = self.ball 356 if ball: 357 return ball.surfaceDist 358 slimItem = self.GetSlimItem() 359 if slimItem: 360 ballPark = sm.GetService('michelle').GetBallpark() 361 if ballPark and slimItem.itemID in ballPark.balls: 362 return ballPark.balls[slimItem.itemID].surfaceDist 363 elif self.trackTransform or self.sr.trackTransform: 364 tf = self.trackTransform or self.sr.trackTransform 365 trans = tf.translation 366 pos = trinity.TriVector(trans[0], trans[1], trans[2]) 367 myPos = maputils.GetMyPos() 368 return (pos - myPos).Length() 369 370 @apply 371 def ball(): 372 doc = '' 373 374 def fget(self): 375 if self._ball: 376 return self._ball() 377 378 def fset(self, value): 379 if value is None: 380 self._ball = None 381 return 382 self._ball = weakref.ref(value) 383 384 return property(**locals()) 385 386 def GetSlimItem(self): 387 return self.slimItem 388 389 def HideBubble(self): 390 if self.sr.bubble is not None: 391 self.sr.bubble.Close() 392 self.sr.bubble = None 393 394 def ShowBubble(self, hint): 395 if self.sr.bubble is not None: 396 self.sr.bubble.Close() 397 self.sr.bubble = None 398 if hint: 399 bubble = BubbleHint(parent=self, name='bubblehint', align=uiconst.TOPLEFT, width=0, height=0, idx=0, state=uiconst.UI_PICKCHILDREN) 400 pointer = {appConst.groupStargate: 5, 401 appConst.groupStation: 3}.get(self.groupID, 0) 402 bubble.ShowHint(hint, pointer) 403 self.sr.bubble = bubble 404 self.sr.bubble.state = uiconst.UI_NORMAL 405 406 def GetLockedPositionTopBottomMargin(self): 407 hasBubble = bool(self.sr.bubble) 408 topMargin = 1 409 bottomMargin = 1 410 if hasBubble: 411 if self.sr.bubble.data[1] in (3, 4, 5): 412 bottomMargin += self.sr.bubble.height + 8 413 elif self.sr.bubble.data[1] in (0, 1, 2): 414 topMargin += self.sr.bubble.height + 8 415 else: 416 if getattr(self, 'subLabel', None): 417 bottomMargin += self.subLabel.textheight 418 if getattr(self, 'fleetTagAndTarget', None): 419 topMargin += self.fleetTagAndTarget.textheight 420 return (topMargin, bottomMargin) 421 422 subItemsUpdateTimer = None 423 424 def OnMouseDown(self, *args): 425 if getattr(self, 'slimItem', None): 426 if GetMenuService().TryExpandActionMenu(self.itemID, self): 427 return 428 sm.GetService('viewState').GetView('inflight').layer.looking = True 429 430 def OnMouseEnter(self, *args): 431 if uicore.uilib.leftbtn: 432 return 433 if self.itemID == sm.GetService('bracket').CheckingOverlaps(): 434 return 435 if not getattr(self, 'invisible', False): 436 sm.GetService('stateSvc').SetState(self.itemID, state.mouseOver, 1) 437 if self.projectBracket and self.projectBracket.bracket: 438 sm.GetService('bracket').CheckOverlaps(self, not getattr(self, 'inflight', 1)) 439 440 def OnMouseExit(self, *args): 441 if uicore.uilib.leftbtn: 442 return 443 if self.projectBracket and self.projectBracket.bracket: 444 if self.itemID == sm.GetService('bracket').CheckingOverlaps(): 445 return 446 sm.GetService('stateSvc').SetState(self.itemID, state.mouseOver, 0) 447 448 def OnClick(self, *args): 449 if self.sr.clicktime and blue.os.TimeDiffInMs(self.sr.clicktime, blue.os.GetWallclockTime()) < 1000.0: 450 sm.GetService('stateSvc').SetState(self.itemID, state.selected, 1) 451 slimItem = getattr(self, 'slimItem', None) 452 if slimItem: 453 if uicore.uilib.Key(uiconst.VK_CONTROL): 454 return 455 GetMenuService().Activate(slimItem) 456 self.sr.clicktime = None 457 else: 458 sm.GetService('stateSvc').SetState(self.itemID, state.selected, 1) 459 if sm.GetService('target').IsTarget(self.itemID): 460 sm.GetService('stateSvc').SetState(self.itemID, state.activeTarget, 1) 461 elif uicore.uilib.Key(uiconst.VK_CONTROL) and uicore.uilib.Key(uiconst.VK_SHIFT): 462 sm.GetService('fleet').SendBroadcast_Target(self.itemID) 463 self.sr.clicktime = blue.os.GetWallclockTime() 464 GetMenuService().TacticalItemClicked(self.itemID) 465 466 def OnDblClick(self, *args): 467 pass 468 469 @telemetry.ZONE_METHOD 470 def Load_update(self, slimItem, *args): 471 if slimItem is None: 472 return 473 self.stateItemID = slimItem.itemID 474 selected, hilited, attacking, hostile, targeting, targeted, activeTarget = sm.GetService('stateSvc').GetStates(self.stateItemID, [state.selected, 475 state.mouseOver, 476 state.threatAttackingMe, 477 state.threatTargetsMe, 478 state.targeting, 479 state.targeted, 480 state.activeTarget]) 481 self.Select(selected) 482 self.Hilite(hilited) 483 self.Targeted(targeted) 484 self.UpdateIconColor(slimItem) 485 self.ActiveTarget(activeTarget) 486 if not activeTarget: 487 self.Targeting(targeting) 488 if not targeting: 489 targeted, = sm.GetService('stateSvc').GetStates(slimItem.itemID, [state.targeted]) 490 self.Targeted(targeted) 491 if self.updateItem: 492 self.UpdateFlagAndBackground(slimItem) 493 self.Attacking(attacking) 494 self.Hostile(not attacking and hostile, attacking) 495 else: 496 if self.sr.flag: 497 self.sr.flag.Close() 498 self.sr.flag = None 499 if self.sr.bgColor: 500 self.sr.bgColor.Close() 501 self.sr.bgColor = None 502 fleetTag = sm.GetService('fleet').GetTargetTag(slimItem.itemID) 503 self.AddFleetTag(fleetTag) 504 if slimItem.groupID == appConst.groupWreck: 505 uthread.worker('bracket.WreckEmpty', self.WreckEmpty, slimItem.isEmpty) 506 broadcastID, broadcastType, broadcastData = sm.GetService('fleet').GetCurrentFleetBroadcastOnItem(slimItem.itemID) 507 if broadcastID is not None: 508 uthread.worker('bracket.UpdateFleetBroadcasts', self.UpdateFleetBroadcasts, broadcastID, broadcastType, broadcastData) 509 510 @telemetry.ZONE_METHOD 511 def UpdateFleetBroadcasts(self, broadcastID, broadcastType, broadcastData): 512 if self.destroyed: 513 return 514 for typeName in iconsByBroadcastType: 515 if broadcastType == getattr(state, 'gb%s' % typeName): 516 handler = getattr(self, 'GB%s' % typeName, None) 517 if handler is None: 518 self.FleetBroadcast(True, typeName, broadcastID, *broadcastData) 519 else: 520 handler(True, broadcastID, *broadcastData) 521 break 522 523 def RefreshBounty(self): 524 self.UpdateFlagAndBackground(self.slimItem) 525 526 @telemetry.ZONE_METHOD 527 def UpdateFlagAndBackground(self, slimItem, *args): 528 if self.destroyed or not self.updateItem: 529 return 530 try: 531 if slimItem.groupID != const.groupAgentsinSpace and (slimItem.ownerID and idCheckers.IsNPC(slimItem.ownerID) or slimItem.charID and idCheckers.IsNPC(slimItem.charID)): 532 if self.sr.flag: 533 self.sr.flag.Close() 534 self.sr.flag = None 535 if self.sr.bgColor: 536 self.sr.bgColor.Close() 537 self.sr.bgColor = None 538 else: 539 stateSvc = sm.GetService('stateSvc') 540 iconFlag, backgroundFlag = stateSvc.GetIconAndBackgroundFlags(slimItem) 541 icon = None 542 if self.sr.icon and self.sr.icon.display: 543 icon = self.sr.icon 544 if icon and iconFlag and iconFlag != -1: 545 if self.sr.flag is None: 546 self.sr.flag = FlagIconWithState(parent=self, left=0, top=0, state=uiconst.UI_DISABLED, align=uiconst.TOPLEFT) 547 flagInfo = stateSvc.GetStatePropsColorAndBlink(iconFlag) 548 self.sr.flag.ModifyIcon(flagInfo=flagInfo, showHint=False, extraInfo=GetExtraInfoForSlimItem(slimItem)) 549 if settings.user.overview.Get(osConst.SETTING_NAME_SMALL_TAGS, 0): 550 self.sr.flag.ChangeFlagPos(icon.left + 10, icon.top + 10, 5, 5) 551 else: 552 self.sr.flag.ChangeFlagPos(icon.left + 9, icon.top + 8, 9, 9) 553 hideIcon = settings.user.overview.Get(osConst.SETTING_NAME_SMALL_TAGS, 0) 554 self.sr.flag.ChangeIconVisibility(display=not hideIcon) 555 props = stateSvc.GetStateProps(iconFlag) 556 col = stateSvc.GetStateFlagColor(iconFlag) 557 blink = stateSvc.GetStateBackgroundBlink(iconFlag) 558 self.sr.flag.children[0].SetRGBA(*props.iconColor) 559 self.sr.flag.children[1].SetRGBA(*col) 560 if blink: 561 if not self.sr.flag.HasAnimation('opacity'): 562 uicore.animations.FadeTo(self.sr.flag, startVal=0.0, endVal=1.0, duration=0.5, loops=uiconst.ANIM_REPEAT, curveType=uiconst.ANIM_WAVE) 563 else: 564 self.sr.flag.StopAnimations() 565 self.sr.flag.opacity = 1.0 566 self.UpdateFlagPositions(icon) 567 if settings.user.overview.Get(osConst.SETTING_NAME_SMALL_TAGS, 0): 568 iconNum = 0 569 else: 570 iconNum = props.iconIndex + 1 571 self.sr.flag.children[0].rectLeft = iconNum * 10 572 self.sr.flag.state = uiconst.UI_DISABLED 573 elif self.sr.flag: 574 self.sr.flag.Close() 575 self.sr.flag = None 576 if backgroundFlag and backgroundFlag != -1: 577 r, g, b, a = stateSvc.GetStateBackgroundColor(backgroundFlag) 578 a = a * 0.5 579 if not self.sr.bgColor: 580 self.sr.bgColor = Fill(name='bgColor', parent=self, state=uiconst.UI_DISABLED, color=(r, 581 g, 582 b, 583 a)) 584 else: 585 self.sr.bgColor.SetRGBA(r, g, b, a) 586 blink = stateSvc.GetStateBackgroundBlink(backgroundFlag) 587 if blink: 588 if not self.sr.bgColor.HasAnimation('opacity'): 589 uicore.animations.FadeTo(self.sr.bgColor, startVal=0.0, endVal=a, duration=0.75, loops=uiconst.ANIM_REPEAT, curveType=uiconst.ANIM_WAVE) 590 else: 591 self.sr.bgColor.StopAnimations() 592 elif self.sr.bgColor: 593 self.sr.bgColor.Close() 594 self.sr.bgColor = None 595 except AttributeError: 596 if not self.destroyed: 597 raise 598 599 def UpdateIconColor(self, slimItem): 600 if self.destroyed: 601 return 602 if self.sr.icon is None or not slimItem: 603 return 604 if self.sr.node and self.sr.node.iconColor is not None and not HasEntityStandingsComponent(slimItem.typeID): 605 iconColor = self.sr.node.iconColor 606 else: 607 iconColor = bracketVarious.GetIconColor(slimItem) 608 self.SetColor(*iconColor) 609 if slimItem.groupID in (appConst.groupWreck, appConst.groupSpawnContainer) and sm.GetService('wreck').IsViewedWreck(slimItem.itemID): 610 self.SetViewState(True) 611 612 def UpdateFlagPositions(self, *args, **kwds): 613 pass 614 615 def CreateFlagMarker(self): 616 flag = Container(parent=self, name='flag', pos=(0, 0, 10, 10), align=uiconst.TOPLEFT, idx=0) 617 icon = Sprite(parent=flag, name='icon', pos=(0, 0, 10, 10), state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/Bracket/flagIcons.png') 618 icon.rectWidth = 10 619 icon.rectHeight = 10 620 Fill(parent=flag) 621 return flag 622 623 def OnStateChange(self, itemID, flag, status, *args): 624 if self.stateItemID != itemID: 625 return 626 if flag == state.mouseOver: 627 self.Hilite(status) 628 elif flag == state.selected: 629 self.Select(status) 630 elif flag == state.targeted: 631 self.Targeted(status) 632 elif flag == state.targeting: 633 self.Targeting(status) 634 elif flag == state.activeTarget: 635 self.ActiveTarget(status) 636 elif flag == state.flagWreckAlreadyOpened: 637 self.SetViewState(status) 638 elif flag == state.flagWreckEmpty: 639 self.WreckEmpty(status) 640 else: 641 for name in iconsByBroadcastType: 642 if flag == getattr(state, 'gb%s' % name): 643 handler = getattr(self, 'GB%s' % name, None) 644 if handler is None: 645 self.FleetBroadcast(status, name, *args) 646 else: 647 handler(status, *args) 648 break 649 650 def SetColor(self, r, g, b, _save = True): 651 if _save: 652 self._originalIconColor = (r, g, b) 653 self.sr.icon.SetRGBA(r, g, b) 654 655 def SetViewState(self, status): 656 if not self._originalIconColor: 657 color = self.sr.icon.color 658 self._originalIconColor = (color.r, color.g, color.b) 659 r, g, b = self._originalIconColor 660 if status: 661 attenuation = 0.55 662 self.SetColor(r * attenuation, g * attenuation, b * attenuation, _save=False) 663 else: 664 self.SetColor(r, g, b, _save=False) 665 666 def WreckEmpty(self, isEmpty): 667 icon = sm.GetService('bracket').GetBracketIcon(self.slimItem.typeID, isEmpty) 668 self.sr.icon.LoadIcon(icon) 669 self.iconNo = icon 670 671 def AddFleetTag(self, tag): 672 self._fleetTag = tag 673 self.UpdateFleetTagAndTarget() 674 675 def UpdateFleetTagAndTarget(self): 676 tagAndTargetStr = '' 677 if self._fleetTargetNo: 678 tagAndTargetStr += unicode(self._fleetTargetNo) 679 if self._fleetTag: 680 if tagAndTargetStr: 681 tagAndTargetStr += ' / ' 682 tagAndTargetStr += unicode(self._fleetTag) 683 if tagAndTargetStr: 684 if not self.fleetTagAndTarget: 685 self.fleetTagAndTarget = BracketLabel(parent=self.parent, name='fleetTagAndTarget', align=uiconst.TOPLEFT, state=uiconst.UI_NORMAL, text=tagAndTargetStr, fontsize=fontconst.EVE_MEDIUM_FONTSIZE, bracket=self, bold=True, idx=0) 686 else: 687 self.fleetTagAndTarget.text = tagAndTargetStr 688 elif self.fleetTagAndTarget: 689 self.fleetTagAndTarget.Close() 690 self.fleetTagAndTarget = None 691 self.update_attached_objects() 692 693 def GBTarget(self, active, fleetBroadcastID, charID, targetNo = None): 694 self.FleetBroadcast(active, 'Target', fleetBroadcastID, charID) 695 if active: 696 self._fleetTargetNo = targetNo 697 else: 698 self._fleetTargetNo = None 699 self.UpdateFleetTagAndTarget() 700 701 def FleetBroadcast(self, active, broadcastType, fleetBroadcastID, charID): 702 if active: 703 self.fleetBroadcastSender = charID 704 self.fleetBroadcastType = broadcastType 705 self.fleetBroadcastID = fleetBroadcastID 706 if self.fleetBroadcastIcon: 707 self.fleetBroadcastIcon.Close() 708 self.fleetBroadcastIcon = None 709 self.update_attached_objects() 710 icon = iconsByBroadcastType[broadcastType] 711 if not self.sr.icon and self.stateItemID != session.shipid: 712 self.LoadIcon(self.iconNo) 713 self.fleetBroadcastIcon = BracketSubIcon(icon=icon, parent=self.parent, state=uiconst.UI_NORMAL, name='fleetBroadcastIcon', bracket=self, hint=fleetbr.GetBroadcastName(broadcastType), idx=0, width=16, height=16) 714 self.update_attached_objects() 715 elif fleetBroadcastID == getattr(self, 'fleetBroadcastID', None): 716 if self.fleetBroadcastIcon: 717 self.fleetBroadcastIcon.Close() 718 self.fleetBroadcastIcon = None 719 self.update_attached_objects() 720 self.fleetBroadcastSender = self.fleetBroadcastType = self.fleetBroadcastID = None 721 722 def _update_attached_objects(self): 723 self.update_attached_objects() 724 725 def update_attached_objects(self): 726 if self.destroyed: 727 return 728 bracketRO = self.renderObject 729 x, y = bracketRO.displayX, bracketRO.displayY 730 bracketLayerWidth = uicore.layer.bracket.renderObject.displayWidth 731 labelsXOffset = 0 732 if self.fleetBroadcastIcon: 733 xb, yb = self.fleetBroadcastIcon.bindings 734 if x <= 0: 735 xb.offset = (self.width + 2, 736 0, 737 0, 738 0) 739 yb.offset = ((self.height - self.fleetBroadcastIcon.height) / 2, 740 0, 741 0, 742 0) 743 labelsXOffset = self.fleetBroadcastIcon.width 744 elif x + self.width >= bracketLayerWidth: 745 xb.offset = (-self.fleetBroadcastIcon.width - 2, 746 0, 747 0, 748 0) 749 yb.offset = ((self.height - self.fleetBroadcastIcon.height) / 2, 750 0, 751 0, 752 0) 753 labelsXOffset = self.fleetBroadcastIcon.width 754 elif self.projectBracket and self.projectBracket.bracket: 755 xb.offset = ((self.width - self.fleetBroadcastIcon.width) / 2, 756 0, 757 0, 758 0) 759 if y <= 0: 760 yb.offset = (self.fleetBroadcastIcon.height, 761 0, 762 0, 763 0) 764 else: 765 yb.offset = (-self.fleetBroadcastIcon.height, 766 0, 767 0, 768 0) 769 else: 770 yb.offset = ((self.height - self.fleetBroadcastIcon.height) / 2, 771 0, 772 0, 773 0) 774 xb.offset = (-self.fleetBroadcastIcon.width - 2, 775 0, 776 0, 777 0) 778 if self.label: 779 newStr = self.displayName 780 if newStr is None: 781 self.Close() 782 return 783 if getattr(self, 'showDistance', 1): 784 distance = self.GetDistance() 785 if distance: 786 newStr += ' ' + FmtDist(distance) 787 self.label.text = newStr 788 mainLabelsYOffset = 0 789 maxLabelWidth = 0 790 if self.label: 791 maxLabelWidth = max(maxLabelWidth, self.label.textwidth) 792 if self.subLabel: 793 maxLabelWidth = max(maxLabelWidth, self.subLabel.textwidth) 794 if self.fleetTagAndTarget: 795 maxLabelWidth = max(maxLabelWidth, self.fleetTagAndTarget.textwidth) 796 xb, yb = self.fleetTagAndTarget.bindings 797 if x + self.width + LABELMARGIN + maxLabelWidth > bracketLayerWidth: 798 xb.offset = (-self.fleetTagAndTarget.textwidth - LABELMARGIN - labelsXOffset, 799 0, 800 0, 801 0) 802 else: 803 xb.offset = (self.width + LABELMARGIN + labelsXOffset, 804 0, 805 0, 806 0) 807 if y <= 0: 808 tagLabelYShift = (self.height - self.fleetTagAndTarget.textheight) / 2 + 1 809 yb.offset = (tagLabelYShift, 810 0, 811 0, 812 0) 813 mainLabelsYOffset = self.fleetTagAndTarget.textheight 814 else: 815 yb.offset = (-self.fleetTagAndTarget.textheight, 816 0, 817 0, 818 0) 819 if self.label: 820 mainLabelsYOffset += (self.height - self.label.textheight) / 2 + 1 821 self.label.y_offset = mainLabelsYOffset 822 if x + self.width + LABELMARGIN + maxLabelWidth > bracketLayerWidth: 823 self.label.x_offset = -self.label.textwidth - LABELMARGIN - labelsXOffset 824 if self.subLabel: 825 self.subLabel.x_offset = -self.subLabel.textwidth - LABELMARGIN - labelsXOffset 826 self.subLabel.y_offset = mainLabelsYOffset + self.label.textheight 827 else: 828 self.label.x_offset = self.width + LABELMARGIN + labelsXOffset 829 if self.subLabel: 830 self.subLabel.x_offset = self.width + LABELMARGIN + labelsXOffset 831 self.subLabel.y_offset = mainLabelsYOffset + self.label.textheight 832 if not (self.label or self.subLabel or self.fleetBroadcastIcon or self.fleetTagAndTarget): 833 self.subItemsUpdateTimer = None 834 elif not getattr(self, 'subItemsUpdateTimer', None): 835 self.subItemsUpdateTimer = timerstuff.AutoTimer(500, self._update_attached_objects) 836 837 def ActiveTarget(self, activestate): 838 for each in self.children[:]: 839 if each.name == 'activetarget': 840 each.Close() 841 842 if activestate: 843 activeTarget = ActiveTargetIndicator(parent=self) 844 else: 845 targeted, = sm.GetService('stateSvc').GetStates(self.stateItemID, [state.targeted]) 846 self.Targeted(targeted, 0) 847 848 def Targeted(self, state, tryActivate = 1): 849 if state: 850 if not self.targeted_indicator: 851 self.targeted_indicator = TargetedIndicator(parent=self) 852 lines = self.targeted_indicator.lines 853 targetCrosshair = sm.GetService('overviewPresetSvc').GetSettingValueOrDefaultFromName(osConst.SETTING_TARGET_CROSSHAIR, True) 854 if not targetCrosshair: 855 lines.display = False 856 else: 857 lines.display = True 858 bracketVarious.FixLines(self.targeted_indicator) 859 circle = self.targeted_indicator.circle 860 if circle is not None and not circle.destroyed: 861 circle.state = uiconst.UI_DISABLED 862 else: 863 if tryActivate: 864 self.ActiveTarget(0) 865 t = self.targeted_indicator 866 self.targeted_indicator = None 867 if t is not None: 868 t.Close() 869 870 def Targeting(self, state): 871 if state: 872 if self.targeted_indicator is None or self.targeted_indicator.destroyed: 873 self.Targeted(1) 874 if self.targeted_indicator: 875 uthread.new(self.CountDown, self.targeted_indicator) 876 self.targeted_indicator.ShowTargetingIndicators() 877 elif self.targeted_indicator: 878 self.targeted_indicator.HideTargetingIndicators() 879 880 def CountDown(self, *args): 881 pass 882 883 def UpdateStructureState(self, slimItem): 884 if not idCheckers.IsStarbase(slimItem.categoryID): 885 return 886 self.lastPosEvent = blue.os.GetWallclockTime() 887 stateName, stateTimestamp, stateDelay = sm.GetService('pwn').GetStructureState(slimItem) 888 if self.sr.posStatus is None: 889 self.sr.posStatus = EveLabelSmall(text=POS_STRUCTURE_STATE[stateName], parent=self, left=24, top=30, state=uiconst.UI_NORMAL) 890 else: 891 self.sr.posStatus.text = POS_STRUCTURE_STATE[stateName] 892 if stateName in ('anchoring', 'onlining', 'unanchoring', 'reinforced', 'operating', 'incapacitated'): 893 uthread.new(self.StructureProgress, self.lastPosEvent, stateName, stateTimestamp, stateDelay) 894 895 def StructureProgress(self, lastPosEvent, stateName, stateTimestamp, stateDelay): 896 if self.destroyed: 897 return 898 t = self.sr.posStatus 899 Frame(parent=self, align=uiconst.RELATIVE, width=82, height=13, left=18, top=30, color=(1.0, 1.0, 1.0, 0.5)) 900 p = Fill(parent=self, align=uiconst.RELATIVE, width=80, height=11, left=19, top=31, color=(1.0, 1.0, 1.0, 0.25)) 901 if stateDelay: 902 stateDelay = float(stateDelay * appConst.MSEC) 903 doneStr = {'anchoring': localization.GetByLabel('UI/Entities/States/Anchored'), 904 'onlining': localization.GetByLabel('UI/Entities/States/Online'), 905 'unanchoring': localization.GetByLabel('UI/Entities/States/Unanchored'), 906 'reinforced': localization.GetByLabel('UI/Entities/States/Online'), 907 'operating': localization.GetByLabel('UI/Entities/States/Operating'), 908 'incapacitated': localization.GetByLabel('UI/Entities/States/Incapacitated')}.get(stateName, localization.GetByLabel('UI/Entities/States/Done')) 909 endTime = 0 910 if stateDelay: 911 endTime = stateTimestamp + stateDelay 912 while 1 and endTime: 913 if not self or self.destroyed or lastPosEvent != self.lastPosEvent: 914 return 915 timeLeft = endTime - blue.os.GetWallclockTime() 916 portion = timeLeft / stateDelay 917 if timeLeft <= 0: 918 t.text = doneStr 919 break 920 t.text = localization.GetByLabel('UI/Inflight/Brackets/StructureProgress', stateName=POS_STRUCTURE_STATE[stateName], timeRemaining=long(timeLeft)) 921 p.width = int(80 * portion) 922 blue.pyos.synchro.SleepWallclock(900) 923 924 blue.pyos.synchro.SleepWallclock(250) 925 if not self or self.destroyed: 926 return 927 for each in self.children[-2:]: 928 if each is not None and not getattr(each, 'destroyed', 0): 929 each.Close() 930 931 if lastPosEvent != self.lastPosEvent: 932 return 933 t.text = '' 934 blue.pyos.synchro.SleepWallclock(250) 935 if not self or self.destroyed or lastPosEvent != self.lastPosEvent: 936 return 937 t.text = doneStr 938 blue.pyos.synchro.SleepWallclock(250) 939 if not self or self.destroyed or lastPosEvent != self.lastPosEvent: 940 return 941 t.text = '' 942 blue.pyos.synchro.SleepWallclock(250) 943 if not self or self.destroyed or lastPosEvent != self.lastPosEvent: 944 return 945 t.text = doneStr 946 947 def SetBracketAnchoredState(self, slimItem): 948 if not evetypes.GetIsGroupAnchorableByGroup(slimItem.groupID): 949 return 950 if not slimItem or slimItem.itemID == session.shipid or slimItem.ownerID != session.charid and slimItem.ownerID != session.corpid: 951 return 952 ball = self.ball 953 if ball is None: 954 bp = sm.GetService('michelle').GetBallpark() 955 ball = bp.GetBall(slimItem.itemID) 956 if not ball: 957 return 958 _iconNo, _dockType, _minDist, _maxDist, _iconOffset, _logflag = sm.GetService('bracket').GetBracketProps(slimItem, ball) 959 iconNo, dockType, minDist, maxDist, iconOffset, logflag = self.data 960 for each in self.children: 961 if each.name == 'anchoredicon': 962 if ball.isFree: 963 self.data = (iconNo, 964 dockType, 965 _minDist, 966 _maxDist, 967 iconOffset, 968 logflag) 969 each.Close() 970 return 971 972 if not ball.isFree: 973 self.data = (iconNo, 974 dockType, 975 0.0, 976 1e+32, 977 iconOffset, 978 logflag) 979 Icon(icon='ui_38_16_15', name='anchoredicon', parent=self, pos=(0, 16, 16, 16), align=uiconst.TOPLEFT) 980 981 982 class Bracket(SimpleBracket): 983 _displayName = None 984 _slimItem = None 985 986 def Startup(self, slimItem, ball = None, transform = None): 987 self.iconNo, dockType, minDist, maxDist, iconOffset, logflag = self.data 988 self.slimItem = slimItem 989 self.itemID = slimItem.itemID 990 self.groupID = slimItem.groupID 991 self.categoryID = slimItem.categoryID 992 SimpleBracket.Startup_update(self) 993 if not self.invisible: 994 self.LoadIcon(self.iconNo) 995 self.UpdateStructureState(slimItem) 996 self.SetBracketAnchoredState(slimItem) 997 SimpleBracket.Load_update(self, slimItem) 998 999 @apply 1000 def slimItem(): 1001 1002 def fget(self): 1003 if self._slimItem: 1004 return self._slimItem() 1005 else: 1006 return None 1007 1008 def fset(self, value): 1009 if value is None: 1010 self._slimItem = None 1011 else: 1012 self._slimItem = weakref.ref(value) 1013 1014 return property(**locals()) 1015 1016 @apply 1017 def displayName(): 1018 doc = 'Property to dynamically fetch displayName if it hasnt been set' 1019 1020 def fset(self, value): 1021 self._displayName = value 1022 1023 def fget(self): 1024 if self._displayName: 1025 return self._displayName 1026 slimItem = self.slimItem 1027 if slimItem: 1028 self._displayName = sm.GetService('bracket').GetDisplayNameForBracket(slimItem) 1029 return self._displayName 1030 1031 return property(**locals()) 1032 1033 def GetMenu(self): 1034 return GetMenuService().CelestialMenu(self.itemID, slimItem=self.slimItem) 1035 1036 def OnAttribute(self, attributeName, item, newValue): 1037 self.scanAttributeChangeFlag = True 1038 1039 def UpdateFlagPositions(self, icon = None): 1040 if icon is None: 1041 icon = self.sr.icon 1042 flag = self.sr.flag 1043 if icon and flag: 1044 if settings.user.overview.Get(osConst.SETTING_NAME_SMALL_TAGS, 0): 1045 flag.width = flag.height = 5 1046 flag.left = icon.left + 10 1047 flag.top = icon.top + 10 1048 else: 1049 flag.width = flag.height = 9 1050 flag.left = icon.left + 9 1051 flag.top = icon.top + 8 1052 1053 @telemetry.ZONE_METHOD 1054 def CountDown(self, target): 1055 if self.destroyed: 1056 return 1057 if not target: 1058 return 1059 self.scanAttributeChangeFlag = False 1060 slimItem = self.slimItem 1061 source = session.shipid 1062 time = sm.GetService('bracket').GetScanSpeed(source, slimItem) 1063 leftTimer = target.leftTimer 1064 rightTimer = target.rightTimer 1065 leftTimer.display = True 1066 rightTimer.display = True 1067 leftTimer.rotationSecondary = math.pi 1068 rightTimer.rotationSecondary = math.pi 1069 leftTimer.opacity = 0.4 1070 rightTimer.opacity = 0.4 1071 targetSvc = sm.GetService('target') 1072 startTime = targetSvc.GetTargetingStartTime(slimItem.itemID) 1073 if startTime is None: 1074 return 1075 t = EveLabelSmall(text='', parent=target, state=uiconst.UI_NORMAL, align=uiconst.CENTERTOP, top=64) 1076 targetSvc = sm.GetService('target') 1077 lockedText = localization.GetByLabel('UI/Inflight/Brackets/TargetLocked') 1078 while not self.destroyed: 1079 now = blue.os.GetSimTime() 1080 dt = blue.os.TimeDiffInMs(startTime, now) 1081 if self.scanAttributeChangeFlag: 1082 waitRatio = dt / float(time) 1083 self.scanAttributeChangeFlag = False 1084 time = sm.GetService('bracket').GetScanSpeed(source, slimItem) 1085 startTime = now - long(time * waitRatio * 10000) 1086 dt = blue.os.TimeDiffInMs(startTime, now) 1087 if t.destroyed: 1088 return 1089 t.text = FmtAmt((time - dt) / 1000.0, showFraction=1) 1090 if dt > time: 1091 t.text = lockedText 1092 break 1093 ratio = (time - dt) / time 1094 if ratio > 0.5: 1095 rightTimer.rotationSecondary = math.pi + ratio * 2 * math.pi 1096 leftTimer.rotationSecondary = math.pi 1097 else: 1098 leftTimer.rotationSecondary = ratio * 2 * math.pi 1099 rightTimer.rotationSecondary = 0 1100 blue.pyos.synchro.Sleep(TARGETTING_UI_UPDATE_RATE) 1101 1102 blue.pyos.synchro.SleepWallclock(250) 1103 if t.destroyed: 1104 return 1105 t.text = '' 1106 blue.pyos.synchro.SleepWallclock(250) 1107 if t.destroyed: 1108 return 1109 t.text = lockedText 1110 blue.pyos.synchro.SleepWallclock(250) 1111 if t.destroyed: 1112 return 1113 t.text = '' 1114 blue.pyos.synchro.SleepWallclock(250) 1115 if t.destroyed: 1116 return 1117 t.text = lockedText 1118 blue.pyos.synchro.SleepWallclock(250) 1119 1120 def GBEnemySpotted(self, active, fleetBroadcastID, charID): 1121 self.NearIDFleetBroadcast(active, fleetBroadcastID, charID, 'EnemySpotted') 1122 1123 def GBNeedBackup(self, active, fleetBroadcastID, charID): 1124 self.NearIDFleetBroadcast(active, fleetBroadcastID, charID, 'NeedBackup') 1125 1126 def GBInPosition(self, active, fleetBroadcastID, charID): 1127 self.NearIDFleetBroadcast(active, fleetBroadcastID, charID, 'InPosition') 1128 1129 def GBHoldPosition(self, active, fleetBroadcastID, charID): 1130 self.NearIDFleetBroadcast(active, fleetBroadcastID, charID, 'HoldPosition') 1131 1132 def NearIDFleetBroadcast(self, active, fleetBroadcastID, charID, broadcastType): 1133 inBubble = bool(SlimItemFromCharID(charID)) 1134 if inBubble: 1135 return self.FleetBroadcast(active, broadcastType, fleetBroadcastID, charID) 1136 if not active: 1137 if fleetBroadcastID == getattr(self, 'fleetBroadcastID', None): 1138 if self.fleetBroadcastIcon is not None: 1139 self.fleetBroadcastIcon.Close() 1140 self.fleetBroadcastIcon = None 1141 self.update_attached_objects() 1142 self.fleetBroadcastSender = self.fleetBroadcastType = self.fleetBroadcastID = None 1143 1144 def GetRadialMenuIndicator(self, create = True, *args): 1145 radialMenuSprite = getattr(self, 'radialMenuSprite', None) 1146 if radialMenuSprite and not radialMenuSprite.destroyed: 1147 return radialMenuSprite 1148 if not create: 1149 return 1150 radialMenuSprite = Sprite(name='radialMenuSprite', parent=self, texturePath='res:/UI/Texture/classes/RadialMenu/bracketHilite.png', pos=(0, 0, 20, 20), color=(0.5, 0.5, 0.5, 0.5), idx=-1, align=uiconst.CENTER, state=uiconst.UI_DISABLED) 1151 self.radialMenuSprite = radialMenuSprite 1152 return radialMenuSprite 1153 1154 def ShowRadialMenuIndicator(self, slimItem, *args): 1155 mySprite = self.GetRadialMenuIndicator(create=True) 1156 mySprite.display = True 1157 1158 def HideRadialMenuIndicator(self, slimItem, *args): 1159 mySprite = self.GetRadialMenuIndicator(create=False) 1160 if mySprite: 1161 mySprite.display = False 1162 1163 1164 import carbon.common.script.util.autoexport as autoexport 1165 exports = autoexport.AutoExports('bracket', locals())