Refactor how rack separation works
This commit is contained in:
@@ -122,6 +122,19 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
|
||||
return empty
|
||||
|
||||
@classmethod
|
||||
def buildDummy(cls, slot):
|
||||
empty = DummyModule(None)
|
||||
empty.__slot = slot
|
||||
empty.__hardpoint = Hardpoint.NONE
|
||||
empty.__item = 0
|
||||
empty.__charge = 0
|
||||
empty.dummySlot = slot
|
||||
empty.__itemModifiedAttributes = ModifiedAttributeDict()
|
||||
empty.__chargeModifiedAttributes = ModifiedAttributeDict()
|
||||
|
||||
return empty
|
||||
|
||||
@property
|
||||
def isEmpty(self):
|
||||
return self.dummySlot is not None
|
||||
@@ -622,3 +635,6 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
copy.charge = self.charge
|
||||
copy.state = self.state
|
||||
return copy
|
||||
|
||||
class DummyModule(Module):
|
||||
pass
|
||||
@@ -23,7 +23,7 @@ from eos.saveddata.price import Price
|
||||
from eos.saveddata.user import User
|
||||
from eos.saveddata.damagePattern import DamagePattern
|
||||
from eos.saveddata.character import Character, Skill
|
||||
from eos.saveddata.module import Module, State, Slot, Hardpoint
|
||||
from eos.saveddata.module import Module, State, Slot, Hardpoint, DummyModule
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.implant import Implant
|
||||
from eos.saveddata.booster import SideEffect
|
||||
|
||||
@@ -2,7 +2,7 @@ from gui import builtinViewColumns
|
||||
from gui.viewColumn import ViewColumn
|
||||
from gui import bitmapLoader
|
||||
import wx
|
||||
from eos.types import Drone, Fit, Module, Slot
|
||||
from eos.types import Drone, Fit, Module, Slot, DummyModule
|
||||
|
||||
class BaseIcon(ViewColumn):
|
||||
name = "Base Icon"
|
||||
@@ -19,6 +19,8 @@ class BaseIcon(ViewColumn):
|
||||
return -1
|
||||
if isinstance(stuff, Fit):
|
||||
return self.shipImage
|
||||
if isinstance(stuff, DummyModule):
|
||||
return -1
|
||||
if isinstance(stuff, Module):
|
||||
if stuff.isEmpty:
|
||||
return self.fittingView.imageList.GetImageIndex("slot_%s_small" % Slot.getName(stuff.slot).lower(), "icons")
|
||||
|
||||
@@ -21,7 +21,7 @@ from gui import builtinViewColumns
|
||||
from gui.viewColumn import ViewColumn
|
||||
from gui import bitmapLoader
|
||||
import wx
|
||||
from eos.types import Drone, Fit, Module, Slot
|
||||
from eos.types import Drone, Fit, Module, Slot, DummyModule
|
||||
|
||||
class BaseName(ViewColumn):
|
||||
name = "Base Name"
|
||||
@@ -36,6 +36,9 @@ class BaseName(ViewColumn):
|
||||
return "%dx %s" % (stuff.amount, stuff.item.name)
|
||||
elif isinstance(stuff, Fit):
|
||||
return "%s (%s)" % (stuff.name, stuff.ship.item.name)
|
||||
elif isinstance(stuff, DummyModule):
|
||||
return ""
|
||||
#return "%s Rack" % Slot.getName(stuff.slot).capitalize()
|
||||
elif isinstance(stuff, Module):
|
||||
if stuff.isEmpty:
|
||||
return "%s Slot" % Slot.getName(stuff.slot).capitalize()
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
from gui.viewColumn import ViewColumn
|
||||
from gui import bitmapLoader
|
||||
import wx
|
||||
from eos.types import Drone, Module
|
||||
from eos.types import Drone, Module, DummyModule
|
||||
from eos.types import State as State_
|
||||
|
||||
class State(ViewColumn):
|
||||
@@ -47,6 +47,8 @@ class State(ViewColumn):
|
||||
def getImageId(self, stuff):
|
||||
if isinstance(stuff, Drone):
|
||||
return self.checkedId if stuff.amountActive > 0 else self.uncheckedId
|
||||
elif isinstance(stuff, DummyModule):
|
||||
return -1
|
||||
elif isinstance(stuff, Module):
|
||||
if stuff.isEmpty:
|
||||
return -1
|
||||
|
||||
@@ -26,7 +26,7 @@ import gui.display as d
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.shipBrowser
|
||||
import gui.multiSwitch
|
||||
from eos.types import Slot
|
||||
from eos.types import Slot, DummyModule
|
||||
from gui.builtinViewColumns.state import State
|
||||
from gui import bitmapLoader
|
||||
import gui.builtinViews.emptyView
|
||||
@@ -147,7 +147,6 @@ class FittingView(d.Display):
|
||||
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
|
||||
self.parent.Bind(gui.chromeTabs.EVT_NOTEBOOK_PAGE_CHANGED, self.pageChanged)
|
||||
|
||||
|
||||
def OnLeaveWindow(self, event):
|
||||
self.SetToolTip(None)
|
||||
self.hoveredRow = None
|
||||
@@ -299,7 +298,6 @@ class FittingView(d.Display):
|
||||
def removeItem(self, event):
|
||||
row, _ = self.HitTest(event.Position)
|
||||
if row != -1 and row not in self.blanks:
|
||||
row = self.modMapping[row]
|
||||
col = self.getColumn(event.Position)
|
||||
if col != self.getColIndex(State):
|
||||
self.removeModule(self.mods[row])
|
||||
@@ -356,6 +354,13 @@ class FittingView(d.Display):
|
||||
self.refresh(self.mods)
|
||||
|
||||
def generateMods(self):
|
||||
'''
|
||||
Generate module list.
|
||||
|
||||
This also injects dummy modules to visually separate racks. These modules are only
|
||||
known to the display, and not the backend, so it's safe.
|
||||
'''
|
||||
|
||||
cFit = service.Fit.getInstance()
|
||||
fit = cFit.getFit(self.activeFitID)
|
||||
|
||||
@@ -364,6 +369,20 @@ class FittingView(d.Display):
|
||||
if fit is not None:
|
||||
self.mods = fit.modules[:]
|
||||
self.mods.sort(key=lambda mod: (slotOrder.index(mod.slot), mod.position))
|
||||
|
||||
# set up blanks
|
||||
slotDivider = self.mods[0].slot # flag to know when to add blank (default: don't add blank for first "slot group")
|
||||
self.blanks = [] # preliminary markers where blanks will be inserted
|
||||
if cFit.serviceFittingOptions["divideSlots"]:
|
||||
for i, mod in enumerate(self.mods):
|
||||
if mod.slot != slotDivider:
|
||||
slotDivider = mod.slot
|
||||
self.blanks.append(i)
|
||||
|
||||
for i, x in enumerate(self.blanks):
|
||||
self.blanks[i] = x+i # modify blanks
|
||||
self.mods.insert(x+i, DummyModule.buildDummy(slotOrder.index(i+1)))
|
||||
|
||||
else:
|
||||
self.mods = None
|
||||
|
||||
@@ -375,6 +394,9 @@ class FittingView(d.Display):
|
||||
try:
|
||||
if self.activeFitID is not None and self.activeFitID == event.fitID:
|
||||
self.generateMods()
|
||||
if self.GetItemCount() != len(self.mods):
|
||||
# This only happens when turning on/off slot divisions
|
||||
self.populate(self.mods)
|
||||
self.refresh(self.mods)
|
||||
|
||||
exportHtml.getInstance().refreshFittingHTMl()
|
||||
@@ -385,8 +407,6 @@ class FittingView(d.Display):
|
||||
finally:
|
||||
event.Skip()
|
||||
|
||||
|
||||
|
||||
def scheduleMenu(self, event):
|
||||
event.Skip()
|
||||
if self.getColumn(event.Position) != self.getColIndex(State):
|
||||
@@ -473,18 +493,8 @@ class FittingView(d.Display):
|
||||
Displays fitting
|
||||
|
||||
Sends data to d.Display.refresh where the rows and columns are set up, then does a
|
||||
bit of post-processing (colors, dividers)
|
||||
|
||||
Module mapping is done here if slot dividers is enabled in preferences. Since we add
|
||||
dividers to the GUI, we can no longer assume that display list index 3 = module index
|
||||
3, so we must create an external-internal mapping
|
||||
bit of post-processing (colors)
|
||||
'''
|
||||
# helps to prevent not showing blanks before showing them
|
||||
self.Freeze()
|
||||
|
||||
# see github:blitzmann/pyfa#12 @todo: look into this more, and document
|
||||
self.populate(stuff)
|
||||
|
||||
d.Display.refresh(self, stuff)
|
||||
|
||||
sFit = service.Fit.getInstance()
|
||||
@@ -495,14 +505,7 @@ class FittingView(d.Display):
|
||||
slot = Slot.getValue(slotType)
|
||||
slotMap[slot] = fit.getSlotsFree(slot) < 0
|
||||
|
||||
# set up blanks
|
||||
slotDivider = self.mods[0].slot # flag to know when to add blank (default: don't add blank for first "slot group")
|
||||
self.blanks = [] # preliminary markers where blanks will be inserted
|
||||
|
||||
for i, mod in enumerate(self.mods):
|
||||
if mod.slot != slotDivider:
|
||||
slotDivider = mod.slot
|
||||
self.blanks.append(i)
|
||||
if slotMap[mod.slot]:
|
||||
self.SetItemBackgroundColour(i, wx.Colour(204, 51, 51))
|
||||
elif sFit.serviceFittingOptions["colorFitBySlot"]:
|
||||
@@ -510,27 +513,6 @@ class FittingView(d.Display):
|
||||
else:
|
||||
self.SetItemBackgroundColour(i, self.GetBackgroundColour())
|
||||
|
||||
# Get list of internal indexes, which is simply range of number of current items
|
||||
internal = range(self.GetItemCount())
|
||||
self.modMapping = {}
|
||||
|
||||
if sFit.serviceFittingOptions["divideSlots"]:
|
||||
# Insert blank row at correct index
|
||||
for i, x in enumerate(self.blanks):
|
||||
self.blanks[i] = x+i # modify blanks
|
||||
self.InsertStringItem( x+i, '' ) # @todo: make it actually display something
|
||||
|
||||
# Create map
|
||||
for i in range(self.GetItemCount()):
|
||||
if i in self.blanks:
|
||||
continue
|
||||
self.modMapping[i] = internal.pop(0)
|
||||
else:
|
||||
# if not dividing by slots, mapping is 1:1 with internal
|
||||
self.modMapping = internal
|
||||
|
||||
self.Thaw()
|
||||
|
||||
self.itemCount = self.GetItemCount()
|
||||
self.itemRect = self.GetItemRect(0)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user