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

fleetWatchList.py (28818B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\fleet\fleetWatchList.py
      2 import weakref
      3 import blue
      4 import destiny
      5 import evefleet.client
      6 import eveicon
      7 import localization
      8 import telemetry
      9 import uthread2
     10 from carbon.common.script.util.commonutils import GetAttrs
     11 from carbonui import const as uiconst
     12 from carbonui.control.animatedsprite import AnimSprite
     13 from carbonui.control.contextMenu.menuData import MenuData
     14 from carbonui.control.contextMenu.menuEntryData import MenuEntryData
     15 from carbonui.primitives.container import Container
     16 from carbonui.primitives.fill import Fill
     17 from carbonui.primitives.sprite import Sprite
     18 from carbonui.uianimations import animations
     19 from carbonui.uicore import uicore
     20 from carbonui.util.sortUtil import SortListOfTuples
     21 from clientsettings.setting import CharSettingBool
     22 from eve.client.script.parklife import states as state
     23 from eve.client.script.ui import eveColor
     24 from eve.client.script.ui.control import eveScroll, eveIcon
     25 from eve.client.script.ui.control.allUserEntries import AllUserEntries
     26 from eve.client.script.ui.control.entries.generic import Generic
     27 from eve.client.script.ui.control.entries.util import GetFromClass
     28 from eve.client.script.ui.inflight.actions import ActionPanel
     29 from eve.client.script.ui.inflight.baseTacticalEntry import BaseTacticalEntry
     30 from eve.client.script.ui.inflight.bracketsAndTargets.targetIconCont import TargetIconCont
     31 from eve.client.script.ui.shared.fleet import fleetbroadcastexports, fleetBroadcastConst
     32 from eve.client.script.ui.shared.fleet.fleetUtil import GetFleetMemberMenuOptions
     33 from eve.client.script.ui.shared.radialMenu.radialMenu import RadialMenuSpaceCharacter
     34 from eve.client.script.ui.util.linkUtil import GetCharIDFromTextLink
     35 from eve.client.script.util.bubble import SlimItemFromCharID, InBubble
     36 from eve.common.script.sys.idCheckers import IsCharacter
     37 from eveexceptions import ExceptionEater
     38 from evefleet import WATCHLIST_COL_1, WATCHLIST_COL_2
     39 from evefleet.watchListOrder import fleet_watchlist_twoColumns
     40 from eveservices.menu import GetMenuService
     41 from menu import MenuLabel
     42 from menucheckers import SessionChecker, CelestialChecker
     43 from utillib import KeyVal
     44 EDIT_MODE_CONFIG = 'fleet_watchlistcolor_editMode'
     45 WATCHLIST_COLORS_CONFIG = 'fleet_watchlistcolors'
     46 
     47 class WatchListPanel(ActionPanel):
     48     __guid__ = 'form.WatchListPanel'
     49     __notifyevents__ = ['OnFleetFavoriteAdded',
     50      'OnFleetFavoriteRemoved',
     51      'OnFleetFavoritesRemoved',
     52      'OnFleetMemberChanged_Local',
     53      'DoBallsAdded',
     54      'DoBallRemove',
     55      'OnFleetBroadcast_Local',
     56      'OnMyFleetInfoChanged',
     57      'DoBallsRemove',
     58      'OnSlimItemChange',
     59      'OnStateChange',
     60      'OnFleetWatchlistColorChanged']
     61     __dependencies__ = ['fleet']
     62     default_windowID = 'watchlistpanel'
     63     cursor = uiconst.UICURSOR_HASMENU
     64 
     65     def ApplyAttributes(self, attributes):
     66         self.sortOrder1 = []
     67         self.sortOrder2 = []
     68         super(WatchListPanel, self).ApplyAttributes(attributes)
     69         self.MakeKillable()
     70         fleet_watchlist_twoColumns.on_change.connect(self.OnNumWatchListColumnsChanged)
     71 
     72     def IsFavorite(self, charid):
     73         if sm.GetService('fleet').IsFavorite(charid):
     74             return True
     75         else:
     76             return False
     77 
     78     def AddBroadcastIcon(self, charid, icon, hint):
     79         if not self.IsFavorite(charid):
     80             return
     81         self.broadcasts[charid] = KeyVal(icon=icon, hint=hint, timestamp=blue.os.GetWallclockTime())
     82         for scroll in (self.mainScroll, self.secondaryScroll):
     83             for eachNode in scroll.GetNodes():
     84                 if eachNode.charID != charid:
     85                     continue
     86                 if eachNode.charID in self.broadcasts:
     87                     eachNode.icon = self.broadcasts[eachNode.charID].icon
     88                     eachNode.hint = localization.GetByLabel('UI/Fleet/Watchlist/WatchlistHintWithBroadcast', role=fleetbroadcastexports.GetRankName(eachNode.member), broadcast=self.broadcasts[eachNode.charID].hint, time=self.broadcasts[eachNode.charID].timestamp)
     89                 else:
     90                     eachNode.icon = None
     91                     eachNode.hint = localization.GetByLabel('UI/Fleet/Watchlist/WatchlistHint', role=fleetbroadcastexports.GetRankName(eachNode.member))
     92                 if eachNode.panel:
     93                     eachNode.panel.Load(eachNode)
     94 
     95     def OnFleetBroadcast_Local(self, broadcast):
     96         if broadcast.name not in fleetBroadcastConst.iconsByBroadcastType:
     97             icon = 'ui_38_16_70'
     98         else:
     99             icon = fleetBroadcastConst.iconsByBroadcastType[broadcast.name]
    100         self.AddBroadcastIcon(broadcast.charID, icon, broadcast.broadcastLabel)
    101 
    102     def ClearBroadcastHistory(self):
    103         self.broadcasts = {}
    104         self.UpdateAll(keepPosition=True)
    105 
    106     def ClearColors(self):
    107         settings.char.ui.Set(WATCHLIST_COLORS_CONFIG, {})
    108         self.UpdateAll()
    109 
    110     def OnMyFleetInfoChanged(self):
    111         self.UpdateAll(keepPosition=True)
    112 
    113     def PostStartup(self):
    114         self.scope = uiconst.SCOPE_INGAME
    115         self.name = 'watchlistpanel'
    116         self.broadcasts = {}
    117         self.rightCont = Container(name='rightCont', parent=self.content, align=uiconst.TORIGHT_PROP, width=0.5)
    118         self.rightCont.display = False
    119         self.secondaryScroll = eveScroll.Scroll(parent=self.rightCont, padLeft=8)
    120         self.secondaryScroll.sr.content.OnDropData = self.DropInWatchList2
    121         self.secondaryScroll.OnChar = self.OnChar
    122         self.leftCont = Container(name='leftCont', parent=self.content, align=uiconst.TOALL)
    123         self.mainScroll = eveScroll.Scroll(parent=self.leftCont)
    124         self.mainScroll.sr.content.OnDropData = self.DropInWatchList
    125         self.mainScroll.OnChar = self.OnChar
    126         self.UpdateColumnDisplay()
    127 
    128     def UpdateColumnDisplay(self):
    129         if fleet_watchlist_twoColumns.get():
    130             self.rightCont.display = True
    131             self.SetMinSize((400, 50))
    132         else:
    133             self.rightCont.display = False
    134             self.SetMinSize((256, 50))
    135 
    136     def OnChar(self, *args):
    137         return False
    138 
    139     def GetMenuMoreOptions(self):
    140         menuData = super(WatchListPanel, self).GetMenuMoreOptions()
    141         menuData += self.GetWatchListMenu()
    142         return menuData
    143 
    144     def GetWatchListMenu(self):
    145         menuData = MenuData()
    146         if IsInColorEditMode():
    147             menuData.AddEntry(localization.GetByLabel('UI/Fleet/Watchlist/ExitColorEditMode'), lambda : self.ChangeColorEditMode(False))
    148         else:
    149             menuData.AddEntry(localization.GetByLabel('UI/Fleet/Watchlist/EnterColorEditMode'), lambda : self.ChangeColorEditMode(True))
    150         if FleetSvc().IsDamageUpdates():
    151             menuData.AddEntry(localization.GetByLabel('UI/Fleet/Watchlist/TurnOffDamageUpdates'), lambda : self.SetDamageUpdates(False))
    152         else:
    153             menuData.AddEntry(localization.GetByLabel('UI/Fleet/Watchlist/TurnOnDamageUpdates'), lambda : self.SetDamageUpdates(True))
    154         menuData.AddCheckbox(localization.GetByLabel('UI/Fleet/Watchlist/Show2Columns'), fleet_watchlist_twoColumns, hint=localization.GetByLabel('UI/Fleet/Watchlist/Show2ColumnsHint'))
    155         menuData.AddSeparator()
    156         menuData.AddEntry(MenuLabel('UI/Fleet/Watchlist/ClearWatchList'), lambda : sm.GetService('fleet').RemoveAllFavorites())
    157         menuData.AddEntry(MenuLabel('UI/Fleet/Watchlist/ClearBroadcastIcons'), lambda : self.ClearBroadcastHistory())
    158         menuData.AddEntry(MenuLabel('UI/Fleet/Watchlist/ClearAllColors'), lambda : self.ClearColors())
    159         return menuData
    160 
    161     def OnNumWatchListColumnsChanged(self, value):
    162         FleetSvc().favoriteOrder.UpdateNumColumns()
    163         self.UpdateColumnDisplay()
    164         self.UpdateAll(keepPosition=True)
    165 
    166     def SetDamageUpdates(self, isit):
    167         FleetSvc().SetDamageUpdates(isit)
    168         self.UpdateColumnDisplay()
    169         self.UpdateAll()
    170 
    171     def ChangeColorEditMode(self, on):
    172         settings.char.ui.Set(EDIT_MODE_CONFIG, bool(on))
    173         self.UpdateAll()
    174 
    175     def UpdateAll(self, keepPosition = False):
    176         scrollToMain = self.mainScroll.GetScrollProportion() if keepPosition else 0.0
    177         scrollToSecondary = self.secondaryScroll.GetScrollProportion() if keepPosition else 0.0
    178         self.mainScroll.Clear()
    179         self.secondaryScroll.Clear()
    180         fleetSvc = FleetSvc()
    181         favorites = fleetSvc.GetFavorites()
    182         mainEntriesToSort = []
    183         secondaryEntriesToSort = []
    184         noSortOrder = []
    185         favoriteOrder = fleetSvc.favoriteOrder
    186         for charID in favorites:
    187             data = self.GetEntryData(charID)
    188             if data is not None:
    189                 entry = GetFromClass(WatchListEntry, data)
    190                 sortKey = favoriteOrder.GetSortKey(charID, WATCHLIST_COL_1)
    191                 if sortKey is not None:
    192                     entry.watchlistColumnID = WATCHLIST_COL_1
    193                     mainEntriesToSort.append((sortKey, entry))
    194                 else:
    195                     sortKey = favoriteOrder.GetSortKey(charID, WATCHLIST_COL_2)
    196                     if sortKey is not None:
    197                         entry.watchlistColumnID = WATCHLIST_COL_2
    198                         secondaryEntriesToSort.append((sortKey, entry))
    199                     else:
    200                         entry.watchlistColumnID = WATCHLIST_COL_1
    201                         noSortOrder.append(entry)
    202 
    203         sortedCol1Entries = SortListOfTuples(mainEntriesToSort) + noSortOrder
    204         noContentHint = self._GetNoContentHint(favorites)
    205         self.mainScroll.Load(contentList=sortedCol1Entries, noContentHint=noContentHint)
    206         self.secondaryScroll.Load(contentList=SortListOfTuples(secondaryEntriesToSort), noContentHint=noContentHint)
    207         if scrollToMain:
    208             self.mainScroll.ScrollToProportion(scrollToMain, threaded=False)
    209         if scrollToSecondary:
    210             self.secondaryScroll.ScrollToProportion(scrollToSecondary, threaded=False)
    211         if self.panelname:
    212             self.SetCaption('%s [%s]' % (self.panelname, len(favorites)))
    213         self.UpdateHintAndStates()
    214 
    215     def _GetNoContentHint(self, favorites):
    216         if favorites:
    217             return localization.GetByLabel('UI/Fleet/Watchlist/DropFleetOrWatchListMembers')
    218         else:
    219             return localization.GetByLabel('UI/Fleet/Watchlist/DropFleetMembers')
    220 
    221     def UpdateHintAndStates(self, favorites = None):
    222         if favorites is None:
    223             favorites = sm.GetService('fleet').GetFavorites()
    224         noContentHint = self._GetNoContentHint(favorites)
    225         favoriteOrder = FleetSvc().favoriteOrder
    226         if not len(favoriteOrder.GetColumn1Order()):
    227             self.mainScroll.ShowHint(noContentHint)
    228         if not len(favoriteOrder.GetColumn2Order()):
    229             self.secondaryScroll.ShowHint(noContentHint)
    230 
    231     def UpdateSlimItem(self, charID):
    232         if not sm.GetService('fleet').GetMemberInfo(charID):
    233             return
    234         for scroll in (self.mainScroll, self.secondaryScroll):
    235             for node in scroll.GetNodes():
    236                 if node.charID == charID:
    237                     slimItem = SlimItemFromCharID(charID)
    238                     node.slimItem = weakref.ref(slimItem) if slimItem else None
    239                     node.slimItemID = None
    240                     if node.panel:
    241                         node.panel.Load(node)
    242                     return
    243 
    244     def BlinkAffected(self, affectedIDs):
    245         for scroll in (self.mainScroll, self.secondaryScroll):
    246             for node in scroll.GetNodes():
    247                 if node.charID in affectedIDs and node.panel:
    248                     node.panel.BlinkEntry()
    249 
    250     def RemoveCharacterFromScroll(self, charID):
    251         for scroll in (self.mainScroll, self.secondaryScroll):
    252             for node in scroll.GetNodes():
    253                 if node.charID == charID:
    254                     scroll.RemoveNodes([node])
    255                     if self.panelname:
    256                         numFavorites = len(FleetSvc().GetFavorites())
    257                         self.SetCaption('%s [%s]' % (self.panelname, numFavorites))
    258                     self.UpdateHintAndStates()
    259                     return
    260 
    261     def OnFleetFavoriteAdded(self):
    262         self.UpdateAll(keepPosition=True)
    263 
    264     def OnFleetFavoriteRemoved(self, charID):
    265         if self.destroyed:
    266             return
    267         self.RemoveCharacterFromScroll(charID)
    268 
    269     def OnFleetFavoritesRemoved(self):
    270         if self.destroyed:
    271             return
    272         self.UpdateAll()
    273 
    274     def OnFleetWatchlistColorChanged(self):
    275         self.UpdateAll()
    276 
    277     def OnFleetMemberChanged_Local(self, charID, *args):
    278         if sm.GetService('fleet').IsFavorite(charID):
    279             self.UpdateAll(keepPosition=True)
    280 
    281     def DoBallsAdded(self, lst):
    282         for ball, slimItem in lst:
    283             if ball.id < destiny.DSTLOCALBALLS:
    284                 return
    285             if sm.GetService('fleet').GetFavorite(slimItem.charID):
    286                 self.UpdateSlimItem(slimItem.charID)
    287 
    288     @telemetry.ZONE_METHOD
    289     def DoBallsRemove(self, pythonBalls, isRelease):
    290         for ball, slimItem, terminal in pythonBalls:
    291             self.DoBallRemove(ball, slimItem, terminal)
    292 
    293     def DoBallRemove(self, ball, slimItem, terminal):
    294         if slimItem is None:
    295             return
    296         if getattr(slimItem, 'charID', None):
    297             if sm.GetService('fleet').IsFavorite(slimItem.charID):
    298                 self.UpdateSlimItem(slimItem.charID)
    299 
    300     def GetEntryData(self, charID):
    301         slimItem = SlimItemFromCharID(charID)
    302         data = KeyVal()
    303         member = sm.GetService('fleet').GetMemberInfo(charID)
    304         if not member:
    305             return
    306         data.charRec = cfg.eveowners.Get(charID)
    307         data.itemID = data.id = data.charID = charID
    308         data.typeID = data.charRec.typeID
    309         data.squadID = member.squadID
    310         data.wingID = member.wingID
    311         data.displayName = member.charName
    312         data.roleString = member.roleName
    313         data.label = localization.GetByLabel('UI/Common/CharacterNameLabel', charID=charID)
    314         data.member = member
    315         data.slimItem = None
    316         if charID in self.broadcasts:
    317             data.icon = self.broadcasts[charID].icon
    318             data.hint = localization.GetByLabel('UI/Fleet/Watchlist/WatchlistHintWithBroadcast', role=fleetbroadcastexports.GetRankName(member), broadcast=self.broadcasts[charID].hint, time=self.broadcasts[charID].timestamp)
    319         else:
    320             data.icon = None
    321             data.hint = localization.GetByLabel('UI/Fleet/Watchlist/WatchlistHint', role=fleetbroadcastexports.GetRankName(member))
    322         data.colorcoded = GetColorForCharID(charID)
    323         data.inColorSettingMode = IsInColorEditMode()
    324         if slimItem:
    325             data.slimItem = weakref.ref(slimItem)
    326         return data
    327 
    328     def DropInWatchList(self, dragObj, nodes, idx = None, *args):
    329         return self._DropInWatchList(WATCHLIST_COL_1, dragObj, nodes, idx)
    330 
    331     def DropInWatchList2(self, dragObj, nodes, idx = None, *args):
    332         return self._DropInWatchList(WATCHLIST_COL_2, dragObj, nodes, idx)
    333 
    334     def _DropInWatchList(self, scrollColumnID, dragObj, nodes, idx = None):
    335         fleetSvc = FleetSvc()
    336         charIDsToAdd = []
    337         allAffectedIDs = []
    338         for eachNode in nodes:
    339             itemID = GetCharIDFromNode(dragObj, eachNode)
    340             if fleetSvc.IsFavorite(itemID):
    341                 allAffectedIDs.append(itemID)
    342             elif itemID and fleetSvc.IsMember(itemID) and itemID != session.charid:
    343                 charIDsToAdd.append(itemID)
    344                 allAffectedIDs.append(itemID)
    345 
    346         if not allAffectedIDs:
    347             return
    348         if charIDsToAdd:
    349             fleetSvc.AddFavorite(charIDsToAdd, updateOrder=False, updateWnd=False)
    350         if dragObj.__guid__ == 'listentry.WatchListEntry' or len(allAffectedIDs) < 2:
    351             allowMove = True
    352         else:
    353             allowMove = False
    354         fleetSvc.UpdateWatchlistMemberOrder(allAffectedIDs, scrollColumnID, idx, allowMove)
    355         self.UpdateAll(keepPosition=True)
    356         uthread2.StartTasklet(self.BlinkAffected, allAffectedIDs)
    357 
    358     def OnSlimItemChange(self, oldSlim, newSlim):
    359         newSlimCharID = newSlim.charID
    360         for scroll in (self.mainScroll, self.secondaryScroll):
    361             for node in scroll.GetNodes():
    362                 if node.charID == newSlimCharID:
    363                     node.slimItem = weakref.ref(newSlim)
    364                     node.slimItemID = None
    365                     if node.panel:
    366                         node.panel.UpdateShipIcon()
    367 
    368     def OnStateChange(self, itemID, flag, newState, *args):
    369         if flag not in (state.targeting, state.targeted):
    370             return
    371         for scroll in (self.mainScroll, self.secondaryScroll):
    372             for node in scroll.GetNodes():
    373                 if node.slimItemID == itemID and node.panel is not None:
    374                     node.panel.OnChangingState(itemID, flag, newState)
    375                     return
    376 
    377     def Close(self, setClosed = False, *args, **kwds):
    378         with ExceptionEater('Failed to close watch list window'):
    379             fleet_watchlist_twoColumns.on_change.disconnect(self.OnNumWatchListColumnsChanged)
    380         super(WatchListPanel, self).Close(setClosed, *args, **kwds)
    381 
    382 
    383 class WatchListEntry(BaseTacticalEntry):
    384     __guid__ = 'listentry.WatchListEntry'
    385     __notifyevents__ = []
    386     isDragObject = True
    387 
    388     def Startup(self, *args, **kw):
    389         BaseTacticalEntry.Startup(self, *args, **kw)
    390         self.blinkFill = Fill(bgParent=self, opacity=0.0)
    391         self.colorcodedFill = Fill(bgParent=self, color=(0, 0, 0, 0))
    392         self.colorPickerParent = Container(name='colorPickerParent', parent=self, align=uiconst.TORIGHT, width=27)
    393         self.colorPicker = evefleet.client.FleetColorPickerCont(parent=self.colorPickerParent, align=uiconst.CENTERLEFT, callback=self.SetColorForEntry, idx=0)
    394         self.targetIconCont = TargetIconCont(parent=self, align=uiconst.CENTERLEFT, pos=(-1, 0, 18, 18))
    395         self.stateItemID = None
    396         self.leftPar = Container(name='leftPar', parent=self, align=uiconst.TOLEFT_NOPUSH, width=16)
    397         self.shipIcon = Sprite(parent=self.leftPar, align=uiconst.CENTERLEFT, pos=(0, 0, 16, 16))
    398         self.sr.posIndicatorCont = Container(name='posIndicator', parent=self, align=uiconst.TOTOP_NOPUSH, state=uiconst.UI_DISABLED, height=2)
    399         self.sr.posIndicator = Fill(parent=self.sr.posIndicatorCont, state=uiconst.UI_HIDDEN, color=(1.0, 1.0, 1.0, 0.5))
    400         self.sr.gaugesContainer = Container(name='gaugesContainer', parent=self, align=uiconst.TORIGHT, width=78)
    401         labelContainer = Container(name='labelContainer', parent=self, align=uiconst.TOALL, clipChildren=True)
    402         self.sr.label.SetParent(labelContainer)
    403         self.broadcastIconContainer = Container(name='broadcastIconContainer', parent=self, align=uiconst.TORIGHT, width=20, idx=labelContainer.GetOrder())
    404         self.sr.icon = eveIcon.Icon(parent=self.broadcastIconContainer, align=uiconst.CENTER, state=uiconst.UI_DISABLED, pos=(0, 0, 16, 16))
    405         self.sr.progress = AnimSprite(parent=self.leftPar, align=uiconst.TOPLEFT, state=uiconst.UI_HIDDEN, pos=(0, 0, 16, 16), icons=[ 'ui_38_16_%s' % (210 + i) for i in xrange(8) ])
    406 
    407     def Load(self, node):
    408         Generic.Load(self, node)
    409         data = node
    410         self.sr.label.left = 20
    411         self.UpdateDamage()
    412         selected, = sm.GetService('stateSvc').GetStates(data.itemID, [state.selected])
    413         if selected:
    414             self.Select()
    415         if node.icon is None:
    416             self.sr.icon.display = False
    417         else:
    418             self.sr.icon.LoadIcon(node.icon)
    419             self.sr.icon.display = True
    420         self.sr.label.Update()
    421         targeting, targeted = sm.GetService('stateSvc').GetStates(self.GetShipID(), [state.targeting, state.targeted])
    422         if targeting:
    423             self.targetIconCont.StartTargeting()
    424         elif targeted:
    425             self.targetIconCont.SetTargetedIcon()
    426         if node.colorcoded:
    427             fillColor = node.colorcoded + (0.25,)
    428             self.colorcodedFill.SetRGBA(*fillColor)
    429         self.UpdateShipIcon()
    430         if node.inColorSettingMode:
    431             self.colorPickerParent.display = True
    432             self.colorPicker.SetCurrentFill(self.sr.node.colorcoded)
    433         else:
    434             self.colorPickerParent.display = False
    435 
    436     def UpdateShipIcon(self):
    437         node = self.sr.node
    438         slimItem = node.slimItem
    439         if slimItem:
    440             if slimItem():
    441                 typeID = slimItem().typeID
    442                 texturePath = sm.GetService('bracket').GetBracketIcon(typeID)
    443             else:
    444                 texturePath = None
    445             self.shipIcon.SetTexturePath(texturePath)
    446         self.SetShipIconDisplay()
    447 
    448     def SetShipIconDisplay(self):
    449         if InBubble(self.GetShipID()):
    450             self.shipIcon.display = True
    451         else:
    452             self.shipIcon.display = False
    453 
    454     def UpdateDamage(self):
    455         if not sm.GetService('fleet').IsDamageUpdates():
    456             self.HideDamageDisplay()
    457             return False
    458         self.SetShipIconDisplay()
    459         if BaseTacticalEntry.UpdateDamage(self):
    460             animations.SpColorMorphTo(self.sr.label, startColor=self.sr.label.rgb, endColor=eveColor.CHERRY_RED[:3], duration=0.5, curveType=uiconst.ANIM_WAVE, loops=5)
    461 
    462     def GetShipID(self):
    463         if not self.sr.node:
    464             return
    465         else:
    466             known = self.sr.node.Get('slimItemID', None)
    467             self.stateItemID = known
    468             if known:
    469                 return known
    470             item = SlimItemFromCharID(self.sr.node.charID)
    471             if item is None:
    472                 return
    473             self.sr.node.slimItemID = item.itemID
    474             self.stateItemID = item.itemID
    475             return item.itemID
    476 
    477     def GetHeight(_self, *args):
    478         return 24
    479 
    480     def BlinkEntry(self):
    481         animations.BlinkIn(self.blinkFill, endVal=0.1, duration=0.6, loops=1, curveType=uiconst.ANIM_BOUNCE)
    482 
    483     def OnClick(self, *args):
    484         item = SlimItemFromCharID(self.sr.node.charID)
    485         if item:
    486             loadedCombatCmd = uicore.cmd.GetCombatCmdLoadedName()
    487             itemID = item.itemID
    488             if loadedCombatCmd and loadedCombatCmd.name == 'CmdLockTargetItem':
    489                 if sm.GetService('target').IsTarget(itemID):
    490                     sm.GetService('stateSvc').SetState(itemID, state.activeTarget, 1)
    491                     return
    492             uicore.cmd.ExecuteCombatCommand(itemID, uiconst.UI_CLICK)
    493         shift = uicore.uilib.Key(uiconst.VK_SHIFT)
    494         if shift:
    495             self.sr.node.scroll.SelectNode(self.sr.node)
    496         elif self.sr.node.scroll.GetSelected():
    497             self.sr.node.scroll.ClearSelection()
    498 
    499     def OnDblClick(self, *args):
    500         if self.sr.node:
    501             self.sr.node.scroll.SelectNode(self.sr.node)
    502 
    503     def OnMouseDown(self, *args):
    504         GetMenuService().TryExpandActionMenu(itemID=self.sr.node.charID, clickedObject=self, radialMenuClass=RadialMenuSpaceCharacter)
    505 
    506     def GetMenu(self):
    507         selectedNodes = self.sr.node.scroll.GetSelected()
    508         isCurrentNodeSelected = self.sr.node in selectedNodes
    509         if isCurrentNodeSelected and len(selectedNodes) > 1:
    510             menuData = MenuData()
    511             menuData.AddEntry(localization.GetByLabel('UI/Fleet/Watchlist/SortByName'), lambda : self.SortAlphabetically())
    512             return menuData
    513         else:
    514             self.sr.node.scroll.DeselectAll()
    515             m = []
    516             shipItem = SlimItemFromCharID(self.sr.node.charID)
    517             if shipItem:
    518                 sessionChecker = SessionChecker(session, sm)
    519                 celestial = CelestialChecker(shipItem, cfg, sessionChecker)
    520                 if celestial.OfferBroadcastHealTarget():
    521                     m += [MenuEntryData(MenuLabel('UI/Fleet/FleetBroadcast/Commands/BroadcastHealTarget'), lambda : sm.GetService('fleet').SendBroadcast_Heal_Target(shipItem.itemID), texturePath=eveicon.heal_first_aid)]
    522             m += GetFleetMemberMenuOptions(self.sr.node.charID)
    523             return m
    524 
    525     def SortAlphabetically(self):
    526         selectedNodes = self.sr.node.scroll.GetSelectedNodes(self.sr.node)
    527         firstNode = selectedNodes[0]
    528         watchlistColumnID = firstNode.watchlistColumnID
    529         idx = firstNode.idx
    530         charIDsToSort = []
    531         for node in selectedNodes:
    532             charIDsToSort.append((cfg.eveowners.Get(node.charID).name.lower(), node.charID))
    533 
    534         sortedCharIDs = SortListOfTuples(charIDsToSort)
    535         FleetSvc().UpdateWatchlistMemberOrder(sortedCharIDs, watchlistColumnID, idx, True)
    536         sm.ScatterEvent('OnFleetFavoriteAdded')
    537 
    538     def SetColorForEntry(self, color, *args):
    539         allColors = settings.char.ui.Get(WATCHLIST_COLORS_CONFIG, {})
    540         allColors[self.sr.node.charID] = color
    541         self.sr.node.colorcoded = color
    542         settings.char.ui.Set(WATCHLIST_COLORS_CONFIG, allColors)
    543         sm.ScatterEvent('OnFleetWatchlistColorChanged')
    544 
    545     def InitGauges(self):
    546         parent = self.sr.gaugesContainer
    547         if getattr(self, 'gaugesInited', False):
    548             self.sr.gaugeParent.state = uiconst.UI_DISABLED
    549             return
    550         barw, barh = (22, 8)
    551         borderw = 2
    552         barsw = (barw + borderw) * 3 + borderw
    553         par = Container(name='gauges', parent=parent, align=uiconst.TORIGHT, width=barsw + 2, height=0, left=0, top=0, idx=0)
    554         self.sr.gauges = []
    555         l = 2
    556         for each in ('STRUCT', 'ARMOR', 'SHIELD'):
    557             g = Container(name=each, align=uiconst.CENTERLEFT, width=barw, height=barh, left=l)
    558             g.name = 'gauge_%s' % each.lower()
    559             g.sr.bar = Fill(parent=g, align=uiconst.TOLEFT, color=eveColor.SILVER_GREY)
    560             Fill(parent=g, color=eveColor.CHERRY_RED[:3])
    561             par.children.append(g)
    562             self.sr.gauges.append(g)
    563             setattr(self.sr, 'gauge_%s' % each.lower(), g)
    564             l += barw + borderw
    565 
    566         self.sr.gaugeParent = par
    567         self.gaugesInited = True
    568 
    569     def GetDragData(self, *args):
    570         selectedNodes = self.sr.node.scroll.GetSelectedNodes(self.sr.node)
    571         for node in selectedNodes:
    572             info = cfg.eveowners.Get(node.itemID)
    573             node.info = info
    574 
    575         return selectedNodes
    576 
    577     def OnDropData(self, dragObj, nodes, *args):
    578         if GetAttrs(self, 'parent', 'OnDropData'):
    579             self.parent.OnDropData(dragObj, nodes, idx=self.sr.node.idx)
    580 
    581     def OnDragEnter(self, dragObj, nodes, *args):
    582         charIDs = filter(None, [ getattr(node, 'charID', None) or GetCharIDFromNode(dragObj, node) for node in nodes ])
    583         if not charIDs:
    584             return
    585         if len(charIDs) == 1 and self.sr.node.charID == charIDs[0]:
    586             return
    587         if any((getattr(node, '__guid__', None) == 'listentry.WatchListEntry' for node in nodes)):
    588             self.sr.posIndicator.state = uiconst.UI_DISABLED
    589         else:
    590             for charID in charIDs:
    591                 if sm.GetService('fleet').CheckCanAddFavorite(charID):
    592                     self.sr.posIndicator.state = uiconst.UI_DISABLED
    593                     break
    594                 elif sm.GetService('fleet').CheckCanMoveFavorite(charID):
    595                     self.sr.posIndicator.state = uiconst.UI_DISABLED
    596                     break
    597 
    598     def OnDragExit(self, *args):
    599         self.sr.posIndicator.state = uiconst.UI_HIDDEN
    600 
    601     def OnChangingState(self, itemID, flag, newState):
    602         if flag == state.targeting:
    603             self.targetIconCont.HandleTargetingChanges(newState)
    604         elif flag == state.targeted:
    605             self.targetIconCont.HandleTargetedChanges(newState)
    606 
    607     def GetIdForItem(self):
    608         return self.GetShipID()
    609 
    610 
    611 def IsInColorEditMode():
    612     return bool(settings.char.ui.Get(EDIT_MODE_CONFIG, True))
    613 
    614 
    615 def GetColorForCharID(charID):
    616     allColors = settings.char.ui.Get(WATCHLIST_COLORS_CONFIG, {})
    617     return allColors.get(charID)
    618 
    619 
    620 def GetCharIDFromNode(dragObj, eachNode):
    621     textlinkCharID = GetCharIDFromTextLink(eachNode)
    622     if textlinkCharID:
    623         return textlinkCharID
    624     nodeGuid = getattr(eachNode, '__guid__', None)
    625     if not nodeGuid:
    626         return
    627     if nodeGuid == 'uicontrols.Label':
    628         itemID = GetLabelCharID(dragObj, eachNode)
    629     elif nodeGuid == 'listentry.FleetCompositionEntry':
    630         itemID = eachNode.charID
    631     elif nodeGuid in AllUserEntries():
    632         itemID = eachNode.itemID
    633     else:
    634         itemID = None
    635     return itemID
    636 
    637 
    638 def GetLabelCharID(dragObj, entry):
    639     if dragObj.__guid__ == 'uicontrols.Label':
    640         labelInfo = entry.url.split('//')
    641         try:
    642             charID = int(labelInfo[1])
    643         except:
    644             return None
    645 
    646         isCharacter = IsCharacter(charID)
    647         if isCharacter:
    648             return charID
    649         else:
    650             return None
    651 
    652 
    653 def FleetSvc():
    654     return sm.GetService('fleet')