dronesWindow.py (26509B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\inflight\drones\dronesWindow.py 2 import appConst 3 import log 4 import eve.client.script.ui.shared.pointerTool.pointerToolConst as pConst 5 import eveicon 6 import evetypes 7 import localization 8 import uthread 9 import uthread2 10 from carbon.client.script.util.misc import Uthreaded 11 from carbonui import TextColor, uiconst 12 from carbonui.control.contextMenu.menuEntryData import MenuEntryData 13 from carbonui.primitives.containerAutoSize import ContainerAutoSize 14 from carbonui.uicore import uicore 15 from carbonui.util.various_unsorted import SortListOfTuples 16 from carbonui.window.header.small import SmallWindowHeader 17 from carbonui.window.widget import WidgetWindow 18 from eve.client.script.ui.control.entries.util import GetFromClass 19 from eve.client.script.ui.control.eveScroll import Scroll 20 from eve.client.script.ui.inflight import actionPanelDefaults 21 from eve.client.script.ui.inflight.drones import droneSignals, dronesDragData 22 from eve.client.script.ui.inflight.drones.droneEntry import DroneInSpaceEntry, DroneInBayEntry, NoDroneInBayEntry, NoDroneInSpaceEntry 23 from eve.client.script.ui.inflight.drones.droneGroup import DroneSubGroup, DroneSubGroupInSpace, DroneSubGroupInBay 24 from eve.client.script.ui.inflight.drones.droneGroupHeader import DroneGroupHeaderInBay, DroneGroupHeaderInSpace 25 from eve.client.script.ui.inflight.drones.droneGroupsController import GetDroneGroupsController 26 from eve.client.script.ui.inflight.drones.droneSettings import drones_aggressive_setting, drones_focus_fire_setting, VIEW_MODE_ICONS, drones_view_mode_setting, VIEW_MODE_LIST, drones_view_mode_compact_setting 27 from eve.client.script.ui.inflight.drones.dronesConst import DRONESTATE_INBAY, DRONESTATE_INSPACE 28 from eve.client.script.ui.inflight.drones.dronesDragData import HasInSpaceDroneIDs 29 from eve.client.script.ui.inflight.drones.dronesUtil import GetDronesInLocalSpace, GetDronesInBay, GetDroneIDsInBay, GetDroneIDsInSpace, ExpandRadialMenuForInBayGroup, ExpandRadialMenuForInSpaceGroup 30 from eve.client.script.ui.inflight.drones.dronesWarpWarning import warp_warning_enabled_setting, WarpWarning 31 from eve.client.script.ui.services.menuSvcExtras import droneFunctions 32 from eve.common.lib import appConst as const 33 from eveDrones.droneConst import DAMAGESTATE_NOT_READY 34 from eveservices.menu import GetMenuService 35 from localization import GetByLabel 36 from menu import MenuLabel, MenuList 37 from utillib import KeyVal 38 NODRONES_CLOSE_TIME = 5 39 40 class DronesWindow(WidgetWindow): 41 __notifyevents__ = ['OnAttribute', 42 'OnAttributes', 43 'OnDroneControlLost', 44 'OnItemChange', 45 'OnClientEvent_WarpStarted', 46 'OnClientEvent_WarpFinished', 47 'OnWarpStarted2', 48 'ProcessSessionChange'] 49 default_windowID = 'droneview' 50 uniqueUiName = pConst.UNIQUE_NAME_DRONE_WND 51 default_minSize = (240, 120) 52 default_scope = uiconst.SCOPE_INFLIGHT 53 default_isKillable = False 54 default_iconNum = eveicon.drones_window 55 56 def get_wnd_menu_unique_name(self): 57 return pConst.UNIQUE_NAME_DRONE_SETTINGS 58 59 @staticmethod 60 def default_left(*args): 61 return actionPanelDefaults.GetDroneViewLeft() 62 63 @staticmethod 64 def default_top(*args): 65 return actionPanelDefaults.GetDroneViewTop() 66 67 @staticmethod 68 def default_width(): 69 return actionPanelDefaults.GetDroneViewWidth() 70 71 @staticmethod 72 def default_height(): 73 return actionPanelDefaults.GetDroneViewHeight() 74 75 def ApplyAttributes(self, attributes): 76 self.inBayHeader = None 77 super(DronesWindow, self).ApplyAttributes(attributes) 78 self.panelname = attributes.panelName 79 self.lastActionSerial = None 80 self.actionsTimer = None 81 self.reloadThread = None 82 self.lastUpdateIDs = None 83 self.reloadPending = False 84 self.inSpace = None 85 self.droneGroupsController = GetDroneGroupsController() 86 self.droneGroupsController.on_groups_changed.connect(self.OnDroneGroupsChanged) 87 if self.panelname: 88 self.SetCaption(self.panelname) 89 self.content.clipChildren = True 90 self.warpWarning = WarpWarning(parent=self.content, align=uiconst.TOTOP, state=uiconst.UI_HIDDEN, padBottom=2) 91 self.ConstructBottomScroll() 92 self.ConstructTopScroll() 93 openState = uicore.registry.GetListGroupOpenState(('dronegroups', DRONESTATE_INBAY), default=False) 94 uicore.registry.GetLockedGroup('dronegroups', DRONESTATE_INBAY, localization.GetByLabel('UI/Inflight/Drone/DronesInBay'), openState=openState) 95 openState = uicore.registry.GetListGroupOpenState(('dronegroups', DRONESTATE_INSPACE), default=False) 96 uicore.registry.GetLockedGroup('dronegroups', DRONESTATE_INSPACE, localization.GetByLabel('UI/Inflight/Drone/DronesInLocalSpace'), openState=openState) 97 droneSettingChanges = {appConst.attributeDroneIsAggressive: drones_aggressive_setting.is_enabled(), 98 appConst.attributeDroneFocusFire: drones_focus_fire_setting.is_enabled()} 99 sm.GetService('godma').GetStateManager().ChangeDroneSettings(droneSettingChanges) 100 if self and not self.destroyed: 101 self.CheckReloadDronesScroll() 102 self.UpdateAll() 103 self.on_compact_mode_changed.connect(self.OnWindowStateChanged) 104 self.on_stacked_changed.connect(self.OnWindowStateChanged) 105 self.on_collapsed_changed.connect(self.OnWindowStateChanged) 106 drones_view_mode_setting.on_change.connect(self.OnDronesViewModeChanged) 107 drones_view_mode_compact_setting.on_change.connect(self.OnDronesViewModeChanged) 108 self.UpdateHeaderPadding() 109 uthread2.StartTasklet(self.CheckCloseThread) 110 111 def OnDroneGroupsChanged(self): 112 self.CheckReloadDronesScroll(force=True) 113 114 def ConstructTopScroll(self): 115 self.inBayHeader = DroneGroupHeaderInBay(parent=self.content, align=uiconst.TOTOP, idx=0) 116 self.inBayHeader.on_open_changed.connect(self.OnInBayHeaderExpandedChanged) 117 self.inBayHeader.OnMouseMoveDrag = self.OnInBayHeaderMouseMoveDrag 118 self.inBayHeader.OnMouseDownDrag = self.OnInBayHeaderMouseDownDrag 119 self.inBayHeader.OnMouseUp = self.OnInBayHeaderMousUp 120 self.topScroll = Scroll(name='dronesInBayScroll', parent=self.content, align=uiconst.TOALL, state=uiconst.UI_PICKCHILDREN) 121 self.topScroll.sr.content.OnDropData = self.OnDropData 122 self.topScroll.sr.content.OnDragEnter = self.OnDragEnter 123 self.topScroll.multiSelect = 1 124 self.topScroll.OnChar = self.OnDronesScrollChar 125 126 def OnInBayHeaderMousUp(self, *args): 127 self.OnMouseUp(*args) 128 129 def OnInBayHeaderMouseDownDrag(self, *args): 130 self.dragMousePosition = (uicore.uilib.x, uicore.uilib.y) 131 self.OnMouseDownDrag(*args) 132 133 def OnInBayHeaderMouseMoveDrag(self, *args): 134 self.OnMouseMoveDrag(*args) 135 136 def OnDropData(self, dragSource, dragData): 137 droneIDs = dronesDragData.GetInSpaceDroneIDs(dragData) 138 if droneIDs: 139 droneFunctions.ReturnToDroneBay(droneIDs) 140 droneSignals.on_drones_dropped_to_bay() 141 142 def OnDragEnter(self, dragSource, dragData): 143 if HasInSpaceDroneIDs(dragData): 144 droneSignals.on_in_bay_entry_drag_enter() 145 146 def OnInBayHeaderExpandedChanged(self, isExpanded): 147 self.topScroll.display = isExpanded 148 self.bottomCont.align = uiconst.TOBOTTOM if isExpanded else uiconst.TOTOP 149 if not isExpanded and not self.inSpaceHeader.isExpanded: 150 self.inSpaceHeader.SetAsExpanded() 151 152 def ConstructBottomScroll(self): 153 self.bottomCont = ContainerAutoSize(name='bottomCont', parent=self.content, align=uiconst.TOBOTTOM) 154 self.inSpaceHeader = DroneGroupHeaderInSpace(parent=self.bottomCont, align=uiconst.TOTOP, padTop=4) 155 self.inSpaceHeader.on_open_changed.connect(self.OnInSpaceHeaderExpanedChanged) 156 self.bottomScroll = Scroll(name='dronesInSpaceScroll', align=uiconst.TOTOP, parent=self.bottomCont, state=uiconst.UI_PICKCHILDREN, padTop=2) 157 self.bottomScroll.multiSelect = 1 158 self.bottomScroll.OnChar = self.OnDronesScrollChar 159 self.bottomScroll.sr.content.state = uiconst.UI_PICKCHILDREN 160 self.bottomScroll.on_content_resize.connect(self.OnBottomScrollContentResize) 161 162 def OnInSpaceHeaderExpanedChanged(self, isExpanded): 163 self.bottomScroll.display = isExpanded 164 if not isExpanded and not self.inBayHeader.isExpanded: 165 self.inBayHeader.SetAsExpanded() 166 167 def OnBottomScrollContentResize(self, height): 168 self.UpdateBottomScrollHeight() 169 170 def UpdateBottomScrollHeight(self): 171 window_height = self.height if not self.stacked else self.GetCurrentAbsoluteSize()[1] 172 maxHeight = max(window_height - (86 if self.compact else 128), 0) 173 self.bottomScroll.height = min(self.bottomScroll.GetEntriesTotalHeight(), maxHeight) 174 175 def _OnResize(self, *args, **kw): 176 super(DronesWindow, self)._OnResize(*args, **kw) 177 self.UpdateBottomScrollHeight() 178 179 def OnDronesViewModeChanged(self, *args): 180 self.CheckReloadDronesScroll(force=True) 181 182 def UpdateHeaderPadding(self): 183 self.extend_content_into_header = self.compact 184 if self.compact: 185 _, _, content_pad_right, _ = self.content_padding 186 _, inset_right = self.header_inset 187 reserved_spaced_right = max(inset_right - content_pad_right, 0) 188 else: 189 reserved_spaced_right = 0 190 self.inBayHeader.reserved_space_right = reserved_spaced_right 191 192 def OnWindowStateChanged(self, *args): 193 self.UpdateHeaderPadding() 194 self._update_header() 195 self.CheckReloadDronesScroll(force=True) 196 197 def Prepare_Header_(self): 198 self._SetHeader(SmallWindowHeader(show_caption=not self.compact, fixed_height=self._get_header_fixed_height())) 199 200 def _update_header(self): 201 self.header.show_caption = not self.compact 202 self.header.fixed_height = self._get_header_fixed_height() 203 204 def _get_header_fixed_height(self): 205 if self.compact: 206 return 40 207 208 def ProcessSessionChange(self, *etc): 209 self.CheckReloadDronesScroll(True) 210 211 ProcessSessionChange = Uthreaded(ProcessSessionChange) 212 213 def OnDroneControlLost(self, droneID): 214 self.CheckReloadDronesScroll(True) 215 216 def OnAttributes(self, l): 217 for attributeName, item, newValue in l: 218 self.OnAttribute(attributeName, item, newValue) 219 220 def OnAttribute(self, attributeName, item, newValue): 221 if not self or self.destroyed: 222 return 223 if item.itemID == session.charid and attributeName == 'maxActiveDrones': 224 t = self.lastUpdateIDs 225 if t is None: 226 self.CheckReloadDronesScroll() 227 228 def OnItemChange(self, item, change, location): 229 if item.locationID == session.shipid: 230 if item.flagID == const.flagDroneBay or change.get(const.ixFlag, None) == const.flagDroneBay: 231 self.CheckReloadDronesScroll() 232 elif change.get(const.ixLocationID, None) == session.shipid and change.get(const.ixFlag, None) == const.flagDroneBay: 233 self.CheckReloadDronesScroll() 234 235 def OnDronesScrollChar(self, *args): 236 return False 237 238 def GetSelected(self, fromNode): 239 nodes = [] 240 sel = fromNode.scroll.GetSelectedNodes(fromNode) 241 for node in sel: 242 if node.Get('typeID', None) is None: 243 continue 244 if evetypes.GetGroupID(node.typeID) == evetypes.GetGroupID(fromNode.typeID): 245 if node.droneState == fromNode.droneState: 246 nodes.append(node) 247 248 return nodes 249 250 def UpdateAll(self): 251 if self.content.state != uiconst.UI_PICKCHILDREN: 252 self.actionsTimer = None 253 return 254 self.CheckReloadDronesScroll() 255 256 def GetSubGroups(self, what): 257 return [] 258 259 def CheckReloadDronesScroll(self, force = False, *args): 260 if force: 261 self.lastUpdateIDs = None 262 if self.reloadThread: 263 self.reloadPending = True 264 else: 265 self.reloadThread = uthread.new(self._CheckReloadDronesScroll) 266 267 def _CheckReloadDronesScroll(self): 268 if session.stationid: 269 return 270 inBayIDs = GetDroneIDsInBay() 271 inLocalSpaceIDs = GetDroneIDsInSpace() 272 uthread.new(sm.GetService('tactical').GetInBayDroneDamageTracker().FetchInBayDroneDamageToServer, inBayIDs) 273 allDroneIDs = (inBayIDs, inLocalSpaceIDs) 274 if self.lastUpdateIDs != allDroneIDs: 275 self.lastUpdateIDs = allDroneIDs 276 self._ReloadScroll(inBayIDs, inLocalSpaceIDs) 277 self.CheckHint() 278 self.UpdateWarpWarning() 279 self.inBayHeader.UpdateLabelText() 280 self.inSpaceHeader.UpdateLabelText() 281 uthread2.Sleep(0.1) 282 if self.reloadPending: 283 self.reloadPending = False 284 self.CheckReloadDronesScroll() 285 self.reloadThread = None 286 287 def _ReloadScroll(self, inBayIDs, inLocalSpaceIDs): 288 self._ReloadTopScroll(inBayIDs) 289 self._ReloadBottomScroll(inLocalSpaceIDs) 290 291 def _ReloadTopScroll(self, inBayIDs): 292 scrolllist = self.GetMainGroupEntriesInBay(DRONESTATE_INBAY, inBayIDs) 293 self.topScroll.Load(contentList=scrolllist) 294 295 def _ReloadBottomScroll(self, inLocalSpaceIDs): 296 scrolllist = self.GetMainGroupEntriesInSpace(DRONESTATE_INSPACE, inLocalSpaceIDs) 297 self.bottomScroll.Load(contentList=scrolllist) 298 299 def CheckCloseThread(self): 300 noDronesCounter = 0 301 while not self.destroyed: 302 uthread2.Sleep(1.0) 303 if not self.HasDronesInBayOrSpace(): 304 noDronesCounter += 1 305 else: 306 noDronesCounter = 0 307 if noDronesCounter >= NODRONES_CLOSE_TIME: 308 self.Close() 309 310 def HasDronesInBayOrSpace(self): 311 return GetDronesInBay() or sm.GetService('michelle').GetDrones() 312 313 def GetSubFolderMenu(self, node): 314 m = MenuList([None]) 315 data = self.droneGroupsController.GetDroneDataForSubGroup(node.droneState, node.groupName) 316 if not data: 317 return m 318 if node.droneState == DRONESTATE_INSPACE: 319 m += GetMenuService().DroneMenu(data) 320 elif node.droneState == DRONESTATE_INBAY: 321 m += GetMenuService().InvItemMenu(data).filter([MenuLabel('UI/Inventory/ItemActions/BuyThisType'), 322 MenuLabel('UI/Inventory/ItemActions/AddTypeToMarketQuickbar'), 323 MenuLabel('UI/Inventory/ItemActions/ViewTypesMarketDetails'), 324 MenuLabel('UI/Inventory/ItemActions/FindInContracts')]) 325 favoriteGroup = self.droneGroupsController.GetFavoriteGroupID() 326 groupIdentifier = node.id[-1] 327 if favoriteGroup == groupIdentifier: 328 m.append(MenuEntryData(text=MenuLabel('UI/Drones/UnmarkAsFavorite'), func=lambda : self.RemoveAsFavorite(groupIdentifier), texturePath=eveicon.star_slash)) 329 else: 330 m.append(MenuEntryData(text=MenuLabel('UI/Drones/MarkAsFavorite'), func=lambda : self.AddAsFavorite(groupIdentifier), texturePath=eveicon.star)) 331 return m 332 333 def AddAsFavorite(self, groupIdentifier): 334 self.droneGroupsController.SetFavoriteGroupID(groupIdentifier) 335 self.CheckReloadDronesScroll(force=True) 336 337 def RemoveAsFavorite(self, groupIdentifier): 338 favoriteGroupID = self.droneGroupsController.GetFavoriteGroupID() 339 if groupIdentifier == favoriteGroupID: 340 self.droneGroupsController.SetFavoriteGroupID(None) 341 self.CheckReloadDronesScroll(force=True) 342 343 def GroupMenu(self, droneNode): 344 selected = self.GetSelected(droneNode) 345 itemIDs = [ n.itemID for n in selected ] 346 m = MenuList() 347 move = [(MenuLabel('UI/Commands/NewGroup'), self.droneGroupsController.CreateSubGroup, (evetypes.GetGroupID(droneNode.typeID), itemIDs))] 348 inGroup = [] 349 for node in selected: 350 group = self.droneGroupsController.GetDroneGroup(node.itemID) 351 if group: 352 inGroup.append(node) 353 354 if inGroup: 355 itemIDs = [ entry.itemID for entry in inGroup ] 356 move += [(MenuLabel('UI/Commands/OutOfThisGroup'), self.droneGroupsController.RemoveFromGroup, (itemIDs,))] 357 groupNames = self.droneGroupsController.GetGroupNames() 358 groupNames.sort(key=lambda x: x.lower()) 359 move += [ (groupName, self.droneGroupsController.MoveToGroup, (evetypes.GetGroupID(droneNode.typeID), groupName, [ d.itemID for d in selected ])) for groupName in groupNames ] 360 m += [(MenuLabel('UI/Commands/MoveDrone'), move)] 361 return m 362 363 def OnMouseDownOnDroneMainGroup(self, group, *args): 364 self.OnMouseDownOnDroneMainGroup_thread(group) 365 366 def OnMouseDownOnDroneMainGroup_thread(self, group): 367 groupNode = group.sr.node 368 droneData = self.droneGroupsController.GetDroneDataForMainGroup(groupNode.droneState) 369 if droneData: 370 return self.GetRadialMenuOnGroup(group, droneData) 371 372 def OnMouseDownOnDroneSubGroup(self, group, *args): 373 uthread.new(self.OnMouseDownOnDroneSubGroup_thread, group) 374 375 def OnMouseDownOnDroneSubGroup_thread(self, group): 376 groupNode = group.sr.node 377 droneData = self.droneGroupsController.GetDroneDataForSubGroup(groupNode.droneState, groupNode.groupName) 378 if droneData: 379 return self.GetRadialMenuOnGroup(group, droneData) 380 381 def GetRadialMenuOnGroup(self, group, droneData): 382 groupNode = group.sr.node 383 if groupNode.droneState == DRONESTATE_INBAY: 384 ExpandRadialMenuForInBayGroup(group, groupNode.cleanLabel, droneData) 385 elif groupNode.droneState == DRONESTATE_INSPACE: 386 ExpandRadialMenuForInSpaceGroup(group, groupNode.cleanLabel, droneData) 387 388 def GetSpaceDrone(self, droneID): 389 return sm.GetService('michelle').GetDroneState(droneID) 390 391 def _GetSubGroupEntryClass(self, droneState): 392 if droneState == DRONESTATE_INSPACE: 393 groupCls = DroneSubGroupInSpace 394 else: 395 if droneState == DRONESTATE_INBAY: 396 return DroneSubGroupInBay 397 groupCls = DroneSubGroup 398 return groupCls 399 400 def GetSubGroupListEntry(self, group, state, items): 401 numDrones = self.GetNumberOfDronesInGroup(state, items) 402 icon = None 403 groupIdentifier = group['id'] 404 favoriteGroup = self.droneGroupsController.GetFavoriteGroupID() 405 if favoriteGroup and favoriteGroup == groupIdentifier: 406 icon = eveicon.star 407 cls = self._GetSubGroupEntryClass(state) 408 return GetFromClass(cls, {'GetSubContent': self.GetSubGroupContent, 409 'MenuFunction': self.GetSubFolderMenu, 410 'label': localization.GetByLabel('UI/Inflight/Drone/DroneGroupWithCount', groupLabel=group['label'], count=numDrones), 411 'id': (state, group['id']), 412 'droneGroupID': group['droneGroupID'], 413 'groupItems': None, 414 'iconMargin': 18, 415 'state': 'locked', 416 'sublevel': 0, 417 'droneState': state, 418 'BlockOpenWindow': 1, 419 'showlen': 0, 420 'groupName': group['label'], 421 'OnMouseDown': self.OnMouseDownOnDroneSubGroup, 422 'showicon': icon, 423 'isFavorite': bool(icon)}) 424 425 def GetNumberOfDronesInGroup(self, droneState, items): 426 t = 0 427 if droneState == DRONESTATE_INBAY: 428 dronebay = {} 429 for drone in GetDronesInBay(): 430 dronebay[drone.itemID] = drone 431 432 for droneID in items: 433 if droneID not in dronebay: 434 log.LogWarn("Drone we thought was in the dronebay wasn't actually there, droneID = ", droneID) 435 continue 436 t += dronebay[droneID].stacksize 437 438 else: 439 t = len(items) 440 return t 441 442 def GetMainGroupEntriesInBay(self, droneState, droneIDs, subLevel = 0): 443 scrollList = [] 444 dronebay = {} 445 for drone in GetDronesInBay(): 446 dronebay[drone.itemID] = drone 447 448 subGroups = {} 449 for droneID in droneIDs: 450 group = self.droneGroupsController.GetDroneGroup(droneID) 451 if group: 452 subGroups.setdefault(group['label'], []).append(droneID) 453 continue 454 if droneID in dronebay: 455 entry = self.GetBayDroneEntry(dronebay[droneID], subLevel, droneState) 456 scrollList.append(((0, entry.label.lower()), entry)) 457 458 self.AppendSubGroups(scrollList, droneState, subGroups) 459 return SortListOfTuples(scrollList) 460 461 def GetMainGroupEntriesInSpace(self, droneState, droneIDs, subLevel = 0): 462 scrollList = [] 463 subGroups = {} 464 for droneID in droneIDs: 465 group = self.droneGroupsController.GetDroneGroup(droneID) 466 if group: 467 subGroups.setdefault(group['label'], []).append(droneID) 468 continue 469 entry = self.GetSpaceDroneEntry(self.GetSpaceDrone(droneID), subLevel, droneState) 470 scrollList.append(((0, entry.label.lower()), entry)) 471 472 self.AppendSubGroups(scrollList, droneState, subGroups) 473 return SortListOfTuples(scrollList) 474 475 def AppendSubGroups(self, scrollList, droneState, subGroups): 476 for groupName, droneIDs in subGroups.iteritems(): 477 group = self.droneGroupsController.GetSubGroup(groupName) 478 if group: 479 entry = self.GetSubGroupListEntry(group, droneState, droneIDs) 480 scrollList.append(((1, entry.label.lower()), entry)) 481 482 if not scrollList: 483 noItemEntry = self.GetNoDroneInBayEntry() if droneState == DRONESTATE_INBAY else self.GetNoDroneInSpaceEntry() 484 scrollList.append((0, noItemEntry)) 485 486 def GetSubGroupContent(self, nodedata, newitems = 0): 487 scrollList = [] 488 subGroupInfo = self.droneGroupsController.GetSubGroup(nodedata.groupName) 489 if nodedata.droneState == DRONESTATE_INBAY: 490 drones = GetDronesInBay() 491 for drone in drones: 492 if drone.itemID in subGroupInfo['droneIDs']: 493 entry = self.GetBayDroneEntry(drone, 1, nodedata.droneState) 494 scrollList.append(((entry.subLevel, entry.label), entry)) 495 496 elif nodedata.droneState == DRONESTATE_INSPACE: 497 drones = GetDronesInLocalSpace() 498 for drone in drones: 499 if drone.droneID in subGroupInfo['droneIDs']: 500 entry = self.GetSpaceDroneEntry(drone, 1, nodedata.droneState) 501 scrollList.append(((entry.subLevel, entry.label), entry)) 502 503 return SortListOfTuples(scrollList) 504 505 def GetNoDroneInBayEntry(self): 506 return GetFromClass(NoDroneInBayEntry, self._GetNoItemEntryData()) 507 508 def GetNoDroneInSpaceEntry(self): 509 return GetFromClass(NoDroneInSpaceEntry, self._GetNoItemEntryData()) 510 511 def _GetNoItemEntryData(self): 512 data = KeyVal() 513 data.label = localization.GetByLabel('/Carbon/UI/Controls/Common/NoItem') 514 data.sublevel = 0 515 data.itemID = None 516 data.height = 24 517 data.fontColor = TextColor.SECONDARY 518 data.selectable = False 519 return data 520 521 def GetDroneDamageState(self, droneID): 522 damageTracker = sm.GetService('tactical').GetInBayDroneDamageTracker() 523 if damageTracker.IsDroneDamageReady(droneID): 524 damageState = damageTracker.GetDamageStateForDrone(droneID) 525 else: 526 damageState = DAMAGESTATE_NOT_READY 527 return damageState 528 529 def GetBayDroneEntry(self, drone, level, droneState): 530 data = KeyVal() 531 data.itemID = drone.itemID 532 data.itemIDs = [drone.itemID] 533 data.typeID = drone.typeID 534 data.invItem = drone 535 data.damageState = self.GetDroneDamageState(drone.itemID) 536 data.displayName = evetypes.GetName(drone.typeID) 537 if drone.stacksize > 1: 538 data.label = localization.GetByLabel('UI/Inflight/Drone/DroneBayEntryWithStacksize', drone=drone.typeID, stacksize=drone.stacksize) 539 else: 540 data.label = evetypes.GetName(drone.typeID) 541 data.sublevel = level 542 data.customMenu = self.GroupMenu 543 data.droneState = droneState 544 return GetFromClass(DroneInBayEntry, data) 545 546 def GetSpaceDroneEntry(self, drone, level, droneState): 547 data = KeyVal() 548 data.itemID = drone.droneID 549 data.itemIDs = [drone.droneID] 550 data.typeID = drone.typeID 551 data.ownerID = drone.ownerID 552 data.controllerID = drone.controllerID 553 data.controllerOwnerID = drone.controllerOwnerID 554 data.displayName = data.label = evetypes.GetName(drone.typeID) 555 data.sublevel = level 556 data.customMenu = self.GroupMenu 557 data.droneState = droneState 558 data.isWindowCompact = self.compact 559 return GetFromClass(DroneInSpaceEntry, data) 560 561 def CheckHint(self): 562 if not self.topScroll.GetNodes(): 563 self.topScroll.ShowHint(localization.GetByLabel('UI/Inflight/Drone/NoDrones')) 564 else: 565 self.topScroll.ShowHint() 566 567 def GetMenuMoreOptions(self): 568 menuData = super(DronesWindow, self).GetMenuMoreOptions() 569 menuData.AddCheckbox(text=localization.GetByLabel('UI/Drones/WarpWarningOption'), setting=warp_warning_enabled_setting) 570 menuData.AddSeparator() 571 menuData.AddCaption(text=GetByLabel('UI/Inventory/ViewMode')) 572 setting = drones_view_mode_compact_setting if self.compact else drones_view_mode_setting 573 menuData.AddRadioButton(text=GetByLabel('UI/Inventory/Icons'), value=VIEW_MODE_ICONS, setting=setting) 574 menuData.AddRadioButton(text=GetByLabel('UI/Inventory/List'), value=VIEW_MODE_LIST, setting=setting) 575 return menuData 576 577 def OnClientEvent_WarpStarted(self, *args): 578 self.UpdateWarpWarning() 579 580 def OnWarpStarted2(self, *args): 581 self.UpdateWarpWarning() 582 583 def OnClientEvent_WarpFinished(self, *args): 584 self.UpdateWarpWarning() 585 586 def UpdateWarpWarning(self): 587 if not warp_warning_enabled_setting.is_enabled(): 588 self.warpWarning.Hide() 589 return 590 michelle = sm.GetService('michelle') 591 if michelle.IsPreparingWarp() and michelle.AreDronesOut(): 592 self.warpWarning.FadeIn() 593 else: 594 self.warpWarning.FadeOut()