diff --git a/eos b/eos index fc317f1ba..dda4794b2 160000 --- a/eos +++ b/eos @@ -1 +1 @@ -Subproject commit fc317f1ba6ba9528bd14f9135ff5bc616c6e1243 +Subproject commit dda4794b2ee5422c64e3560bee62f781027c6433 diff --git a/gui/additionsPane.py b/gui/additionsPane.py index 0c186b200..eaacc647e 100644 --- a/gui/additionsPane.py +++ b/gui/additionsPane.py @@ -52,7 +52,7 @@ class AdditionsPane(TogglePanel): self.notebook.AddPage(DroneView(self.notebook), "Drones") self.notebook.AddPage(ImplantView(self.notebook), "Implants") self.notebook.AddPage(BoosterView(self.notebook), "Boosters") -# self.notebook.AddPage(ProjectedView(self.notebook), "Projected") + self.notebook.AddPage(ProjectedView(self.notebook), "Projected") # self.Expand() diff --git a/gui/builtinContextMenus/__init__.py b/gui/builtinContextMenus/__init__.py index f1396d4cd..b26d02851 100644 --- a/gui/builtinContextMenus/__init__.py +++ b/gui/builtinContextMenus/__init__.py @@ -1,2 +1,2 @@ __all__ = ["moduleAmmoPicker", "itemStats", "damagePattern", "marketJump", "droneSplit", - "ammoPattern"] + "ammoPattern", "project"] diff --git a/gui/builtinContextMenus/ammoPattern.py b/gui/builtinContextMenus/ammoPattern.py index fae1477fc..8693e2c21 100644 --- a/gui/builtinContextMenus/ammoPattern.py +++ b/gui/builtinContextMenus/ammoPattern.py @@ -16,9 +16,6 @@ class AmmoPattern(ContextMenu): return False item = selection[0] - if context == "itemSearch": - item = service.Market.getInstance().getItem(item.ID) - for attr in ("emDamage", "thermalDamage", "explosiveDamage", "kineticDamage"): if item.getAttribute(attr) is not None: return True @@ -30,9 +27,6 @@ class AmmoPattern(ContextMenu): def activate(self, context, selection, i): item = selection[0] - if context == "itemSearch": - item = service.Market.getInstance().getItem(item.ID) - fit = self.mainFrame.getActiveFit() sFit = service.Fit.getInstance() sFit.setAsPattern(fit, item) diff --git a/gui/builtinContextMenus/droneSplit.py b/gui/builtinContextMenus/droneSplit.py index 0ae722f50..7e6e360e0 100644 --- a/gui/builtinContextMenus/droneSplit.py +++ b/gui/builtinContextMenus/droneSplit.py @@ -10,13 +10,13 @@ class DroneSplit(ContextMenu): self.mainFrame = gui.mainFrame.MainFrame.getInstance() def display(self, context, selection): - return context in ("drone") and selection[0].amount > 1 + return context in ("drone", "projectedDrone") and selection[0].amount > 1 def getText(self, context, selection): return "Split stack" def activate(self, context, selection, i): - dlg = DroneSpinner(self.mainFrame, selection[0]) + dlg = DroneSpinner(self.mainFrame, selection[0], context) dlg.ShowModal() dlg.Destroy() @@ -25,9 +25,10 @@ DroneSplit.register() class DroneSpinner(wx.Dialog): - def __init__(self, parent, drone): + def __init__(self, parent, drone, context): wx.Dialog.__init__(self, parent, title="Select Amount", size=wx.Size(220, 60)) self.drone = drone + self.context = context bSizer1 = wx.BoxSizer(wx.HORIZONTAL) @@ -49,6 +50,9 @@ class DroneSpinner(wx.Dialog): sFit = service.Fit.getInstance() mainFrame = gui.mainFrame.MainFrame.getInstance() fitID = mainFrame.getActiveFit() - sFit.splitDroneStack(fitID, self.drone, self.spinner.GetValue()) + if self.context == "drone": + sFit.splitDroneStack(fitID, self.drone, self.spinner.GetValue()) + else: + sFit.splitProjectedDroneStack(fitID, self.drone, self.spinner.GetValue()) wx.PostEvent(mainFrame, gui.fittingView.FitChanged(fitID=fitID)) event.Skip() diff --git a/gui/builtinViewColumns/__init__.py b/gui/builtinViewColumns/__init__.py index 091d61743..a38c54ec2 100644 --- a/gui/builtinViewColumns/__init__.py +++ b/gui/builtinViewColumns/__init__.py @@ -1,3 +1,4 @@ __all__ = ["moduleState", "moduleNameOrSlot", "attributeDisplay", "maxRange", "name", "droneDps", "droneNameAmount", "droneCheckbox", "moduleAmmo", - "capacitorUse", "activityCheckbox", "moduleAmmoIcon", "modulePrice"] + "capacitorUse", "activityCheckbox", "moduleAmmoIcon", "modulePrice", + "projectedName", "projectedState"] diff --git a/gui/marketBrowser.py b/gui/marketBrowser.py index 5a3eba276..1e6d620ce 100644 --- a/gui/marketBrowser.py +++ b/gui/marketBrowser.py @@ -158,9 +158,6 @@ class MarketTree(wx.TreeCtrl): def jump(self, item): cMarket = service.Market.getInstance() - # Refetch items, else it'll try to reuse the object fetched in the other thread - # Which makes it go BOOM CRACK DOOM - item = cMarket.getItem(item.ID) mg = item.marketGroup if mg is None and item.metaGroup is not None: mg = item.metaGroup.parent.marketGroup @@ -311,7 +308,15 @@ class ItemView(d.Display): if sel == -1: return - menu = ContextMenu.getMenu((self.active[sel],), "item" if self.searching is False else "itemSearch") + item = self.active[sel] + # We were searching, this means that our results come from the worker thread + # Refetch items, else it'll try to reuse the object fetched in the other thread + # Which makes it go BOOM CRACK DOOM + if self.searching: + sMarket = service.Market.getInstance() + item = sMarket.getItem(item.ID) + + menu = ContextMenu.getMenu((item,), "item" if self.searching is False else "itemSearch") self.PopupMenu(menu) def itemSort(self, item): diff --git a/gui/projectedView.py b/gui/projectedView.py index 70e800bb0..8ce2bdf57 100644 --- a/gui/projectedView.py +++ b/gui/projectedView.py @@ -18,8 +18,90 @@ #=============================================================================== import wx +import gui.display as d +import gui.fittingView as fv +import service +import gui.droneView +from gui.builtinViewColumns.projectedState import ProjectedState +from gui.contextMenu import ContextMenu + +class ProjectedView(d.Display): + DEFAULT_COLS = ["Projected State", + "Projected Name"] -class ProjectedView(wx.Panel): def __init__(self, parent): - wx.Panel.__init__(self, parent) - self.SetBackgroundColour('green') + d.Display.__init__(self, parent) + self.mainFrame.Bind(fv.FIT_CHANGED, self.fitChanged) + self.Bind(wx.EVT_LEFT_DOWN, self.click) + self.Bind(wx.EVT_RIGHT_DOWN, self.click) + self.Bind(wx.EVT_LEFT_DCLICK, self.remove) + self.droneView = gui.droneView.DroneView + + def moduleSort(self, module): + return module.item.name + + def droneSort(self, drone): + item = drone.item + if item.marketGroup is None: + item = item.metaGroup.parent + + return (self.droneView.DRONE_ORDER.index(item.marketGroup.name), + drone.item.name) + + def fitSort(self, fit): + return fit.name + + def fitChanged(self, event): + cFit = service.Fit.getInstance() + fit = cFit.getFit(event.fitID) + stuff = [] + if fit is not None: + self.modules = fit.projectedModules[:] + self.drones = fit.projectedDrones[:] + self.fits = fit.projectedFits[:] + + self.modules.sort(key=self.moduleSort) + self.drones.sort(key=self.droneSort) + self.fits.sort(key=self.fitSort) + + stuff.extend(self.modules) + stuff.extend(self.drones) + stuff.extend(self.fits) + + self.update(stuff) + + def get(self, row): + numMods = len(self.modules) + numDrones = len(self.drones) + if row < numMods: + stuff = self.modules[row] + elif row - numMods < numDrones: + stuff = self.drones[row - numMods] + else: + stuff = self.fits[row - numMods - numDrones] + + return stuff + + def click(self, event): + event.Skip() + row, _ = self.HitTest(event.Position) + if row != -1: + col = self.getColumn(event.Position) + if col == self.getColIndex(ProjectedState): + fitID = self.mainFrame.getActiveFit() + cFit = service.Fit.getInstance() + cFit.toggleProjected(fitID, self.get(row), "right" if event.Button == 3 else "left") + wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID)) + elif event.Button == 3: + menu = ContextMenu.getMenu((self.get(row),), "projectedDrone") + self.PopupMenu(menu) + + def remove(self, event): + row, _ = self.HitTest(event.Position) + if row != -1: + col = self.getColumn(event.Position) + if col != self.getColIndex(ProjectedState): + fitID = self.mainFrame.getActiveFit() + cFit = service.Fit.getInstance() + cFit.removeProjected(fitID, self.get(row)) + wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID)) diff --git a/service/fit.py b/service/fit.py index e912ab9ee..82eb990eb 100644 --- a/service/fit.py +++ b/service/fit.py @@ -160,6 +160,50 @@ class Fit(object): fit.calculateModifiedAttributes() return True + def project(self, fitID, thing): + fit = eos.db.getFit(fitID) + if isinstance(thing, eos.types.Fit): + fit.projectedFits.append(thing) + elif thing.category.name == "Drone": + d = fit.projectedDrones.find(thing) + if d is None or d.amountActive == d.amount or d.amount >= 5: + d = eos.types.Drone(thing) + fit.projectedDrones.append(d) + + d.amount += 1 + else: + fit.projectedModules.append(eos.types.Module(thing)) + + eos.db.commit() + fit.clear() + fit.calculateModifiedAttributes() + + def toggleProjected(self, fitID, thing, click): + fit = eos.db.getFit(fitID) + if isinstance(thing, eos.types.Drone): + if thing.amount == thing.amountActive: + thing.amountActive = 0 + else: + thing.amountActive = thing.amount + elif isinstance(thing, eos.types.Module): + thing.state = self.__getProposedState(thing, click) + + eos.db.commit() + fit.clear() + fit.calculateModifiedAttributes() + + def removeProjected(self, fitID, thing): + fit = eos.db.getFit(fitID) + if isinstance(thing, eos.types.Drone): + fit.projectedDrones.remove(thing) + elif isinstance(thing, eos.types.Module): + fit.projectedModules.remove(thing) + else: + fit.projectedFits.remove(thing) + + eos.db.commit() + fit.clear() + fit.calculateModifiedAttributes() def appendModule(self, fitID, itemID): fit = eos.db.getFit(fitID) @@ -229,12 +273,7 @@ class Fit(object): else: return False - def splitDroneStack(self, fitID, d, amount): - if fitID == None: - return False - - fit = eos.db.getFit(fitID) - + def splitDrones(self, fit, d, amount, l): total = d.amount active = d.amountActive > 0 d.amount = amount @@ -243,9 +282,23 @@ class Fit(object): newD = eos.types.Drone(d.item) newD.amount = total - amount newD.amountActive = newD.amount if active else 0 - fit.drones.append(newD) + l.append(newD) eos.db.commit() + def splitProjectedDroneStack(self, fitID, d, amount): + if fitID == None: + return False + + fit = eos.db.getFit(fitID) + self.splitDrones(fit, d, amount, fit.projectedDrones) + + def splitDroneStack(self, fitID, d, amount): + if fitID == None: + return False + + fit = eos.db.getFit(fitID) + self.splitDrones(fit, d, amount, fit.drones) + def removeDrone(self, fitID, i): fit = eos.db.getFit(fitID) d = fit.drones[i]