NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

inSpaceBracket.py (74013B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\inflight\bracketsAndTargets\inSpaceBracket.py
      2 import math
      3 import appConst
      4 import blue
      5 import carbonui.const as uiconst
      6 import eve.client.script.ui.inflight.overview.overviewConst as overviewConst
      7 import eve.common.script.mgt.entityConst as entityConst
      8 import evetypes
      9 import hackingcommon.hackingConstants as hackingConst
     10 import inventorycommon.util as invutil
     11 import localization
     12 import overviewPresets.overviewSettingsConst as osConst
     13 import telemetry
     14 import trinity
     15 import uthread
     16 import weakref
     17 from carbon.client.script.environment.AudioUtil import PlaySound
     18 from carbon.common.script.util import timerstuff
     19 from carbon.common.script.util.format import FmtAmt, FmtDate, FmtDist
     20 from carbonui.fontconst import EVE_MEDIUM_FONTSIZE
     21 from carbonui.primitives.bracket import Bracket
     22 from carbonui.primitives.container import Container
     23 from carbonui.primitives.fill import Fill
     24 from carbonui.primitives.frame import Frame
     25 from carbonui.primitives.sprite import Sprite
     26 from carbonui.uicore import uicore
     27 from eve.client.script.parklife import states as state
     28 from eve.client.script.spacecomponents.activatecontroller import ActivateCounterController
     29 from eve.client.script.spacecomponents.hostileBaiterController import HostileBaiterCounterController
     30 from eve.client.script.spacecomponents.jumppolarizationcontroller import JumpPolarizationCounterController
     31 from eve.client.script.spacecomponents.linkWithShipController import LinkWithShipCounterController
     32 from eve.client.script.spacecomponents.proximitylockcontroller import ProximityLockCounterController
     33 from eve.client.script.spacecomponents.reinforcecontroller import ReinforceCounterController
     34 from eve.client.script.ui.control import eveIcon, eveLabel
     35 from eve.client.script.ui.control.eveHint import BubbleHint
     36 from eve.client.script.ui.control.hackingNumberGrid import HackingNumberGrid
     37 from eve.client.script.ui.control.hackingProgressBar import HackingProgressBar
     38 from eve.client.script.ui.inflight.bracket import BracketShadowLabel
     39 from eve.client.script.ui.inflight.bracketsAndTargets import bracketVarious
     40 from eve.client.script.ui.inflight.bracketsAndTargets.activeTargetIndicator import ActiveTargetIndicator, TargetedIndicator
     41 from eve.client.script.ui.inflight.bracketsAndTargets.blinkingSpriteOnSharedCurve import BlinkingSpriteOnSharedCurve
     42 from eve.client.script.ui.inflight.bracketsAndTargets.bracketVarious import BracketSubIconNew
     43 from eve.client.script.ui.inflight.bracketsAndTargets.expanded_bracket import ExpandedBracket
     44 from eve.client.script.ui.inflight.squadrons.squadronManagementCont import SquadronNumber
     45 from eve.client.script.ui.shared.fleet import fleetbroadcastexports as fleetbr
     46 from eve.client.script.ui.shared.fleet.fleetBroadcastConst import iconsByBroadcastType
     47 from eve.client.script.ui.shared.maps.maputils import GetMyPos
     48 from eve.client.script.ui.shared.stateFlag import FlagIconWithState, GetExtraInfoForSlimItem, GetIconFlagAndBackgroundFlag
     49 from eve.client.script.ui.tooltips.tooltipHandler import TOOLTIP_DELAY_BRACKET, TOOLTIP_SETTINGS_BRACKET
     50 from eve.client.script.util.bubble import SlimItemFromCharID
     51 from eve.common.script.sys import idCheckers
     52 from eveprefs import prefs
     53 from eveservices.menu import GetMenuService
     54 from hackingcommon import hacking_util
     55 from spacecomponents.common.helper import HasActivateComponent, HasReinforceComponent, HasJumpPolarizationComponent, HasProximityUnlockComponent, HasEntityStandingsComponent, HasLinkWithShipComponent, HasHostileBaiterComponent
     56 TARGETTING_UI_UPDATE_RATE = 50
     57 LABELMARGIN = 6
     58 OWN_BRACKET_PATH = 'res:/UI/Texture/Shared/Brackets/ownShip.png'
     59 
     60 class InSpaceBracket(Bracket):
     61     default_width = 16
     62     default_height = 16
     63     IsBracket = 1
     64     invisible = False
     65     inflight = False
     66     categoryID = None
     67     groupID = None
     68     itemID = None
     69     displayName = ''
     70     displaySubLabel = ''
     71     subItemsUpdateTimer = None
     72     subLabelCallback = None
     73     targetingPath = None
     74     stateItemID = None
     75     fleetBroadcastIcon = None
     76     fleetTagAndTarget = None
     77     label = None
     78     subLabel = None
     79     iconNo = None
     80     iconXOffset = 0
     81     lastPosEvent = None
     82     scanAttributeChangeFlag = False
     83     iconTop = 0
     84     tagAndTargetStr = None
     85     squadronNumber = None
     86     always_show_label = False
     87     expanded_bracket = None
     88     _originalIconColor = None
     89     _fleetTag = None
     90     _fleetTargetNo = None
     91     _displayName = None
     92     _slimItem = None
     93     _ball = None
     94 
     95     def __init__(self, ball, slimItem, is_update_item = False, **kwargs):
     96         super(InSpaceBracket, self).__init__(**kwargs)
     97         self.ball = ball
     98         self.slimItem = slimItem
     99         self.is_update_item = is_update_item
    100         self.icon_sprite = None
    101         self.data = sm.GetService('bracket').GetBracketProps(self.slimItem, self.ball)
    102         self.iconNo, self.dock, self.minDispRange, self.maxDispRange, iconOffset, logflag = self.data
    103         self._init_project_bracket()
    104         self.invisible = False
    105         self.itemID = slimItem.itemID
    106         self.typeID = slimItem.typeID
    107         self.groupID = slimItem.groupID
    108         self.categoryID = slimItem.categoryID
    109         self.targeted_indicator = None
    110         self.active_target_indicator = None
    111         self.highlight_sprite = None
    112         self.selection_sprite = None
    113         self.subLabelCallback = None
    114         self.controllers = []
    115         self.isSelected = None
    116         if not self.invisible:
    117             self.construct_icon(self.iconNo)
    118         self.UpdateStructureState(slimItem)
    119         self.UpdateCaptureProgress(None)
    120         self.UpdatePlanetaryLaunchContainer(slimItem)
    121         self.SetBracketAnchoredState(slimItem)
    122         self.CreateSpaceComponentUI(slimItem)
    123         self._update_always_show_label_flag()
    124         self.UpdateOwnShip()
    125 
    126     def _update_always_show_label_flag(self):
    127         if prefs.GetValue('bracketsAlwaysShowShipText', False) and self.slimItem.categoryID == appConst.categoryShip and self.slimItem.groupID != appConst.groupCapsule:
    128             self.always_show_label = True
    129         else:
    130             self.always_show_label = False
    131 
    132     def UpdateOwnShip(self):
    133         if self.itemID == session.shipid:
    134             if self.icon_sprite:
    135                 self.icon_sprite.SetTexturePath(OWN_BRACKET_PATH)
    136             self.showMyIconDist = bracketVarious.GetMinDispRangeForOwnShip(self.slimItem.typeID)
    137             self.projectBracket.bracketUpdateCallback = self.OnOwnBracketUpdated
    138 
    139     def _init_project_bracket(self):
    140         self.projectBracket.trackBall = self.ball
    141         self.projectBracket.parent = uicore.layer.inflight.GetRenderObject()
    142         self.projectBracket.dock = self.dock
    143         self.projectBracket.marginRight = self.projectBracket.marginLeft + self.width
    144         self.projectBracket.marginBottom = self.projectBracket.marginTop + self.height
    145 
    146     def CloseSubLabel(self):
    147         if getattr(self, 'subLabel', None):
    148             self.subLabel.Close()
    149         self.subLabel = None
    150 
    151     def CloseLabel(self):
    152         if getattr(self, 'label', None):
    153             self.label.Close()
    154         self.label = None
    155 
    156     def Close(self, *args, **kw):
    157         self.subItemsUpdateTimer = None
    158         self.remove_all_attachments()
    159         if getattr(self, 'fleetBroadcastIcon', None):
    160             self.fleetBroadcastIcon.Close()
    161             self.fleetBroadcastIcon = None
    162         if getattr(self, 'fleetTagAndTarget', None):
    163             self.fleetTagAndTarget.Close()
    164             self.fleetTagAndTarget = None
    165         if getattr(self, 'capture', None):
    166             self.capture.Close()
    167             self.capture = None
    168         super(InSpaceBracket, self).Close()
    169 
    170     def IsFloating(self):
    171         bracketRO = self.renderObject
    172         x, y = bracketRO.displayX, bracketRO.displayY
    173         bracketLayerWidth = self.parent.renderObject.displayWidth
    174         bracketLayerHeight = self.parent.renderObject.displayHeight
    175         if x <= 0:
    176             return False
    177         if y <= 0:
    178             return False
    179         if x + bracketRO.displayWidth >= bracketLayerWidth:
    180             return False
    181         if y + bracketRO.displayHeight >= bracketLayerHeight:
    182             return False
    183         return True
    184 
    185     def Show(self):
    186         projectBracket = self.projectBracket
    187         if projectBracket:
    188             projectBracket.bracket = self.renderObject
    189         Bracket.Show(self)
    190 
    191     def Hide(self):
    192         Bracket.Hide(self)
    193         self.KillLabel()
    194         projectBracket = self.projectBracket
    195         if projectBracket:
    196             projectBracket.bracket = None
    197 
    198     @telemetry.ZONE_METHOD
    199     def construct_icon(self, iconNo):
    200         if self.icon_sprite is None:
    201             self.icon_sprite = Sprite(parent=self, name='iconSprite', state=uiconst.UI_DISABLED, pos=(0, 0, 16, 16), texturePath=iconNo, align=uiconst.CENTER)
    202         else:
    203             self.icon_sprite.LoadIcon(iconNo)
    204 
    205     def UpdateIcon(self):
    206         if not self.icon_sprite:
    207             return
    208         self.iconNo = sm.GetService('bracket').GetBracketIcon(self.slimItem.typeID, itemID=self.slimItem.itemID)
    209         self.icon_sprite.LoadIcon(self.iconNo)
    210 
    211     def ShowLabel(self, *args):
    212         if not self.destroyed and (self.displayName == '' or not getattr(self, 'showLabel', True)):
    213             return
    214         if self.always_show_label and self.itemID == session.shipid:
    215             return
    216         if not self.label:
    217             self.construct_label()
    218         else:
    219             self.label.SetOrder(0)
    220         if self.SubLabelExists():
    221             self.subLabel.SetOrder(0)
    222         else:
    223             self.CreateSubLabelIfNeeded()
    224             return
    225         self.update_attached_objects()
    226 
    227     def construct_label(self):
    228         self.label = BracketShadowLabel(parent=self.parent, name='labelparent', align=uiconst.TOPLEFT, state=uiconst.UI_NORMAL, text=self.displayName, bracket=self, idx=0)
    229 
    230     def SubLabelExists(self):
    231         if self.subLabel is None:
    232             return False
    233         if self.subLabel.destroyed:
    234             return False
    235         return True
    236 
    237     def CreateSubLabelIfNeeded(self):
    238         if self.SubLabelExists():
    239             return
    240         if self.displaySubLabel:
    241             self.subLabel = BracketShadowLabel(parent=self.parent, name='sublabelparent', align=uiconst.TOPLEFT, state=uiconst.UI_NORMAL, text=self.displaySubLabel, bracket=self, color=(0.75, 0.75, 0.75, 0.75), idx=0)
    242         self.update_attached_objects()
    243 
    244     def KillLabel(self, *args, **kwds):
    245         if not (self.projectBracket and self.projectBracket.bracket):
    246             return
    247         self.CloseLabel()
    248         self.CloseSubLabel()
    249         self.update_attached_objects()
    250 
    251     def remove_all_attachments(self):
    252         self.CloseLabel()
    253         self.CloseSubLabel()
    254         self.close_expanded_bracket()
    255 
    256     @apply
    257     def ball():
    258         doc = ''
    259 
    260         def fget(self):
    261             if self._ball:
    262                 return self._ball()
    263 
    264         def fset(self, value):
    265             if value is None:
    266                 self._ball = None
    267                 return
    268             self._ball = weakref.ref(value)
    269 
    270         return property(**locals())
    271 
    272     def GetSlimItem(self):
    273         return self.slimItem
    274 
    275     @apply
    276     def slimItem():
    277 
    278         def fget(self):
    279             if self._slimItem:
    280                 return self._slimItem()
    281             else:
    282                 return None
    283 
    284         def fset(self, value):
    285             if value is None:
    286                 self._slimItem = None
    287             else:
    288                 self._slimItem = weakref.ref(value)
    289 
    290         return property(**locals())
    291 
    292     @apply
    293     def displayName():
    294         doc = 'Property to dynamically fetch displayName if it hasnt been set'
    295 
    296         def fset(self, value):
    297             self._displayName = value
    298 
    299         def fget(self):
    300             if self._displayName:
    301                 return self._displayName
    302             slimItem = self.slimItem
    303             if slimItem:
    304                 self._displayName = sm.GetService('bracket').GetDisplayNameForBracket(slimItem)
    305             return self._displayName
    306 
    307         return property(**locals())
    308 
    309     def GetMenu(self):
    310         return GetMenuService().CelestialMenu(self.itemID, slimItem=self.slimItem)
    311 
    312     @telemetry.ZONE_METHOD
    313     def GetDistance(self):
    314         ball = self.ball
    315         if ball:
    316             return ball.surfaceDist
    317         slimItem = self.GetSlimItem()
    318         if slimItem:
    319             ballPark = sm.GetService('michelle').GetBallpark()
    320             if ballPark and slimItem.itemID in ballPark.balls:
    321                 return ballPark.balls[slimItem.itemID].surfaceDist
    322         elif self.trackTransform or self.sr.trackTransform:
    323             tf = self.trackTransform or self.sr.trackTransform
    324             trans = tf.translation
    325             pos = trinity.TriVector(trans[0], trans[1], trans[2])
    326             myPos = GetMyPos()
    327             return (pos - myPos).Length()
    328 
    329     def HideBubble(self):
    330         if self.sr.bubble is not None:
    331             self.sr.bubble.Close()
    332             self.sr.bubble = None
    333 
    334     def ShowBubble(self, hint):
    335         if self.sr.bubble is not None:
    336             self.sr.bubble.Close()
    337             self.sr.bubble = None
    338         if hint:
    339             bubble = BubbleHint(parent=self, name='bubblehint', align=uiconst.TOPLEFT, width=0, height=0, idx=0, state=uiconst.UI_PICKCHILDREN)
    340             pointer = {const.groupStargate: 5,
    341              const.groupStation: 3}.get(self.groupID, 0)
    342             bubble.ShowHint(hint, pointer)
    343             self.sr.bubble = bubble
    344             self.sr.bubble.state = uiconst.UI_NORMAL
    345 
    346     def GetLockedPositionTopBottomMargin(self):
    347         hasBubble = bool(self.sr.bubble)
    348         topMargin = 1
    349         bottomMargin = 1
    350         if hasBubble:
    351             if self.sr.bubble.data[1] in (3, 4, 5):
    352                 bottomMargin += self.sr.bubble.height + 8
    353             elif self.sr.bubble.data[1] in (0, 1, 2):
    354                 topMargin += self.sr.bubble.height + 8
    355         else:
    356             if getattr(self, 'subLabel', None):
    357                 bottomMargin += self.subLabel.textheight
    358             if getattr(self, 'fleetTagAndTarget', None):
    359                 topMargin += self.fleetTagAndTarget.textheight
    360         return (topMargin, bottomMargin)
    361 
    362     def OnAttribute(self, attributeName, item, newValue):
    363         self.scanAttributeChangeFlag = True
    364 
    365     @telemetry.ZONE_METHOD
    366     def UpdateFlagPositions(self, icon = None):
    367         if icon is None:
    368             icon = self.icon_sprite
    369         flag = self.sr.flag
    370         if icon and flag:
    371             if settings.user.overview.Get(osConst.SETTING_NAME_SMALL_TAGS, 0):
    372                 flag.width = flag.height = 5
    373                 flag.left = icon.left + 10
    374                 flag.top = icon.top + 10
    375             else:
    376                 flag.width = flag.height = 9
    377                 flag.left = icon.left + 9
    378                 flag.top = icon.top + 8
    379 
    380     @telemetry.ZONE_METHOD
    381     def CountDown(self, target):
    382         if self.destroyed:
    383             return
    384         self.scanAttributeChangeFlag = False
    385         if not target:
    386             return
    387         if not target.IsTargetingIndicatorsEnabled():
    388             return
    389         slimItem = self.slimItem
    390         source = session.shipid
    391         time = sm.GetService('bracket').GetScanSpeed(source, slimItem)
    392         leftTimer = target.leftTimer
    393         rightTimer = target.rightTimer
    394         leftTimer.display = True
    395         rightTimer.display = True
    396         leftTimer.rotationSecondary = math.pi
    397         rightTimer.rotationSecondary = math.pi
    398         leftTimer.opacity = 0.4
    399         rightTimer.opacity = 0.4
    400         t = target.lockingText
    401         targetSvc = sm.GetService('target')
    402         startTime = targetSvc.GetTargetingStartTime(slimItem.itemID)
    403         if startTime is None:
    404             return
    405         lockedText = localization.GetByLabel('UI/Inflight/Brackets/TargetLocked')
    406         while not self.destroyed:
    407             if not target.IsTargetingIndicatorsEnabled():
    408                 return
    409             now = blue.os.GetSimTime()
    410             dt = blue.os.TimeDiffInMs(startTime, now)
    411             if self.scanAttributeChangeFlag:
    412                 waitRatio = dt / float(time)
    413                 self.scanAttributeChangeFlag = False
    414                 time = sm.GetService('bracket').GetScanSpeed(source, slimItem)
    415                 startTime = now - long(time * waitRatio * 10000)
    416                 dt = blue.os.TimeDiffInMs(startTime, now)
    417             if t.destroyed:
    418                 return
    419             t.text = FmtAmt((time - dt) / 1000.0, showFraction=1)
    420             if dt > time:
    421                 t.text = lockedText
    422                 break
    423             ratio = (time - dt) / time
    424             if ratio > 0.5:
    425                 rightTimer.rotationSecondary = math.pi + ratio * 2 * math.pi
    426                 leftTimer.rotationSecondary = math.pi
    427             else:
    428                 leftTimer.rotationSecondary = ratio * 2 * math.pi
    429                 rightTimer.rotationSecondary = 0
    430             blue.pyos.synchro.Sleep(TARGETTING_UI_UPDATE_RATE)
    431 
    432         if not target.IsTargetingIndicatorsEnabled():
    433             return
    434         leftTimer.rotationSecondary = 0
    435         rightTimer.rotationSecondary = 0
    436         target.BlinkArrowsAndText()
    437 
    438     def GBEnemySpotted(self, active, fleetBroadcastID, charID):
    439         self.NearIDFleetBroadcast(active, fleetBroadcastID, charID, 'EnemySpotted')
    440 
    441     def GBNeedBackup(self, active, fleetBroadcastID, charID):
    442         self.NearIDFleetBroadcast(active, fleetBroadcastID, charID, 'NeedBackup')
    443 
    444     def GBInPosition(self, active, fleetBroadcastID, charID):
    445         self.NearIDFleetBroadcast(active, fleetBroadcastID, charID, 'InPosition')
    446 
    447     def GBHoldPosition(self, active, fleetBroadcastID, charID):
    448         self.NearIDFleetBroadcast(active, fleetBroadcastID, charID, 'HoldPosition')
    449 
    450     @telemetry.ZONE_METHOD
    451     def NearIDFleetBroadcast(self, active, fleetBroadcastID, charID, broadcastType):
    452         inBubble = bool(SlimItemFromCharID(charID))
    453         if inBubble:
    454             return self.FleetBroadcast(active, broadcastType, fleetBroadcastID, charID)
    455         if not active:
    456             if fleetBroadcastID == getattr(self, 'fleetBroadcastID', None):
    457                 if self.fleetBroadcastIcon is not None:
    458                     self.fleetBroadcastIcon.Close()
    459                     self.fleetBroadcastIcon = None
    460                     self.update_attached_objects()
    461                 self.fleetBroadcastSender = self.fleetBroadcastType = self.fleetBroadcastID = None
    462 
    463     def GetHostileUI(self):
    464         if self.sr.hostile:
    465             return self.sr.hostile
    466         threat = BlinkingSpriteOnSharedCurve(parent=self, name='threatHostile', pos=(0, 0, 32, 32), align=uiconst.CENTER, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/Bracket/targetAggressIcon.png', curveSetName='sharedHostileCurveSet')
    467         self.sr.hostile = threat
    468         return threat
    469 
    470     def GetHostileAttackingUI(self):
    471         if self.sr.hostile_attacking:
    472             return self.sr.hostile_attacking
    473         threat = BlinkingSpriteOnSharedCurve(parent=self, name='threatAttacking', pos=(0, 0, 32, 32), align=uiconst.CENTER, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/Bracket/targetAggressIcon.png', curveSetName='sharedHostileCurveSet')
    474         self.sr.hostile_attacking = threat
    475         return threat
    476 
    477     @telemetry.ZONE_METHOD
    478     def GetHitSprite(self, create = True, *args):
    479         hitSprite = getattr(self, 'hitSprite', None)
    480         if hitSprite and not hitSprite.destroyed:
    481             return hitSprite
    482         if not create:
    483             return
    484         texturePath = 'res:/UI/Texture/classes/Bracket/damageDealer.png'
    485         hitSprite = Sprite(parent=self, name='hitSprite', pos=(0, 0, 100, 100), state=uiconst.UI_PICKCHILDREN, texturePath=texturePath, align=uiconst.CENTER, color=(1, 0, 0, 0))
    486         self.hitSprite = hitSprite
    487         return hitSprite
    488 
    489     @telemetry.ZONE_METHOD
    490     def GetCanTargetSprite(self, create = True, *args):
    491         canTargetSprite = getattr(self, 'canTargetSprite', None)
    492         if canTargetSprite and not canTargetSprite.destroyed:
    493             return canTargetSprite
    494         if not create:
    495             return
    496         canTargetSprite = Sprite(parent=self, name='canTargetSprite', pos=(0, 0, 40, 40), state=uiconst.UI_PICKCHILDREN, texturePath='res:/UI/Texture/classes/Bracket/canTarget2.png', align=uiconst.CENTER)
    497         self.canTargetSprite = canTargetSprite
    498         canTargetSprite.SetRGBA(1.0, 1.0, 1.0, 0.05)
    499         return canTargetSprite
    500 
    501     @telemetry.ZONE_METHOD
    502     def GetRadialMenuIndicator(self, create = True, *args):
    503         radialMenuSprite = getattr(self, 'radialMenuSprite', None)
    504         if radialMenuSprite and not radialMenuSprite.destroyed:
    505             return radialMenuSprite
    506         if not create:
    507             return
    508         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)
    509         self.radialMenuSprite = radialMenuSprite
    510         return radialMenuSprite
    511 
    512     @telemetry.ZONE_METHOD
    513     def AddBinding(self, sourceObject, sourceAttribute, destObject, destAttribute, curveSet):
    514         binding = trinity.TriValueBinding()
    515         binding.sourceObject = sourceObject
    516         binding.sourceAttribute = sourceAttribute
    517         binding.destinationObject = destObject.GetRenderObject()
    518         binding.destinationAttribute = destAttribute
    519         curveSet.bindings.append(binding)
    520         return binding
    521 
    522     @telemetry.ZONE_METHOD
    523     def Select(self, is_selected):
    524         wasSelected = self.isSelected
    525         self.isSelected = bool(is_selected)
    526         if self.isSelected:
    527             if not self.selection_sprite:
    528                 self._construct_selection_sprite()
    529             self.selection_sprite.display = True
    530             sm.ScatterEvent('OnClientEvent_SelectSpaceBracket', self.slimItem)
    531         elif self.selection_sprite:
    532             self.selection_sprite.state = uiconst.UI_HIDDEN
    533         if is_selected:
    534             self.check_show_expanded_bracket()
    535         elif self.expanded_bracket:
    536             self.close_expanded_bracket()
    537         self.update_label_visibility()
    538         if bool(wasSelected) != bool(self.isSelected):
    539             sm.ScatterEvent('OnSpaceBracketSelectionChanged', self.slimItem)
    540 
    541     def check_show_expanded_bracket(self):
    542         if self.has_expanded_bracket():
    543             self.show_expanded_bracket()
    544             self.update_attached_objects()
    545 
    546     def show_expanded_bracket(self):
    547         if not self.expanded_bracket:
    548             self.expanded_bracket = ExpandedBracket(item_id=self.itemID, parent=self.parent, bracket=self, idx=0)
    549 
    550     def has_expanded_bracket(self):
    551         return False
    552 
    553     def close_expanded_bracket(self):
    554         if self.expanded_bracket:
    555             self.expanded_bracket.Close()
    556             self.expanded_bracket = None
    557 
    558     def _construct_selection_sprite(self):
    559         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))
    560 
    561     def OnOwnBracketUpdated(self, projectBracket):
    562         if self.icon_sprite is None or self.icon_sprite.destroyed or getattr(self.icon_sprite, 'showingMyShip', False):
    563             return
    564         if projectBracket.cameraDistance > self.showMyIconDist and not self.always_show_label:
    565             self.icon_sprite.display = True
    566         else:
    567             self.icon_sprite.display = False
    568 
    569     def ShowOwnShip(self):
    570         if self.icon_sprite:
    571             self.icon_sprite.display = True
    572             self.icon_sprite.glowExpand = 0.01
    573             self.icon_sprite.glowColor = overviewConst.OVERVIEW_OWN_SHIP_COLOR + (0.08,)
    574             self.icon_sprite.showingMyShip = True
    575 
    576     def SetNormalInvisibleStateForOwnShip(self):
    577         if self.icon_sprite:
    578             self.icon_sprite.glowExpand = 0
    579             self.icon_sprite.showingMyShip = False
    580 
    581     def OnMouseDown(self, *args):
    582         if getattr(self, 'slimItem', None):
    583             if GetMenuService().TryExpandActionMenu(self.itemID, self):
    584                 return
    585         sm.GetService('viewState').GetView('inflight').layer.looking = True
    586 
    587     def OnMouseEnter(self, *args):
    588         if uicore.uilib.leftbtn:
    589             return
    590         if bracketVarious.IsTargetingOrSettingSecondPoint():
    591             return
    592         if not getattr(self, 'invisible', False) or self.itemID == session.shipid:
    593             PlaySound(uiconst.SOUND_ENTRY_HOVER)
    594             sm.GetService('stateSvc').SetState(self.itemID, state.mouseOver, 1)
    595 
    596     def OnMouseExit(self, *args):
    597         if uicore.uilib.leftbtn:
    598             return
    599         if self.projectBracket and self.projectBracket.bracket:
    600             sm.GetService('stateSvc').SetState(self.itemID, state.mouseOver, 0)
    601 
    602     def LoadTooltipPanel(self, tooltipPanel, *args):
    603         uicore.layer.inflight.PrepareTooltipLoad(self)
    604 
    605     def GetTooltipDelay(self):
    606         return settings.user.ui.Get(TOOLTIP_SETTINGS_BRACKET, TOOLTIP_DELAY_BRACKET)
    607 
    608     def GetAbsolutePosition(self):
    609         if self.destroyed or not self.display:
    610             return (0, 0)
    611         x = self.renderObject.displayX
    612         y = self.renderObject.displayY
    613         parent = self.parent
    614         while parent:
    615             x += parent.renderObject.displayX
    616             y += parent.renderObject.displayY
    617             parent = parent.parent
    618 
    619         return (uicore.ReverseScaleDpi(x), uicore.ReverseScaleDpi(y))
    620 
    621     def OnClick(self, *args):
    622         if bracketVarious.IsTargetingOrSettingSecondPoint():
    623             uicore.layer.inflight.SetMouseDownAndDoMouseUp()
    624             return
    625         PlaySound(uiconst.SOUND_ENTRY_SELECT)
    626         if self.sr.clicktime and blue.os.TimeDiffInMs(self.sr.clicktime, blue.os.GetWallclockTime()) < 1000.0:
    627             sm.GetService('stateSvc').SetState(self.itemID, state.selected, 1)
    628             slimItem = getattr(self, 'slimItem', None)
    629             if slimItem:
    630                 if uicore.cmd.IsSomeCombatCommandLoaded():
    631                     return
    632                 GetMenuService().Activate(slimItem)
    633             self.sr.clicktime = None
    634         else:
    635             self.OnClickSelect()
    636             if sm.GetService('target').IsTarget(self.itemID):
    637                 sm.GetService('stateSvc').SetState(self.itemID, state.activeTarget, 1)
    638             self.sr.clicktime = blue.os.GetWallclockTime()
    639         self.OnTacticalItemClick()
    640 
    641     def OnClickSelect(self):
    642         sm.GetService('stateSvc').SetState(self.itemID, state.selected, 1)
    643 
    644     def OnTacticalItemClick(self):
    645         GetMenuService().TacticalItemClicked(self.itemID)
    646 
    647     @telemetry.ZONE_METHOD
    648     def Load_update(self, slimItem, *args):
    649         if slimItem is None:
    650             return
    651         self.stateItemID = slimItem.itemID
    652         selected, hilited, attacking, hostile, targeting, targeted, activeTarget = sm.GetService('stateSvc').GetStates(self.stateItemID, [state.selected,
    653          state.mouseOver,
    654          state.threatAttackingMe,
    655          state.threatTargetsMe,
    656          state.targeting,
    657          state.targeted,
    658          state.activeTarget])
    659         self.Select(selected)
    660         self.Hilite(hilited)
    661         self.Targeted(targeted)
    662         self.ActiveTarget(activeTarget)
    663         self.UpdateIconColor(slimItem)
    664         if not activeTarget:
    665             self.Targeting(targeting)
    666         if self.is_update_item:
    667             self.UpdateFlagAndBackground(slimItem)
    668             self.Attacking(attacking)
    669             self.Hostile(not attacking and hostile, attacking)
    670         else:
    671             if self.sr.flag:
    672                 self.sr.flag.Close()
    673                 self.sr.flag = None
    674             self.RemoveBackgroundColor()
    675             if self.sr.hostile_attacking:
    676                 self._RemoveHostileAttackingUI()
    677             if self.sr.hostile:
    678                 self._RemoveHostileUI()
    679         fleetTag = sm.GetService('fleet').GetTargetTag(slimItem.itemID)
    680         self.AddFleetTag(fleetTag)
    681         if slimItem.groupID == const.groupWreck:
    682             uthread.worker('bracket.WreckEmpty', self.WreckEmpty, slimItem.isEmpty)
    683         elif slimItem.hackingSecurityState is not None:
    684             uthread.new(self.SetHackingIcon, slimItem.hackingSecurityState)
    685         broadcastID, broadcastType, broadcastData = sm.GetService('fleet').GetCurrentFleetBroadcastOnItem(slimItem.itemID)
    686         if broadcastID is not None:
    687             uthread.worker('bracket.UpdateFleetBroadcasts', self.UpdateFleetBroadcasts, broadcastID, broadcastType, broadcastData)
    688 
    689     @telemetry.ZONE_METHOD
    690     def UpdateFleetBroadcasts(self, broadcastID, broadcastType, broadcastData):
    691         if self.destroyed:
    692             return
    693         for typeName in iconsByBroadcastType:
    694             if broadcastType == getattr(state, 'gb%s' % typeName):
    695                 handler = getattr(self, 'GB%s' % typeName, None)
    696                 if handler is None:
    697                     self.FleetBroadcast(True, typeName, broadcastID, *broadcastData)
    698                 else:
    699                     handler(True, broadcastID, *broadcastData)
    700                 break
    701 
    702     def RefreshBounty(self):
    703         self.UpdateFlagAndBackground(self.slimItem)
    704 
    705     def UpdateSquadronNumber(self, tubeFlagID):
    706         if tubeFlagID is None:
    707             if self.squadronNumber:
    708                 self.squadronNumber.Close()
    709                 self.squadronNumber = None
    710         else:
    711             self.squadronNumber = SquadronNumber(parent=self, top=-10, left=-10)
    712             self.squadronNumber.SetColor(False)
    713             self.squadronNumber.SetText(tubeFlagID)
    714 
    715     @telemetry.ZONE_METHOD
    716     def UpdateFlagAndBackground(self, slimItem, *args):
    717         if self.destroyed or not self.is_update_item:
    718             return
    719         try:
    720             if slimItem.groupID != const.groupAgentsinSpace and (slimItem.ownerID and invutil.IsNPC(slimItem.ownerID) or slimItem.charID and invutil.IsNPC(slimItem.charID)) and slimItem.categoryID != const.categoryStation and slimItem.groupID != const.groupStargate:
    721                 if self.sr.flag:
    722                     self.sr.flag.Close()
    723                     self.sr.flag = None
    724                 self.RemoveBackgroundColor()
    725             else:
    726                 stateSvc = sm.GetService('stateSvc')
    727                 iconFlag, backgroundFlag = GetIconFlagAndBackgroundFlag(slimItem, stateSvc)
    728                 icon = None
    729                 if self.icon_sprite and self.icon_sprite.display:
    730                     icon = self.icon_sprite
    731                 if icon and iconFlag and iconFlag != -1:
    732                     if self.sr.flag is None:
    733                         self.sr.flag = FlagIconWithState(parent=self, state=uiconst.UI_DISABLED, align=uiconst.TOPLEFT)
    734                     flagInfo = stateSvc.GetStatePropsColorAndBlink(iconFlag)
    735                     self.sr.flag.ModifyIcon(flagInfo=flagInfo, showHint=False, extraInfo=GetExtraInfoForSlimItem(slimItem))
    736                     if settings.user.overview.Get(osConst.SETTING_NAME_SMALL_TAGS, 0):
    737                         self.sr.flag.ChangeFlagPos(icon.left + 10, icon.top + 10, 5, 5)
    738                     else:
    739                         self.sr.flag.ChangeFlagPos(icon.left + 9, icon.top + 8, 9, 9)
    740                     hideIcon = settings.user.overview.Get(osConst.SETTING_NAME_SMALL_TAGS, 0)
    741                     self.sr.flag.ChangeIconVisibility(display=not hideIcon)
    742                 elif self.sr.flag:
    743                     self.sr.flag.Close()
    744                     self.sr.flag = None
    745                 if backgroundFlag and backgroundFlag != -1:
    746                     r, g, b, a = stateSvc.GetStateBackgroundColor(backgroundFlag)
    747                     a = a * 0.5
    748                     if not self.sr.bgColor:
    749                         self.sr.bgColor = Sprite(bgParent=self, name='bgColor', texturePath='res:/UI/Texture/classes/Bracket/bracketBackground.png', color=(r,
    750                          g,
    751                          b,
    752                          a))
    753                     else:
    754                         self.sr.bgColor.SetRGBA(r, g, b, a)
    755                     blink = stateSvc.GetStateBackgroundBlink(backgroundFlag)
    756                     if blink:
    757                         if not self.sr.bgColor.HasAnimation('opacity'):
    758                             uicore.animations.FadeTo(self.sr.bgColor, startVal=0.0, endVal=a, duration=0.75, loops=uiconst.ANIM_REPEAT, curveType=uiconst.ANIM_WAVE)
    759                     else:
    760                         self.sr.bgColor.StopAnimations()
    761                 elif self.sr.bgColor:
    762                     self.RemoveBackgroundColor()
    763                 self.TryCorrectHostileUI()
    764         except AttributeError:
    765             if not self.destroyed:
    766                 raise
    767 
    768     def RemoveBackgroundColor(self, *args):
    769         if self.sr.bgColor and self.sr.bgColor in self.background:
    770             self.background.remove(self.sr.bgColor)
    771             self.sr.bgColor = None
    772 
    773     @telemetry.ZONE_METHOD
    774     def UpdateIconColor(self, slimItem):
    775         if self.destroyed:
    776             return
    777         if self.icon_sprite is None or not slimItem:
    778             return
    779         if self.sr.node and self.sr.node.iconColor is not None and not HasEntityStandingsComponent(slimItem.typeID):
    780             iconColor = self.sr.node.iconColor
    781         else:
    782             iconColor = bracketVarious.GetIconColor(slimItem)
    783         self.SetColor(*iconColor)
    784         if slimItem.groupID in (const.groupWreck, const.groupSpawnContainer) and sm.GetService('wreck').IsViewedWreck(slimItem.itemID):
    785             self.SetViewState(isViewed=True)
    786 
    787     def _IsFleetMember(self):
    788         if not session.fleetid or not self.slimItem or not self.slimItem.ownerID:
    789             return False
    790         return sm.GetService('fleet').IsMember(self.slimItem.ownerID)
    791 
    792     @telemetry.ZONE_METHOD
    793     def OnStateChange(self, itemID, flag, status, *args):
    794         if self.stateItemID != itemID:
    795             return
    796         if flag == state.mouseOver:
    797             self.Hilite(status)
    798         elif flag == state.selected:
    799             self.Select(status)
    800         elif flag == state.threatTargetsMe:
    801             attacking = sm.StartService('stateSvc').GetStates(itemID, [state.threatAttackingMe])
    802             if attacking is not None and len(attacking) > 0:
    803                 attacking = attacking[0]
    804             else:
    805                 attacking = 0
    806             self.Hostile(status, attacking=attacking)
    807         elif flag == state.threatAttackingMe:
    808             self.Attacking(status)
    809         elif flag == state.targeted:
    810             self.Targeted(status)
    811         elif flag == state.targeting:
    812             self.Targeting(status)
    813         elif flag == state.activeTarget:
    814             self.ActiveTarget(status)
    815         elif flag == state.flagWreckAlreadyOpened:
    816             self.SetViewState(isViewed=status)
    817         elif flag == state.flagWreckEmpty:
    818             self.WreckEmpty(status)
    819         else:
    820             for name in iconsByBroadcastType:
    821                 if flag == getattr(state, 'gb%s' % name):
    822                     handler = getattr(self, 'GB%s' % name, None)
    823                     if handler is None:
    824                         self.FleetBroadcast(status, name, *args)
    825                     else:
    826                         handler(status, *args)
    827                     break
    828 
    829     def SetColor(self, r, g, b, _save = True):
    830         if _save:
    831             self._originalIconColor = (r, g, b)
    832         self.icon_sprite.SetRGB(r, g, b)
    833 
    834     @telemetry.ZONE_METHOD
    835     def SetViewState(self, isViewed):
    836         if not self._originalIconColor:
    837             color = self.icon_sprite.color
    838             self._originalIconColor = (color.r, color.g, color.b)
    839         r, g, b = self._originalIconColor
    840         if isViewed:
    841             attenuation = 0.55
    842             self.SetColor(r * attenuation, g * attenuation, b * attenuation, _save=False)
    843         else:
    844             self.SetColor(r, g, b, _save=False)
    845 
    846     def WreckEmpty(self, isEmpty):
    847         icon = sm.GetService('bracket').GetBracketIcon(self.slimItem.typeID, isEmpty)
    848         self.icon_sprite.LoadIcon(icon)
    849         self.iconNo = icon
    850 
    851     def SetHackingIcon(self, securityState):
    852         iconNo, iconHint = hacking_util.GetHackingIcon(securityState)
    853         self.icon_sprite.LoadIcon(iconNo)
    854         self.iconNo = iconNo
    855 
    856     def AddFleetTag(self, tag):
    857         self._fleetTag = tag
    858         self.UpdateFleetTagAndTarget()
    859 
    860     @telemetry.ZONE_METHOD
    861     def UpdateFleetTagAndTarget(self):
    862         tagAndTargetStr = ''
    863         if self._fleetTargetNo:
    864             tagAndTargetStr += unicode(self._fleetTargetNo)
    865         if self._fleetTag:
    866             if tagAndTargetStr:
    867                 tagAndTargetStr += ' / '
    868             tagAndTargetStr += unicode(self._fleetTag)
    869         self.tagAndTargetStr = tagAndTargetStr
    870         if tagAndTargetStr:
    871             if not self.fleetTagAndTarget:
    872                 self.fleetTagAndTarget = BracketShadowLabel(parent=self.parent, name='fleetTagAndTarget', align=uiconst.TOPLEFT, state=uiconst.UI_NORMAL, text=tagAndTargetStr, fontsize=EVE_MEDIUM_FONTSIZE, bracket=self, bold=True, idx=0)
    873             else:
    874                 self.fleetTagAndTarget.text = tagAndTargetStr
    875         elif self.fleetTagAndTarget:
    876             self.fleetTagAndTarget.Close()
    877             self.fleetTagAndTarget = None
    878         self.update_attached_objects()
    879 
    880     @telemetry.ZONE_METHOD
    881     def GBTarget(self, active, fleetBroadcastID, charID, targetNo = None):
    882         self.FleetBroadcast(active, 'Target', fleetBroadcastID, charID)
    883         if active:
    884             self._fleetTargetNo = targetNo
    885         else:
    886             self._fleetTargetNo = None
    887         self.UpdateFleetTagAndTarget()
    888 
    889     @telemetry.ZONE_METHOD
    890     def FleetBroadcast(self, active, broadcastType, fleetBroadcastID, charID):
    891         if active:
    892             self.fleetBroadcastSender = charID
    893             self.fleetBroadcastType = broadcastType
    894             self.fleetBroadcastID = fleetBroadcastID
    895             if self.fleetBroadcastIcon:
    896                 self.fleetBroadcastIcon.Close()
    897                 self.fleetBroadcastIcon = None
    898                 self.update_attached_objects()
    899             icon = iconsByBroadcastType[broadcastType]
    900             if not self.icon_sprite and self.stateItemID != session.shipid:
    901                 self.construct_icon(self.iconNo)
    902             self.fleetBroadcastIcon = BracketSubIconNew(icon=icon, parent=self.parent, state=uiconst.UI_NORMAL, name='fleetBroadcastIcon', bracket=self, hint=fleetbr.GetBroadcastName(broadcastType), idx=0, width=16, height=16)
    903             self.update_attached_objects()
    904         elif fleetBroadcastID == getattr(self, 'fleetBroadcastID', None):
    905             if self.fleetBroadcastIcon:
    906                 self.fleetBroadcastIcon.Close()
    907                 self.fleetBroadcastIcon = None
    908                 self.update_attached_objects()
    909             self.fleetBroadcastSender = self.fleetBroadcastType = self.fleetBroadcastID = None
    910 
    911     def _update_attached_objects(self):
    912         self.update_attached_objects()
    913 
    914     def GetLabelMargin(self):
    915         if self.controllers:
    916             return LABELMARGIN + max((c.GetHorizontalLabelPixelOffset() for c in self.controllers))
    917         else:
    918             return LABELMARGIN
    919 
    920     def _UpdateFleetTagAndTargetOffset(self, bracketLayerWidth, labelsXOffset, mainLabelsYOffset, maxLabelWidth, x, y):
    921         maxLabelWidth = max(maxLabelWidth, self.fleetTagAndTarget.textwidth)
    922         labelMargin = self.GetLabelMargin()
    923         if x + self.width + labelMargin + maxLabelWidth > bracketLayerWidth:
    924             self.fleetTagAndTarget.x_offset = -self.fleetTagAndTarget.textwidth - labelMargin - labelsXOffset
    925         else:
    926             self.fleetTagAndTarget.x_offset = self.width + labelMargin + labelsXOffset
    927         if y <= 0:
    928             tagLabelYShift = (self.height - self.fleetTagAndTarget.textheight) / 2 + 1
    929             self.fleetTagAndTarget.y_offset = tagLabelYShift
    930             mainLabelsYOffset = self.fleetTagAndTarget.textheight
    931         else:
    932             self.fleetTagAndTarget.y_offset = -self.fleetTagAndTarget.textheight
    933         return (mainLabelsYOffset, maxLabelWidth)
    934 
    935     def _UpdateLabelOffsets(self, bracketLayerWidth, labelsXOffset, mainLabelsYOffset, maxLabelWidth, x):
    936         labelMargin = self.GetLabelMargin()
    937         is_left_of_bracket = x + self.width + labelMargin + maxLabelWidth > bracketLayerWidth
    938         mainLabelsYOffset += (self.height - self.label.textheight) / 2 + 1
    939         if is_left_of_bracket:
    940             x_offset = -self.label.textwidth - labelMargin - labelsXOffset
    941         else:
    942             x_offset = self.width + labelMargin + labelsXOffset
    943         self.label.x_offset = x_offset
    944         self.label.y_offset = mainLabelsYOffset
    945         if self.subLabel:
    946             if is_left_of_bracket:
    947                 x_offset = -self.subLabel.textwidth - labelMargin - labelsXOffset
    948                 y_offset = mainLabelsYOffset + self.label.textheight
    949             else:
    950                 x_offset = self.width + labelMargin + labelsXOffset
    951                 y_offset = mainLabelsYOffset + self.label.textheight
    952             self.subLabel.x_offset = x_offset
    953             self.subLabel.y_offset = y_offset
    954 
    955     def _UpdateFleetBroadcastIcon(self, bracketLayerWidth, labelsXOffset, x, y):
    956         if x <= 0:
    957             self.fleetBroadcastIcon.x_offset = self.width + 2
    958             self.fleetBroadcastIcon.y_offset = (self.height - self.fleetBroadcastIcon.height) / 2
    959             labelsXOffset = self.fleetBroadcastIcon.width
    960         elif x + self.width >= bracketLayerWidth:
    961             self.fleetBroadcastIcon.x_offset = -self.fleetBroadcastIcon.width - 2
    962             self.fleetBroadcastIcon.y_offset = (self.height - self.fleetBroadcastIcon.height) / 2
    963             labelsXOffset = self.fleetBroadcastIcon.width
    964         elif self.projectBracket and self.projectBracket.bracket:
    965             self.fleetBroadcastIcon.x_offset = (self.width - self.fleetBroadcastIcon.width) / 2
    966             if y <= 0:
    967                 self.fleetBroadcastIcon.y_offset = self.fleetBroadcastIcon.height
    968             else:
    969                 self.fleetBroadcastIcon.y_offset = -self.fleetBroadcastIcon.height
    970         else:
    971             self.fleetBroadcastIcon.y_offset = (self.height - self.fleetBroadcastIcon.height) / 2
    972             self.fleetBroadcastIcon.x_offset = -self.fleetBroadcastIcon.width - 2
    973         return labelsXOffset
    974 
    975     def UpdateSubLabelText(self):
    976         if self.subLabel is None:
    977             return
    978         if not self.subLabelCallback:
    979             return
    980         self.displaySubLabel = self.subLabelCallback()
    981         self.subLabel.text = self.displaySubLabel or ''
    982 
    983     def GetSubLabelCallback(self):
    984         return self.subLabelCallback
    985 
    986     def SetSubLabelCallback(self, callback):
    987         self.subLabelCallback = callback
    988         self.displaySubLabel = callback()
    989 
    990     def RemoveSubLabelCallback(self, callback):
    991         if callback != self.subLabelCallback:
    992             return
    993         self.subLabelCallback = None
    994         self.CloseSubLabel()
    995         self.displaySubLabel = None
    996 
    997     @telemetry.ZONE_METHOD
    998     def update_attached_objects(self):
    999         if self.destroyed:
   1000             return
   1001         bracketRO = self.renderObject
   1002         x, y = bracketRO.displayX, bracketRO.displayY
   1003         bracketLayerWidth = uicore.layer.bracket.renderObject.displayWidth
   1004         labelsXOffset = self.get_label_x_offset()
   1005         labelsYOffset = self.get_label_y_offset()
   1006         if self.fleetBroadcastIcon:
   1007             labelsXOffset = self._UpdateFleetBroadcastIcon(bracketLayerWidth, labelsXOffset, x, y)
   1008         if self.label:
   1009             if self.displayName is None:
   1010                 sm.GetService('bracket').RemoveBracket(self.itemID)
   1011                 return
   1012             newStr = self.get_label_text(self.displayName)
   1013             self.label.text = newStr
   1014         self.UpdateSubLabelText()
   1015         mainLabelsYOffset = labelsYOffset
   1016         maxLabelWidth = 0
   1017         if self.label:
   1018             maxLabelWidth = max(maxLabelWidth, self.label.textwidth)
   1019         if self.SubLabelExists():
   1020             maxLabelWidth = max(maxLabelWidth, self.subLabel.textwidth)
   1021         if self.fleetTagAndTarget:
   1022             self.fleetTagAndTarget.display = self.display
   1023             mainLabelsYOffset, maxLabelWidth = self._UpdateFleetTagAndTargetOffset(bracketLayerWidth, labelsXOffset, mainLabelsYOffset, maxLabelWidth, x, y)
   1024         if self.label:
   1025             self._UpdateLabelOffsets(bracketLayerWidth, labelsXOffset, mainLabelsYOffset, maxLabelWidth, x)
   1026         if not self.has_attached_objects():
   1027             self.subItemsUpdateTimer = None
   1028         elif not self.subItemsUpdateTimer:
   1029             self.subItemsUpdateTimer = timerstuff.AutoTimer(500, self._update_attached_objects)
   1030         self.check_update_expanded_bracket()
   1031 
   1032     def check_update_expanded_bracket(self):
   1033         if self.expanded_bracket:
   1034             self.expanded_bracket.update(self.IsFloating())
   1035 
   1036     def has_attached_objects(self):
   1037         return self.label or self.subLabel or self.fleetBroadcastIcon or self.fleetTagAndTarget or self.expanded_bracket
   1038 
   1039     def get_label_text(self, newStr):
   1040         if hasattr(self, 'GetDocked'):
   1041             docked = self.GetDocked()
   1042             if docked is not None:
   1043                 newStr += ' [{}]'.format(docked)
   1044         if getattr(self, 'showDistance', 1):
   1045             distance = self.GetDistance()
   1046             if distance:
   1047                 newStr += ' ' + FmtDist(distance)
   1048         return newStr
   1049 
   1050     def get_label_x_offset(self):
   1051         return 0
   1052 
   1053     def get_label_y_offset(self):
   1054         return 0
   1055 
   1056     def getActiveStateOverride(self, activeState):
   1057         if sm.GetService('target').disableSpinnyReticule:
   1058             activeState = False
   1059         return activeState
   1060 
   1061     @telemetry.ZONE_METHOD
   1062     def ActiveTarget(self, activestate):
   1063         activestate = self.getActiveStateOverride(activestate)
   1064         if activestate:
   1065             if not self.active_target_indicator:
   1066                 self.active_target_indicator = ActiveTargetIndicator(parent=self, itemID=self.itemID)
   1067             if self.targeted_indicator:
   1068                 self.targeted_indicator.ChangeLineOpacity(faded=0)
   1069         else:
   1070             if self.active_target_indicator:
   1071                 self.active_target_indicator.Close()
   1072                 self.active_target_indicator = None
   1073             if self.targeted_indicator:
   1074                 self.targeted_indicator.ChangeLineOpacity(faded=1)
   1075 
   1076     @telemetry.ZONE_METHOD
   1077     def Targeted(self, is_targeted):
   1078         is_targeted = self.getActiveStateOverride(is_targeted)
   1079         if is_targeted:
   1080             if not self.targeted_indicator:
   1081                 self.targeted_indicator = TargetedIndicator(parent=self)
   1082                 lines = self.targeted_indicator.lines
   1083                 targetCrosshair = sm.GetService('overviewPresetSvc').GetSettingValueOrDefaultFromName(osConst.SETTING_TARGET_CROSSHAIR, True)
   1084                 if not targetCrosshair:
   1085                     lines.display = False
   1086                 else:
   1087                     lines.display = True
   1088                     bracketVarious.FixLines(self.targeted_indicator)
   1089             circle = self.targeted_indicator.circle
   1090             if circle is not None and not circle.destroyed:
   1091                 circle.state = uiconst.UI_DISABLED
   1092         else:
   1093             if self.active_target_indicator:
   1094                 self.active_target_indicator.Close()
   1095                 self.active_target_indicator = None
   1096             if self.targeted_indicator:
   1097                 self.targeted_indicator.Close()
   1098                 self.targeted_indicator = None
   1099 
   1100     @telemetry.ZONE_METHOD
   1101     def Targeting(self, is_targeting):
   1102         is_targeting = self.getActiveStateOverride(is_targeting)
   1103         if is_targeting:
   1104             if self.targeted_indicator is None or self.targeted_indicator.destroyed:
   1105                 self.Targeted(1)
   1106             if self.targeted_indicator:
   1107                 uthread.new(self.CountDown, self.targeted_indicator)
   1108                 self.targeted_indicator.ShowTargetingIndicators()
   1109         elif self.targeted_indicator:
   1110             self.targeted_indicator.HideTargetingIndicators()
   1111 
   1112     @telemetry.ZONE_METHOD
   1113     def Hilite(self, is_hilited):
   1114         if is_hilited and self.state != uiconst.UI_HIDDEN:
   1115             if not self.highlight_sprite:
   1116                 self.highlight_sprite = Sprite(parent=self, pos=(0, 0, 30, 30), name='highlight_sprite', state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/Bracket/selectionCircle.png', align=uiconst.CENTER, color=(1, 1, 1, 0.3))
   1117             self.highlight_sprite.Show()
   1118         elif self.highlight_sprite:
   1119             self.highlight_sprite.Close()
   1120             self.highlight_sprite = None
   1121         self.update_label_visibility()
   1122 
   1123     def update_label_visibility(self):
   1124         if self._is_label_visible():
   1125             self.ShowLabel()
   1126         elif self.label:
   1127             self.KillLabel()
   1128 
   1129     def _is_label_visible(self):
   1130         if self.expanded_bracket:
   1131             return False
   1132         return self.isSelected or self.always_show_label or sm.GetService('stateSvc').GetExclState(state.mouseOver) == self.itemID and self.IsFloating()
   1133 
   1134     @telemetry.ZONE_METHOD
   1135     def Hostile(self, is_hostile, attacking = 0):
   1136         if is_hostile:
   1137             if self.sr.hostile_attacking is not None:
   1138                 self._RemoveHostileAttackingUI()
   1139             fleetMember = self._IsFleetMember()
   1140             yellowColor = (1, 0.8, 0, 0.5)
   1141             if fleetMember:
   1142                 color = sm.GetService('bracket').GetFleetBracketColor() or yellowColor
   1143             else:
   1144                 color = yellowColor
   1145             attckingIcon = self.GetHostileUI()
   1146             attckingIcon.SetRGBA(*color)
   1147             attckingIcon.state = uiconst.UI_DISABLED
   1148         elif not attacking and self.sr.hostile:
   1149             self._RemoveHostileUI()
   1150         self.UpdateIconColor(self.slimItem)
   1151 
   1152     def _RemoveHostileAttackingUI(self):
   1153         self.sr.hostile_attacking.Close()
   1154         self.sr.hostile_attacking = None
   1155 
   1156     def _RemoveHostileUI(self):
   1157         attckingIcon = self.sr.hostile
   1158         self.sr.hostile = None
   1159         attckingIcon.Close()
   1160 
   1161     def TryCorrectHostileUI(self):
   1162         if not self.sr.hostile:
   1163             return
   1164         isFleetMember = self._IsFleetMember()
   1165         if getattr(self.sr.hostile, 'isFleetMember', False) != isFleetMember:
   1166             self.Hostile(1)
   1167 
   1168     @telemetry.ZONE_METHOD
   1169     def Attacking(self, state):
   1170         if state:
   1171             if self.sr.hostile is not None:
   1172                 self._RemoveHostileUI()
   1173             attckingIcon = self.GetHostileAttackingUI()
   1174             attckingIcon.SetRGBA(0.8, 0, 0, 0.3)
   1175             attckingIcon.state = uiconst.UI_DISABLED
   1176         elif self.itemID in sm.GetService('target').GetTargetedBy():
   1177             self.Hostile(1)
   1178         elif self.sr.hostile_attacking:
   1179             attckingIcon = self.sr.hostile_attacking
   1180             self.sr.hostile_attacking = None
   1181             attckingIcon.Close()
   1182         self.UpdateIconColor(self.slimItem)
   1183 
   1184     @telemetry.ZONE_METHOD
   1185     def UpdateStructureState(self, slimItem):
   1186         if not idCheckers.IsStarbase(slimItem.categoryID):
   1187             return
   1188         self.lastPosEvent = blue.os.GetWallclockTime()
   1189         stateName, stateTimestamp, stateDelay = sm.GetService('pwn').GetStructureState(slimItem)
   1190         if self.sr.posStatus is None:
   1191             self.sr.posStatus = eveLabel.EveLabelSmall(text=entityConst.POS_STRUCTURE_STATE[stateName], parent=self, left=24, top=30, state=uiconst.UI_NORMAL)
   1192         else:
   1193             self.sr.posStatus.text = entityConst.POS_STRUCTURE_STATE[stateName]
   1194         if stateName in ('anchoring', 'onlining', 'unanchoring', 'reinforced', 'operating', 'incapacitated'):
   1195             uthread.new(self.StructureProgress, self.lastPosEvent, stateName, stateTimestamp, stateDelay)
   1196 
   1197     @telemetry.ZONE_METHOD
   1198     def UpdateOrbitalState(self, slimItem):
   1199         if not idCheckers.IsOrbital(slimItem.categoryID):
   1200             return
   1201         self.lastOrbitalEvent = blue.os.GetWallclockTime()
   1202         if slimItem.orbitalState in (entityConst.STATE_ANCHORING, entityConst.STATE_ONLINING, entityConst.STATE_SHIELD_REINFORCE) or slimItem.groupID == const.groupOrbitalConstructionPlatforms:
   1203             statusString = bracketVarious.GetEntityStateString(slimItem.orbitalState)
   1204             if self.sr.orbitalStatus is None:
   1205                 self.sr.orbitalStatus = eveLabel.EveLabelSmall(text=statusString, parent=self, left=24, top=30, state=uiconst.UI_NORMAL)
   1206             else:
   1207                 self.sr.orbitalStatus.text = statusString
   1208         if slimItem.orbitalState in (entityConst.STATE_UNANCHORED, entityConst.STATE_IDLE, entityConst.STATE_ANCHORED) and slimItem.groupID != const.groupOrbitalConstructionPlatforms:
   1209             if self.sr.orbitalStatus is not None:
   1210                 self.sr.orbitalStatus.Close()
   1211                 self.sr.orbitalStatus = None
   1212         if slimItem.orbitalHackerID is not None:
   1213             if self.sr.orbitalHack is None:
   1214                 self.sr.orbitalHack = HackingNumberGrid(parent=self, width=140, height=140, numCellRows=7, cellsPerRow=7, cellHeight=20, cellWidth=20, align=uiconst.CENTERTOP, top=-150)
   1215                 self.sr.orbitalHack.BeginColorCycling()
   1216             progress = 0.0 if slimItem.orbitalHackerProgress is None else slimItem.orbitalHackerProgress
   1217             self.sr.orbitalHack.SetProgress(progress)
   1218         elif self.sr.orbitalHack is not None:
   1219             self.sr.orbitalHack.StopColorCycling()
   1220             self.children.remove(self.sr.orbitalHack)
   1221             self.sr.orbitalHack = None
   1222         if slimItem.orbitalState in (entityConst.STATE_ONLINING,
   1223          entityConst.STATE_OFFLINING,
   1224          entityConst.STATE_ANCHORING,
   1225          entityConst.STATE_UNANCHORING,
   1226          entityConst.STATE_SHIELD_REINFORCE):
   1227             uthread.new(self.OrbitalProgress, self.lastOrbitalEvent, slimItem)
   1228 
   1229     @telemetry.ZONE_METHOD
   1230     def UpdatePlanetaryLaunchContainer(self, slimItem):
   1231         if slimItem.typeID != const.typePlanetaryLaunchContainer:
   1232             return
   1233         uthread.new(self._UpdatePlanetaryLaunchContainer, slimItem)
   1234 
   1235     @telemetry.ZONE_METHOD
   1236     def _UpdatePlanetaryLaunchContainer(self, slimItem):
   1237         cnt = 0
   1238         while slimItem.launchTime is None and cnt < 90:
   1239             blue.pyos.synchro.SleepWallclock(1000)
   1240             cnt += 1
   1241 
   1242         if getattr(self, 'planetaryLaunchContainerThreadRunning', False) == False and slimItem.launchTime is not None:
   1243             uthread.new(self.PlanetaryLaunchContainerProgress, slimItem.launchTime, long(slimItem.launchTime + const.piLaunchOrbitDecayTime))
   1244 
   1245     @telemetry.ZONE_METHOD
   1246     def PlanetaryLaunchContainerProgress(self, startTime, endTime):
   1247         self.planetaryLaunchContainerThreadRunning = True
   1248         try:
   1249             boxwidth = 82
   1250             fillwidth = boxwidth - 2
   1251             boxheight = 14
   1252             fillheight = boxheight - 2
   1253             boxtop = 30
   1254             filltop = boxtop + 1
   1255             boxleft = -(boxwidth / 2) + 5
   1256             fillleft = boxleft + 1
   1257             boxcolor = (1.0, 1.0, 1.0, 0.35)
   1258             fillcolor = (1.0, 1.0, 1.0, 0.25)
   1259             if not hasattr(self, 'burnupFill'):
   1260                 self.burnupFill = Fill(parent=self, align=uiconst.RELATIVE, width=fillwidth, height=fillheight, left=fillleft, top=filltop, color=fillcolor)
   1261             burnupFill = self.burnupFill
   1262             if not hasattr(self, 'burnupTimeText'):
   1263                 self.burnupTimeText = eveLabel.EveLabelSmall(text=' ', parent=self, left=-10, top=32, lineSpacing=0.2, state=uiconst.UI_NORMAL)
   1264             timeText = self.burnupTimeText
   1265             if not hasattr(self, 'burnupFrame'):
   1266                 self.burnupFrame = Frame(parent=self, align=uiconst.RELATIVE, width=boxwidth, height=boxheight, left=boxleft, top=boxtop, color=boxcolor)
   1267             frame = self.burnupFrame
   1268             while not self.destroyed and self.planetaryLaunchContainerThreadRunning:
   1269                 currentTime = blue.os.GetWallclockTime()
   1270                 portion = float(currentTime - startTime) / (endTime - startTime)
   1271                 if portion > 1.0:
   1272                     break
   1273                 width = min(int(portion * fillwidth), fillwidth)
   1274                 width = fillwidth - abs(width)
   1275                 if burnupFill.width != width:
   1276                     burnupFill.width = width
   1277                 newTimeText = FmtDate(endTime - currentTime, 'ss')
   1278                 if timeText.text != newTimeText:
   1279                     timeText.text = newTimeText
   1280                     timeText.left = -32
   1281                 blue.pyos.synchro.SleepWallclock(1000)
   1282 
   1283         finally:
   1284             self.planetaryLaunchContainerThreadRunning = False
   1285 
   1286     @telemetry.ZONE_METHOD
   1287     def UpdateCaptureProgress(self, captureData):
   1288         slimItem = self.slimItem
   1289         if slimItem.groupID not in (const.groupCapturePointTower, const.groupSatellite):
   1290             return
   1291         if captureData:
   1292             self.captureData = captureData
   1293         else:
   1294             self.captureData = sm.GetService('bracket').GetCaptureData(self.itemID)
   1295         if not self.captureData:
   1296             return
   1297         if self.captureData.get('completion'):
   1298             self.captureData['points'] = 100.0 - (self.captureData['completion'] - blue.os.GetSimTime()) / (self.captureData['captureTime'] * const.MIN) * 100.0
   1299         if not getattr(self, 'captureTaskletRunning', False):
   1300             uthread.new(self.CaptureProgress)
   1301 
   1302     def GetCaptureProgress(self):
   1303         portion = float(self.captureData['points']) / 100
   1304         if self.captureData.get('captureID') != 'contested':
   1305             difference = blue.os.TimeDiffInMs(self.captureData['lastIncident'], blue.os.GetSimTime())
   1306             portion += float(difference) / self.captureData['captureTime'] / 60 / 1000
   1307         return min(max(portion, -1), 1)
   1308 
   1309     @telemetry.ZONE_METHOD
   1310     def CaptureProgress(self):
   1311         self.captureTaskletRunning = True
   1312         try:
   1313             boxwidth = 82
   1314             fillwidth = boxwidth - 2
   1315             boxheight = 14
   1316             fillheight = boxheight - 2
   1317             boxtop = 30
   1318             filltop = boxtop + 1
   1319             boxleft = -(boxwidth / 2) + 5
   1320             fillleft = boxleft + 1
   1321             boxcolor = (1.0, 1.0, 1.0, 0.35)
   1322             fillcolor = (1.0, 1.0, 1.0, 0.25)
   1323             if not getattr(self, 'capture', None):
   1324                 self.capture = Container(parent=self, align=uiconst.TOALL, state=uiconst.UI_DISABLED)
   1325                 self.sr.captureFrame = Frame(parent=self.capture, align=uiconst.RELATIVE, width=boxwidth, height=boxheight, left=boxleft, top=boxtop, color=boxcolor)
   1326                 self.sr.captureState = Fill(parent=self.capture, align=uiconst.RELATIVE, width=0, height=fillheight, left=fillleft, top=filltop, color=fillcolor)
   1327                 self.sr.captureStateText = eveLabel.EveLabelSmall(text=' ', parent=self.capture, left=boxleft, top=boxtop + boxheight + 2, state=uiconst.UI_DISABLED)
   1328                 self.sr.captureStateTimeText = eveLabel.EveLabelSmall(text=' ', parent=self.capture, left=-10, top=filltop + 1, state=uiconst.UI_DISABLED)
   1329                 self.sr.captureLogo = None
   1330             while not self.destroyed:
   1331                 self.capture.state = uiconst.UI_DISABLED
   1332                 progress = self.GetCaptureProgress()
   1333                 if self.captureData.get('captureID') is None and self.captureData['lastCapturing'] is None:
   1334                     self.capture.Close()
   1335                     self.capture = None
   1336                     return
   1337                 if self.GetDistance() > const.minCaptureBracketDistance:
   1338                     self.capture.state = uiconst.UI_HIDDEN
   1339                 elif progress == 1 and self.captureData['lastCapturing']:
   1340                     self.SetCaptureLogo(self.captureData['lastCapturing'])
   1341                     self.sr.captureState.width = abs(int(progress * fillwidth))
   1342                     self.sr.captureStateText.text = cfg.eveowners.Get(self.captureData['lastCapturing']).name
   1343                     self.sr.captureStateTimeText.text = self.GetCaptureTimeString(progress)
   1344                 elif self.captureData.get('captureID') == 'contested':
   1345                     self.SetCaptureLogo(self.captureData['lastCapturing'])
   1346                     self.sr.captureState.width = abs(int(progress * fillwidth))
   1347                     self.sr.captureStateText.text = localization.GetByLabel('UI/Inflight/Brackets/SystemContested')
   1348                     self.sr.captureStateTimeText.text = self.GetCaptureTimeString(progress)
   1349                 elif self.captureData.get('captureID'):
   1350                     if progress < 0.0:
   1351                         self.SetCaptureLogo(self.captureData['lastCapturing'])
   1352                     else:
   1353                         self.SetCaptureLogo(self.captureData['captureID'])
   1354                     self.sr.captureState.width = abs(int(progress * fillwidth))
   1355                     self.sr.captureStateText.text = localization.GetByLabel('UI/Inflight/Brackets/FacWarCapturing', ownerName=cfg.eveowners.Get(self.captureData['captureID']).name)
   1356                     self.sr.captureStateTimeText.text = self.GetCaptureTimeString(progress)
   1357                     self.sr.captureStateTimeText.left = -8
   1358                 blue.pyos.synchro.SleepWallclock(900)
   1359 
   1360         finally:
   1361             self.captureTaskletRunning = False
   1362 
   1363     @telemetry.ZONE_METHOD
   1364     def GetCaptureTimeString(self, portion):
   1365         if self.captureData['captureID'] == 'contested':
   1366             return ' '
   1367         timeScalar = 1 - portion
   1368         if timeScalar <= 0:
   1369             return localization.GetByLabel('UI/Inflight/Brackets/FacWarCaptured')
   1370         maxTime = self.captureData['captureTime']
   1371         timeLeft = timeScalar * maxTime
   1372         properTime = long(60000 * const.dgmTauConstant * timeLeft)
   1373         return FmtDate(properTime, 'ns')
   1374 
   1375     @telemetry.ZONE_METHOD
   1376     def SetCaptureLogo(self, teamID):
   1377         if teamID == 'contested' or teamID is None:
   1378             return
   1379         if self.sr.Get('captureLogo'):
   1380             if self.sr.captureLogo.name == cfg.eveowners.Get(teamID).name:
   1381                 self.sr.captureLogo.state = uiconst.UI_DISABLED
   1382                 return
   1383             self.sr.captureLogo.Close()
   1384         itemID = const.raceByFaction.get(teamID, teamID)
   1385         self.sr.captureLogo = eveIcon.LogoIcon(itemID=itemID, parent=self.capture, state=uiconst.UI_DISABLED, size=32, pos=(-70, 22, 32, 32), name=cfg.eveowners.Get(teamID).name, align=uiconst.RELATIVE, ignoreSize=True, isSmall=True)
   1386 
   1387     @telemetry.ZONE_METHOD
   1388     def StructureProgress(self, lastPosEvent, stateName, stateTimestamp, stateDelay):
   1389         if self.destroyed:
   1390             return
   1391         t = self.sr.posStatus
   1392         Frame(parent=self, align=uiconst.RELATIVE, width=82, height=13, left=18, top=30, color=(1.0, 1.0, 1.0, 0.5))
   1393         p = Fill(parent=self, align=uiconst.RELATIVE, width=80, height=11, left=19, top=31, color=(1.0, 1.0, 1.0, 0.25))
   1394         startTime = blue.os.GetWallclockTime()
   1395         if stateDelay:
   1396             stateDelay = float(stateDelay * const.MSEC)
   1397         doneStr = {'anchoring': localization.GetByLabel('UI/Entities/States/Anchored'),
   1398          'onlining': localization.GetByLabel('UI/Entities/States/Online'),
   1399          'unanchoring': localization.GetByLabel('UI/Entities/States/Unanchored'),
   1400          'reinforced': localization.GetByLabel('UI/Entities/States/Online'),
   1401          'operating': localization.GetByLabel('UI/Entities/States/Operating'),
   1402          'incapacitated': localization.GetByLabel('UI/Entities/States/Incapacitated')}.get(stateName, localization.GetByLabel('UI/Entities/States/Done'))
   1403         endTime = 0
   1404         if stateDelay:
   1405             endTime = stateTimestamp + stateDelay
   1406         while 1 and endTime:
   1407             if not self or self.destroyed or lastPosEvent != self.lastPosEvent:
   1408                 return
   1409             timeLeft = endTime - blue.os.GetWallclockTime()
   1410             portion = timeLeft / stateDelay
   1411             timeLeftSec = timeLeft / 1000.0
   1412             if timeLeft <= 0:
   1413                 t.text = doneStr
   1414                 break
   1415             t.text = localization.GetByLabel('UI/Inflight/Brackets/StructureProgress', stateName=entityConst.POS_STRUCTURE_STATE[stateName], timeRemaining=long(timeLeft))
   1416             p.width = int(80 * portion)
   1417             blue.pyos.synchro.SleepWallclock(900)
   1418 
   1419         blue.pyos.synchro.SleepWallclock(250)
   1420         if not self or self.destroyed:
   1421             return
   1422         for each in self.children[-2:]:
   1423             if each is not None and not getattr(each, 'destroyed', 0):
   1424                 each.Close()
   1425 
   1426         if lastPosEvent != self.lastPosEvent:
   1427             return
   1428         t.text = ''
   1429         blue.pyos.synchro.SleepWallclock(250)
   1430         if not self or self.destroyed or lastPosEvent != self.lastPosEvent:
   1431             return
   1432         t.text = doneStr
   1433         blue.pyos.synchro.SleepWallclock(250)
   1434         if not self or self.destroyed or lastPosEvent != self.lastPosEvent:
   1435             return
   1436         t.text = ''
   1437         blue.pyos.synchro.SleepWallclock(250)
   1438         if not self or self.destroyed or lastPosEvent != self.lastPosEvent:
   1439             return
   1440         t.text = doneStr
   1441 
   1442     @telemetry.ZONE_METHOD
   1443     def OrbitalProgress(self, lastOrbitalEvent, slimItem):
   1444         if self.destroyed:
   1445             return
   1446         t = self.sr.orbitalStatus
   1447         Frame(parent=self, align=uiconst.TOPLEFT, width=82, height=13, left=18, top=30, color=(1.0, 1.0, 1.0, 0.5))
   1448         p = Fill(parent=self, align=uiconst.TOPLEFT, width=80, height=11, left=19, top=31, color=(1.0, 1.0, 1.0, 0.25))
   1449         stateName = bracketVarious.GetEntityStateString(slimItem.orbitalState)
   1450         stateTimestamp = slimItem.orbitalTimestamp
   1451         stateDelay = None
   1452         doneText = localization.GetByLabel('UI/Entities/States/Done')
   1453         godmaSM = sm.GetService('godma').GetStateManager()
   1454         if slimItem.orbitalState == entityConst.STATE_ANCHORING:
   1455             stateDelay = godmaSM.GetType(slimItem.typeID).anchoringDelay
   1456             doneText = bracketVarious.GetEntityStateString(entityConst.STATE_ANCHORED)
   1457         elif slimItem.orbitalState == entityConst.STATE_ONLINING:
   1458             stateName = localization.GetByLabel('UI/Entities/States/Upgrading')
   1459             stateDelay = godmaSM.GetType(slimItem.typeID).onliningDelay
   1460             doneText = localization.GetByLabel('UI/Entities/States/Online')
   1461         elif slimItem.orbitalState == entityConst.STATE_UNANCHORING:
   1462             stateDelay = godmaSM.GetType(slimItem.typeID).unanchoringDelay
   1463             doneText = bracketVarious.GetEntityStateString(entityConst.STATE_UNANCHORED)
   1464         elif slimItem.orbitalState == entityConst.STATE_SHIELD_REINFORCE:
   1465             doneText = bracketVarious.GetEntityStateString(entityConst.STATE_ANCHORED)
   1466         if stateDelay:
   1467             stateDelay = float(stateDelay * const.MSEC)
   1468         else:
   1469             stateDelay = const.DAY
   1470         timeLeft = stateTimestamp - blue.os.GetWallclockTime()
   1471         try:
   1472             while timeLeft > 0:
   1473                 blue.pyos.synchro.SleepWallclock(900)
   1474                 if not self or self.destroyed or lastOrbitalEvent != self.lastOrbitalEvent:
   1475                     return
   1476                 timeLeft = stateTimestamp - blue.os.GetWallclockTime()
   1477                 portion = max(0.0, min(1.0, timeLeft / stateDelay))
   1478                 t.text = localization.GetByLabel('UI/Inflight/Brackets/StructureProgress', stateName=stateName, timeRemaining=long(timeLeft))
   1479                 p.width = int(80 * portion)
   1480 
   1481             t.text = doneText
   1482             blue.pyos.synchro.SleepWallclock(250)
   1483             if not self or self.destroyed:
   1484                 return
   1485         finally:
   1486             if self and not self.destroyed:
   1487                 t.text = doneText
   1488                 for each in self.children[-2:]:
   1489                     if each is not None and not getattr(each, 'destroyed', 0):
   1490                         each.Close()
   1491 
   1492         if lastOrbitalEvent != self.lastOrbitalEvent:
   1493             return
   1494         t.text = ''
   1495         blue.pyos.synchro.SleepWallclock(250)
   1496         if not self or self.destroyed or lastOrbitalEvent != self.lastOrbitalEvent:
   1497             return
   1498         t.text = doneText
   1499         blue.pyos.synchro.SleepWallclock(250)
   1500         if not self or self.destroyed or lastOrbitalEvent != self.lastOrbitalEvent:
   1501             return
   1502         t.text = ''
   1503         blue.pyos.synchro.SleepWallclock(250)
   1504         if not self or self.destroyed or lastOrbitalEvent != self.lastOrbitalEvent:
   1505             return
   1506         t.text = doneText
   1507 
   1508     @telemetry.ZONE_METHOD
   1509     def SetBracketAnchoredState(self, slimItem):
   1510         if not evetypes.GetIsGroupAnchorableByGroup(slimItem.groupID):
   1511             return
   1512         if not slimItem or slimItem.itemID == session.shipid or slimItem.ownerID != session.charid and slimItem.ownerID != session.corpid:
   1513             return
   1514         ball = self.ball
   1515         if ball is None:
   1516             bp = sm.GetService('michelle').GetBallpark()
   1517             ball = bp.GetBall(slimItem.itemID)
   1518             if not ball:
   1519                 return
   1520         _iconNo, _dockType, _minDist, _maxDist, _iconOffset, _logflag = sm.GetService('bracket').GetBracketProps(slimItem, ball)
   1521         iconNo, dockType, minDist, maxDist, iconOffset, logflag = self.data
   1522         for each in self.children:
   1523             if each.name == 'anchoredicon':
   1524                 if ball.isFree:
   1525                     self.data = (iconNo,
   1526                      dockType,
   1527                      _minDist,
   1528                      _maxDist,
   1529                      iconOffset,
   1530                      logflag)
   1531                     each.Close()
   1532                 return
   1533 
   1534         if not ball.isFree:
   1535             self.data = (iconNo,
   1536              dockType,
   1537              0.0,
   1538              1e+32,
   1539              iconOffset,
   1540              logflag)
   1541             Sprite(icon='res:/UI/Texture/Icons/38_16_15', name='anchoredicon', parent=self, pos=(0, 16, 16, 16), align=uiconst.TOPLEFT)
   1542 
   1543     @telemetry.ZONE_METHOD
   1544     def UpdateHackProgress(self, hackProgress):
   1545         if self.sr.orbitalHackLocal is None:
   1546             return
   1547         self.sr.orbitalHackLocal.SetValue(hackProgress)
   1548 
   1549     @telemetry.ZONE_METHOD
   1550     def BeginHacking(self):
   1551         if self.sr.orbitalHackLocal is None:
   1552             self.sr.orbitalHackLocal = HackingProgressBar(parent=self, height=20, width=120, align=uiconst.CENTERBOTTOM, top=-50, color=(0.0, 0.8, 0.0, 1.0), backgroundColor=(0.25, 0.0, 0.0, 1.0))
   1553 
   1554     def _StopHacking(self):
   1555         blue.pyos.synchro.SleepWallclock(5000)
   1556         if self and self.sr.orbitalHackLocal:
   1557             self.sr.orbitalHackLocal.state = uiconst.UI_HIDDEN
   1558             self.sr.orbitalHackLocal.Close()
   1559             self.sr.orbitalHackLocal = None
   1560 
   1561     def StopHacking(self, success = False):
   1562         if self.sr.orbitalHackLocal is not None:
   1563             self.sr.orbitalHackLocal.Finalize(complete=success)
   1564             uthread.new(self._StopHacking)
   1565 
   1566     def ShowRadialMenuIndicator(self, slimItem = None, *args):
   1567         if getattr(self, 'invisible', False) and (self.selection_sprite is None or not self.selection_sprite.display):
   1568             return
   1569         mySprite = self.GetRadialMenuIndicator(create=True)
   1570         mySprite.display = True
   1571 
   1572     def HideRadialMenuIndicator(self, slimItem = None, *args):
   1573         mySprite = self.GetRadialMenuIndicator(create=False)
   1574         if mySprite:
   1575             mySprite.display = False
   1576 
   1577     def CreateCounterController(self, controllerClass, componentRegistry, slimItem):
   1578         try:
   1579             controller = controllerClass(self, componentRegistry, slimItem)
   1580             self.controllers.append(controller)
   1581         except KeyError:
   1582             pass
   1583 
   1584     def GetCounterControllerForClass(self, controllerClass):
   1585         for c in self.controllers:
   1586             if isinstance(c, controllerClass):
   1587                 return c
   1588 
   1589     def CreateSpaceComponentUI(self, slimItem):
   1590         bp = sm.GetService('michelle').GetBallpark()
   1591         if bp is not None:
   1592             componentRegistry = bp.componentRegistry
   1593             if HasActivateComponent(slimItem.typeID):
   1594                 self.CreateCounterController(ActivateCounterController, componentRegistry, slimItem)
   1595             if HasReinforceComponent(slimItem.typeID):
   1596                 self.CreateCounterController(ReinforceCounterController, componentRegistry, slimItem)
   1597             if HasJumpPolarizationComponent(slimItem.typeID):
   1598                 self.CreateCounterController(JumpPolarizationCounterController, componentRegistry, slimItem)
   1599             if HasProximityUnlockComponent(slimItem.typeID):
   1600                 self.CreateCounterController(ProximityLockCounterController, componentRegistry, slimItem)
   1601             if HasLinkWithShipComponent(slimItem.typeID):
   1602                 self.CreateCounterController(LinkWithShipCounterController, componentRegistry, slimItem)
   1603             if HasHostileBaiterComponent(slimItem.typeID):
   1604                 self.CreateCounterController(HostileBaiterCounterController, componentRegistry, slimItem)
   1605 
   1606     def IsSelectedOrHilted(self):
   1607         stateSvc = sm.GetService('stateSvc')
   1608         selected = stateSvc.GetExclState(state.selected)
   1609         if selected == self.itemID:
   1610             return True
   1611         hilited = stateSvc.GetExclState(state.mouseOver)
   1612         if hilited == self.itemID:
   1613             return True
   1614         return False
   1615 
   1616     def UpdateSubLabelIfNeeded(self, text):
   1617         self.displaySubLabel = text
   1618         if self.IsSelectedOrHilted():
   1619             self.CreateSubLabelIfNeeded()
   1620             if self.SubLabelExists():
   1621                 self.subLabel.text = self.displaySubLabel
   1622 
   1623     def OnSlimItemChange(self, oldSlim, newSlim):
   1624         self.slimItem = newSlim
   1625         if self._ShouldUpdateIconColor(oldSlim, newSlim):
   1626             self.UpdateIconColor(newSlim)
   1627 
   1628     def _ShouldUpdateIconColor(self, oldSlim, newSlim):
   1629         if not hasattr(newSlim, 'hostile_response_threshold'):
   1630             return False
   1631         elif oldSlim.hostile_response_threshold != newSlim.hostile_response_threshold:
   1632             return True
   1633         elif oldSlim.friendly_response_threshold != newSlim.friendly_response_threshold:
   1634             return True
   1635         else:
   1636             return False