Merge branch 'master' into wx3
This commit is contained in:
@@ -25,7 +25,7 @@ import time
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
from gui.utils.compat import OrderedDict
|
||||
from utils.compat import OrderedDict
|
||||
|
||||
cachedBitmapsCount = 0
|
||||
cachedBitmaps = OrderedDict()
|
||||
|
||||
@@ -14,5 +14,8 @@ __all__ = [
|
||||
"whProjector",
|
||||
"cargo",
|
||||
"shipJump",
|
||||
"targetResists"
|
||||
#"changeAffectingSkills",
|
||||
"tacticalMode",
|
||||
"targetResists",
|
||||
"priceClear"
|
||||
]
|
||||
|
||||
@@ -8,7 +8,6 @@ class AmmoPattern(ContextMenu):
|
||||
def __init__(self):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
if srcContext not in ("marketItemGroup", "marketItemMisc") or self.mainFrame.getActiveFit() is None:
|
||||
return False
|
||||
@@ -33,5 +32,4 @@ class AmmoPattern(ContextMenu):
|
||||
def getBitmap(self, context, selection):
|
||||
return None
|
||||
|
||||
|
||||
AmmoPattern.register()
|
||||
|
||||
@@ -10,17 +10,17 @@ import gui.globalEvents as GE
|
||||
class ChangeAffectingSkills(ContextMenu):
|
||||
def __init__(self):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
self.sChar = service.Character.getInstance()
|
||||
|
||||
self.sFit = service.Fit.getInstance()
|
||||
fit = self.sFit.getFit(self.mainFrame.getActiveFit())
|
||||
|
||||
self.charID = fit.character.ID
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
if self.mainFrame.getActiveFit() is None or srcContext not in ("fittingModule", "fittingShip"):
|
||||
return False
|
||||
|
||||
self.sChar = service.Character.getInstance()
|
||||
self.sFit = service.Fit.getInstance()
|
||||
fit = self.sFit.getFit(self.mainFrame.getActiveFit())
|
||||
|
||||
self.charID = fit.character.ID
|
||||
|
||||
if self.sChar.getCharName(self.charID) in ("All 0", "All 5"):
|
||||
return False
|
||||
|
||||
@@ -52,9 +52,6 @@ class ChangeAffectingSkills(ContextMenu):
|
||||
def getText(self, itmContext, selection):
|
||||
return "Change %s Skills" % itmContext
|
||||
|
||||
def activate(self, fullContext, selection, i):
|
||||
pass
|
||||
|
||||
def addSkill(self, rootMenu, skill, i):
|
||||
if i < 0:
|
||||
label = "Not Learned"
|
||||
@@ -63,32 +60,31 @@ class ChangeAffectingSkills(ContextMenu):
|
||||
|
||||
id = wx.NewId()
|
||||
self.skillIds[id] = (skill, i)
|
||||
menuItem = wx.MenuItem(rootMenu, id, label, kind=wx.ITEM_CHECK)
|
||||
menuItem = wx.MenuItem(rootMenu, id, label, kind=wx.ITEM_RADIO)
|
||||
rootMenu.Bind(wx.EVT_MENU, self.handleSkillChange, menuItem)
|
||||
return menuItem
|
||||
|
||||
def getSubMenu(self, context, selection, menu, i, pitem):
|
||||
self.context = context
|
||||
def getSubMenu(self, context, selection, rootMenu, i, pitem):
|
||||
msw = True if "wxMSW" in wx.PlatformInfo else False
|
||||
self.skillIds = {}
|
||||
|
||||
m = wx.Menu()
|
||||
sub = wx.Menu()
|
||||
|
||||
for skill in self.skills:
|
||||
skillItem = wx.MenuItem(m, wx.NewId(), skill.item.name)
|
||||
sub = wx.Menu()
|
||||
skillItem.SetSubMenu(sub)
|
||||
skillItem = wx.MenuItem(sub, wx.NewId(), skill.item.name)
|
||||
grandSub = wx.Menu()
|
||||
skillItem.SetSubMenu(grandSub)
|
||||
if skill.learned:
|
||||
bitmap = bitmapLoader.getBitmap("lvl%s" % skill.level, "icons")
|
||||
if bitmap is not None:
|
||||
skillItem.SetBitmap(bitmap)
|
||||
|
||||
for i in xrange(-1, 6):
|
||||
levelItem = self.addSkill(menu, skill, i)
|
||||
sub.AppendItem(levelItem)
|
||||
levelItem = self.addSkill(rootMenu if msw else grandSub, skill, i)
|
||||
grandSub.AppendItem(levelItem)
|
||||
#@ todo: add check to current level. Need to fix #109 first
|
||||
m.AppendItem(skillItem)
|
||||
sub.AppendItem(skillItem)
|
||||
|
||||
return m
|
||||
return sub
|
||||
|
||||
def handleSkillChange(self, event):
|
||||
skill, level = self.skillIds[event.Id]
|
||||
|
||||
@@ -15,7 +15,7 @@ class DamagePattern(ContextMenu):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
return srcContext in ("resistancesViewFull",) and self.mainFrame.getActiveFit() is not None
|
||||
return srcContext == "resistancesViewFull" and self.mainFrame.getActiveFit() is not None
|
||||
|
||||
def getText(self, itmContext, selection):
|
||||
sDP = service.DamagePattern.getInstance()
|
||||
@@ -24,12 +24,11 @@ class DamagePattern(ContextMenu):
|
||||
self.fit = sFit.getFit(fitID)
|
||||
|
||||
self.patterns = sDP.getDamagePatternList()
|
||||
self.patterns.sort( key=lambda p: (p.name not in ["Uniform",
|
||||
"Selected Ammo"], p.name) )
|
||||
self.patterns.sort(key=lambda p: (p.name not in ["Uniform","Selected Ammo"], p.name))
|
||||
|
||||
self.patternIds = {}
|
||||
self.subMenus = OrderedDict()
|
||||
self.singles = []
|
||||
self.singles = []
|
||||
|
||||
# iterate and separate damage patterns based on "[Parent] Child"
|
||||
for pattern in self.patterns:
|
||||
@@ -48,6 +47,51 @@ class DamagePattern(ContextMenu):
|
||||
self.m = map(lambda p: p.name, self.singles) + self.subMenus.keys()
|
||||
return self.m
|
||||
|
||||
def addPattern(self, rootMenu, pattern):
|
||||
id = wx.NewId()
|
||||
name = getattr(pattern, "_name", pattern.name) if pattern is not None else "No Profile"
|
||||
|
||||
self.patternIds[id] = pattern
|
||||
menuItem = wx.MenuItem(rootMenu, id, name)
|
||||
rootMenu.Bind(wx.EVT_MENU, self.handlePatternSwitch, menuItem)
|
||||
|
||||
# set pattern attr to menu item
|
||||
menuItem.pattern = pattern
|
||||
|
||||
# determine active pattern
|
||||
sFit = service.Fit.getInstance()
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
f = sFit.getFit(fitID)
|
||||
dp = f.damagePattern
|
||||
|
||||
if dp == pattern:
|
||||
bitmap = bitmapLoader.getBitmap("state_active_small", "icons")
|
||||
menuItem.SetBitmap(bitmap)
|
||||
return menuItem
|
||||
|
||||
def getSubMenu(self, context, selection, rootMenu, i, pitem):
|
||||
msw = True if "wxMSW" in wx.PlatformInfo else False
|
||||
rootMenu.Bind(wx.EVT_MENU, self.handlePatternSwitch) # this bit is required for some reason
|
||||
|
||||
if self.m[i] not in self.subMenus:
|
||||
# if we're trying to get submenu to something that shouldn't have one,
|
||||
# redirect event of the item to handlePatternSwitch and put pattern in
|
||||
# our patternIds mapping, then return None for no submenu
|
||||
id = pitem.GetId()
|
||||
self.patternIds[id] = self.singles[i]
|
||||
if self.patternIds[id] == self.fit.damagePattern:
|
||||
bitmap = bitmapLoader.getBitmap("state_active_small", "icons")
|
||||
pitem.SetBitmap(bitmap)
|
||||
return None
|
||||
|
||||
sub = wx.Menu()
|
||||
|
||||
# Items that have a parent
|
||||
for pattern in self.subMenus[self.m[i]]:
|
||||
sub.AppendItem(self.addPattern(rootMenu if msw else sub, pattern))
|
||||
|
||||
return sub
|
||||
|
||||
def handlePatternSwitch(self, event):
|
||||
pattern = self.patternIds.get(event.Id, False)
|
||||
if pattern is False:
|
||||
@@ -60,50 +104,4 @@ class DamagePattern(ContextMenu):
|
||||
setattr(self.mainFrame,"_activeDmgPattern", pattern)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
def addPattern(self, menu, pattern):
|
||||
id = wx.NewId()
|
||||
name = getattr(pattern, "_name", pattern.name) if pattern is not None else "No Profile"
|
||||
|
||||
self.patternIds[id] = pattern
|
||||
item = wx.MenuItem(menu, id, name)
|
||||
menu.Bind(wx.EVT_MENU, self.handlePatternSwitch, item)
|
||||
|
||||
# set pattern attr to menu item
|
||||
item.pattern = pattern
|
||||
|
||||
# determine active pattern
|
||||
sFit = service.Fit.getInstance()
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
f = sFit.getFit(fitID)
|
||||
dp = f.damagePattern
|
||||
|
||||
if dp == pattern:
|
||||
bitmap = bitmapLoader.getBitmap("state_active_small", "icons")
|
||||
item.SetBitmap(bitmap)
|
||||
return item
|
||||
|
||||
def getSubMenu(self, context, selection, menu, i, pitem):
|
||||
menu.Bind(wx.EVT_MENU, self.handlePatternSwitch) # this bit is required for some reason
|
||||
|
||||
if self.m[i] not in self.subMenus:
|
||||
# if we're trying to get submenu to something that shouldn't have one,
|
||||
# redirect event of the item to handlePatternSwitch and put pattern in
|
||||
# our patternIds mapping, then return None for no submenu
|
||||
id = pitem.GetId()
|
||||
self.patternIds[id] = self.singles[i]
|
||||
menu.Bind(wx.EVT_MENU, self.handlePatternSwitch, pitem)
|
||||
if self.patternIds[id] == self.fit.damagePattern:
|
||||
bitmap = bitmapLoader.getBitmap("state_active_small", "icons")
|
||||
pitem.SetBitmap(bitmap)
|
||||
return None
|
||||
|
||||
sub = wx.Menu()
|
||||
sub.Bind(wx.EVT_MENU, self.handlePatternSwitch)
|
||||
|
||||
# Items that have a parent
|
||||
for pattern in self.subMenus[self.m[i]]:
|
||||
sub.AppendItem(self.addPattern(sub, pattern))
|
||||
|
||||
return sub
|
||||
|
||||
DamagePattern.register()
|
||||
|
||||
@@ -15,7 +15,6 @@ class ItemRemove(ContextMenu):
|
||||
return "Remove {0} Stack".format(itmContext)
|
||||
|
||||
def activate(self, fullContext, selection, i):
|
||||
srcContext = fullContext[0]
|
||||
sFit = service.Fit.getInstance()
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
fit = sFit.getFit(fitID)
|
||||
|
||||
@@ -10,7 +10,7 @@ class FactorReload(ContextMenu):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
return srcContext in ("firepowerViewFull",) and self.mainFrame.getActiveFit() is not None
|
||||
return srcContext == "firepowerViewFull" and self.mainFrame.getActiveFit() is not None
|
||||
|
||||
def getText(self, itmContext, selection):
|
||||
return "Factor in Reload Time"
|
||||
|
||||
@@ -9,7 +9,10 @@ class ItemRemove(ContextMenu):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
return srcContext in ("fittingModule", "fittingCharge", "droneItem", "implantItem", "boosterItem", "projectedModule", "projectedCharge",
|
||||
return srcContext in ("fittingModule", "fittingCharge",
|
||||
"droneItem", "implantItem",
|
||||
"boosterItem", "projectedModule",
|
||||
"projectedCharge", "cargoItem",
|
||||
"projectedFit", "projectedDrone")
|
||||
|
||||
def getText(self, itmContext, selection):
|
||||
@@ -33,6 +36,8 @@ class ItemRemove(ContextMenu):
|
||||
sFit.removeImplant(fitID, fit.implants.index(selection[0]))
|
||||
elif srcContext == "boosterItem":
|
||||
sFit.removeBooster(fitID, fit.boosters.index(selection[0]))
|
||||
elif srcContext == "cargoItem":
|
||||
sFit.removeCargo(fitID, fit.cargo.index(selection[0]))
|
||||
else:
|
||||
sFit.removeProjected(fitID, selection[0])
|
||||
|
||||
|
||||
@@ -9,8 +9,13 @@ class ItemStats(ContextMenu):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
return srcContext in ("marketItemGroup", "marketItemMisc", "fittingModule", "fittingCharge", "fittingShip", "baseShip", "cargoItem",
|
||||
"droneItem", "implantItem", "boosterItem", "skillItem", "projectedModule", "projectedDrone", "projectedCharge")
|
||||
return srcContext in ("marketItemGroup", "marketItemMisc",
|
||||
"fittingModule", "fittingCharge",
|
||||
"fittingShip", "baseShip",
|
||||
"cargoItem", "droneItem",
|
||||
"implantItem", "boosterItem",
|
||||
"skillItem", "projectedModule",
|
||||
"projectedDrone", "projectedCharge")
|
||||
|
||||
def getText(self, itmContext, selection):
|
||||
return "{0} Stats".format(itmContext if itmContext is not None else "Item")
|
||||
@@ -33,7 +38,7 @@ class ItemStats(ContextMenu):
|
||||
if mstate.CmdDown():
|
||||
reuse = True
|
||||
|
||||
if self.mainFrame.GetActiveStatsWindow() == None and reuse:
|
||||
if self.mainFrame.GetActiveStatsWindow() is None and reuse:
|
||||
ItemStatsDialog(stuff, fullContext)
|
||||
|
||||
elif reuse:
|
||||
|
||||
@@ -8,19 +8,24 @@ class MarketJump(ContextMenu):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
validContexts = ("marketItemMisc", "fittingModule", "fittingCharge", "droneItem", "implantItem",
|
||||
"boosterItem", "projectedModule", "projectedDrone", "projectedCharge", "cargoItem")
|
||||
if not srcContext in validContexts:
|
||||
validContexts = ("marketItemMisc", "fittingModule",
|
||||
"fittingCharge", "droneItem",
|
||||
"implantItem", "boosterItem",
|
||||
"projectedModule", "projectedDrone",
|
||||
"projectedCharge", "cargoItem")
|
||||
|
||||
if not srcContext in validContexts or selection is None or len(selection) < 1:
|
||||
return False
|
||||
|
||||
sMkt = service.Market.getInstance()
|
||||
if selection is None or len(selection) < 1:
|
||||
return False
|
||||
item = getattr(selection[0], "item", selection[0])
|
||||
mktGrp = sMkt.getMarketGroupByItem(item)
|
||||
|
||||
# 1663 is Special Edition Festival Assets, we don't have root group for it
|
||||
if mktGrp is None or mktGrp.ID == 1663:
|
||||
return False
|
||||
doit = not selection[0].isEmpty if srcContext == "fittingModule" else True
|
||||
|
||||
doit = not selection[0].isEmpty if srcContext == "fittingModule" else True
|
||||
return doit
|
||||
|
||||
def getText(self, itmContext, selection):
|
||||
@@ -28,7 +33,9 @@ class MarketJump(ContextMenu):
|
||||
|
||||
def activate(self, fullContext, selection, i):
|
||||
srcContext = fullContext[0]
|
||||
if srcContext in ("fittingModule", "droneItem", "implantItem", "boosterItem", "projectedModule", "projectedDrone", "cargoItem"):
|
||||
if srcContext in ("fittingModule", "droneItem", "implantItem",
|
||||
"boosterItem", "projectedModule", "projectedDrone",
|
||||
"cargoItem"):
|
||||
item = selection[0].item
|
||||
elif srcContext in ("fittingCharge", "projectedCharge"):
|
||||
item = selection[0].charge
|
||||
|
||||
@@ -8,6 +8,9 @@ from eos.types import Hardpoint
|
||||
import gui.globalEvents as GE
|
||||
|
||||
class ModuleAmmoPicker(ContextMenu):
|
||||
DAMAGE_TYPES = ("em", "explosive", "kinetic", "thermal")
|
||||
MISSILE_ORDER = ("em", "thermal", "kinetic", "explosive", "mixed")
|
||||
|
||||
def __init__(self):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
@@ -19,7 +22,9 @@ class ModuleAmmoPicker(ContextMenu):
|
||||
|
||||
validCharges = None
|
||||
checkedTypes = set()
|
||||
|
||||
for mod in modules:
|
||||
# loop through modules and gather list of valid charges
|
||||
if mod.item.ID in checkedTypes:
|
||||
continue
|
||||
checkedTypes.add(mod.item.ID)
|
||||
@@ -41,10 +46,6 @@ class ModuleAmmoPicker(ContextMenu):
|
||||
def getText(self, itmContext, selection):
|
||||
return "Charge"
|
||||
|
||||
def activate(self, fullContext, selection, i):
|
||||
pass
|
||||
|
||||
DAMAGE_TYPES = ("em", "explosive", "kinetic", "thermal")
|
||||
def turretSorter(self, charge):
|
||||
damage = 0
|
||||
range = (self.module.getModifiedItemAttr("maxRange") or 0) * (charge.getAttribute("weaponRangeMultiplier") or 1)
|
||||
@@ -57,15 +58,14 @@ class ModuleAmmoPicker(ContextMenu):
|
||||
# Take optimal and half falloff as range factor
|
||||
rangeFactor = range + falloff / 2
|
||||
|
||||
return (- rangeFactor, charge.name.rsplit()[-2:], damage, charge.name)
|
||||
return - rangeFactor, charge.name.rsplit()[-2:], damage, charge.name
|
||||
|
||||
MISSILE_ORDER = ("em", "thermal", "kinetic", "explosive", "mixed")
|
||||
def missileSorter(self, charge):
|
||||
# Get charge damage type and total damage
|
||||
chargeDamageType, totalDamage = self.damageInfo(charge)
|
||||
# Find its position in sort list
|
||||
position = self.MISSILE_ORDER.index(chargeDamageType)
|
||||
return (position, totalDamage, charge.name)
|
||||
return position, totalDamage, charge.name
|
||||
|
||||
def damageInfo(self, charge):
|
||||
# Set up data storage for missile damage stuff
|
||||
@@ -90,7 +90,6 @@ class ModuleAmmoPicker(ContextMenu):
|
||||
|
||||
return chargeDamageType, totalDamage
|
||||
|
||||
|
||||
def numericConverter(self, string):
|
||||
return int(string) if string.isdigit() else string
|
||||
|
||||
@@ -103,6 +102,7 @@ class ModuleAmmoPicker(ContextMenu):
|
||||
name = charge.name if charge is not None else "Empty"
|
||||
self.chargeIds[id] = charge
|
||||
item = wx.MenuItem(menu, id, name)
|
||||
menu.Bind(wx.EVT_MENU, self.handleAmmoSwitch, item)
|
||||
item.charge = charge
|
||||
if charge is not None and charge.icon is not None:
|
||||
bitmap = bitmapLoader.getBitmap(charge.icon.iconFile, "pack")
|
||||
@@ -116,11 +116,9 @@ class ModuleAmmoPicker(ContextMenu):
|
||||
m.Append(id, u'─ %s ─' % text)
|
||||
m.Enable(id, False)
|
||||
|
||||
def getSubMenu(self, context, selection, menu, i, pitem):
|
||||
self.context = context
|
||||
menu.Bind(wx.EVT_MENU, self.handleAmmoSwitch)
|
||||
def getSubMenu(self, context, selection, rootMenu, i, pitem):
|
||||
msw = True if "wxMSW" in wx.PlatformInfo else False
|
||||
m = wx.Menu()
|
||||
m.Bind(wx.EVT_MENU, self.handleAmmoSwitch)
|
||||
self.chargeIds = {}
|
||||
hardpoint = self.module.hardpoint
|
||||
moduleName = self.module.item.name
|
||||
@@ -150,7 +148,7 @@ class ModuleAmmoPicker(ContextMenu):
|
||||
base = charge
|
||||
nameBase = currBase
|
||||
range = currRange
|
||||
item = self.addCharge(m, charge)
|
||||
item = self.addCharge(rootMenu if msw else m, charge)
|
||||
items.append(item)
|
||||
else:
|
||||
if sub is None:
|
||||
@@ -158,9 +156,9 @@ class ModuleAmmoPicker(ContextMenu):
|
||||
sub.Bind(wx.EVT_MENU, self.handleAmmoSwitch)
|
||||
self.addSeperator(sub, "Less Damage")
|
||||
item.SetSubMenu(sub)
|
||||
sub.AppendItem(self.addCharge(sub, base))
|
||||
sub.AppendItem(self.addCharge(rootMenu if msw else sub, base))
|
||||
|
||||
sub.AppendItem(self.addCharge(sub, charge))
|
||||
sub.AppendItem(self.addCharge(rootMenu if msw else sub, charge))
|
||||
|
||||
if sub is not None:
|
||||
self.addSeperator(sub, "More Damage")
|
||||
@@ -194,20 +192,20 @@ class ModuleAmmoPicker(ContextMenu):
|
||||
m.AppendItem(item)
|
||||
|
||||
if charge.name not in ("Light Defender Missile I", "Heavy Defender Missile I"):
|
||||
sub.AppendItem(self.addCharge(sub, charge))
|
||||
sub.AppendItem(self.addCharge(rootMenu if msw else sub, charge))
|
||||
else:
|
||||
defender = charge
|
||||
|
||||
if defender is not None:
|
||||
m.AppendItem(self.addCharge(sub, defender))
|
||||
m.AppendItem(self.addCharge(rootMenu if msw else m, defender))
|
||||
if sub is not None:
|
||||
self.addSeperator(sub, "More Damage")
|
||||
else:
|
||||
self.charges.sort(key=self.nameSorter)
|
||||
for charge in self.charges:
|
||||
m.AppendItem(self.addCharge(m, charge))
|
||||
m.AppendItem(self.addCharge(rootMenu if msw else m, charge))
|
||||
|
||||
m.AppendItem(self.addCharge(m, None))
|
||||
m.AppendItem(self.addCharge(rootMenu if msw else m, None))
|
||||
return m
|
||||
|
||||
def handleAmmoSwitch(self, event):
|
||||
|
||||
@@ -33,7 +33,7 @@ class ModuleGlobalAmmoPicker(ModuleAmmoPicker):
|
||||
selectedModule = self.modules[0]
|
||||
allModules = []
|
||||
for mod in fit.modules:
|
||||
if mod.itemID == None:
|
||||
if mod.itemID is None:
|
||||
continue
|
||||
if mod.itemID == selectedModule.itemID:
|
||||
allModules.append(mod)
|
||||
|
||||
@@ -8,7 +8,7 @@ class OpenFit(ContextMenu):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
return "projectedFit" in srcContext
|
||||
return srcContext == "projectedFit"
|
||||
|
||||
def getText(self, itmContext, selection):
|
||||
return "Open Fit in New Tab"
|
||||
|
||||
22
gui/builtinContextMenus/priceClear.py
Normal file
22
gui/builtinContextMenus/priceClear.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import wx
|
||||
import gui.globalEvents as GE
|
||||
import service
|
||||
|
||||
class PriceClear(ContextMenu):
|
||||
def __init__(self):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
return srcContext == "priceViewFull"
|
||||
|
||||
def getText(self, itmContext, selection):
|
||||
return "Reset Price Cache"
|
||||
|
||||
def activate(self, fullContext, selection, i):
|
||||
sMkt = service.Market.getInstance()
|
||||
sMkt.clearPriceCache()
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
|
||||
|
||||
PriceClear.register()
|
||||
@@ -9,10 +9,7 @@ class ShipJump(ContextMenu):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
validContexts = ("fittingShip")
|
||||
if not srcContext in validContexts:
|
||||
return False
|
||||
return True
|
||||
return srcContext == "fittingShip"
|
||||
|
||||
def getText(self, itmContext, selection):
|
||||
return "Open in Ship Browser"
|
||||
|
||||
60
gui/builtinContextMenus/tacticalMode.py
Normal file
60
gui/builtinContextMenus/tacticalMode.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import wx
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
|
||||
class TacticalMode(ContextMenu):
|
||||
def __init__(self):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
if self.mainFrame.getActiveFit() is None or srcContext != "fittingShip":
|
||||
return False
|
||||
|
||||
sFit = service.Fit.getInstance()
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
fit = sFit.getFit(fitID)
|
||||
|
||||
self.modes = fit.ship.getModes()
|
||||
self.currMode = fit.mode
|
||||
|
||||
return srcContext == "fittingShip" and self.modes is not None
|
||||
|
||||
def getText(self, itmContext, selection):
|
||||
return "Tactical Mode"
|
||||
|
||||
def addMode(self, menu, mode):
|
||||
label = mode.item.name.rsplit()[-2]
|
||||
id = wx.NewId()
|
||||
self.modeIds[id] = mode
|
||||
menuItem = wx.MenuItem(menu, id, label, kind=wx.ITEM_RADIO)
|
||||
menu.Bind(wx.EVT_MENU, self.handleMode, menuItem)
|
||||
return menuItem
|
||||
|
||||
def getSubMenu(self, context, selection, rootMenu, i, pitem):
|
||||
msw = True if "wxMSW" in wx.PlatformInfo else False
|
||||
self.context = context
|
||||
self.modeIds = {}
|
||||
|
||||
sub = wx.Menu()
|
||||
|
||||
for mode in self.modes:
|
||||
menuItem = self.addMode(rootMenu if msw else sub, mode)
|
||||
sub.AppendItem(menuItem)
|
||||
menuItem.Check(self.currMode.item == mode.item)
|
||||
|
||||
return sub
|
||||
|
||||
def handleMode(self, event):
|
||||
item = self.modeIds[event.Id]
|
||||
if item is False or item not in self.modes:
|
||||
event.Skip()
|
||||
return
|
||||
|
||||
sFit = service.Fit.getInstance()
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
sFit.setMode(fitID, self.modeIds[event.Id])
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
TacticalMode.register()
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import service
|
||||
@@ -17,21 +15,18 @@ class TargetResists(ContextMenu):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
if self.mainFrame.getActiveFit() is None or srcContext not in ("firepowerViewFull",):
|
||||
if self.mainFrame.getActiveFit() is None or srcContext != "firepowerViewFull":
|
||||
return False
|
||||
|
||||
sTR = service.TargetResists.getInstance()
|
||||
self.patterns = sTR.getTargetResistsList()
|
||||
self.patterns.sort( key=lambda p: (p.name in ["None"], p.name) )
|
||||
self.patterns.sort(key=lambda p: (p.name in ["None"], p.name))
|
||||
|
||||
return len(self.patterns) > 0
|
||||
|
||||
def getText(self, itmContext, selection):
|
||||
return "Target Resists"
|
||||
|
||||
def activate(self, fullContext, selection, i):
|
||||
pass
|
||||
|
||||
def handleResistSwitch(self, event):
|
||||
pattern = self.patternIds.get(event.Id, False)
|
||||
if pattern is False:
|
||||
@@ -43,12 +38,14 @@ class TargetResists(ContextMenu):
|
||||
sFit.setTargetResists(fitID, pattern)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
def addPattern(self, menu, pattern, currBase = None):
|
||||
def addPattern(self, rootMenu, pattern):
|
||||
id = wx.NewId()
|
||||
name = getattr(pattern, "_name", pattern.name) if pattern is not None else "No Profile"
|
||||
|
||||
self.patternIds[id] = pattern
|
||||
item = wx.MenuItem(menu, id, name)
|
||||
item = wx.MenuItem(rootMenu, id, name)
|
||||
rootMenu.Bind(wx.EVT_MENU, self.handleResistSwitch, item)
|
||||
|
||||
# set pattern attr to menu item
|
||||
item.pattern = pattern
|
||||
|
||||
@@ -63,21 +60,13 @@ class TargetResists(ContextMenu):
|
||||
item.SetBitmap(bitmap)
|
||||
return item
|
||||
|
||||
def addSeperator(self, m, text):
|
||||
id = wx.NewId()
|
||||
m.Append(id, u'─ %s ─' % text)
|
||||
m.Enable(id, False)
|
||||
|
||||
def getSubMenu(self, context, selection, menu, i, pitem):
|
||||
self.context = context
|
||||
menu.Bind(wx.EVT_MENU, self.handleResistSwitch)
|
||||
m = wx.Menu()
|
||||
m.Bind(wx.EVT_MENU, self.handleResistSwitch)
|
||||
def getSubMenu(self, context, selection, rootMenu, i, pitem):
|
||||
msw = True if "wxMSW" in wx.PlatformInfo else False
|
||||
self.patternIds = {}
|
||||
|
||||
self.subMenus = OrderedDict()
|
||||
self.singles = []
|
||||
|
||||
sub = wx.Menu()
|
||||
for pattern in self.patterns:
|
||||
start, end = pattern.name.find('['), pattern.name.find(']')
|
||||
if start is not -1 and end is not -1:
|
||||
@@ -90,30 +79,30 @@ class TargetResists(ContextMenu):
|
||||
else:
|
||||
self.singles.append(pattern)
|
||||
|
||||
m.AppendItem(self.addPattern(m, None)) # Add reset
|
||||
m.AppendSeparator()
|
||||
sub.AppendItem(self.addPattern(rootMenu if msw else sub, None)) # Add reset
|
||||
sub.AppendSeparator()
|
||||
|
||||
# Single items, no parent
|
||||
for pattern in self.singles:
|
||||
m.AppendItem(self.addPattern(m, pattern))
|
||||
sub.AppendItem(self.addPattern(rootMenu if msw else sub, pattern))
|
||||
|
||||
# Items that have a parent
|
||||
for menuName, patterns in self.subMenus.items():
|
||||
# Create parent item for root menu that is simply name of parent
|
||||
item = wx.MenuItem(menu, wx.NewId(), menuName)
|
||||
item = wx.MenuItem(rootMenu, wx.NewId(), menuName)
|
||||
|
||||
# Create menu for child items
|
||||
sub = wx.Menu()
|
||||
sub.Bind(wx.EVT_MENU, self.handleResistSwitch)
|
||||
grandSub = wx.Menu()
|
||||
#sub.Bind(wx.EVT_MENU, self.handleResistSwitch)
|
||||
|
||||
# Apply child menu to parent item
|
||||
item.SetSubMenu(sub)
|
||||
item.SetSubMenu(grandSub)
|
||||
|
||||
# Append child items to child menu
|
||||
for pattern in patterns:
|
||||
sub.AppendItem(self.addPattern(sub, pattern))
|
||||
m.AppendItem(item) #finally, append parent item to root menu
|
||||
grandSub.AppendItem(self.addPattern(rootMenu if msw else grandSub, pattern))
|
||||
sub.AppendItem(item) #finally, append parent item to root menu
|
||||
|
||||
return m
|
||||
return sub
|
||||
|
||||
TargetResists.register()
|
||||
|
||||
@@ -14,29 +14,31 @@ class WhProjector(ContextMenu):
|
||||
def getText(self, itmContext, selection):
|
||||
return "Add System Effects"
|
||||
|
||||
def activate(self, fullContext, selection, i):
|
||||
pass
|
||||
|
||||
def getSubMenu(self, context, selection, menu, i, pitem):
|
||||
self.idmap = {}
|
||||
menu.Bind(wx.EVT_MENU, self.handleSelection)
|
||||
m = wx.Menu()
|
||||
def getSubMenu(self, context, selection, rootMenu, i, pitem):
|
||||
msw = True if "wxMSW" in wx.PlatformInfo else False
|
||||
sMkt = service.Market.getInstance()
|
||||
effdata = sMkt.getSystemWideEffects()
|
||||
|
||||
self.idmap = {}
|
||||
sub = wx.Menu()
|
||||
|
||||
for swType in sorted(effdata):
|
||||
item = wx.MenuItem(m, wx.ID_ANY, swType)
|
||||
sub = wx.Menu()
|
||||
sub.Bind(wx.EVT_MENU, self.handleSelection)
|
||||
item.SetSubMenu(sub)
|
||||
m.AppendItem(item)
|
||||
subItem = wx.MenuItem(sub, wx.ID_ANY, swType)
|
||||
grandSub = wx.Menu()
|
||||
subItem.SetSubMenu(grandSub)
|
||||
sub.AppendItem(subItem)
|
||||
|
||||
for swData in sorted(effdata[swType], key=lambda tpl: tpl[2]):
|
||||
wxid = wx.NewId()
|
||||
swObj, swName, swClass = swData
|
||||
self.idmap[wxid] = (swObj, swName)
|
||||
subitem = wx.MenuItem(sub, wxid, swClass)
|
||||
sub.AppendItem(subitem)
|
||||
return m
|
||||
|
||||
grandSubItem = wx.MenuItem(grandSub, wxid, swClass)
|
||||
if msw:
|
||||
rootMenu.Bind(wx.EVT_MENU, self.handleSelection, grandSubItem)
|
||||
else:
|
||||
grandSub.Bind(wx.EVT_MENU, self.handleSelection, grandSubItem)
|
||||
grandSub.AppendItem(grandSubItem)
|
||||
return sub
|
||||
|
||||
def handleSelection(self, event):
|
||||
#Skip events ids that aren't mapped
|
||||
|
||||
@@ -30,6 +30,7 @@ class FirepowerViewFull(StatsView):
|
||||
StatsView.__init__(self)
|
||||
self.parent = parent
|
||||
self._cachedValues = []
|
||||
|
||||
def getHeaderText(self, fit):
|
||||
return "Firepower"
|
||||
|
||||
@@ -44,7 +45,7 @@ class FirepowerViewFull(StatsView):
|
||||
self.headerPanel = headerPanel
|
||||
headerContentSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
hsizer = headerPanel.GetSizer()
|
||||
hsizer.Add(headerContentSizer,0,0,0)
|
||||
hsizer.Add(headerContentSizer, 0, 0, 0)
|
||||
self.stEff = wx.StaticText(headerPanel, wx.ID_ANY, "( Effective )")
|
||||
headerContentSizer.Add(self.stEff)
|
||||
headerPanel.GetParent().AddToggleItem(self.stEff)
|
||||
@@ -54,7 +55,7 @@ class FirepowerViewFull(StatsView):
|
||||
sizerFirepower = wx.FlexGridSizer(1, 4)
|
||||
sizerFirepower.AddGrowableCol(1)
|
||||
|
||||
contentSizer.Add( sizerFirepower, 0, wx.EXPAND, 0)
|
||||
contentSizer.Add(sizerFirepower, 0, wx.EXPAND, 0)
|
||||
|
||||
counter = 0
|
||||
|
||||
@@ -73,10 +74,9 @@ class FirepowerViewFull(StatsView):
|
||||
box.Add(hbox, 1, wx.ALIGN_CENTER)
|
||||
|
||||
lbl = wx.StaticText(parent, wx.ID_ANY, "0.0 DPS")
|
||||
setattr(self, "label%sDps%s" % (panel.capitalize() ,damageType.capitalize()), lbl)
|
||||
setattr(self, "label%sDps%s" % (panel.capitalize(), damageType.capitalize()), lbl)
|
||||
|
||||
hbox.Add(lbl, 0, wx.ALIGN_CENTER)
|
||||
# hbox.Add(wx.StaticText(parent, wx.ID_ANY, " DPS"), 0, wx.ALIGN_CENTER)
|
||||
self._cachedValues.append(0)
|
||||
counter += 1
|
||||
targetSizer = sizerFirepower
|
||||
@@ -143,7 +143,7 @@ class FirepowerViewFull(StatsView):
|
||||
|
||||
stats = (("labelFullDpsWeapon", lambda: fit.weaponDPS, 3, 0, 0, "%s DPS",None),
|
||||
("labelFullDpsDrone", lambda: fit.droneDPS, 3, 0, 0, "%s DPS", None),
|
||||
("labelFullVolleyTotal", lambda: fit.weaponVolley, 3, 0, 0, "%s", "Volley: %.1f"),
|
||||
("labelFullVolleyTotal", lambda: fit.totalVolley, 3, 0, 0, "%s", "Volley: %.1f"),
|
||||
("labelFullDpsTotal", lambda: fit.totalDPS, 3, 0, 0, "%s", None))
|
||||
# See GH issue #
|
||||
#if fit is not None and fit.totalYield > 0:
|
||||
|
||||
@@ -41,7 +41,7 @@ class PriceViewFull(StatsView):
|
||||
self._cachedFittings = 0
|
||||
self._cachedTotal = 0
|
||||
|
||||
def OnTimer( self, event):
|
||||
def OnTimer(self, event):
|
||||
if self._timerId == event.GetId():
|
||||
if self._timerRuns >= self._timerRunsBeforeUpdate:
|
||||
self._timerRuns = 0
|
||||
@@ -53,11 +53,12 @@ class PriceViewFull(StatsView):
|
||||
if self._timerIdUpdate == event.GetId():
|
||||
self._timerUpdate.Stop()
|
||||
self.labelEMStatus.SetLabel("")
|
||||
|
||||
def getHeaderText(self, fit):
|
||||
return "Price"
|
||||
|
||||
def getTextExtentW(self, text):
|
||||
width, height = self.parent.GetTextExtent( text )
|
||||
width, height = self.parent.GetTextExtent(text)
|
||||
return width
|
||||
|
||||
def populatePanel(self, contentPanel, headerPanel):
|
||||
@@ -65,8 +66,15 @@ class PriceViewFull(StatsView):
|
||||
self.panel = contentPanel
|
||||
self.headerPanel = headerPanel
|
||||
|
||||
headerContentSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
hsizer = headerPanel.GetSizer()
|
||||
hsizer.Add(headerContentSizer, 0, 0, 0)
|
||||
self.labelEMStatus = wx.StaticText(headerPanel, wx.ID_ANY, "")
|
||||
headerContentSizer.Add(self.labelEMStatus)
|
||||
headerPanel.GetParent().AddToggleItem(self.labelEMStatus)
|
||||
|
||||
gridPrice = wx.GridSizer(1, 3)
|
||||
contentSizer.Add( gridPrice, 0, wx.EXPAND | wx.ALL, 0)
|
||||
contentSizer.Add(gridPrice, 0, wx.EXPAND | wx.ALL, 0)
|
||||
for type in ("ship", "fittings", "total"):
|
||||
image = "%sPrice_big" % type if type != "ship" else "ship_big"
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
@@ -86,9 +94,6 @@ class PriceViewFull(StatsView):
|
||||
setattr(self, "labelPrice%s" % type.capitalize(), lbl)
|
||||
hbox.Add(lbl, 0, wx.ALIGN_LEFT)
|
||||
|
||||
# hbox.Add(wx.StaticText(contentPanel, wx.ID_ANY, " ISK"), 0, wx.ALIGN_LEFT)
|
||||
self.labelEMStatus = wx.StaticText(contentPanel, wx.ID_ANY, "")
|
||||
contentSizer.Add(self.labelEMStatus,0)
|
||||
def refreshPanel(self, fit):
|
||||
if fit is not None:
|
||||
self.fit = fit
|
||||
|
||||
@@ -26,7 +26,7 @@ import locale
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
from gui.utils.compat import OrderedDict
|
||||
from utils.compat import OrderedDict
|
||||
|
||||
class TargetingMiscViewFull(StatsView):
|
||||
name = "targetingmiscViewFull"
|
||||
|
||||
@@ -42,7 +42,10 @@ class BaseName(ViewColumn):
|
||||
return "%s (%s)" % (stuff.name, stuff.ship.item.name)
|
||||
elif isinstance(stuff, Rack):
|
||||
if service.Fit.getInstance().serviceFittingOptions["rackLabels"]:
|
||||
return u'─ {} Slots ─'.format(Slot.getName(stuff.slot).capitalize())
|
||||
if stuff.slot == Slot.MODE:
|
||||
return u'─ Tactical Mode ─'
|
||||
else:
|
||||
return u'─ {} Slots ─'.format(Slot.getName(stuff.slot).capitalize())
|
||||
else:
|
||||
return ""
|
||||
elif isinstance(stuff, Module):
|
||||
|
||||
@@ -23,6 +23,7 @@ import service
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
from gui.viewColumn import ViewColumn
|
||||
from gui import bitmapLoader
|
||||
from eos.types import Mode
|
||||
|
||||
class CapacitorUse(ViewColumn):
|
||||
name = "Capacitor Usage"
|
||||
@@ -38,6 +39,9 @@ class CapacitorUse(ViewColumn):
|
||||
|
||||
|
||||
def getText(self, mod):
|
||||
if isinstance(mod, Mode):
|
||||
return ""
|
||||
|
||||
capUse = mod.capUse
|
||||
if capUse:
|
||||
return "%s%s" % ("+" if capUse < 0 else "", (formatAmount(-capUse, 3, 0, 3)))
|
||||
|
||||
@@ -23,6 +23,7 @@ from gui import bitmapLoader
|
||||
import service
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
import wx
|
||||
from eos.types import Mode
|
||||
|
||||
class MaxRange(ViewColumn):
|
||||
name = "Max Range"
|
||||
@@ -51,6 +52,9 @@ class MaxRange(ViewColumn):
|
||||
self.mask |= wx.LIST_MASK_TEXT
|
||||
|
||||
def getText(self, stuff):
|
||||
if isinstance(stuff, Mode):
|
||||
return ""
|
||||
|
||||
maxRange = stuff.maxRange if hasattr(stuff, "maxRange") else stuff.getModifiedItemAttr("maxRange")
|
||||
falloff = stuff.falloff
|
||||
if falloff:
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
|
||||
import gui.mainFrame
|
||||
from gui import builtinViewColumns
|
||||
from gui.viewColumn import ViewColumn
|
||||
from gui import bitmapLoader
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
@@ -62,19 +61,30 @@ class Miscellanea(ViewColumn):
|
||||
return (("displayName", bool, False),
|
||||
("showIcon", bool, True))
|
||||
|
||||
|
||||
def __getData(self, stuff):
|
||||
item = stuff.item
|
||||
if item is None:
|
||||
return "", None
|
||||
itemGroup = item.group.name
|
||||
if itemGroup in ("Energy Weapon", "Hybrid Weapon", "Projectile Weapon", "Combat Drone", "Fighter Drone"):
|
||||
itemCategory = item.category.name
|
||||
|
||||
if itemGroup == "Ship Modifiers":
|
||||
return "", None
|
||||
elif itemGroup in ("Energy Weapon", "Hybrid Weapon", "Projectile Weapon", "Combat Drone", "Fighter Drone"):
|
||||
trackingSpeed = stuff.getModifiedItemAttr("trackingSpeed")
|
||||
if not trackingSpeed:
|
||||
return "", None
|
||||
text = "{0}".format(formatAmount(trackingSpeed, 3, 0, 3))
|
||||
tooltip = "Tracking speed"
|
||||
return text, tooltip
|
||||
elif itemCategory == "Subsystem":
|
||||
slots = ("hi", "med", "low")
|
||||
info = []
|
||||
for slot in slots:
|
||||
n = int(stuff.getModifiedItemAttr("%sSlotModifier"%slot))
|
||||
if n > 0:
|
||||
info.append("{0}{1}".format(n, slot[0].upper()))
|
||||
return "+ "+", ".join(info), "Slot Modifiers"
|
||||
elif itemGroup == "Energy Destabilizer":
|
||||
neutAmount = stuff.getModifiedItemAttr("energyDestabilizationAmount")
|
||||
cycleTime = stuff.cycleTime
|
||||
|
||||
@@ -403,6 +403,10 @@ class FittingView(d.Display):
|
||||
self.mods = fit.modules[:]
|
||||
self.mods.sort(key=lambda mod: (slotOrder.index(mod.slot), mod.position))
|
||||
|
||||
# Blanks is a list of indexes that mark non-module positions (such
|
||||
# as Racks and tactical Modes. This allows us to skip over common
|
||||
# module operations such as swapping, removing, copying, etc. that
|
||||
# would otherwise cause complications
|
||||
self.blanks = [] # preliminary markers where blanks will be inserted
|
||||
|
||||
if sFit.serviceFittingOptions["rackSlots"]:
|
||||
@@ -419,6 +423,15 @@ class FittingView(d.Display):
|
||||
for i, (x, slot) in enumerate(self.blanks):
|
||||
self.blanks[i] = x+i # modify blanks with actual index
|
||||
self.mods.insert(x+i, Rack.buildRack(slot))
|
||||
|
||||
if fit.mode:
|
||||
# Modes are special snowflakes and need a little manual loving
|
||||
# We basically append the Mode rack and Mode to the modules
|
||||
# while also marking their positions in the Blanks list
|
||||
self.blanks.append(len(self.mods))
|
||||
self.mods.append(Rack.buildRack(Slot.MODE))
|
||||
self.blanks.append(len(self.mods))
|
||||
self.mods.append(fit.mode)
|
||||
else:
|
||||
self.mods = None
|
||||
|
||||
@@ -457,7 +470,7 @@ class FittingView(d.Display):
|
||||
sel = self.GetFirstSelected()
|
||||
contexts = []
|
||||
|
||||
while sel != -1:
|
||||
while sel != -1 and sel not in self.blanks:
|
||||
mod = self.mods[self.GetItemData(sel)]
|
||||
if not mod.isEmpty:
|
||||
srcContext = "fittingModule"
|
||||
@@ -544,14 +557,17 @@ class FittingView(d.Display):
|
||||
|
||||
font = (self.GetClassDefaultAttributes()).font
|
||||
for i, mod in enumerate(self.mods):
|
||||
if slotMap[mod.slot]:
|
||||
if hasattr(mod,"slot") and slotMap[mod.slot]:
|
||||
self.SetItemBackgroundColour(i, wx.Colour(204, 51, 51))
|
||||
elif sFit.serviceFittingOptions["colorFitBySlot"] and not isinstance(mod, Rack):
|
||||
self.SetItemBackgroundColour(i, self.slotColour(mod.slot))
|
||||
else:
|
||||
self.SetItemBackgroundColour(i, self.GetBackgroundColour())
|
||||
|
||||
if i in self.blanks and sFit.serviceFittingOptions["rackSlots"] and sFit.serviceFittingOptions["rackLabels"]:
|
||||
# Set rack face to bold
|
||||
if isinstance(mod, Rack) and \
|
||||
sFit.serviceFittingOptions["rackSlots"] and \
|
||||
sFit.serviceFittingOptions["rackLabels"]:
|
||||
font.SetWeight(wx.FONTWEIGHT_BOLD)
|
||||
self.SetItemFont(i, font)
|
||||
else:
|
||||
|
||||
@@ -31,13 +31,13 @@ class CharacterSelection(wx.Panel):
|
||||
mainSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.SetSizer(mainSizer)
|
||||
|
||||
mainSizer.Add(wx.StaticText(self, wx.ID_ANY, "Character: "), 0, wx.CENTER | wx.TOP | wx.RIGHT | wx.LEFT, 3)
|
||||
mainSizer.Add(wx.StaticText(self, wx.ID_ANY, "Character: "), 0, wx.CENTER | wx.RIGHT | wx.LEFT, 3)
|
||||
|
||||
# cache current selection to fall back in case we choose to open char editor
|
||||
self.charCache = None
|
||||
|
||||
self.charChoice = wx.Choice(self)
|
||||
mainSizer.Add(self.charChoice, 1, wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.RIGHT | wx.LEFT, 3)
|
||||
mainSizer.Add(self.charChoice, 1, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 3)
|
||||
|
||||
self.refreshCharacterList()
|
||||
|
||||
@@ -56,11 +56,11 @@ class CharacterSelection(wx.Panel):
|
||||
self.btnRefresh.Bind(wx.EVT_BUTTON, self.refreshApi)
|
||||
self.btnRefresh.Enable(False)
|
||||
|
||||
mainSizer.Add(self.btnRefresh, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.RIGHT | wx.LEFT, 2)
|
||||
mainSizer.Add(self.btnRefresh, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 2)
|
||||
|
||||
self.skillReqsStaticBitmap = wx.StaticBitmap(self)
|
||||
self.skillReqsStaticBitmap.SetBitmap(self.cleanSkills)
|
||||
mainSizer.Add(self.skillReqsStaticBitmap, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.RIGHT | wx.LEFT, 3)
|
||||
mainSizer.Add(self.skillReqsStaticBitmap, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 3)
|
||||
|
||||
self.Bind(wx.EVT_CHOICE, self.charChanged)
|
||||
self.mainFrame.Bind(GE.CHAR_LIST_UPDATED, self.refreshCharacterList)
|
||||
|
||||
@@ -21,29 +21,47 @@ import wx
|
||||
|
||||
class ContextMenu(object):
|
||||
menus = []
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
ContextMenu.menus.append(cls)
|
||||
|
||||
@classmethod
|
||||
def getMenu(cls, selection, *fullContexts):
|
||||
menu = wx.Menu()
|
||||
menu.info = {}
|
||||
menu.selection = selection
|
||||
"""
|
||||
getMenu returns a menu that is used with wx.PopupMenu.
|
||||
|
||||
selection: provides a list of what was selected. If only 1 item was
|
||||
selected, it's is a 1-item list or tuple. Can also be None for
|
||||
contexts without selection, such as statsPane or projected view
|
||||
fullContexts: a number of tuples of the following tuple:
|
||||
srcContext - context were menu was spawned, eg: projectedFit,
|
||||
cargoItem, etc
|
||||
itemContext - usually the name of the item's category
|
||||
|
||||
eg:
|
||||
(('fittingModule', 'Module'), ('fittingShip', 'Ship'))
|
||||
(('marketItemGroup', 'Implant'),)
|
||||
(('fittingShip', 'Ship'),)
|
||||
"""
|
||||
|
||||
rootMenu = wx.Menu()
|
||||
rootMenu.info = {}
|
||||
rootMenu.selection = (selection,) if not hasattr(selection, "__iter__") else selection
|
||||
empty = True
|
||||
menu.Bind(wx.EVT_MENU, cls.handler)
|
||||
for i, fullContext in enumerate(fullContexts):
|
||||
amount = 0
|
||||
srcContext = fullContext[0]
|
||||
try:
|
||||
itmContext = fullContext[1]
|
||||
itemContext = fullContext[1]
|
||||
except IndexError:
|
||||
itmContext = None
|
||||
itemContext = None
|
||||
for menuHandler in cls.menus:
|
||||
# loop through registered menus
|
||||
m = menuHandler()
|
||||
if m.display(srcContext, selection):
|
||||
amount += 1
|
||||
texts = m.getText(itmContext, selection)
|
||||
texts = m.getText(itemContext, selection)
|
||||
if isinstance(texts, basestring):
|
||||
texts = (texts,)
|
||||
|
||||
@@ -51,54 +69,72 @@ class ContextMenu(object):
|
||||
multiple = not isinstance(bitmap, wx.Bitmap)
|
||||
for it, text in enumerate(texts):
|
||||
id = wx.NewId()
|
||||
item = wx.MenuItem(menu, id, text)
|
||||
menu.info[id] = (m, fullContext, it)
|
||||
rootItem = wx.MenuItem(rootMenu, id, text)
|
||||
rootMenu.info[id] = (m, fullContext, it)
|
||||
|
||||
sub = m.getSubMenu(srcContext, selection, menu, it, item)
|
||||
if sub is not None:
|
||||
item.SetSubMenu(sub)
|
||||
sub = m.getSubMenu(srcContext, selection, rootMenu, it, rootItem)
|
||||
if sub is None:
|
||||
# if there is no sub menu, bind the handler to the rootItem
|
||||
rootMenu.Bind(wx.EVT_MENU, cls.handler, rootItem)
|
||||
else:
|
||||
# If there is a submenu, it is expected that the sub
|
||||
# logic take care of it's own binding. No binding is
|
||||
# done here
|
||||
#
|
||||
# It is important to remember that when binding sub
|
||||
# menu items, bind them to the rootMenu for proper
|
||||
# event handling, eg:
|
||||
# rootMenu.Bind(wx.EVE_MENU, self.handle, menuItem)
|
||||
rootItem.SetSubMenu(sub)
|
||||
|
||||
if bitmap is not None:
|
||||
if multiple:
|
||||
bp = bitmap[it]
|
||||
if bp:
|
||||
item.SetBitmap(bp)
|
||||
rootItem.SetBitmap(bp)
|
||||
else:
|
||||
item.SetBitmap(bitmap)
|
||||
rootItem.SetBitmap(bitmap)
|
||||
|
||||
menu.AppendItem(item)
|
||||
rootMenu.AppendItem(rootItem)
|
||||
|
||||
empty = False
|
||||
|
||||
if amount > 0 and i != len(fullContexts) - 1:
|
||||
menu.AppendSeparator()
|
||||
rootMenu.AppendSeparator()
|
||||
|
||||
return menu if empty is False else None
|
||||
return rootMenu if empty is False else None
|
||||
|
||||
@classmethod
|
||||
def handler(cls, event):
|
||||
menu = event.EventObject
|
||||
stuff = menu.info.get(event.Id)
|
||||
if stuff is not None:
|
||||
m, context, i = stuff
|
||||
menuHandler, context, i = stuff
|
||||
selection = menu.selection
|
||||
if not hasattr(selection, "__iter__"):
|
||||
selection = (selection,)
|
||||
|
||||
m.activate(context, selection, i)
|
||||
menuHandler.activate(context, selection, i)
|
||||
else:
|
||||
event.Skip()
|
||||
|
||||
def display(self, context, selection):
|
||||
raise NotImplementedError()
|
||||
|
||||
def activate(self, context, selection, i):
|
||||
def activate(self, fullContext, selection, i):
|
||||
return None
|
||||
|
||||
def getSubMenu(self, context, selection, menu, i, pitem):
|
||||
def getSubMenu(self, context, selection, rootMenu, i, pitem):
|
||||
return None
|
||||
|
||||
def getText(self, context, selection):
|
||||
"""
|
||||
getText should be implemented in child classes, and should return either
|
||||
a string that will make up a menu item label or a list of strings which
|
||||
will make numerous menu items.
|
||||
|
||||
These menu items will be added to the root menu
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def getBitmap(self, context, selection):
|
||||
|
||||
@@ -203,6 +203,8 @@ class GraphFrame(wx.Frame):
|
||||
legend.append(fit.name)
|
||||
except:
|
||||
self.SetStatusText("Invalid values in '%s'" % fit.name)
|
||||
self.canvas.draw()
|
||||
return
|
||||
|
||||
if self.legendFix and len(legend) > 0:
|
||||
leg = self.subplot.legend(tuple(legend), "upper right" , shadow = False)
|
||||
|
||||
@@ -22,9 +22,9 @@ import re
|
||||
import gui.mainFrame
|
||||
import bitmapLoader
|
||||
import sys
|
||||
import wx.lib.mixins.listctrl as listmix
|
||||
import wx.lib.mixins.listctrl as listmix
|
||||
import wx.html
|
||||
from eos.types import Ship, Module, Skill, Booster, Implant, Drone
|
||||
from eos.types import Ship, Module, Skill, Booster, Implant, Drone, Mode
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
import service
|
||||
import config
|
||||
@@ -32,7 +32,7 @@ import config
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
from gui.utils.compat import OrderedDict
|
||||
from utils.compat import OrderedDict
|
||||
|
||||
class ItemStatsDialog(wx.Dialog):
|
||||
counter = 0
|
||||
@@ -535,7 +535,7 @@ class ItemEffects (wx.Panel):
|
||||
|
||||
|
||||
class ItemAffectedBy (wx.Panel):
|
||||
ORDER = [Ship, Module, Drone, Implant, Booster, Skill]
|
||||
ORDER = [Ship, Mode, Module, Drone, Implant, Booster, Skill]
|
||||
def __init__(self, parent, stuff, item):
|
||||
wx.Panel.__init__ (self, parent)
|
||||
self.stuff = stuff
|
||||
|
||||
@@ -100,7 +100,8 @@ class MainFrame(wx.Frame):
|
||||
return cls.__instance if cls.__instance is not None else MainFrame()
|
||||
|
||||
def __init__(self):
|
||||
wx.Frame.__init__(self, None, wx.ID_ANY, title="pyfa - Python Fitting Assistant")
|
||||
title="pyfa %s%s - Python Fitting Assistant"%(config.version, "" if config.tag.lower() != 'git' else " (git)")
|
||||
wx.Frame.__init__(self, None, wx.ID_ANY, title)
|
||||
|
||||
MainFrame.__instance = self
|
||||
|
||||
@@ -166,7 +167,7 @@ class MainFrame(wx.Frame):
|
||||
self.statsPane = StatsPane(self)
|
||||
cstatsSizer.Add(self.statsPane, 0, wx.EXPAND)
|
||||
|
||||
mainSizer.Add(cstatsSizer, 0 , wx.EXPAND)
|
||||
mainSizer.Add(cstatsSizer, 0, wx.EXPAND)
|
||||
|
||||
self.SetSizer(mainSizer)
|
||||
|
||||
@@ -214,7 +215,7 @@ class MainFrame(wx.Frame):
|
||||
|
||||
|
||||
def LoadMainFrameAttribs(self):
|
||||
mainFrameDefaultAttribs = {"wnd_width":1000, "wnd_height": 700, "wnd_maximized": False}
|
||||
mainFrameDefaultAttribs = {"wnd_width": 1000, "wnd_height": 680, "wnd_maximized": False}
|
||||
self.mainFrameAttribs = service.SettingsProvider.getInstance().getSettings("pyfaMainWindowAttribs", mainFrameDefaultAttribs)
|
||||
|
||||
if self.mainFrameAttribs["wnd_maximized"]:
|
||||
@@ -289,6 +290,7 @@ class MainFrame(wx.Frame):
|
||||
event.Skip()
|
||||
|
||||
def ShowAboutBox(self, evt):
|
||||
import eos.config
|
||||
info = wx.AboutDialogInfo()
|
||||
info.Name = "pyfa"
|
||||
info.Version = gui.aboutData.versionString
|
||||
@@ -298,7 +300,8 @@ class MainFrame(wx.Frame):
|
||||
"\n\t".join(gui.aboutData.credits) +
|
||||
"\n\nLicenses:\n\t" +
|
||||
"\n\t".join(gui.aboutData.licenses) +
|
||||
"\n\nPython: \t" + sys.version +
|
||||
"\n\nEVE Data: \t" + eos.config.gamedata_version +
|
||||
"\nPython: \t" + sys.version +
|
||||
"\nwxPython: \t" + wx.__version__ +
|
||||
"\nSQLAlchemy: \t" + sqlalchemy.__version__,
|
||||
700, wx.ClientDC(self))
|
||||
|
||||
@@ -708,7 +708,12 @@ class ShipBrowser(wx.Panel):
|
||||
self.raceselect.Show(False)
|
||||
self.Layout()
|
||||
|
||||
RACE_ORDER = ["amarr", "caldari", "gallente", "minmatar", "sisters", "ore", "serpentis", "angel", "blood", "sansha", "guristas", "jove", None]
|
||||
RACE_ORDER = [
|
||||
"amarr", "caldari", "gallente", "minmatar",
|
||||
"sisters", "ore",
|
||||
"serpentis", "angel", "blood", "sansha", "guristas", "mordu",
|
||||
"jove", None
|
||||
]
|
||||
|
||||
def raceNameKey(self, ship):
|
||||
return self.RACE_ORDER.index(ship.race), ship.name
|
||||
|
||||
@@ -79,7 +79,7 @@ class StatsPane(wx.Panel):
|
||||
|
||||
mainSizer.Add(tp, 0, wx.EXPAND | wx.LEFT, 3)
|
||||
if i < maxviews - 1:
|
||||
mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, style=wx.HORIZONTAL), 0, wx.EXPAND | wx.ALL,2)
|
||||
mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, style=wx.HORIZONTAL), 0, wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, 2)
|
||||
i+=1
|
||||
tp.OnStateChange(tp.GetBestSize())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user