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

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())