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

squadronsUI.py (22265B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\inflight\squadrons\squadronsUI.py
      2 from collections import namedtuple
      3 from carbon.common.lib.const import SEC
      4 from carbonui.primitives.container import Container
      5 from carbonui.primitives.containerAutoSize import ContainerAutoSize
      6 from eve.client.script.parklife import states
      7 from carbonui.control.buttonIcon import ButtonIcon
      8 from eve.client.script.ui.inflight.shipHud.leftSideButton import LeftSideButton
      9 from eve.client.script.ui.inflight.squadrons.effectsCont import EffectsCont
     10 from eve.client.script.ui.inflight.squadrons.abilitiesCont import AbilitiesCont
     11 from eve.client.script.ui.inflight.squadrons.shipFighterState import GetShipFighterState
     12 from eve.client.script.ui.inflight.squadrons.squadronCont import SquadronCont, SquadronContEmpty
     13 from eve.client.script.ui.inflight.squadrons.squadronController import SquadronController
     14 import carbonui.const as uiconst
     15 from eve.client.script.ui.inflight.squadrons.squadronManagementController import SquadronMgmtController
     16 from eve.client.script.ui.inflight.squadrons.squadronMenu import GetSquadronMenu
     17 from eve.client.script.ui.services.menuSvcExtras import movementFunctions
     18 from eve.client.script.ui.shared.inventory.invWindow import Inventory
     19 from eve.common.script.mgt.fighterConst import TUBE_STATE_EMPTY, TUBE_STATE_UNLOADING
     20 from eve.common.script.sys.eveCfg import GetActiveShip
     21 from fighters import TARGET_MODE_POINTTARGETED, TARGET_MODE_UNTARGETED, TARGET_MODE_ITEMTARGETED
     22 from fighters.client import GetFighterTubesForShip
     23 import gametime
     24 from localization import GetByLabel
     25 from utillib import KeyVal
     26 from carbonui.uicore import uicore
     27 import eve.client.script.ui.shared.pointerTool.pointerToolConst as pConst
     28 SelectedFighterTuple = namedtuple('SelectedFighterTuple', ['fighterItemID', 'tubeFlagID', 'squadron'])
     29 SQUADRON_WIDTH = 80
     30 BUTTONCONT_WIDTH = 36
     31 HUDBUTTON_HEIGHT = 32
     32 
     33 class SquadronsUI(ContainerAutoSize):
     34     default_width = SQUADRON_WIDTH
     35     default_height = 266
     36 
     37     def ApplyAttributes(self, attributes):
     38         self.shipHudSlotOffset = 0
     39         ContainerAutoSize.ApplyAttributes(self, attributes)
     40         self.shipFighterState = GetShipFighterState()
     41         self.parentFunc = attributes.parentFunc
     42         self.squadrons = []
     43         self.lastSelected = None
     44         left = BUTTONCONT_WIDTH + 4
     45         numOfTubes = GetFighterTubesForShip()
     46         self.DrawControlButtons()
     47         for i, tubeFlagID in enumerate(const.fighterTubeFlags):
     48             if i < numOfTubes:
     49                 squadron = SquadronUI(parent=self, align=uiconst.BOTTOMLEFT, tubeFlagID=tubeFlagID, left=left)
     50                 left = squadron.left + squadron.width + 6
     51                 self.squadrons.append(squadron)
     52                 self.width += SQUADRON_WIDTH
     53 
     54     def DrawControlButtons(self):
     55         buttonCont = Container(parent=self, align=uiconst.BOTTOMLEFT, width=BUTTONCONT_WIDTH, height=120)
     56         self.fighterToggleBtn = FighterDragButton(name='fighterToggleBtn', parent=buttonCont, align=uiconst.BOTTOMLEFT, top=0, left=2, iconSize=24, texturePath='res:/UI/Texture/classes/ShipUI/Fighters/positionFighters_Up.png', func=self.OnToggleFightersDetached, uniqueUiName=pConst.UNIQUE_NAME_FIGHTERS_DETACH)
     57         self.recallAll = FightersButtonRecallAll(parent=buttonCont, align=uiconst.BOTTOMLEFT, top=25)
     58         self.openFighterBay = self.GetFighterBayBtn(buttonCont)
     59         self.launchAll = FightersButtonLaunchAll(parent=buttonCont, align=uiconst.BOTTOMLEFT, top=25 + HUDBUTTON_HEIGHT * 2)
     60 
     61     def SetToggleBtnTexture(self, isDetached):
     62         self.fighterToggleBtn.SetToggleBtnTexture(isDetached)
     63 
     64     def GetFighterBayBtn(self, buttonCont):
     65         if session.structureid:
     66             return FightersButtonOpenStructureBay(parent=buttonCont, align=uiconst.BOTTOMLEFT, top=25 + HUDBUTTON_HEIGHT)
     67         else:
     68             return FightersButtonOpenBay(parent=buttonCont, align=uiconst.BOTTOMLEFT, top=25 + HUDBUTTON_HEIGHT)
     69 
     70     def OnToggleFightersDetached(self, *args):
     71         self.parentFunc(args)
     72         self.KeepSelection()
     73 
     74     def KeepSelection(self):
     75         selectedFighters = movementFunctions.GetFightersSelectedForNavigation()
     76         for fighterID in selectedFighters:
     77             movementFunctions.SelectForNavigation(fighterID)
     78 
     79     def SelectAll(self):
     80         for squadron in self.squadrons:
     81             squadron.SelectSquadron()
     82 
     83     def ClearSelection(self):
     84         for squadron in self.squadrons:
     85             squadron.DeselectSquadron()
     86 
     87     def GetSelectedSquadrons(self):
     88         selectedSquadrons = []
     89         for squadron in self.squadrons:
     90             if squadron.IsSelected():
     91                 selectedSquadrons.append(SelectedFighterTuple(fighterItemID=squadron.GetFighterItemID(), tubeFlagID=squadron.tubeFlagID, squadron=squadron))
     92 
     93         return selectedSquadrons
     94 
     95     def OnF(self, abilitySlotID):
     96         untargetedAbilityFighters = []
     97         itemTargetedAbilityFighters = []
     98         pointTargetedAbilityFighters = []
     99         isAllAbilitiesActive = self.shipFighterState.IsAllAbilitiesInSlotActiveOrInCooldown(abilitySlotID)
    100         for squadron in self.GetSelectedSquadrons():
    101             try:
    102                 ability = squadron.squadron.modulesCont.abilityIcons[abilitySlotID]
    103             except KeyError:
    104                 continue
    105 
    106             abilityActivationStatus = self.shipFighterState.GetAbilityActivationStatus(squadron.fighterItemID, abilitySlotID)
    107             if isAllAbilitiesActive:
    108                 if abilityActivationStatus:
    109                     if abilityActivationStatus.isPending:
    110                         continue
    111                     if abilityActivationStatus.isDeactivating:
    112                         continue
    113             else:
    114                 if abilityActivationStatus:
    115                     continue
    116                 if self.shipFighterState.GetAbilityCooldown(squadron.fighterItemID, abilitySlotID):
    117                     continue
    118             if ability.targetMode == TARGET_MODE_UNTARGETED:
    119                 untargetedAbilityFighters.append(squadron.fighterItemID)
    120             elif ability.targetMode == TARGET_MODE_ITEMTARGETED:
    121                 itemTargetedAbilityFighters.append(squadron.fighterItemID)
    122             elif ability.targetMode == TARGET_MODE_POINTTARGETED:
    123                 pointTargetedAbilityFighters.append(squadron.fighterItemID)
    124 
    125         fightersSvc = sm.GetService('fighters')
    126         if isAllAbilitiesActive:
    127             fighterIDs = untargetedAbilityFighters + itemTargetedAbilityFighters + pointTargetedAbilityFighters
    128             fightersSvc.DeactivateAbilitySlots(fighterIDs, abilitySlotID)
    129         else:
    130             if untargetedAbilityFighters:
    131                 fightersSvc.ActivateAbilitySlotsOnSelf(untargetedAbilityFighters, abilitySlotID)
    132             if itemTargetedAbilityFighters:
    133                 targetID = sm.GetService('target').GetActiveTargetID()
    134                 fightersSvc.ActivateAbilitySlotsOnTarget(itemTargetedAbilityFighters, abilitySlotID, targetID)
    135             if pointTargetedAbilityFighters:
    136                 eveCommands = sm.GetService('cmd')
    137                 eveCommands.CmdAimMultiSquadronFighterAbilities(pointTargetedAbilityFighters, abilitySlotID)
    138 
    139     def SetLastSelectedTube(self, tubeFlagID):
    140         self.lastSelected = tubeFlagID
    141 
    142     def GetLastSelectedTube(self):
    143         return self.lastSelected
    144 
    145     def MultiSelectSquadrons(self, selectedSquadron):
    146         if selectedSquadron <= self.lastSelected:
    147             minSelected = selectedSquadron
    148             maxSelected = self.lastSelected
    149         else:
    150             minSelected = self.lastSelected
    151             maxSelected = selectedSquadron
    152         for squadron in self.squadrons:
    153             if squadron.tubeFlagID >= minSelected and squadron.tubeFlagID <= maxSelected:
    154                 squadron.SelectSquadron()
    155 
    156 
    157 class SquadronUI(Container):
    158     __notifyevents__ = ['OnStateChange']
    159     default_width = SQUADRON_WIDTH
    160     default_height = 266
    161     default_name = 'squadronCont'
    162 
    163     def ApplyAttributes(self, attributes):
    164         Container.ApplyAttributes(self, attributes)
    165         sm.RegisterNotify(self)
    166         self.squadronMgmtController = SquadronMgmtController()
    167         self.inSpace = False
    168         self.shipFighterState = GetShipFighterState()
    169         self.tubeFlagID = attributes.tubeFlagID
    170         fighters = self.GetFightersState()
    171         if fighters:
    172             fighterID = fighters.itemID
    173             fighterTypeID = fighters.typeID
    174             squadronSize = fighters.squadronSize
    175         else:
    176             fighterID = None
    177             fighterTypeID = None
    178             squadronSize = None
    179         self.fighterID = fighterID
    180         self.fighterTypeID = fighterTypeID
    181         self.controller = SquadronController()
    182         self.squadronCont = SquadronCont(parent=self, controller=self.controller, align=uiconst.BOTTOMLEFT, tubeFlagID=self.tubeFlagID, state=uiconst.UI_NORMAL)
    183         self.squadronCont.OnClick = self.OnSquadronClick
    184         self.squadronCont.GetMenu = self.GetSqMenu
    185         self.squadronCont.SetNewSquadron(fighterID, fighterTypeID, squadronSize)
    186         self.squadronContEmpty = SquadronContEmpty(parent=self, controller=self.controller, fighterID=fighterID, fighterTypeID=fighterTypeID, align=uiconst.BOTTOMLEFT, tubeFlagID=self.tubeFlagID)
    187         self.squadronContEmpty.fighterCont.GetMenu = self.GetSqMenu
    188         if not fighterID and not fighterTypeID:
    189             self.ShowEmpty()
    190         else:
    191             self.HideEmpty()
    192         self.effectsCont = EffectsCont(parent=self, controller=self.controller, fighterID=fighterID, fighterTypeID=fighterTypeID, tubeFlagID=self.tubeFlagID, top=self.squadronCont.height, align=uiconst.BOTTOMLEFT)
    193         self.modulesCont = AbilitiesCont(parent=self, left=20, top=self.squadronCont.height, align=uiconst.BOTTOMLEFT)
    194         self.modulesCont.SetNewSquadron(fighterID, fighterTypeID)
    195         self.SetupFighters()
    196         self.shipFighterState.signalOnFighterTubeStateUpdate.connect(self.OnFighterTubeStateUpdate)
    197         self.shipFighterState.signalOnFighterTubeContentUpdate.connect(self.OnFighterTubeContentUpdate)
    198         self.shipFighterState.signalOnFighterInSpaceUpdate.connect(self.OnFighterInSpaceUpdate)
    199         self.shipFighterState.signalOnIncomingEwarStarted.connect(self.OnEwarUpdated)
    200         self.shipFighterState.signalOnIncomingEwarEnded.connect(self.OnEwarUpdated)
    201 
    202     def SetupFighters(self):
    203         if self.inSpace:
    204             self.ShowInSpaceUI()
    205         else:
    206             self.HideInSpaceUI()
    207 
    208     def ShowInSpaceUI(self):
    209         self.modulesCont.ShowModules()
    210         self.effectsCont.ShowEffects()
    211 
    212     def HideInSpaceUI(self):
    213         self.modulesCont.HideModules()
    214         self.effectsCont.HideEffects()
    215 
    216     def ShowEmpty(self):
    217         self.squadronContEmpty.display = True
    218         self.squadronCont.display = False
    219 
    220     def HideEmpty(self):
    221         self.squadronContEmpty.display = False
    222         self.squadronCont.display = True
    223 
    224     def GetFightersInSpaceState(self):
    225         fighterInSpace = self.shipFighterState.GetFightersInSpace(self.tubeFlagID)
    226         if fighterInSpace is not None:
    227             self.inSpace = True
    228             return fighterInSpace
    229 
    230     def GetFightersInTubeState(self):
    231         fighterInTube = self.shipFighterState.GetFightersInTube(self.tubeFlagID)
    232         if fighterInTube is not None:
    233             self.inSpace = False
    234             return fighterInTube
    235 
    236     def GetFightersState(self):
    237         fightersInTube = self.GetFightersInTubeState()
    238         if fightersInTube:
    239             return fightersInTube
    240         fightersInSpace = self.GetFightersInSpaceState()
    241         if fightersInSpace:
    242             return fightersInSpace
    243 
    244     def OnEwarUpdated(self, targetBallID, sourceBallID, sourceModuleID, jammingType):
    245         if targetBallID != self.fighterID:
    246             return
    247         self.effectsCont.BuildEffectsData()
    248 
    249     def OnFighterTubeStateUpdate(self, tubeFlagID):
    250         if tubeFlagID == self.tubeFlagID:
    251             tubeStatus = self.shipFighterState.GetTubeStatus(self.tubeFlagID)
    252             self.squadronCont.SetSquadronAction(self.tubeFlagID)
    253             if tubeStatus.statusID == TUBE_STATE_EMPTY:
    254                 self.ShowEmpty()
    255             else:
    256                 self.HideEmpty()
    257                 if tubeStatus.endTime:
    258                     self.squadronCont.loadingGauge.display = True
    259                     now = gametime.GetSimTime()
    260                     duration = float(tubeStatus.endTime - tubeStatus.startTime)
    261                     loadingProgress = max(0.0, min(1.0, (now - tubeStatus.startTime) / duration))
    262                     self.squadronCont.loadingGauge.SetValue(loadingProgress, animate=False)
    263                     remainingTime = tubeStatus.endTime - now
    264                     remainingTimeSeconds = max(float(remainingTime) / SEC, 0.1)
    265                     self.squadronCont.loadingGauge.SetValueTimed(1.0, remainingTimeSeconds)
    266                 else:
    267                     self.squadronCont.loadingGauge.display = False
    268 
    269     def OnFighterTubeContentUpdate(self, tubeFlagID):
    270         if tubeFlagID == self.tubeFlagID:
    271             tubeStatus = self.shipFighterState.GetTubeStatus(self.tubeFlagID)
    272             if tubeStatus.statusID in (TUBE_STATE_EMPTY, TUBE_STATE_UNLOADING):
    273                 self.ShowEmpty()
    274                 self.squadronCont.ClearFighters()
    275             else:
    276                 self.HideEmpty()
    277                 fightersInTube = self.GetFightersInTubeState()
    278                 if fightersInTube:
    279                     self.squadronCont.SetNewSquadron(fightersInTube.itemID, fightersInTube.typeID, fightersInTube.squadronSize)
    280                     self.fighterID = fightersInTube.itemID
    281                     self.fighterTypeID = fightersInTube.typeID
    282                     self.effectsCont.UpdateFighterID(self.fighterID)
    283 
    284     def OnFighterInSpaceUpdate(self, fighterID, tubeFlagID):
    285         if tubeFlagID == self.tubeFlagID:
    286             fightersInSpace = self.GetFightersInSpaceState()
    287             if fightersInSpace:
    288                 self.squadronCont.SetNewSquadron(fightersInSpace.itemID, fightersInSpace.typeID, fightersInSpace.squadronSize)
    289                 self.modulesCont.SetNewSquadron(fightersInSpace.itemID, fightersInSpace.typeID)
    290                 self.squadronCont.SetSquadronInfo(tubeFlagID)
    291                 self.ShowInSpaceUI()
    292             else:
    293                 self.squadronCont.StopSquadronTimer()
    294                 self.DeselectSquadron()
    295                 self.HideInSpaceUI()
    296 
    297     def Close(self):
    298         self.shipFighterState.signalOnFighterTubeStateUpdate.disconnect(self.OnFighterTubeStateUpdate)
    299         self.shipFighterState.signalOnFighterTubeContentUpdate.disconnect(self.OnFighterTubeContentUpdate)
    300         self.shipFighterState.signalOnFighterInSpaceUpdate.disconnect(self.OnFighterInSpaceUpdate)
    301         self.shipFighterState.signalOnIncomingEwarStarted.disconnect(self.OnEwarUpdated)
    302         self.shipFighterState.signalOnIncomingEwarEnded.disconnect(self.OnEwarUpdated)
    303         self.squadronCont.damageTimer = None
    304         Container.Close(self)
    305 
    306     def OnSquadronClick(self, *args):
    307         ctrl = uicore.uilib.Key(uiconst.VK_CONTROL)
    308         shift = uicore.uilib.Key(uiconst.VK_SHIFT)
    309         if not ctrl and not shift and uicore.cmd.IsSomeCombatCommandLoaded():
    310             uicore.cmd.ExecuteCombatCommand(self.fighterID, uiconst.UI_CLICK)
    311         elif shift:
    312             if self.parent.GetLastSelectedTube():
    313                 self.parent.MultiSelectSquadrons(self.tubeFlagID)
    314                 self.parent.SetLastSelectedTube(self.tubeFlagID)
    315         elif ctrl:
    316             if movementFunctions.IsSelectedForNavigation(self.fighterID):
    317                 self.DeselectSquadron()
    318             else:
    319                 self.SelectSquadron()
    320                 self.parent.SetLastSelectedTube(self.tubeFlagID)
    321         else:
    322             self.parent.ClearSelection()
    323             if movementFunctions.IsSelectedForNavigation(session.shipid):
    324                 movementFunctions.DeselectForNavigation(session.shipid)
    325             self.SelectSquadron()
    326             self.parent.SetLastSelectedTube(self.tubeFlagID)
    327 
    328     def IsSelected(self):
    329         if self.shipFighterState.GetFightersInSpace(self.tubeFlagID) is None:
    330             return False
    331         return movementFunctions.IsSelectedForNavigation(self.fighterID)
    332 
    333     def OnStateChange(self, itemID, flag, flagState, *args):
    334         if flag == states.selectedForNavigation and itemID == self.fighterID:
    335             if flagState:
    336                 self.squadronCont.ShowSelectionHilite()
    337             else:
    338                 self.squadronCont.HideSelectionHilite()
    339 
    340     def SelectSquadron(self):
    341         movementFunctions.SelectForNavigation(self.fighterID)
    342 
    343     def DeselectSquadron(self):
    344         movementFunctions.DeselectForNavigation(self.fighterID)
    345 
    346     def GetFighterItemID(self):
    347         return self.squadronCont.GetFighterItemID()
    348 
    349     def GetSqMenu(self):
    350         return GetSquadronMenu(self)
    351 
    352     def RecallFighterToTube(self):
    353         self.squadronMgmtController.RecallFighterToTube(self.fighterID)
    354 
    355     def LoadFighterToTube(self, fighterID):
    356         self.squadronMgmtController.LoadFightersToTube(fighterID, self.tubeFlagID)
    357 
    358     def UnloadTubeToFighterBay(self):
    359         self.squadronMgmtController.UnloadTubeToFighterBay(self.tubeFlagID)
    360 
    361     def LaunchFightersFromTube(self):
    362         self.squadronMgmtController.LaunchFightersFromTube(self.tubeFlagID)
    363 
    364     def AbandonFighter(self):
    365         sm.GetService('fighters').AbandonFighter(self.fighterID)
    366 
    367     def ReturnAndOrbit(self):
    368         sm.GetService('fighters').CmdReturnAndOrbit([self.fighterID])
    369 
    370 
    371 class FightersButtonOpenBay(LeftSideButton):
    372     default_name = 'inFlightFigtherBayBtn'
    373     default_texturePath = 'res:/UI/Texture/classes/ShipUI/Fighters/iconFighterBay.png'
    374     invIDText = 'ShipFighterBay'
    375     toolTipDescriptionPath = 'Tooltips/Hud/FighterBay_description'
    376 
    377     def OnClick(self, *args):
    378         LeftSideButton.OnClick(self)
    379         shipID = GetActiveShip()
    380         if shipID is None:
    381             return
    382         Inventory.OpenOrShow((self.invIDText, shipID), usePrimary=False, toggle=True)
    383 
    384     def LoadTooltipPanel(self, tooltipPanel, *args):
    385         tooltipPanel.LoadGeneric2ColumnTemplate()
    386         cmd = uicore.cmd.commandMap.GetCommandByName('OpenFighterBayOfActiveShip')
    387         if cmd:
    388             shortcut = cmd.GetShortcutAsString()
    389         else:
    390             shortcut = ''
    391         tooltipPanel.AddLabelShortcut(GetByLabel('Tooltips/Hud/FighterBay'), shortcut)
    392         tooltipPanel.AddLabelMedium(text=GetByLabel(self.toolTipDescriptionPath), wrapWidth=200, colSpan=tooltipPanel.columns, color=(0.6, 0.6, 0.6, 1))
    393 
    394 
    395 class FightersButtonOpenStructureBay(FightersButtonOpenBay):
    396     invIDText = 'StructureFighterBay'
    397     toolTipDescriptionPath = 'Tooltips/Hud/FighterBayStructure_description'
    398 
    399 
    400 class FightersButtonLaunchAll(LeftSideButton):
    401     default_name = 'launchAllFightersBtn'
    402     default_texturePath = 'res:/UI/Texture/classes/ShipUI/Fighters/iconScrambleSquads-.png'
    403 
    404     def OnClick(self, *args):
    405         LeftSideButton.OnClick(self)
    406         shipID = GetActiveShip()
    407         if shipID is None:
    408             return
    409         uicore.layer.shipui.fighterCont.SelectAll()
    410         sm.GetService('fighters').LaunchAllFighters()
    411 
    412     def LoadTooltipPanel(self, tooltipPanel, *args):
    413         tooltipPanel.LoadGeneric2ColumnTemplate()
    414         cmd = uicore.cmd.commandMap.GetCommandByName('CmdLaunchAllFighters')
    415         shortcut = cmd.GetShortcutAsString()
    416         tooltipPanel.AddLabelShortcut(GetByLabel('Tooltips/Hud/LaunchAll'), shortcut)
    417         tooltipPanel.AddLabelMedium(text=GetByLabel('Tooltips/Hud/LaunchAll_description'), wrapWidth=200, colSpan=tooltipPanel.columns, color=(0.6, 0.6, 0.6, 1))
    418 
    419 
    420 class FightersButtonRecallAll(LeftSideButton):
    421     default_name = 'recallAllFightersBtn'
    422     default_texturePath = 'res:/UI/Texture/classes/ShipUI/Fighters/iconRecallSquads.png'
    423 
    424     def OnClick(self, *args):
    425         LeftSideButton.OnClick(self)
    426         shipID = GetActiveShip()
    427         if shipID is None:
    428             return
    429         uicore.layer.shipui.fighterCont.SelectAll()
    430         sm.GetService('fighters').RecallAllFightersToTubes()
    431 
    432     def LoadTooltipPanel(self, tooltipPanel, *args):
    433         tooltipPanel.LoadGeneric2ColumnTemplate()
    434         mainShortcut = uicore.cmd.GetShortcutStringByFuncName('CmdDronesReturnToBay')
    435         cmd = uicore.cmd.commandMap.GetCommandByName('CmdRecallAllFightersToTubes')
    436         if cmd:
    437             mainShortcut = cmd.GetShortcutAsString() or mainShortcut
    438         tooltipPanel.AddLabelShortcut(GetByLabel('Tooltips/Hud/RecallAll'), mainShortcut)
    439         tooltipPanel.AddLabelMedium(text=GetByLabel('Tooltips/Hud/RecallAll_description'), wrapWidth=200, colSpan=tooltipPanel.columns, color=(0.6, 0.6, 0.6, 1))
    440 
    441 
    442 class FighterDragButton(ButtonIcon):
    443     isDragObject = True
    444 
    445     def GetDragData(self, *args):
    446         return [KeyVal(__guid__='fakeDragData')]
    447 
    448     def PrepareDrag(self, dragContainer, dragSource):
    449         settings.user.ui.Set('detachFighterUI', True)
    450         buttonWidth = 32
    451         shipUI = uicore.layer.shipui
    452         uicore.uilib.ClipCursor(0, buttonWidth, uicore.desktop.width - buttonWidth, uicore.desktop.height)
    453         shipUI.RemoveFighterHudBinding()
    454         dragContainer.width = shipUI.fighterCont.width
    455         dragContainer.height = shipUI.fighterCont.height
    456         shipUI.fighterCont.SetParent(dragContainer)
    457         shipUI.fighterCont.left = 0
    458         shipUI.fighterCont.top = -shipUI.fighterCont.height
    459         shipUI.fighterCont.SetAlign(uiconst.TOPLEFT)
    460         self.SetToggleBtnTexture(True)
    461         return (0, 0)
    462 
    463     def OnEndDrag(self, dragSource, dropLocation, dragData):
    464         shipUI = uicore.layer.shipui
    465         posX = uicore.uilib.x
    466         posY = uicore.uilib.y - shipUI.fighterCont.height
    467         settings.char.ui.Set('fightersDetachedPosition', (posX, posY))
    468         shipUI.DrawFighters()
    469         uicore.uilib.UnclipCursor()
    470 
    471     def SetToggleBtnTexture(self, isDetached):
    472         if isDetached:
    473             texturePath = 'res:/UI/Texture/classes/ShipUI/Fighters/moveFighters_Up.png'
    474         else:
    475             texturePath = 'res:/UI/Texture/classes/ShipUI/Fighters/positionFighters_Up.png'
    476         self.SetTexturePath(texturePath)