From 2f90ac64ec1dc5856fc9e06bd8843775a409fda1 Mon Sep 17 00:00:00 2001 From: blitzmann Date: Mon, 24 Mar 2014 19:04:11 -0400 Subject: [PATCH] Refactor how rack separation works --- eos/saveddata/module.py | 16 +++++++ eos/types.py | 2 +- gui/builtinViewColumns/baseIcon.py | 4 +- gui/builtinViewColumns/baseName.py | 5 ++- gui/builtinViewColumns/state.py | 4 +- gui/builtinViews/fittingView.py | 70 +++++++++++------------------- 6 files changed, 53 insertions(+), 48 deletions(-) diff --git a/eos/saveddata/module.py b/eos/saveddata/module.py index c25d11ca5..b17fdcd37 100755 --- a/eos/saveddata/module.py +++ b/eos/saveddata/module.py @@ -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 \ No newline at end of file diff --git a/eos/types.py b/eos/types.py index 0b0e791da..544f075d3 100755 --- a/eos/types.py +++ b/eos/types.py @@ -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 diff --git a/gui/builtinViewColumns/baseIcon.py b/gui/builtinViewColumns/baseIcon.py index ddc5fe615..9c9862ae5 100644 --- a/gui/builtinViewColumns/baseIcon.py +++ b/gui/builtinViewColumns/baseIcon.py @@ -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") diff --git a/gui/builtinViewColumns/baseName.py b/gui/builtinViewColumns/baseName.py index 2effecbf2..65d3c4d14 100644 --- a/gui/builtinViewColumns/baseName.py +++ b/gui/builtinViewColumns/baseName.py @@ -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() diff --git a/gui/builtinViewColumns/state.py b/gui/builtinViewColumns/state.py index fb4ae7360..a88757a1b 100644 --- a/gui/builtinViewColumns/state.py +++ b/gui/builtinViewColumns/state.py @@ -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 diff --git a/gui/builtinViews/fittingView.py b/gui/builtinViews/fittingView.py index 62291ad2c..7229badd2 100644 --- a/gui/builtinViews/fittingView.py +++ b/gui/builtinViews/fittingView.py @@ -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)