From 96b756fa9d785b2bf22d9a2513cf202134564a38 Mon Sep 17 00:00:00 2001 From: cncfanatics Date: Thu, 21 Oct 2010 07:08:47 +0200 Subject: [PATCH 1/6] Add support for toggling implants on and off --- gui/builtinViewColumns/__init__.py | 2 +- gui/builtinViewColumns/implantCheckbox.py | 47 +++++++++++++++++++++++ gui/implantView.py | 18 ++++++++- service/fit.py | 10 +++++ 4 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 gui/builtinViewColumns/implantCheckbox.py diff --git a/gui/builtinViewColumns/__init__.py b/gui/builtinViewColumns/__init__.py index 7b869c9ac..0ed5e8293 100644 --- a/gui/builtinViewColumns/__init__.py +++ b/gui/builtinViewColumns/__init__.py @@ -1,3 +1,3 @@ __all__ = ["moduleState", "moduleNameOrSlot", "attributeDisplay", "maxRange", "name", "droneDps", "droneNameAmount", "droneCheckbox", "moduleAmmo", - "capacitorUse"] + "capacitorUse", "implantCheckbox"] diff --git a/gui/builtinViewColumns/implantCheckbox.py b/gui/builtinViewColumns/implantCheckbox.py new file mode 100644 index 000000000..55848969f --- /dev/null +++ b/gui/builtinViewColumns/implantCheckbox.py @@ -0,0 +1,47 @@ +#=============================================================================== +# Copyright (C) 2010 Diego Duclos +# +# This file is part of pyfa. +# +# pyfa is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# pyfa is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with pyfa. If not, see . +#=============================================================================== + +from gui import builtinViewColumns +from gui.viewColumn import ViewColumn +import gui.mainFrame +import wx + +class ImplantCheckbox(ViewColumn): + name = "Implant Checkbox" + def __init__(self, fittingView, params): + ViewColumn.__init__(self, fittingView) + self.resizable = False + self.size = 24 + for name, state in (("checked", wx.CONTROL_CHECKED), ("unchecked", 0)): + bitmap = wx.EmptyBitmap(16, 16) + dc = wx.MemoryDC() + dc.SelectObject(bitmap) + dc.SetBackground(wx.TheBrushList.FindOrCreateBrush(fittingView.GetBackgroundColour(), wx.SOLID)) + dc.Clear() + wx.RendererNative.Get().DrawCheckBox(fittingView, dc, wx.Rect(0, 0, 16, 16), state) + dc.Destroy() + setattr(self, "%sId" % name, fittingView.imageList.Add(bitmap)) + + def getText(self, mod): + return "" + + def getImageId(self, implant): + return self.checkedId if implant.active else self.uncheckedId + +ImplantCheckbox.register() diff --git a/gui/implantView.py b/gui/implantView.py index 42c1bd2cd..8aa095f71 100644 --- a/gui/implantView.py +++ b/gui/implantView.py @@ -22,9 +22,11 @@ import service import gui.display as d import gui.fittingView as fv import gui.marketBrowser as mb +from gui.builtinViewColumns.implantCheckbox import ImplantCheckbox class ImplantView(d.Display): - DEFAULT_COLS = ["Name", + DEFAULT_COLS = ["Implant Checkbox", + "Name", "attr:implantness"] def __init__(self, parent): @@ -33,6 +35,7 @@ class ImplantView(d.Display): self.mainFrame.Bind(mb.ITEM_SELECTED, self.addItem) self.Bind(wx.EVT_LEFT_DCLICK, self.removeItem) self.Bind(wx.EVT_KEY_UP, self.kbEvent) + self.Bind(wx.EVT_LEFT_DOWN, self.click) def kbEvent(self,event): keycode = event.GetKeyCode() @@ -44,6 +47,7 @@ class ImplantView(d.Display): cFit.removeImplant(fitID, self.GetItemData(row)) row = self.GetNextSelected(row) wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID)) + def fitChanged(self, event): cFit = service.Fit.getInstance() fit = cFit.getFit(event.fitID) @@ -68,4 +72,14 @@ class ImplantView(d.Display): fitID = self.mainFrame.getActiveFit() cFit = service.Fit.getInstance() cFit.removeImplant(fitID, self.GetItemData(row)) - wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID)) \ No newline at end of file + wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID)) + + def click(self, event): + row, _ = self.HitTest(event.Position) + if row != -1: + col = self.getColumn(event.Position) + if col == self.getColIndex(ImplantCheckbox): + fitID = self.mainFrame.getActiveFit() + cFit = service.Fit.getInstance() + cFit.toggleImplant(fitID, row) + wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID)) diff --git a/service/fit.py b/service/fit.py index d2874b27b..0fd3e41cd 100644 --- a/service/fit.py +++ b/service/fit.py @@ -234,6 +234,16 @@ class Fit(object): fit.calculateModifiedAttributes() return True + def toggleImplant(self, fitID, i): + fit = eos.db.getFit(fitID) + implant = fit.implants[i] + implant.active = not implant.active + + eos.db.commit() + fit.clear() + fit.calculateModifiedAttributes() + return True + def changeChar(self, fitID, charID): if fitID is None or charID is None: return From 68c352a44c42ca13509a8a191e483f9f5de953e5 Mon Sep 17 00:00:00 2001 From: cncfanatics Date: Thu, 21 Oct 2010 07:24:53 +0200 Subject: [PATCH 2/6] Add a jump to market group context menu entry --- gui/builtinContextMenus/__init__.py | 2 +- gui/builtinContextMenus/marketJump.py | 19 +++++++++++++++++++ gui/marketBrowser.py | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 gui/builtinContextMenus/marketJump.py diff --git a/gui/builtinContextMenus/__init__.py b/gui/builtinContextMenus/__init__.py index d0bbe4881..c2b1386a3 100644 --- a/gui/builtinContextMenus/__init__.py +++ b/gui/builtinContextMenus/__init__.py @@ -1 +1 @@ -__all__ = ["moduleAmmoPicker", "itemStats", "damagePattern"] +__all__ = ["moduleAmmoPicker", "itemStats", "damagePattern", "marketJump"] diff --git a/gui/builtinContextMenus/marketJump.py b/gui/builtinContextMenus/marketJump.py new file mode 100644 index 000000000..889107475 --- /dev/null +++ b/gui/builtinContextMenus/marketJump.py @@ -0,0 +1,19 @@ +from gui.contextMenu import ContextMenu +from gui.itemStats import ItemStatsDialog +import gui.mainFrame +import service + +class MarketJump(ContextMenu): + def __init__(self): + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + + def display(self, context, selection): + return context in ("module", "ammo", "itemSearch") + + def getText(self, context, selection): + return "Jump to %s Market Group" % (context.capitalize() if context != "itemSearch" else "Item") + + def activate(self, context, selection, i): + self.mainFrame.marketBrowser.jump(selection[0]) + +MarketJump.register() diff --git a/gui/marketBrowser.py b/gui/marketBrowser.py index 1cf31b04a..3f77d8d80 100644 --- a/gui/marketBrowser.py +++ b/gui/marketBrowser.py @@ -129,6 +129,25 @@ class MarketBrowser(wx.Panel): self.mainFrame = gui.mainFrame.MainFrame.getInstance() + def jump(self, item): + mg = item.marketGroup + jumpList = [] + while mg is not None: + jumpList.append(mg.ID) + mg = mg.parent + + item = self.marketRoot + for i in range(len(jumpList) -1, -1, -1): + target = jumpList[i] + child, cookie = self.marketView.GetFirstChild(item) + while self.marketView.GetItemPyData(child) != target: + child, cookie = self.marketView.GetNextChild(child, cookie) + + item = child + self.marketView.Expand(item) + + self.marketView.SelectItem(item) + def addMarketViewImage(self, iconFile): if iconFile is None: return -1 From 1e75f09e0bf767552fa585624da37fdec8ae93dc Mon Sep 17 00:00:00 2001 From: cncfanatics Date: Thu, 21 Oct 2010 07:34:23 +0200 Subject: [PATCH 3/6] Switch to the relevant additions pane when items are added to it --- gui/additionsPane.py | 4 +++- gui/boosterView.py | 1 + gui/droneView.py | 1 + gui/implantView.py | 1 + 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/gui/additionsPane.py b/gui/additionsPane.py index 79f0becae..0c186b200 100644 --- a/gui/additionsPane.py +++ b/gui/additionsPane.py @@ -49,7 +49,6 @@ class AdditionsPane(TogglePanel): size.SetHeight(200) self.notebook.SetMinSize(size) baseSizer.Add(self.notebook, 1, wx.EXPAND) - self.notebook.AddPage(DroneView(self.notebook), "Drones") self.notebook.AddPage(ImplantView(self.notebook), "Implants") self.notebook.AddPage(BoosterView(self.notebook), "Boosters") @@ -57,3 +56,6 @@ class AdditionsPane(TogglePanel): # self.Expand() + PANES = ["Drones", "Implants", "Boosters"] + def select(self, name): + self.notebook.SetSelection(self.PANES.index(name)) diff --git a/gui/boosterView.py b/gui/boosterView.py index 51e318acf..8461d7246 100644 --- a/gui/boosterView.py +++ b/gui/boosterView.py @@ -48,6 +48,7 @@ class BoosterView(d.Display): trigger = cFit.addBooster(fitID, event.itemID) if trigger: wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID)) + self.mainFrame.additionsPane.select("Boosters") event.Skip() diff --git a/gui/droneView.py b/gui/droneView.py index 73748d0e6..47f3893ae 100644 --- a/gui/droneView.py +++ b/gui/droneView.py @@ -55,6 +55,7 @@ class DroneView(d.Display): trigger = cFit.addDrone(fitID, event.itemID) if trigger: wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID)) + self.mainFrame.additionsPane.select("Drones") event.Skip() diff --git a/gui/implantView.py b/gui/implantView.py index 8aa095f71..6b061de21 100644 --- a/gui/implantView.py +++ b/gui/implantView.py @@ -63,6 +63,7 @@ class ImplantView(d.Display): trigger = cFit.addImplant(fitID, event.itemID) if trigger: wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID)) + self.mainFrame.additionsPane.select("Implants") event.Skip() From e447bca32e377d0e1b048e47f1fd99d9478720de Mon Sep 17 00:00:00 2001 From: cncfanatics Date: Thu, 21 Oct 2010 10:20:49 +0200 Subject: [PATCH 4/6] Sort ammo by their range + falloff on the turret they're getting fit on --- gui/builtinContextMenus/moduleAmmoPicker.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/gui/builtinContextMenus/moduleAmmoPicker.py b/gui/builtinContextMenus/moduleAmmoPicker.py index 6265abf52..0ae3b7aa7 100644 --- a/gui/builtinContextMenus/moduleAmmoPicker.py +++ b/gui/builtinContextMenus/moduleAmmoPicker.py @@ -24,7 +24,7 @@ class ModuleAmmoPicker(ContextMenu): validCharges = currCharges self.charges = list(validCharges) - self.hardpoint = mod.hardpoint + self.module = mod return len(self.charges) > 0 def getText(self, context, selection): @@ -34,23 +34,15 @@ class ModuleAmmoPicker(ContextMenu): pass def turretSorter(self, charge): - s = [] damage = 0 - range = charge.getAttribute("weaponRangeMultiplier") - falloff = charge.getAttribute("fallofMultiplier") or 1 - types = [] + range = self.module.getModifiedItemAttr("maxRange") * charge.getAttribute("weaponRangeMultiplier") + falloff = self.module.getModifiedItemAttr("falloff") * (charge.getAttribute("fallofMultiplier") or 1) for type in ("em", "explosive", "kinetic", "thermal"): d = charge.getAttribute("%sDamage" % type) if d > 0: - types.append(type) damage += d - s.append(-range) - s.append(-falloff) - s.append(charge.name.rsplit()[-2:]) - s.append(damage) - s.append(charge.name) - return s + return (-range - falloff, charge.name.rsplit()[-2:], damage, charge.name) MISSILE_ORDER = ["em", "thermal", "kinetic", "explosive"] def missileSorter(self, charge): @@ -86,7 +78,8 @@ class ModuleAmmoPicker(ContextMenu): m = wx.Menu() m.Bind(wx.EVT_MENU, self.handleAmmoSwitch) self.chargeIds = {} - if self.hardpoint == Hardpoint.TURRET: + hardpoint = self.module.hardpoint + if hardpoint == Hardpoint.TURRET: self.addSeperator(m, "Long Range") items = [] range = None @@ -122,7 +115,7 @@ class ModuleAmmoPicker(ContextMenu): m.AppendItem(item) self.addSeperator(m, "High Damage") - elif self.hardpoint == Hardpoint.MISSILE: + elif hardpoint == Hardpoint.MISSILE: self.charges.sort(key=self.missileSorter) type = None sub = None From fc9a5bde3a015f84d1aded429e4ed5568c708e31 Mon Sep 17 00:00:00 2001 From: cncfanatics Date: Thu, 21 Oct 2010 10:29:43 +0200 Subject: [PATCH 5/6] Fix some bugs with market group jump --- gui/builtinContextMenus/marketJump.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gui/builtinContextMenus/marketJump.py b/gui/builtinContextMenus/marketJump.py index 889107475..3962ab40e 100644 --- a/gui/builtinContextMenus/marketJump.py +++ b/gui/builtinContextMenus/marketJump.py @@ -8,12 +8,19 @@ class MarketJump(ContextMenu): self.mainFrame = gui.mainFrame.MainFrame.getInstance() def display(self, context, selection): - return context in ("module", "ammo", "itemSearch") + return context in ("module", "ammo", "itemSearch") and (not selection[0].isEmpty if context == "module" else True) def getText(self, context, selection): return "Jump to %s Market Group" % (context.capitalize() if context != "itemSearch" else "Item") def activate(self, context, selection, i): - self.mainFrame.marketBrowser.jump(selection[0]) + if context == "module": + item = selection[0].item + elif context == "ammo": + item = selection[0].charge + else: + item = selection[0] + + self.mainFrame.marketBrowser.jump(item) MarketJump.register() From 415f126356e19c960e9b359c6d76095c89b5a85c Mon Sep 17 00:00:00 2001 From: cncfanatics Date: Thu, 21 Oct 2010 10:39:25 +0200 Subject: [PATCH 6/6] Add a row != -1 check to the click handler --- gui/fittingView.py | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/gui/fittingView.py b/gui/fittingView.py index 23004c40a..a53a96416 100644 --- a/gui/fittingView.py +++ b/gui/fittingView.py @@ -70,13 +70,14 @@ class FittingView(d.Display): self.Bind(wx.EVT_RIGHT_DOWN, self.click) def startDrag(self, event): - data = wx.PyTextDataObject() row = event.GetIndex() - data.SetText(str(self.GetItemData(row))) + if row != -1: + data = wx.PyTextDataObject() + data.SetText(str(self.GetItemData(row))) - dropSource = wx.DropSource(self) - dropSource.SetData(data) - res = dropSource.DoDragDrop() + dropSource = wx.DropSource(self) + dropSource.SetData(data) + res = dropSource.DoDragDrop() def getSelectedMods(self): @@ -226,18 +227,18 @@ class FittingView(d.Display): def click(self, event): event.Skip() row, _ = self.HitTest(event.Position) - sel = [] - curr = self.GetFirstSelected() - while curr != -1: - sel.append(curr) - curr = self.GetNextSelected(curr) - - if curr not in sel: - mods = [self.mods[self.GetItemData(row)]] - else: - mods = self.getSelectedMods() - if row != -1: + sel = [] + curr = self.GetFirstSelected() + while curr != -1: + sel.append(curr) + curr = self.GetNextSelected(curr) + + if curr not in sel: + mods = [self.mods[self.GetItemData(row)]] + else: + mods = self.getSelectedMods() + col = self.getColumn(event.Position) if col == self.getColIndex(ModuleState): sFit = service.Fit.getInstance()