fleet.py (51234B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\fleet\fleet.py 2 import eveicon 3 from carbonui.control.animatedsprite import AnimSprite 4 from carbonui.control.contextMenu.menuEntryData import MenuEntryData 5 from carbonui.primitives.container import Container 6 from carbonui.primitives.fill import Fill 7 from carbonui.primitives.sprite import Sprite 8 from carbonui.util.various_unsorted import ParanoidDecoMethod, SortListOfTuples 9 from eve.client.script.parklife import states as state 10 from eve.client.script.ui.control.entries.generic import Generic 11 from eve.client.script.ui.control.entries.util import GetFromClass 12 from eve.client.script.ui.control.glowSprite import GlowSprite 13 from eve.client.script.ui.control.listgroup import ListGroup as Group 14 from eve.client.script.ui.inflight.baseTacticalEntry import BaseTacticalEntry 15 from eve.client.script.ui.services.menuAction import Action 16 from eve.client.script.ui.shared.fleet.fleetConst import FLEET_VIEW_FLAT_LIST_SETTING 17 from eve.client.script.ui.shared.fleet.fleetUtil import GetFleetMemberMenuOptions 18 from eve.client.script.ui.shared.radialMenu.radialMenu import RadialMenuSpaceCharacter 19 import weakref 20 from eve.client.script.ui.util import uix 21 from eve.client.script.util.bubble import SlimItemFromCharID 22 import uthread 23 from eve.client.script.ui.control import eveIcon, eveLabel, eveScroll 24 import blue 25 import carbonui.const as uiconst 26 import log 27 import localization 28 from collections import defaultdict 29 import evefleet.client 30 from evefleet import fleetActivityNames, ACTIVITY_MISC 31 from utillib import KeyVal 32 from carbonui.uicore import uicore 33 from eveservices.menu import GetMenuService 34 from menu import MenuLabel, MenuList 35 CONNOT_BE_MOVED_INCOMPATIBLE = -1 36 CANNOT_BE_MOVED = 0 37 CAN_BE_COMMANDER = 1 38 CAN_ONLY_BE_MEMBER = 2 39 COLOR_CANNOT_BE_MOVED = (1, 40 0, 41 0, 42 0.15) 43 COLOR_CAN_BE_COMMANDER = (1, 44 1, 45 1, 46 0.2) 47 COLOR_CAN_ONLY_BE_MEMBER = (1, 48 1, 49 1, 50 0.07) 51 EDIT_MODE_CONFIG = 'fleet_watchlistcolor_editMode' 52 WATCHLIST_COLORS_CONFIG = 'fleet_watchlistcolors' 53 54 def CommanderName(group): 55 cmdr = group['commander'] 56 if cmdr: 57 return cfg.eveowners.Get(cmdr).name 58 else: 59 return '<color=0x%%(alpha)xffffff>%s</color>' % localization.GetByLabel('UI/Fleet/FleetWindow/NoCommander') 60 61 62 def SquadronName(fleet, squadID): 63 squadron = fleet['squads'][squadID] 64 squadronName = squadron['name'] 65 if squadronName == '': 66 squadno = GroupNumber(fleet, 'squad', squadID) 67 squadronName = localization.GetByLabel('UI/Fleet/DefaultSquadName', squadNumber=squadno) 68 return squadronName 69 70 71 def WingName(fleet, wingID): 72 wing = fleet['wings'][wingID] 73 wingName = wing['name'] 74 if wingName == '': 75 wingno = GroupNumber(fleet, 'wing', wingID) 76 wingName = localization.GetByLabel('UI/Fleet/DefaultWingName', wingNumber=wingno) 77 return wingName 78 79 80 def GroupNumber(fleet, groupType, groupID): 81 ids = fleet['%ss' % groupType].keys() 82 ids.sort() 83 return ids.index(groupID) + 1 84 85 86 def GetSquadMenu(squadID): 87 m = MenuList() 88 fleetSvc = sm.GetService('fleet') 89 if fleetSvc.IsCommanderOrBoss(): 90 m = MenuList([(MenuLabel('UI/Fleet/FleetWindow/ChangeName'), lambda : fleetSvc.ChangeSquadName(squadID)), (MenuLabel('UI/Fleet/FleetWindow/DeleteSquad'), lambda : fleetSvc.DeleteSquad(squadID))]) 91 if squadID == fleetSvc.GetAutoJoinSquadID(): 92 m.append((MenuLabel('UI/Fleet/FleetWindow/RemoveSquadAsAutoJoin'), lambda : fleetSvc.SetAutoJoinSquadID(None))) 93 else: 94 m.append((MenuLabel('UI/Fleet/FleetWindow/SetSquadAsAutoJoin'), lambda : fleetSvc.SetAutoJoinSquadID(squadID))) 95 m.append((MenuLabel('UI/Fleet/FleetWindow/AddSquadMembersToWatchlist'), lambda : fleetSvc.AddFavoriteSquad(squadID))) 96 return m 97 98 99 class MyFleetPanel(Container): 100 __guid__ = 'form.FleetView' 101 __notifyevents__ = ['OnFleetMemberChanging', 102 'OnManyFleetMembersChanging', 103 'OnCollapsed', 104 'OnExpanded', 105 'OnFleetJoin_Local', 106 'OnFleetLeave_Local', 107 'OnFleetWingAdded_Local', 108 'OnFleetWingDeleted_Local', 109 'OnFleetSquadAdded_Local', 110 'OnFleetSquadDeleted_Local', 111 'OnFleetMemberChanged_Local', 112 'OnFleetWingNameChanged_Local', 113 'OnFleetSquadNameChanged_Local', 114 'OnFleetOptionsChanged_Local'] 115 116 def PostStartup(self): 117 sm.RegisterNotify(self) 118 header = self 119 header.baseHeight = 30 120 self.sr.topEntry = FleetRoleCont(parent=header, align=uiconst.TOTOP, height=16, padBottom=8) 121 self.sr.scroll = eveScroll.Scroll(parent=self) 122 self.sr.scroll.sr.content.OnDropData = self.OnDropData 123 self.members = {} 124 self.myGroups = {} 125 self.pending_RefreshFromRec = [] 126 self.scrollToProportion = 0 127 self.fleet = None 128 self.HandleFleetChanged() 129 FLEET_VIEW_FLAT_LIST_SETTING.on_change.connect(self.HandleFleetChanged) 130 131 def LoadPanel(self): 132 if not self.sr.Get('inited', 0): 133 setattr(self.sr, 'inited', 1) 134 self.PostStartup() 135 if session.fleetid is not None: 136 if getattr(self.sr, 'scroll', None): 137 self.sr.scroll._OnResize() 138 139 def OnFleetMemberChanging(self, charID): 140 rec = self.members.get(charID) 141 if rec is not None: 142 rec.changing = True 143 self.RefreshFromRec(rec) 144 145 def OnManyFleetMembersChanging(self, charIDs): 146 squadMembersByWingID = defaultdict(list) 147 otherMembers = [] 148 for eachCharID in charIDs: 149 rec = self.members.get(eachCharID) 150 if rec is None: 151 continue 152 if not FLEET_VIEW_FLAT_LIST_SETTING.is_enabled() and rec.squadID not in (None, -1) and rec.wingID not in (None, -1): 153 rec.changing = True 154 squadMembersByWingID[rec.wingID].append(rec) 155 else: 156 otherMembers.append(eachCharID) 157 158 for charsInWing in squadMembersByWingID.itervalues(): 159 recForFirstChar = charsInWing[0] 160 if recForFirstChar: 161 self.RefreshFromRec(recForFirstChar) 162 163 for charID in otherMembers: 164 self.OnFleetMemberChanging(charID) 165 166 def UpdateHeader(self): 167 from eve.client.script.ui.shared.fleet.fleetwindow import FleetWindow 168 wnd = FleetWindow.GetIfOpen() 169 if wnd: 170 wnd.UpdateHeader() 171 172 def CheckHint(self): 173 if not self.sr.scroll.GetNodes(): 174 self.sr.scroll.ShowHint(localization.GetByLabel('UI/Fleet/NoFleet')) 175 else: 176 self.sr.scroll.ShowHint() 177 self.UpdateHeader() 178 179 def OnFleetWingAdded_Local(self, *args): 180 self.HandleFleetChanged() 181 182 def OnFleetWingDeleted_Local(self, *args): 183 self.HandleFleetChanged() 184 185 def OnFleetSquadAdded_Local(self, *args): 186 self.HandleFleetChanged() 187 188 def OnFleetSquadDeleted_Local(self, *args): 189 self.HandleFleetChanged() 190 191 def OnFleetSquadNameChanged_Local(self, squadID, name): 192 self.fleet['squads'][squadID]['name'] = name 193 headerNode = self.HeaderNodeFromGroupTypeAndID('squad', squadID) 194 if headerNode: 195 numMembers = len(sm.GetService('fleet').GetMembersInSquad(squadID)) 196 if numMembers == 0: 197 headerNode.label = localization.GetByLabel('UI/Fleet/FleetWindow/UnitHeaderEmpty', unitName=name) 198 else: 199 headerNode.groupInfo = localization.GetByLabel('UI/Fleet/FleetWindow/UnitHeaderWithCount', unitName=name, memberCount=numMembers) 200 if headerNode.panel: 201 headerNode.panel.Load(headerNode) 202 203 def OnFleetOptionsChanged_Local(self, oldOptions, newOptions): 204 oldSquadID = oldOptions.autoJoinSquadID 205 newSquadID = newOptions.autoJoinSquadID 206 if oldSquadID == newSquadID: 207 return 208 if not FleetSvc().IsCommanderOrBoss(): 209 return 210 oldHeaderNode = self.HeaderNodeFromGroupTypeAndID('squad', oldSquadID) 211 newHeaderNode = self.HeaderNodeFromGroupTypeAndID('squad', newSquadID) 212 for eachHeaderNode in (oldHeaderNode, newHeaderNode): 213 if eachHeaderNode and eachHeaderNode.panel: 214 eachHeaderNode.showAsAutoJoinSquad = eachHeaderNode.groupID == newSquadID 215 eachHeaderNode.panel.Load(eachHeaderNode) 216 217 def OnFleetWingNameChanged_Local(self, wingID, name): 218 self.fleet['wings'][wingID]['name'] = name 219 headerNode = self.HeaderNodeFromGroupTypeAndID('wing', wingID) 220 if headerNode: 221 numMembers = len(sm.GetService('fleet').GetMembersInWing(wingID)) 222 if numMembers == 0: 223 headerNode.groupInfo = localization.GetByLabel('UI/Fleet/FleetWindow/UnitHeaderEmpty', unitName=name) 224 else: 225 headerNode.groupInfo = localization.GetByLabel('UI/Fleet/FleetWindow/UnitHeaderWithCount', unitName=name, memberCount=numMembers) 226 if headerNode.panel: 227 headerNode.panel.Load(headerNode) 228 229 def OnFleetJoin_Local(self, rec): 230 if not self or self.destroyed: 231 return 232 if rec.charID == session.charid: 233 self.HandleFleetChanged() 234 else: 235 self.AddChar(rec) 236 237 def AddChar(self, rec): 238 if self.fleet is None: 239 return 240 self.members[rec.charID] = rec 241 FleetSvc().AddToFleet(self.fleet, rec) 242 if not FLEET_VIEW_FLAT_LIST_SETTING.is_enabled(): 243 self.HandleFleetChanged() 244 self.RefreshFromRec(rec) 245 246 def OnFleetLeave_Local(self, rec): 247 if rec.charID == session.charid: 248 return 249 self.RemoveChar(rec.charID) 250 if rec.role == evefleet.fleetRoleSquadCmdr: 251 self.FlashHeader('squad', rec.squadID) 252 elif rec.role == evefleet.fleetRoleWingCmdr: 253 self.FlashHeader('wing', rec.wingID) 254 elif rec.role == evefleet.fleetRoleLeader: 255 self.FlashHeader('fleet', session.fleetid) 256 257 def RemoveChar(self, charID): 258 rec = self.members.pop(charID, None) 259 if rec is None or self.fleet is None: 260 return 261 if None not in (rec.squadID, rec.wingID): 262 self.RemoveFromFleet(self.fleet, rec) 263 if FLEET_VIEW_FLAT_LIST_SETTING.is_enabled(): 264 self.RemoveCharFromScroll(charID) 265 else: 266 self.HandleFleetChanged() 267 self.RefreshFromRec(rec, removing=1) 268 269 def OnFleetMemberChanged_Local(self, charID, fleetID, oldWingID, oldSquadID, oldRole, oldJob, oldMemberOptOuts, newWingID, newSquadID, newRole, newJob, newMemberOptOuts): 270 rec = self.members[charID] 271 272 def UpdateRec(): 273 rec.changing = False 274 rec.role, rec.job = newRole, newJob 275 rec.wingID, rec.squadID = newWingID, newSquadID 276 rec.memberOptOuts = newMemberOptOuts 277 278 if (oldWingID, oldSquadID) != (newWingID, newSquadID): 279 if FLEET_VIEW_FLAT_LIST_SETTING.is_enabled(): 280 UpdateRec() 281 self.RefreshFromRec(rec) 282 else: 283 if evefleet.fleetRoleLeader in (oldRole, newRole): 284 self.HandleFleetChanged() 285 else: 286 self.RemoveChar(charID) 287 UpdateRec() 288 self.AddChar(rec) 289 self.UpdateHeader() 290 else: 291 UpdateRec() 292 if oldRole == evefleet.fleetRoleSquadCmdr != newRole: 293 self.fleet['squads'][rec.squadID]['commander'] = None 294 elif oldRole == evefleet.fleetRoleMember != newRole: 295 self.fleet['squads'][rec.squadID]['commander'] = rec.charID 296 self.RefreshFromRec(rec) 297 if oldRole == evefleet.fleetRoleSquadCmdr and (newRole != evefleet.fleetRoleSquadCmdr or newSquadID != oldSquadID): 298 self.FlashHeader('squad', oldSquadID) 299 elif oldRole == evefleet.fleetRoleWingCmdr and (newRole != evefleet.fleetRoleWingCmdr or newWingID != oldWingID): 300 self.FlashHeader('wing', oldWingID) 301 elif oldRole == evefleet.fleetRoleLeader != newRole: 302 self.FlashHeader('fleet', session.fleetid) 303 304 def FlashHeader(self, groupType, groupID): 305 uthread.new(self.FlashHeader_thread, groupType, groupID) 306 307 def FlashHeader_thread(self, groupType, groupID): 308 headerNode = self.HeaderNodeFromGroupTypeAndID(groupType, groupID) 309 if headerNode and headerNode.panel: 310 if hasattr(headerNode.panel, 'Flash'): 311 headerNode.panel.Flash() 312 313 def RemoveFromFleet(self, fleet, rec): 314 315 def Name(charID): 316 return charID and cfg.eveowners.Get(charID).name 317 318 def RemoveCommander(group, charID): 319 if group['commander'] == charID: 320 group['commander'] = None 321 else: 322 log.LogError('Commander is', Name(group['commander']), 'not', Name(charID)) 323 324 if rec.squadID != -1: 325 squad = fleet['squads'][rec.squadID] 326 if rec.role == evefleet.fleetRoleSquadCmdr: 327 RemoveCommander(squad, rec.charID) 328 try: 329 squad['members'].remove(rec.charID) 330 except ValueError: 331 log.LogError(Name(rec.charID), 'not in squad.') 332 333 elif rec.wingID != -1: 334 RemoveCommander(fleet['wings'][rec.wingID], rec.charID) 335 else: 336 RemoveCommander(fleet, rec.charID) 337 338 def RefreshFromRec(self, rec, removing = 0): 339 self.scrollToProportion = self.sr.scroll.GetScrollProportion() 340 if getattr(self, 'loading_RefreshFromRec', 0): 341 self.pending_RefreshFromRec.append(rec) 342 return 343 setattr(self, 'loading_RefreshFromRec', 1) 344 try: 345 if FLEET_VIEW_FLAT_LIST_SETTING.is_enabled(): 346 if not removing: 347 self.AddOrUpdateScrollEntry(rec.charID) 348 elif rec.wingID not in (None, -1): 349 self.RefreshRecMemberInWing(rec.wingID, rec.squadID) 350 else: 351 self.HandleFleetChanged() 352 self.UpdateHeader() 353 self.loading_RefreshFromRec = 0 354 if self.pending_RefreshFromRec: 355 recToRefresh = self.pending_RefreshFromRec.pop(0) 356 self.RefreshFromRec(recToRefresh) 357 finally: 358 self.sr.scroll.ScrollToProportion(self.scrollToProportion) 359 setattr(self, 'loading_RefreshFromRec', 0) 360 361 def RefreshRecMemberInWing(self, wingID, squadID): 362 inSquad = squadID not in (None, -1) 363 if inSquad: 364 loadingVariable = 'refreshing_squadMembers_wingID_%s' % wingID 365 pendingVariable = 'pendingRefresing_squadMembers_wingID_%s' % wingID 366 else: 367 loadingVariable = 'refreshing_non_squadMembers_wingID_%s' % wingID 368 pendingVariable = 'pending_non_refreshingWingID_%s' % wingID 369 if getattr(self, loadingVariable, False): 370 setattr(self, pendingVariable, True) 371 return 372 setattr(self, loadingVariable, True) 373 wingHeaderNode = self.HeaderNodeFromGroupTypeAndID('wing', wingID) 374 try: 375 if inSquad: 376 if wingHeaderNode: 377 self.ReloadScrollEntry(wingHeaderNode) 378 else: 379 fleetHeaderNode = self.HeaderNodeFromGroupTypeAndID('fleet', session.fleetid) 380 if fleetHeaderNode: 381 self.ReloadScrollEntry(fleetHeaderNode) 382 finally: 383 setattr(self, loadingVariable, False) 384 if getattr(self, pendingVariable, False): 385 setattr(self, pendingVariable, False) 386 self.RefreshRecMemberInWingCaller_thread(wingID, squadID) 387 388 def RefreshRecMemberInWingCaller_thread(self, wingID, squadID): 389 blue.pyos.synchro.SleepWallclock(0) 390 self.RefreshRecMemberInWing(wingID, squadID) 391 392 def ReloadScrollEntry(self, headerNode): 393 if headerNode: 394 scroll = getattr(headerNode, 'scroll', None) 395 if scroll: 396 scroll.PrepareSubContent(headerNode) 397 398 def HeaderNodeFromGroupTypeAndID(self, groupType, groupID): 399 for entry in self.sr.scroll.GetNodes(): 400 if entry.groupType == groupType and entry.groupID == groupID: 401 return entry 402 403 def HandleFleetChanged(self, *args): 404 uthread.pool('FleetView::HandleFleetChanged', self.DoHandleFleetChanged) 405 406 def DoHandleFleetChanged(self): 407 if not self or self.destroyed: 408 return 409 if getattr(self, 'loading_HandleFleetChanged', 0): 410 setattr(self, 'pending_HandleFleetChanged', 1) 411 return 412 setattr(self, 'loading_HandleFleetChanged', 1) 413 blue.pyos.synchro.SleepWallclock(1000) 414 setattr(self, 'pending_HandleFleetChanged', 0) 415 try: 416 try: 417 self.members = FleetSvc().GetMembers().copy() 418 if session.charid in self.members: 419 self.sr.scroll.Load(contentList=[]) 420 self.LoadFleet() 421 self.CheckHint() 422 setattr(self, 'loading_HandleFleetChanged', 0) 423 if getattr(self, 'pending_HandleFleetChanged', 0): 424 setattr(self, 'pending_HandleFleetChanged', 0) 425 self.HandleFleetChanged() 426 finally: 427 setattr(self, 'loading_HandleFleetChanged', 0) 428 429 except: 430 pass 431 432 def EmptyGroupEntry(self, label, indent, groupType, groupID): 433 return GetFromClass(EmptyGroup, {'label': label, 434 'indent': indent, 435 'groupType': groupType, 436 'groupID': groupID}) 437 438 def MakeCharEntry(self, charID, sublevel = 0, isLast = False): 439 data = self.GetMemberData(charID, sublevel=sublevel) 440 data.isLast = isLast 441 data.groupType = 'fleetMember' 442 return GetFromClass(FleetMember, data) 443 444 def MakeSquadEntry(self, squadID, sublevel = 0): 445 headerdata = self.GetHeaderData('squad', squadID, sublevel) 446 if headerdata.numMembers == 0: 447 return GetFromClass(EmptyGroup, {'squadID': squadID, 448 'groupType': 'squad', 449 'groupID': squadID, 450 'label': localization.GetByLabel('UI/Fleet/FleetWindow/UnitHeaderEmpty', unitName=SquadronName(self.fleet, squadID)), 451 'GetMenu': self.EmptySquadMenu, 452 'indent': 2, 453 'showAsAutoJoinSquad': headerdata.showAsAutoJoinSquad}) 454 else: 455 return GetFromClass(FleetHeader, headerdata) 456 457 def EmptySquadMenu(self, entry): 458 return GetSquadMenu(entry.sr.node.squadID) 459 460 def MakeWingEntry(self, wingID, sublevel = 0): 461 headerdata = self.GetHeaderData('wing', wingID, sublevel) 462 return GetFromClass(FleetHeader, headerdata) 463 464 def MakeFleetEntry(self): 465 headerdata = self.GetHeaderData('fleet', session.fleetid, 0) 466 return GetFromClass(FleetHeader, headerdata) 467 468 def AddToScroll(self, *entries): 469 self.sr.scroll.AddEntries(-1, entries) 470 471 def RemoveCharFromScroll(self, charID): 472 for entry in self.sr.scroll.GetNodes(): 473 if entry.charID == charID: 474 self.sr.scroll.RemoveEntries([entry]) 475 return 476 477 def LoadFleet(self): 478 fleetMembers = {} 479 for charID, member in self.members.iteritems(): 480 if None not in (member.squadID, member.wingID): 481 fleetMembers[charID] = member 482 if charID == session.charid: 483 self.myGroups['squad'] = member.squadID 484 self.myGroups['wing'] = member.wingID 485 486 self.fleet = FleetSvc().GetFleetHierarchy(fleetMembers) 487 if FLEET_VIEW_FLAT_LIST_SETTING.is_enabled(): 488 scrollList = [] 489 for charID in self.members.keys(): 490 entry = self.MakeCharEntry(charID, sublevel=1, isLast=True) 491 scrollList.append((cfg.eveowners.Get(charID).name.lower(), entry)) 492 493 scrollList = SortListOfTuples(scrollList) 494 self.sr.scroll.Load(contentList=scrollList) 495 else: 496 self.AddToScroll(self.MakeFleetEntry()) 497 self.sr.scroll.ScrollToProportion(self.scrollToProportion) 498 499 def GetMemberData(self, charID, slimItem = None, member = None, sublevel = 0): 500 if slimItem is None: 501 slimItem = SlimItemFromCharID(charID) 502 data = KeyVal() 503 data.charRec = cfg.eveowners.Get(charID) 504 data.itemID = data.id = data.charID = charID 505 data.typeID = data.charRec.typeID 506 data.squadID = None 507 data.wingID = None 508 data.displayName = data.charRec.name 509 data.roleIcons = [] 510 member = member or self.members.get(charID) 511 if member: 512 data.squadID = member.squadID 513 data.wingID = member.wingID 514 data.role = member.role 515 if member.job & evefleet.fleetJobCreator: 516 data.roleIcons.append({'id': '73_20', 517 'hint': localization.GetByLabel('UI/Fleet/Ranks/Boss')}) 518 if member.role == evefleet.fleetRoleLeader: 519 data.roleIcons.append({'id': '73_17', 520 'hint': localization.GetByLabel('UI/Fleet/Ranks/FleetCommander')}) 521 elif member.role == evefleet.fleetRoleWingCmdr: 522 data.roleIcons.append({'id': '73_18', 523 'hint': localization.GetByLabel('UI/Fleet/Ranks/WingCommander')}) 524 elif member.role == evefleet.fleetRoleSquadCmdr: 525 data.roleIcons.append({'id': '73_19', 526 'hint': localization.GetByLabel('UI/Fleet/Ranks/SquadCommander')}) 527 if False in (member.memberOptOuts.acceptsFleetWarp, member.memberOptOuts.acceptsConduitJumps, member.memberOptOuts.acceptsFleetRegroups): 528 hintList = [] 529 if not member.memberOptOuts.acceptsFleetWarp: 530 hintList.append(localization.GetByLabel('UI/Fleet/FleetWindow/DoesNotTakeFleetWarp')) 531 if not member.memberOptOuts.acceptsConduitJumps: 532 hintList.append(localization.GetByLabel('UI/Fleet/FleetWindow/DoesNotAcceptConduitJumps')) 533 if not member.memberOptOuts.acceptsFleetRegroups: 534 hintList.append(localization.GetByLabel('UI/Fleet/FleetWindow/DoesNotAcceptFleetRegroup')) 535 hint = '<br>'.join(hintList) 536 data.roleIcons.append({'id': '73_47', 537 'hint': hint}) 538 data.label = data.displayName 539 data.isSub = 0 540 data.sort_name = data.displayName 541 data.sublevel = sublevel 542 data.member = member 543 if slimItem: 544 data.slimItem = weakref.ref(slimItem) 545 else: 546 data.slimItem = None 547 data.changing = getattr(member, 'changing', False) 548 return data 549 550 def GetHeaderData(self, gtype, gid, sublevel): 551 data = KeyVal() 552 data.id = ('fleet', '%s_%s' % (gtype, gid)) 553 data.groupType = gtype 554 data.groupID = gid 555 data.rawText = '' 556 data.displayName = data.label = '' 557 data.sublevel = sublevel 558 data.expanded = True 559 data.showicon = 'hide' 560 data.hideFill = True 561 data.hideTopLine = True 562 data.hideExpanderLine = True 563 data.showlen = False 564 data.BlockOpenWindow = 1 565 data.labelstyle = {'uppercase': True, 566 'fontsize': 9, 567 'letterspacing': 2} 568 data.myGroups = self.myGroups 569 group = self.GetGroup(gtype, gid) 570 data.commanderName = CommanderName(group) % {'alpha': 119} 571 data.commanderData = None 572 fleetSvc = sm.GetService('fleet') 573 if gtype == 'squad': 574 data.GetSubContent = self.SquadContentGetter(gid, sublevel) 575 num = len(fleetSvc.GetMembersInSquad(gid)) 576 if num == 0: 577 data.groupInfo = localization.GetByLabel('UI/Fleet/FleetWindow/UnitHeaderEmpty', unitName=SquadronName(self.fleet, gid)) 578 else: 579 data.groupInfo = localization.GetByLabel('UI/Fleet/FleetWindow/UnitHeaderWithCount', unitName=SquadronName(self.fleet, gid), memberCount=num) 580 if fleetSvc.options.autoJoinSquadID == gid and FleetSvc().IsCommanderOrBoss(): 581 data.showAsAutoJoinSquad = True 582 else: 583 data.showAsAutoJoinSquad = False 584 elif gtype == 'wing': 585 data.GetSubContent = self.WingContentGetter(gid, sublevel) 586 num = len(fleetSvc.GetMembersInWing(gid)) 587 data.groupInfo = localization.GetByLabel('UI/Fleet/FleetWindow/UnitHeaderWithCount', unitName=WingName(self.fleet, gid), memberCount=num) 588 elif gtype == 'fleet': 589 data.GetSubContent = self.FleetContentGetter(gid, sublevel) 590 num = len(self.members) 591 data.groupInfo = localization.GetByLabel('UI/Fleet/FleetWindow/UnitHeaderWithCount', unitName=localization.GetByLabel('UI/Fleet/Fleet'), memberCount=num) 592 data.scroll = self.sr.scroll 593 else: 594 raise NotImplementedError 595 data.numMembers = num 596 if group['commander']: 597 commanderData = self.GetMemberData(group['commander']) 598 data.commanderData = commanderData 599 data.openByDefault = data.open = True 600 return data 601 602 def AddOrUpdateScrollEntry(self, charID): 603 newEntry = self.MakeCharEntry(charID) 604 newEntry.sublevel = 1 605 newEntry.isLast = 1 606 for i, data in enumerate(self.sr.scroll.GetNodes()): 607 if data.Get('id', None) == charID: 608 newEntry.panel = data.Get('panel', None) 609 scroll = data.Get('scroll', None) 610 if scroll is not None: 611 newEntry.scroll = scroll 612 newEntry.idx = i 613 self.sr.scroll.GetNodes()[i] = newEntry 614 if newEntry.panel is not None: 615 newEntry.panel.Load(newEntry) 616 return 617 618 self.sr.scroll.AddEntries(-1, [newEntry]) 619 self.sr.scroll.Sort(by='name') 620 621 def SquadContentGetter(self, squadID, sublevel): 622 623 def GetContent(*blah): 624 squad = self.fleet['squads'][squadID] 625 ret = [] 626 if squad['members']: 627 sortedMembers = SortListOfTuples([ ((charID != squad['commander'], self.members[charID].job != evefleet.fleetJobCreator, cfg.eveowners.Get(charID).name.lower()), charID) for charID in squad['members'] ]) 628 if squad['commander'] is not None: 629 sortedMembers.remove(squad['commander']) 630 for i in range(len(sortedMembers)): 631 charID = sortedMembers[i] 632 ret.append(self.MakeCharEntry(charID, sublevel=sublevel + 1, isLast=i == len(sortedMembers) - 1)) 633 634 if not ret: 635 emptyGroupEntry = self.EmptyGroupEntry(localization.GetByLabel('UI/Fleet/FleetWindow/SquadEmpty'), sublevel + 1, 'squad', squadID) 636 ret = [emptyGroupEntry] 637 return ret 638 639 return GetContent 640 641 def WingContentGetter(self, wingID, sublevel): 642 643 def GetContent(*blah): 644 wing = self.fleet['wings'][wingID] 645 ret = [] 646 squads = wing['squads'][:] 647 squads.sort() 648 for squadID in squads: 649 ret.append(self.MakeSquadEntry(squadID, sublevel + 1)) 650 651 if not ret: 652 emptyGroupEntery = self.EmptyGroupEntry(localization.GetByLabel('UI/Fleet/FleetWindow/WingEmpty'), sublevel + 1, 'wing', wingID) 653 ret = [emptyGroupEntery] 654 return ret 655 656 return GetContent 657 658 def FleetContentGetter(self, fleetID, sublevel): 659 660 def GetContent(*blah): 661 ret = [] 662 wings = self.fleet['wings'].keys() 663 wings.sort() 664 for wingID in wings: 665 ret.append(self.MakeWingEntry(wingID, sublevel + 1)) 666 667 return ret 668 669 return GetContent 670 671 def GetGroup(self, groupType, groupID): 672 if groupType == 'fleet': 673 return self.fleet 674 if groupType == 'wing': 675 return self.fleet['wings'][groupID] 676 if groupType == 'squad': 677 return self.fleet['squads'][groupID] 678 raise NotImplementedError 679 680 def GetMemberEntry(self, charID): 681 for entry in self.sr.scroll.GetNodes(): 682 if entry.charID == charID: 683 return entry 684 685 def OnExpanded(self, wnd, *args): 686 pass 687 688 def OnDropData(self, dragObject, droppedGuys, *args): 689 if not sm.GetService('fleet').IsCommanderOrBoss(): 690 return 691 sm.GetService('fleet').DropOnFleetCommander(droppedGuys, CAN_ONLY_BE_MEMBER) 692 693 694 class FleetHeader(Group): 695 __guid__ = 'listentry.FleetHeader' 696 isDragObject = True 697 698 def Startup(self, *args, **kw): 699 Group.Startup(self, *args, **kw) 700 text_gaugepar = Container(name='text_gaugepar', parent=self, idx=0, align=uiconst.TOALL, pos=(0, 0, 0, 0)) 701 text_gaugepar.width = 0 702 self.sr.text_gaugepar = text_gaugepar 703 self.sr.label.parent.width = 0 704 self.sr.label.parent.SetParent(text_gaugepar) 705 Container(name='toppush', parent=self.sr.label.parent, align=uiconst.TOTOP, height=14) 706 roleIconsContainer = Container(name='roleIconsContainer', parent=self.sr.label.parent, width=0, align=uiconst.TORIGHT) 707 self.roleIconsContainer = roleIconsContainer 708 self.sr.topLabel = eveLabel.EveLabelMedium(text='', parent=self.sr.label.parent, left=0, top=0, state=uiconst.UI_DISABLED, color=None, idx=0) 709 self.sr.bottomLabel = eveLabel.EveLabelMedium(text='', parent=self.sr.label.parent, left=0, top=12, state=uiconst.UI_DISABLED, color=None, idx=0) 710 changing = AnimSprite(icons=[ 'ui_38_16_%s' % (210 + i) for i in xrange(8) ], align=uiconst.TOPRIGHT, parent=self, pos=(0, 13, 16, 16)) 711 self.sr.changing = changing 712 changing.state = uiconst.UI_NORMAL 713 self.sr.myGroupSelection = Fill(name='myGroupSelection', bgParent=self, padding=(0, 1, 0, 1), color=(0.0, 0.5, 0.0, 0.1)) 714 self.sr.myGroupSelection.display = False 715 self.movingHilite = Fill(bgParent=self, name='movingHilite', color=(1, 0, 0, 0.25)) 716 self.movingHilite.display = False 717 718 def Load(self, node, *args, **kw): 719 sublevel = node.Get('sublevel', 0) 720 if node.groupType != 'fleet': 721 node.hasArrow = True 722 Group.Load(self, node, *args, **kw) 723 self.sr.label.left += 2 724 self.sr.topLabel.left = self.sr.label.left 725 self.sr.bottomLabel.left = self.sr.label.left 726 if node.commanderData and node.commanderData.itemID == session.charid: 727 self.sr.myGroupSelection.display = True 728 else: 729 isMyGroup = node.myGroups.get(node.groupType, None) == node.groupID or node.groupType == 'fleet' 730 if isMyGroup: 731 self.sr.expander.icon.ignoreColorBlindMode = False 732 self.sr.expander.SetRGBA(0.0, 0.5, 0.0, 0.8) 733 label = self.GetTopLabelText(node) 734 self.sr.topLabel.text = label 735 self.sr.bottomLabel.top = max(12, self.sr.topLabel.top + self.sr.topLabel.textheight) 736 bottomLabelText = self.GetBottomLabelText(node) 737 self.sr.bottomLabel.text = bottomLabelText 738 icons = getattr(node.commanderData, 'roleIcons', []) 739 UpdateRoleIcons(self.roleIconsContainer, icons) 740 if node.commanderData and node.commanderData.changing: 741 self.sr.changing.state = uiconst.UI_DISABLED 742 self.hint = localization.GetByLabel('UI/Fleet/FleetWindow/MemberChanging') 743 self.sr.changing.Play() 744 else: 745 self.hint = None 746 self.sr.changing.Stop() 747 self.sr.changing.state = uiconst.UI_HIDDEN 748 autoJoinIcon = getattr(self, 'autoJoinIcon', None) 749 if node.showAsAutoJoinSquad: 750 left = self.sr.topLabel.left + self.sr.topLabel.textwidth + 4 751 if autoJoinIcon is None or autoJoinIcon.destroyed: 752 self.autoJoinIcon = Sprite(parent=self, texturePath='res:/UI/Texture/classes/fleet/defaultSquad.png', hint=localization.GetByLabel('UI/Fleet/FleetWindow/DefaultSquadHint'), align=uiconst.TOPLEFT, pos=(left, 753 0, 754 16, 755 16)) 756 self.autoJoinIcon.display = True 757 self.autoJoinIcon.left = left 758 elif autoJoinIcon: 759 autoJoinIcon.display = False 760 761 def OnDropData(self, dragObject, droppedGuys, *args): 762 try: 763 sm.GetService('fleet').OnDropCommanderDropData(dragObject, droppedGuys, self.sr.node) 764 finally: 765 self.movingHilite.display = False 766 767 def OnDragEnter(self, dragObj, nodes): 768 draggedGuy = nodes[0] 769 if hasattr(draggedGuy, 'charID'): 770 if self.sr.node.commanderData and self.sr.node.commanderData.itemID == draggedGuy.charID: 771 return 772 groupType = self.sr.node.groupType 773 groupID = self.sr.node.groupID 774 isMultiMove = len(nodes) > 1 775 canMove = sm.GetService('fleet').CanMoveToThisEntry(draggedGuy, self.sr.node, groupType, groupID=groupID, isMultiMove=isMultiMove) 776 if canMove == CONNOT_BE_MOVED_INCOMPATIBLE: 777 return 778 if canMove == CANNOT_BE_MOVED: 779 self.movingHilite.SetRGBA(*COLOR_CANNOT_BE_MOVED) 780 elif canMove == CAN_BE_COMMANDER: 781 self.movingHilite.SetRGBA(*COLOR_CAN_BE_COMMANDER) 782 else: 783 self.movingHilite.SetRGBA(*COLOR_CAN_ONLY_BE_MEMBER) 784 self.movingHilite.display = True 785 786 def OnDragExit(self, dragObj, nodes): 787 self.movingHilite.display = False 788 789 def GetHeight(self, *args): 790 node, width = args 791 topLabelHeight = uix.GetTextHeight('<b>' + node.groupInfo + '</b>', maxLines=1) 792 bottomLabelHeight = uix.GetTextHeight(node.commanderName, maxLines=1) 793 node.height = max(12, topLabelHeight) + bottomLabelHeight + 2 794 return node.height 795 796 def ToggleAllSquads(self, node, isOpen = True): 797 toggleThread = uthread.new(self.ToggleAllSquads_thread, node, isOpen) 798 toggleThread.context = 'FleetHeader::ToggleAllSquads' 799 800 def ToggleAllSquads_thread(self, node, isOpen = True): 801 if isOpen: 802 self.DoToggleFleetHeader(node, isOpen, groupType='fleet') 803 self.DoToggleFleetHeader(node, isOpen, groupType='wing') 804 self.DoToggleFleetHeader(node, isOpen, groupType='squad') 805 806 def ToggleAllWings(self, node, isOpen = True): 807 toggleThread = uthread.new(self.ToggleAllWings_thread, node, isOpen) 808 toggleThread.context = 'FleetHeader::ToggleAllWings' 809 810 def ToggleAllWings_thread(self, node, isOpen = True): 811 if isOpen: 812 self.DoToggleFleetHeader(node, isOpen, groupType='fleet') 813 self.DoToggleFleetHeader(node, isOpen, groupType='wing') 814 815 def DoToggleFleetHeader(self, node, isOpen, groupType): 816 scroll = node.scroll 817 for entry in scroll.GetNodes(): 818 if entry.__guid__ != 'listentry.FleetHeader': 819 continue 820 if entry.groupType == groupType: 821 if entry.panel: 822 self.ShowOpenState(isOpen) 823 self.UpdateLabel() 824 uicore.registry.SetListGroupOpenState(entry.id, isOpen) 825 scroll.PrepareSubContent(entry) 826 else: 827 uicore.registry.SetListGroupOpenState(entry.id, isOpen) 828 entry.scroll.PrepareSubContent(entry) 829 830 def OnMouseDown(self, *args): 831 commanderData = self.sr.node.commanderData 832 if commanderData is None: 833 return 834 GetMenuService().TryExpandActionMenu(itemID=commanderData.charID, clickedObject=self, radialMenuClass=RadialMenuSpaceCharacter) 835 836 def GetMenu(self): 837 m = MenuList() 838 commanderData = self.sr.node.commanderData 839 if commanderData: 840 m += GetMenuService().FleetMenu(commanderData.charID, unparsed=False) 841 m += [None] 842 m.append(MenuEntryData(MenuLabel('UI/Common/Pilot', {'character': commanderData.charID}), subMenuData=lambda : self._GetPilotSubMenuData(commanderData.charID), texturePath=eveicon.person)) 843 m += [None] 844 if self.sr.node.groupType == 'squad': 845 return m + GetSquadMenu(self.sr.node.groupID) 846 if self.sr.node.groupType == 'wing': 847 return m + self.GetWingMenu(self.sr.node.groupID) 848 if self.sr.node.groupType == 'fleet': 849 m += self.GetFleetMenu() 850 m += [None] 851 m += [(MenuLabel('UI/Fleet/FleetWindow/OpenAllWings'), self.ToggleAllWings, (self.sr.node, True)), 852 (MenuLabel('UI/Fleet/FleetWindow/CloseAllWings'), self.ToggleAllWings, (self.sr.node, False)), 853 (MenuLabel('UI/Fleet/FleetWindow/OpenAllSquads'), self.ToggleAllSquads, (self.sr.node, True)), 854 (MenuLabel('UI/Fleet/FleetWindow/CloseAllSquads'), self.ToggleAllSquads, (self.sr.node, False))] 855 return m 856 raise NotImplementedError 857 858 def _GetPilotSubMenuData(self, charID): 859 subMenuData = GetMenuService().CharacterMenu(charID) 860 return MenuList(subMenuData).filter(['UI/Fleet/Fleet', 'UI/Commands/ShowInfo']) 861 862 def GetFleetMenu(self): 863 ret = MenuList() 864 if session.fleetrole != evefleet.fleetRoleLeader: 865 ret += [(MenuLabel('UI/Fleet/LeaveMyFleet'), FleetSvc().LeaveFleet)] 866 if FleetSvc().IsBoss() or session.fleetrole == evefleet.fleetRoleLeader: 867 ret.extend([None, (MenuLabel('UI/Fleet/FleetWindow/CreateNewWing'), lambda : FleetSvc().CreateWing())]) 868 else: 869 ret.append(None) 870 if session.fleetrole in evefleet.fleetCmdrRoles: 871 ret.append((MenuLabel('UI/Fleet/FleetWindow/Regroup'), lambda : FleetSvc().Regroup())) 872 if FleetSvc().HasActiveBeacon(session.charid): 873 ret.append((MenuLabel('UI/Fleet/FleetBroadcast/Commands/JumpBeacon'), lambda : FleetSvc().SendBroadcast_JumpBeacon())) 874 ret.append((MenuLabel('UI/Fleet/FleetBroadcast/Commands/Location'), lambda : FleetSvc().SendBroadcast_Location())) 875 return ret 876 877 def GetWingMenu(self, wingID): 878 if FleetSvc().IsBoss() or session.fleetrole in (evefleet.fleetRoleLeader, evefleet.fleetRoleWingCmdr): 879 return MenuList([(MenuLabel('UI/Fleet/FleetWindow/DeleteWing'), lambda : sm.GetService('fleet').DeleteWing(wingID)), (MenuLabel('UI/Fleet/FleetWindow/ChangeName'), lambda : sm.GetService('fleet').ChangeWingName(wingID)), (MenuLabel('UI/Fleet/FleetWindow/CreateNewSquad'), lambda : sm.GetService('fleet').CreateSquad(wingID))]) 880 else: 881 return MenuList() 882 883 def Flash(self): 884 sm.GetService('ui').BlinkSpriteA(self.sr.topLabel, 1.0, 400, 8, passColor=0) 885 sm.GetService('ui').BlinkSpriteA(self.sr.bottomLabel, 1.0, 400, 8, passColor=0) 886 887 def GetDragData(self, *args): 888 commanderData = self.sr.node.commanderData 889 if commanderData: 890 info = cfg.eveowners.Get(commanderData.charID) 891 fakeNode = self.sr.node 892 fakeNode.info = info 893 fakeNode.charID = commanderData.charID 894 fakeNode.itemID = commanderData.charID 895 return [fakeNode] 896 else: 897 return [] 898 899 @classmethod 900 def GetTopLabelText(cls, node, *args): 901 label = localization.GetByLabel('UI/Fleet/FleetWindow/UnitHeader', unitTitle=node.groupInfo) 902 if node.numMembers == 0: 903 label = '<color=0x88ffffff>%s</color>' % label 904 return label 905 906 @classmethod 907 def GetBottomLabelText(cls, node, *args): 908 label = node.commanderName 909 return label 910 911 @classmethod 912 def GetCopyData(cls, node): 913 sublevel = node.Get('sublevel', 0) 914 indent = ' ' * sublevel * 4 915 topLabel = cls.GetTopLabelText(node) 916 bottomLabel = cls.GetBottomLabelText(node) 917 text = indent + '-' + topLabel + '\n ' + indent + bottomLabel 918 return text 919 920 921 def UpdateRoleIcons(parent, icons): 922 parent.Flush() 923 left = 0 924 if icons is not None and len(icons): 925 parent.width = len(icons) * 20 926 for icon in icons: 927 iconpath = icon['id'] 928 eveIcon.Icon(icon=iconpath, parent=parent, pos=(left, 929 0, 930 16, 931 16), align=uiconst.TOPLEFT, hint=icon['hint']) 932 left += 20 933 934 935 def FleetSvc(): 936 return sm.GetService('fleet') 937 938 939 def GetFleetMenu(): 940 ret = MenuList([(localization.GetByLabel('UI/Fleet/LeaveMyFleet'), FleetSvc().LeaveFleet)]) 941 if FleetSvc().IsBoss() or session.fleetrole == evefleet.fleetRoleLeader: 942 ret.extend([None, (localization.GetByLabel('UI/Fleet/FleetWindow/Regroup'), lambda : FleetSvc().Regroup())]) 943 else: 944 ret.append(None) 945 if FleetSvc().HasActiveBeacon(session.charid): 946 ret.append((localization.GetByLabel('UI/Fleet/FleetBroadcast/Commands/JumpBeacon'), lambda : FleetSvc().SendBroadcast_JumpBeacon())) 947 ret.append((localization.GetByLabel('UI/Fleet/FleetBroadcast/Commands/Location'), lambda : FleetSvc().SendBroadcast_Location())) 948 return ret 949 950 951 class EmptyGroup(Generic): 952 __guid__ = 'listentry.EmptyGroup' 953 954 def Load(self, data): 955 Generic.Load(self, data) 956 self.sr.label.left = 20 + 16 * data.indent 957 self.sr.label.opacity = 0.7 958 self.sr.label.Update() 959 self.movingHilite = Fill(bgParent=self, name='movingHilite', color=(1, 0, 0, 0.25)) 960 self.movingHilite.display = False 961 autoJoinIcon = getattr(self, 'autoJoinIcon', None) 962 if data.showAsAutoJoinSquad: 963 left = self.sr.label.left + self.sr.label.textwidth + 4 964 if autoJoinIcon is None or autoJoinIcon.destroyed: 965 self.autoJoinIcon = Sprite(parent=self, texturePath='res:/UI/Texture/classes/fleet/defaultSquad.png', hint=localization.GetByLabel('UI/Fleet/FleetWindow/DefaultSquadHint'), align=uiconst.CENTERLEFT, pos=(left, 966 0, 967 16, 968 16)) 969 self.autoJoinIcon.display = True 970 self.autoJoinIcon.left = left 971 elif autoJoinIcon: 972 autoJoinIcon.display = False 973 974 def OnDropData(self, dragObject, droppedGuys, *args): 975 try: 976 sm.GetService('fleet').OnDropCommanderDropData(dragObject, droppedGuys, self.sr.node) 977 finally: 978 self.movingHilite.display = False 979 980 def OnDragEnter(self, dragObj, nodes): 981 draggedGuy = nodes[0] 982 groupType = self.sr.node.groupType 983 groupID = self.sr.node.groupID 984 isMultiMove = len(nodes) > 1 985 canMove = sm.GetService('fleet').CanMoveToThisEntry(draggedGuy, self.sr.node, groupType, groupID=groupID, isMultiMove=isMultiMove) 986 if canMove == CONNOT_BE_MOVED_INCOMPATIBLE: 987 return 988 if canMove == CANNOT_BE_MOVED: 989 self.movingHilite.SetRGBA(*COLOR_CANNOT_BE_MOVED) 990 elif canMove == CAN_BE_COMMANDER: 991 self.movingHilite.SetRGBA(*COLOR_CAN_BE_COMMANDER) 992 else: 993 self.movingHilite.SetRGBA(*COLOR_CAN_ONLY_BE_MEMBER) 994 self.movingHilite.display = True 995 996 def OnDragExit(self, dragObj, nodes): 997 self.movingHilite.display = False 998 999 @classmethod 1000 def GetCopyData(cls, node): 1001 sublevel = node.Get('isSub', 0) 1002 indent = ' ' * sublevel * 4 1003 return indent + node.label 1004 1005 1006 class FleetMember(BaseTacticalEntry): 1007 __guid__ = 'listentry.FleetMember' 1008 isDragObject = True 1009 1010 def Startup(self, *args, **kw): 1011 BaseTacticalEntry.Startup(self, *args, **kw) 1012 idx = self.sr.label.parent.children.index(self.sr.label) 1013 text_gaugepar = Container(name='text_gaugepar', parent=self, idx=idx, align=uiconst.TOALL, pos=(0, 0, 0, 0)) 1014 text_gaugepar.width = 0 1015 textpar = Container(name='textpar', parent=text_gaugepar, idx=idx, align=uiconst.TOALL, pos=(0, 0, 0, 0), clipChildren=True) 1016 self.sr.text_gaugepar = text_gaugepar 1017 self.children.remove(self.sr.label) 1018 textpar.children.append(self.sr.label) 1019 Container(name='toppush', parent=textpar, align=uiconst.TOTOP, height=2) 1020 roleIconsContainer = Container(name='roleIconsContainer', parent=textpar, width=0, align=uiconst.TORIGHT) 1021 self.roleIconsContainer = roleIconsContainer 1022 changing = AnimSprite(icons=[ 'ui_38_16_%s' % (210 + i) for i in xrange(8) ], align=uiconst.TOPRIGHT, parent=self, pos=(0, 0, 16, 16)) 1023 self.sr.changing = changing 1024 changing.state = uiconst.UI_HIDDEN 1025 self.sr.myGroupSelection = Fill(name='myGroupSelection', bgParent=self, padding=(0, 1, 0, 1), color=(0.0, 0.5, 0.0, 0.15)) 1026 self.sr.myGroupSelection.display = False 1027 self.movingHilite = Fill(bgParent=self, name='movingHilite', color=(1, 0, 0, 0.25)) 1028 self.movingHilite.display = False 1029 1030 def Load(self, node): 1031 Generic.Load(self, node) 1032 data = node 1033 if settings.user.ui.Get('flatFleetView', False): 1034 left = 0 1035 else: 1036 left = 20 1037 if node.itemID == session.charid: 1038 self.sr.myGroupSelection.display = True 1039 indent = left + node.sublevel * 16 1040 self.sr.label.left = indent 1041 selected, = sm.GetService('stateSvc').GetStates(data.itemID, [state.selected]) 1042 if selected: 1043 self.Select() 1044 icons = node.Get('roleIcons', None) 1045 UpdateRoleIcons(self.roleIconsContainer, icons) 1046 if node.changing: 1047 self.sr.changing.state = uiconst.UI_DISABLED 1048 self.hint = localization.GetByLabel('UI/Fleet/FleetWindow/MemberChanging') 1049 self.sr.changing.Play() 1050 else: 1051 self.hint = None 1052 self.sr.changing.Stop() 1053 self.sr.changing.state = uiconst.UI_HIDDEN 1054 self.sr.label.Update() 1055 1056 def GetHeight(_self, *args): 1057 node, width = args 1058 node.height = uix.GetTextHeight(node.label, maxLines=1) + 4 1059 return node.height 1060 1061 def GetDragData(self, *args): 1062 selectedNodes = self.sr.node.scroll.GetSelectedNodes(self.sr.node) 1063 for eachNode in selectedNodes: 1064 info = cfg.eveowners.Get(eachNode.itemID) 1065 eachNode.info = info 1066 1067 return selectedNodes 1068 1069 def OnDropData(self, dragObject, droppedGuys, *args): 1070 if FLEET_VIEW_FLAT_LIST_SETTING.is_enabled(): 1071 self.movingHilite.display = False 1072 return 1073 try: 1074 sm.GetService('fleet').OnDropCommanderDropData(dragObject, droppedGuys, self.sr.node) 1075 finally: 1076 self.movingHilite.display = False 1077 1078 def OnDragEnter(self, dragObj, nodes): 1079 draggedGuy = nodes[0] 1080 if hasattr(draggedGuy, 'charID'): 1081 if self.sr.node.itemID == draggedGuy.charID: 1082 return 1083 isMultiMove = len(nodes) > 1 1084 canMove = sm.GetService('fleet').CanMoveToThisEntry(draggedGuy, self.sr.node, 'fleetMember', groupID=None, isMultiMove=isMultiMove) 1085 if canMove == CONNOT_BE_MOVED_INCOMPATIBLE: 1086 return 1087 if canMove == CANNOT_BE_MOVED: 1088 self.movingHilite.SetRGBA(*COLOR_CANNOT_BE_MOVED) 1089 else: 1090 self.movingHilite.SetRGBA(*COLOR_CAN_ONLY_BE_MEMBER) 1091 self.movingHilite.display = True 1092 1093 def OnDragExit(self, dragObj, nodes): 1094 self.movingHilite.display = False 1095 1096 def GetMenu(self): 1097 return GetFleetMemberMenuOptions(self.sr.node.charID) 1098 1099 def OnMouseDown(self, *args): 1100 GetMenuService().TryExpandActionMenu(itemID=self.sr.node.charID, clickedObject=self, radialMenuClass=RadialMenuSpaceCharacter) 1101 1102 @classmethod 1103 def GetCopyData(cls, node): 1104 sublevel = node.Get('isSub', 0) 1105 indent = ' ' * sublevel * 4 1106 return indent + node.label 1107 1108 GetMenu = ParanoidDecoMethod(GetMenu, ('sr', 'node')) 1109 1110 1111 class FleetAction(Action): 1112 1113 def ApplyAttributes(self, attributes): 1114 super(FleetAction, self).ApplyAttributes(attributes) 1115 self.broadcastID = attributes.broadcastID 1116 texturePath = attributes.texturePath 1117 self.func = attributes.func 1118 self.sr.icon = self.icon = GlowSprite(texturePath=texturePath, parent=self, align=uiconst.CENTER, pos=(1, 0, 16, 16), state=uiconst.UI_DISABLED) 1119 self.sr.fill = Fill(parent=self, state=uiconst.UI_HIDDEN, width=self.width, height=self.height, align=uiconst.RELATIVE, color=(1, 1, 1, 0.5)) 1120 1121 def Prepare_(self, icon = None): 1122 pass 1123 1124 def OnMouseMove(self, *args): 1125 pass 1126 1127 def OnClick(self, *args): 1128 self.func() 1129 1130 def LoadTooltipPanel(self, tooltipPanel, *args): 1131 if not self.broadcastID: 1132 return 1133 cmdName = 'CmdFleetBroadcast_%s' % self.broadcastID 1134 cmd = uicore.cmd.commandMap.GetCommandByName(cmdName) 1135 shortcutStr = cmd.GetShortcutAsString() 1136 tooltipPanel.LoadGeneric3ColumnTemplate() 1137 tooltipPanel.AddLabelMedium(text=self.hint, cellPadding=(0, 0, 7, 0), colSpan=tooltipPanel.columns - 1, width=200, autoFitToText=True) 1138 if shortcutStr: 1139 tooltipPanel.AddShortcutCell(shortcutStr) 1140 else: 1141 tooltipPanel.AddCell() 1142 1143 1144 class FleetRoleCont(Container): 1145 __guid__ = 'xtriui.FleetRoleCont' 1146 __notifyevents__ = ['OnMyFleetInfoChanged', 'OnSessionChanged'] 1147 __dependencies__ = ['fleet'] 1148 default_height = 16 1149 default_name = 'fleetRoleCont' 1150 1151 def ApplyAttributes(self, attributes): 1152 Container.ApplyAttributes(self, attributes) 1153 sm.RegisterNotify(self) 1154 self.buttons = {} 1155 self.roleIconsContainer = Container(name='roleIconsContainer', parent=self, align=uiconst.TOLEFT) 1156 self.UpdateRoleIcons() 1157 1158 def UpdateRoleIcons(self): 1159 info = sm.GetService('fleet').GetMemberInfo(session.charid) 1160 if info is None: 1161 return 1162 icons = [] 1163 if info.role == evefleet.fleetRoleLeader: 1164 icons.append({'id': 'ui_73_16_17', 1165 'hint': localization.GetByLabel('UI/Fleet/Ranks/FleetCommander')}) 1166 elif info.role == evefleet.fleetRoleWingCmdr: 1167 icons.append({'id': 'ui_73_16_18', 1168 'hint': localization.GetByLabel('UI/Fleet/Ranks/WingCommander')}) 1169 elif info.role == evefleet.fleetRoleSquadCmdr: 1170 icons.append({'id': 'ui_73_16_19', 1171 'hint': localization.GetByLabel('UI/Fleet/Ranks/SquadCommander')}) 1172 if info.job & evefleet.fleetJobCreator: 1173 icons.append({'id': 'ui_73_16_20', 1174 'hint': localization.GetByLabel('UI/Fleet/Ranks/Boss')}) 1175 self.display = bool(icons) 1176 UpdateRoleIcons(self.roleIconsContainer, icons) 1177 1178 def OnMyFleetInfoChanged(self): 1179 self.UpdateRoleIcons() 1180 1181 def OnSessionChanged(self, isRemote, sess, change): 1182 if not self.destroyed: 1183 self.UpdateRoleIcons() 1184 1185 1186 def GetAllFleetActivities(): 1187 return {k:localization.GetByLabel(v) for k, v in fleetActivityNames.iteritems()} 1188 1189 1190 def GetFleetActivityName(activityID): 1191 if activityID not in fleetActivityNames: 1192 activityID = ACTIVITY_MISC 1193 labelPath = fleetActivityNames.get(activityID, 'UI/Agency/Fleetup/UnknownActivity') 1194 return localization.GetByLabel(labelPath)