oh god this isn't gonna work

Merge branch 'ebag_importchanges' into test_import

Conflicts:
	config.py
	eos/db/saveddata/queries.py
	eos/effects/chargebonuswarfarecharge.py
	eos/effects/elitebonuscommandshipinformationhiddencs3.py
	eos/effects/elitebonuslogisticremotearmorrepairoptimalfalloff1.py
	eos/effects/energydestabilizationnew.py
	eos/effects/iceharvestingdroneoperationdurationbonus.py
	eos/effects/miningforemanstrengthbonus.py
	eos/effects/modulebonuswarfarelinkarmor.py
	eos/effects/modulebonuswarfarelinkinfo.py
	eos/effects/modulebonuswarfarelinkmining.py
	eos/effects/modulebonuswarfarelinkshield.py
	eos/effects/modulebonuswarfarelinkskirmish.py
	eos/effects/moduletitaneffectgenerator.py
	eos/effects/remotehullrepair.py
	eos/effects/rolebonusremotearmorrepairoptimalfalloff.py
	eos/effects/shipbonusforceauxiliarya4warfarelinksbonus.py
	eos/effects/shipmodesmallmissiledamagepostdiv.py
	eos/effects/structureenergyneutralizerfalloff.py
	eos/effects/structuremoduleeffectstasiswebifier.py
	eos/effects/structurerigmaxtargets.py
	eos/effects/subsystembonusamarrdefensiveinformationwarfarehidden.py
	eos/effects/subsystembonuscaldaridefensiveinformationwarfarehidden.py
	eos/effects/subsystembonusgallentedefensiveinformationwarfarehidden.py
	eos/effects/techtwocommandburstbonus.py
	eos/saveddata/fighter.py
	eos/saveddata/fit.py
	eos/saveddata/module.py
	eve.db
	gui/bitmapLoader.py
	gui/builtinContextMenus/itemStats.py
	gui/builtinStatsViews/miningyieldViewFull.py
	gui/builtinViewColumns/misc.py
	gui/builtinViews/__init__.py
	gui/builtinViews/fittingView.py
	gui/contextMenu.py
	gui/graphFrame.py
	gui/itemStats.py
	gui/mainFrame.py
	gui/marketBrowser.py
	service/__init__.py
	service/character.py
	service/fit.py
	service/port.py
	service/prefetch.py
	service/pycrest/eve.py
	service/settings.py
This commit is contained in:
blitzman
2017-01-23 21:06:12 -05:00
284 changed files with 8161 additions and 7135 deletions

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,13 +15,15 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
class PFListPane(wx.ScrolledWindow):
def __init__(self, parent):
wx.ScrolledWindow.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(1, 1), style=wx.TAB_TRAVERSAL)
wx.ScrolledWindow.__init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(1, 1),
style=wx.TAB_TRAVERSAL)
self._wList = []
self._wCount = 0
@@ -29,19 +31,18 @@ class PFListPane(wx.ScrolledWindow):
self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
self.SetVirtualSize((1, 1))
self.SetScrollRate(0, 1)
self.Bind(wx.EVT_SCROLLWIN_LINEUP, self.MScrollUp)
self.Bind(wx.EVT_SCROLLWIN_LINEDOWN, self.MScrollDown)
# self.Bind(wx.EVT_CHILD_FOCUS, self.OnChildFocus)
# self.Bind(wx.EVT_LEFT_DOWN, self.ForceFocus)
# self.Bind(wx.EVT_CHILD_FOCUS, self.OnChildFocus)
# self.Bind(wx.EVT_LEFT_DOWN, self.ForceFocus)
self.SetFocus()
# self.Bind(wx.EVT_MOUSE_CAPTURE_CHANGED, self.ForceFocus)
# self.Bind(wx.EVT_MOUSE_CAPTURE_CHANGED, self.ForceFocus)
self.Bind(wx.EVT_SCROLLWIN_THUMBRELEASE, self.ForceFocus)
def ForceFocus(self,event):
def ForceFocus(self, event):
if self.FindFocus() and self.FindFocus().Parent != self:
self.SetFocus()
event.Skip()
@@ -67,13 +68,12 @@ class PFListPane(wx.ScrolledWindow):
event.Skip()
def ScrollChildIntoView(self, child):
"""
Scrolls the panel such that the specified child window is in view.
"""
sppu_x, sppu_y = self.GetScrollPixelsPerUnit()
vs_x, vs_y = self.GetViewStart()
vs_x, vs_y = self.GetViewStart()
cr = child.GetRect()
clntsz = self.GetSize()
new_vs_x, new_vs_y = -1, -1
@@ -110,8 +110,6 @@ class PFListPane(wx.ScrolledWindow):
if new_vs_x != -1 or new_vs_y != -1:
self.Scroll(new_vs_x, new_vs_y)
def AddWidget(self, widget):
widget.Reparent(self)
self._wList.append(widget)
@@ -124,13 +122,11 @@ class PFListPane(wx.ScrolledWindow):
def IsWidgetSelectedByContext(self, widget):
return False
def RefreshList(self, doRefresh = False, doFocus = False):
ypos = 0
def RefreshList(self, doRefresh=False, doFocus=False):
maxy = 0
scrollTo = 0
selected = None
for i in xrange( len(self._wList) ):
for i in xrange(len(self._wList)):
iwidth, iheight = self._wList[i].GetSize()
xa, ya = self.CalcScrolledPosition((0, maxy))
self._wList[i].SetPosition((xa, ya))
@@ -143,16 +139,16 @@ class PFListPane(wx.ScrolledWindow):
if selected:
self.ScrollChildIntoView(selected)
#selected.SetFocus()
# selected.SetFocus()
elif doFocus:
self.SetFocus()
clientW,clientH = self.GetSize()
for i in xrange( len(self._wList) ):
clientW, clientH = self.GetSize()
for i in xrange(len(self._wList)):
iwidth, iheight = self._wList[i].GetSize()
itemX,itemY = self._wList[i].GetPosition()
itemX, itemY = self._wList[i].GetPosition()
self._wList[i].SetSize((cwidth, iheight))
if doRefresh == True:
if doRefresh is True:
self._wList[i].Refresh()
self.itemsHeight = max(self.itemsHeight, iheight - 1)
@@ -160,7 +156,6 @@ class PFListPane(wx.ScrolledWindow):
child.Destroy()
self._wList.remove(child)
def RemoveAllChildren(self):
for widget in self._wList:
widget.Destroy()

View File

@@ -1,17 +1,16 @@
import wx
import gui.utils.colorUtils as colorUtils
import gui.utils.drawUtils as drawUtils
from gui.bitmapLoader import BitmapLoader
SearchButton, EVT_SEARCH_BTN = wx.lib.newevent.NewEvent()
CancelButton, EVT_CANCEL_BTN = wx.lib.newevent.NewEvent()
TextEnter, EVT_TEXT_ENTER = wx.lib.newevent.NewEvent()
TextTyped, EVT_TEXT = wx.lib.newevent.NewEvent()
class PFSearchBox(wx.Window):
def __init__(self, parent, id = wx.ID_ANY, value = "", pos = wx.DefaultPosition, size = wx.Size(-1,24), style = 0):
wx.Window.__init__(self, parent, id, pos, size, style = style)
def __init__(self, parent, id=wx.ID_ANY, value="", pos=wx.DefaultPosition, size=wx.Size(-1, 24), style=0):
wx.Window.__init__(self, parent, id, pos, size, style=style)
self.isSearchButtonVisible = False
self.isCancelButtonVisible = False
@@ -35,13 +34,14 @@ class PFSearchBox(wx.Window):
self.editX = 0
self.editY = 0
self.padding = 4
self._hl = False
w,h = size
self.EditBox = wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPosition, (-1, h - 2 if 'wxGTK' in wx.PlatformInfo else -1 ), wx.TE_PROCESS_ENTER | (wx.BORDER_NONE if 'wxGTK' in wx.PlatformInfo else 0))
w, h = size
self.EditBox = wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPosition,
(-1, h - 2 if 'wxGTK' in wx.PlatformInfo else -1),
wx.TE_PROCESS_ENTER | (wx.BORDER_NONE if 'wxGTK' in wx.PlatformInfo else 0))
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBk)
@@ -50,7 +50,7 @@ class PFSearchBox(wx.Window):
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
# self.EditBox.ChangeValue(self.descriptiveText)
# self.EditBox.ChangeValue(self.descriptiveText)
self.EditBox.Bind(wx.EVT_SET_FOCUS, self.OnEditSetFocus)
self.EditBox.Bind(wx.EVT_KILL_FOCUS, self.OnEditKillFocus)
@@ -68,11 +68,10 @@ class PFSearchBox(wx.Window):
wx.PostEvent(self, TextEnter())
event.Skip()
def OnEditSetFocus(self, event):
# value = self.EditBox.GetValue()
# if value == self.descriptiveText:
# self.EditBox.ChangeValue("")
# value = self.EditBox.GetValue()
# if value == self.descriptiveText:
# self.EditBox.ChangeValue("")
event.Skip()
def OnEditKillFocus(self, event):
@@ -80,10 +79,9 @@ class PFSearchBox(wx.Window):
self.Clear()
event.Skip()
def Clear(self):
self.EditBox.Clear()
# self.EditBox.ChangeValue(self.descriptiveText)
# self.EditBox.ChangeValue(self.descriptiveText)
def Focus(self):
self.EditBox.SetFocus()
@@ -110,8 +108,8 @@ class PFSearchBox(wx.Window):
def GetButtonsPos(self):
btnpos = []
btnpos.append( (self.searchButtonX, self.searchButtonY) )
btnpos.append( (self.cancelButtonX, self.cancelButtonY) )
btnpos.append((self.searchButtonX, self.searchButtonY))
btnpos.append((self.cancelButtonX, self.cancelButtonY))
return btnpos
def GetButtonsSize(self):
@@ -131,8 +129,8 @@ class PFSearchBox(wx.Window):
cw = 0
ch = 0
btnsize.append( (sw,sh))
btnsize.append( (cw,ch))
btnsize.append((sw, sh))
btnsize.append((cw, ch))
return btnsize
def OnLeftDown(self, event):
@@ -140,7 +138,7 @@ class PFSearchBox(wx.Window):
btnsize = self.GetButtonsSize()
self.CaptureMouse()
for btn in xrange(2):
for btn in range(2):
if self.HitTest(btnpos[btn], event.GetPosition(), btnsize[btn]):
if btn == 0:
if not self.searchButtonPressed:
@@ -158,7 +156,7 @@ class PFSearchBox(wx.Window):
if self.HasCapture():
self.ReleaseMouse()
for btn in xrange(2):
for btn in range(2):
if self.HitTest(btnpos[btn], event.GetPosition(), btnsize[btn]):
if btn == 0:
if self.searchButtonPressed:
@@ -218,9 +216,9 @@ class PFSearchBox(wx.Window):
editWidth, editHeight = self.EditBox.GetSize()
self.editY = (cheight - editHeight)/2
self.editY = (cheight - editHeight) / 2
self.EditBox.SetPosition((self.editX, self.editY))
self.EditBox.SetSize( (self.cancelButtonX - self.padding - self.editX, -1))
self.EditBox.SetSize((self.cancelButtonX - self.padding - self.editX, -1))
def OnPaint(self, event):
dc = wx.BufferedPaintDC(self)
@@ -246,7 +244,6 @@ class PFSearchBox(wx.Window):
dc.DrawBitmap(self.searchBitmapShadow, self.searchButtonX + 1, self.searchButtonY + 1)
dc.DrawBitmap(self.searchBitmap, self.searchButtonX + spad, self.searchButtonY + spad)
if self.isCancelButtonVisible:
if self.cancelBitmap:
if self.cancelButtonPressed:
@@ -256,8 +253,8 @@ class PFSearchBox(wx.Window):
dc.DrawBitmap(self.cancelBitmapShadow, self.cancelButtonX + 1, self.cancelButtonY + 1)
dc.DrawBitmap(self.cancelBitmap, self.cancelButtonX + cpad, self.cancelButtonY + cpad)
dc.SetPen(wx.Pen(sepColor,1))
dc.DrawLine(0,rect.height - 1, rect.width, rect.height - 1)
dc.SetPen(wx.Pen(sepColor, 1))
dc.DrawLine(0, rect.height - 1, rect.width, rect.height - 1)
def SetSearchBitmap(self, bitmap):
self.searchBitmap = bitmap
@@ -273,10 +270,10 @@ class PFSearchBox(wx.Window):
def IsCancelButtonVisible(self):
return self.isCancelButtonVisible
def ShowSearchButton(self, show = True):
def ShowSearchButton(self, show=True):
self.isSearchButtonVisible = show
def ShowCancelButton(self, show = True):
def ShowCancelButton(self, show=True):
self.isCancelButtonVisible = show
def SetDescriptiveText(self, text):
@@ -284,4 +281,3 @@ class PFSearchBox(wx.Window):
def GetDescriptiveText(self):
return self.descriptiveText

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,7 +15,8 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import config
versionString = "{0} {1} - {2} {3}".format(config.version, config.tag, config.expansionName, config.expansionVersion)
@@ -27,7 +28,7 @@ licenses = (
)
developers = (
"blitzmann \tSable Blitzmann (maintainer)",
"cncfanatics \tSakari Orisi (retired)" ,
"cncfanatics \tSakari Orisi (retired)",
"DarkPhoenix \tKadesh Priestess (retired)",
"Darriele \t\tDarriele (retired)",
"Ebag333 \t\tEbag Trescientas"

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import gui.mainFrame
@@ -33,11 +33,11 @@ from gui.bitmapLoader import BitmapLoader
import gui.chromeTabs
class AdditionsPane(TogglePanel):
class AdditionsPane(TogglePanel):
def __init__(self, parent):
TogglePanel.__init__(self, parent, forceLayout = 1)
TogglePanel.__init__(self, parent, forceLayout=1)
self.SetLabel("Additions")
pane = self.GetContentPane()
@@ -62,28 +62,28 @@ class AdditionsPane(TogglePanel):
notesImg = BitmapLoader.getImage("skill_small", "gui")
self.drone = DroneView(self.notebook)
self.notebook.AddPage(self.drone, "Drones", tabImage = droneImg, showClose = False)
self.notebook.AddPage(self.drone, "Drones", tabImage=droneImg, showClose=False)
self.fighter = FighterView(self.notebook)
self.notebook.AddPage(self.fighter, "Fighters", tabImage = fighterImg, showClose = False)
self.notebook.AddPage(self.fighter, "Fighters", tabImage=fighterImg, showClose=False)
self.cargo = CargoView(self.notebook)
self.notebook.AddPage(self.cargo, "Cargo", tabImage = cargoImg, showClose = False)
self.notebook.AddPage(self.cargo, "Cargo", tabImage=cargoImg, showClose=False)
self.implant = ImplantView(self.notebook)
self.notebook.AddPage(self.implant, "Implants", tabImage = implantImg, showClose = False)
self.notebook.AddPage(self.implant, "Implants", tabImage=implantImg, showClose=False)
self.booster = BoosterView(self.notebook)
self.notebook.AddPage(self.booster, "Boosters", tabImage = boosterImg, showClose = False)
self.notebook.AddPage(self.booster, "Boosters", tabImage=boosterImg, showClose=False)
self.projectedPage = ProjectedView(self.notebook)
self.notebook.AddPage(self.projectedPage, "Projected", tabImage = projectedImg, showClose = False)
self.notebook.AddPage(self.projectedPage, "Projected", tabImage=projectedImg, showClose=False)
self.gangPage = CommandView(self.notebook)
self.notebook.AddPage(self.gangPage, "Command", tabImage = gangImg, showClose = False)
self.notebook.AddPage(self.gangPage, "Command", tabImage=gangImg, showClose=False)
self.notes = NotesView(self.notebook)
self.notebook.AddPage(self.notes, "Notes", tabImage = notesImg, showClose = False)
self.notebook.AddPage(self.notes, "Notes", tabImage=notesImg, showClose=False)
self.notebook.SetSelection(0)
@@ -100,12 +100,12 @@ class AdditionsPane(TogglePanel):
def toggleContent(self, event):
TogglePanel.toggleContent(self, event)
h = self.headerPanel.GetSize()[1]+4
h = self.headerPanel.GetSize()[1] + 4
if self.IsCollapsed():
self.old_pos = self.parent.GetSashPosition()
self.parent.SetMinimumPaneSize(h)
self.parent.SetSashPosition(h*-1, True)
self.parent.SetSashPosition(h * -1, True)
# only available in >= wx2.9
if getattr(self.parent, "SetSashInvisible", None):
self.parent.SetSashInvisible(True)
@@ -114,4 +114,3 @@ class AdditionsPane(TogglePanel):
self.parent.SetSashInvisible(False)
self.parent.SetMinimumPaneSize(200)
self.parent.SetSashPosition(self.old_pos, True)

View File

@@ -1,4 +1,4 @@
# ===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
# ===============================================================================
# =============================================================================
import cStringIO
import os.path
@@ -86,11 +86,11 @@ class BitmapLoader():
sbuf = cStringIO.StringIO(img_data)
return wx.ImageFromStream(sbuf)
except KeyError:
print "Missing icon file from zip: {0}".format(path)
print("Missing icon file from zip: {0}".format(path))
else:
path = config.getPyfaPath('imgs\\' + location + "\\" + filename)
if os.path.exists(path):
return wx.Image(path)
else:
print "Missing icon file: {0}".format(path)
print("Missing icon file: {0}".format(path))

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,29 +15,31 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import service
import gui.display as d
import gui.globalEvents as GE
import gui.marketBrowser as mb
from gui.builtinViewColumns.state import State
from gui.contextMenu import ContextMenu
from service.fit import Fit
class BoosterViewDrop(wx.PyDropTarget):
def __init__(self, dropFn):
wx.PyDropTarget.__init__(self)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.SetDataObject(self.dropData)
def __init__(self, dropFn):
wx.PyDropTarget.__init__(self)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
if self.GetData():
data = self.dropData.GetText().split(':')
self.dropFn(x, y, data)
return t
def OnData(self, x, y, t):
if self.GetData():
data = self.dropData.GetText().split(':')
self.dropFn(x, y, data)
return t
class BoosterView(d.Display):
DEFAULT_COLS = ["State",
@@ -58,7 +60,7 @@ class BoosterView(d.Display):
self.SetDropTarget(BoosterViewDrop(self.handleListDrag))
if "__WXGTK__" in wx.PlatformInfo:
if "__WXGTK__" in wx.PlatformInfo:
self.Bind(wx.EVT_RIGHT_UP, self.scheduleMenu)
else:
self.Bind(wx.EVT_RIGHT_DOWN, self.scheduleMenu)
@@ -75,7 +77,7 @@ class BoosterView(d.Display):
if data[0] == "market":
wx.PostEvent(self.mainFrame, mb.ItemSelected(itemID=int(data[1])))
def kbEvent(self,event):
def kbEvent(self, event):
keycode = event.GetKeyCode()
if keycode == wx.WXK_DELETE or keycode == wx.WXK_NUMPAD_DELETE:
row = self.GetFirstSelected()
@@ -85,12 +87,12 @@ class BoosterView(d.Display):
event.Skip()
def fitChanged(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(event.fitID)
self.Parent.Parent.DisablePage(self, not fit or fit.isStructure)
#Clear list and get out if current fitId is None
# Clear list and get out if current fitId is None
if event.fitID is None and self.lastFitId is not None:
self.DeleteAllItems()
self.lastFitId = None
@@ -115,7 +117,7 @@ class BoosterView(d.Display):
event.Skip()
def addItem(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
@@ -139,7 +141,7 @@ class BoosterView(d.Display):
def removeBooster(self, booster):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.removeBooster(fitID, self.origional.index(booster))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -150,11 +152,10 @@ class BoosterView(d.Display):
col = self.getColumn(event.Position)
if col == self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.toggleBooster(fitID, row)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def scheduleMenu(self, event):
event.Skip()
if self.getColumn(event.Position) != self.getColIndex(State):
@@ -163,7 +164,7 @@ class BoosterView(d.Display):
def spawnMenu(self):
sel = self.GetFirstSelected()
if sel != -1:
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(self.mainFrame.getActiveFit())
item = fit.boosters[sel]

View File

@@ -1,6 +1,6 @@
__all__ = [
"openFit",
#"moduleGlobalAmmoPicker",
# "moduleGlobalAmmoPicker",
"moduleAmmoPicker",
"itemStats",
"damagePattern",

View File

@@ -1,35 +1,37 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import wx
import gui.globalEvents as GE
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
item = selection[0]
for attr in ("emDamage", "thermalDamage", "explosiveDamage", "kineticDamage"):
if item.getAttribute(attr) is not None:
return True
return False
def getText(self, itmContext, selection):
return "Set {0} as Damage Pattern".format(itmContext if itmContext is not None else "Item")
def activate(self, fullContext, selection, i):
item = selection[0]
fit = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit.setAsPattern(fit, item)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fit))
def getBitmap(self, context, selection):
return None
AmmoPattern.register()
from gui.contextMenu import ContextMenu
import gui.mainFrame
import wx
import gui.globalEvents as GE
from service.fit import Fit
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
item = selection[0]
for attr in ("emDamage", "thermalDamage", "explosiveDamage", "kineticDamage"):
if item.getAttribute(attr) is not None:
return True
return False
def getText(self, itmContext, selection):
return "Set {0} as Damage Pattern".format(itmContext if itmContext is not None else "Item")
def activate(self, fullContext, selection, i):
item = selection[0]
fit = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
sFit.setAsPattern(fit, item)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fit))
def getBitmap(self, context, selection):
return None
AmmoPattern.register()

View File

@@ -1,17 +1,19 @@
from gui.contextMenu import ContextMenu
from gui.itemStats import ItemStatsDialog
import eos.types
import gui.mainFrame
import service
import gui.globalEvents as GE
import wx
from service.fit import Fit
from eos.saveddata.cargo import Cargo as es_Cargo
from eos.saveddata.fighter import Fighter as es_Fighter
class ChangeAmount(ContextMenu):
def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
def display(self, srcContext, selection):
return srcContext in ("cargoItem","projectedFit","fighterItem","projectedFighter")
return srcContext in ("cargoItem", "projectedFit", "fighterItem", "projectedFighter")
def getText(self, itmContext, selection):
return "Change {0} Quantity".format(itmContext)
@@ -21,10 +23,11 @@ class ChangeAmount(ContextMenu):
dlg = AmountChanger(self.mainFrame, selection[0], srcContext)
dlg.ShowModal()
ChangeAmount.register()
class AmountChanger(wx.Dialog):
class AmountChanger(wx.Dialog):
def __init__(self, parent, thing, context):
wx.Dialog.__init__(self, parent, title="Select Amount", size=wx.Size(220, 60))
self.thing = thing
@@ -46,15 +49,15 @@ class AmountChanger(wx.Dialog):
self.button.Bind(wx.EVT_BUTTON, self.change)
def change(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
mainFrame = gui.mainFrame.MainFrame.getInstance()
fitID = mainFrame.getActiveFit()
if isinstance(self.thing, eos.types.Cargo):
if isinstance(self.thing, es_Cargo):
sFit.addCargo(fitID, self.thing.item.ID, int(self.input.GetLineText(0)), replace=True)
elif isinstance(self.thing, eos.types.Fit):
sFit.changeAmount(fitID, self.thing, int(self.input.GetLineText(0)))
elif isinstance(self.thing, eos.types.Fighter):
elif isinstance(self.thing, es_Fighter):
sFit.changeActiveFighters(fitID, self.thing, int(self.input.GetLineText(0)))
wx.PostEvent(mainFrame, GE.FitChanged(fitID=fitID))
@@ -62,15 +65,14 @@ class AmountChanger(wx.Dialog):
event.Skip()
self.Close()
## checks to make sure it's valid number
# checks to make sure it's valid number
def onChar(self, event):
key = event.GetKeyCode()
acceptable_characters = "1234567890"
acceptable_keycode = [3, 22, 13, 8, 127] # modifiers like delete, copy, paste
acceptable_keycode = [3, 22, 13, 8, 127] # modifiers like delete, copy, paste
if key in acceptable_keycode or key >= 255 or (key < 255 and chr(key) in acceptable_characters):
event.Skip()
return
else:
return False

View File

@@ -1,17 +1,16 @@
from gui.contextMenu import ContextMenu
from gui.itemStats import ItemStatsDialog
import eos.types
import gui.mainFrame
import service
import gui.globalEvents as GE
import wx
from service.fit import Fit
class Cargo(ContextMenu):
def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
def display(self, srcContext, selection):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
@@ -24,7 +23,7 @@ class Cargo(ContextMenu):
return "Add {0} to Cargo".format(itmContext)
def activate(self, fullContext, selection, i):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
typeID = int(selection[0].ID)
@@ -32,4 +31,5 @@ class Cargo(ContextMenu):
self.mainFrame.additionsPane.select("Cargo")
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
Cargo.register()

View File

@@ -1,11 +1,13 @@
# -*- coding: utf-8 -*-
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import wx
from gui.bitmapLoader import BitmapLoader
from eos.types import Skill
import gui.globalEvents as GE
from service.fit import Fit
from service.character import Character
class ChangeAffectingSkills(ContextMenu):
def __init__(self):
@@ -15,18 +17,18 @@ class ChangeAffectingSkills(ContextMenu):
if self.mainFrame.getActiveFit() is None or srcContext not in ("fittingModule", "fittingCharge", "fittingShip"):
return False
self.sChar = service.Character.getInstance()
self.sFit = service.Fit.getInstance()
self.sChar = Character.getInstance()
self.sFit = 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"):
# if self.sChar.getCharName(self.charID) in ("All 0", "All 5"):
# return False
if srcContext == "fittingShip":
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
self.stuff = sFit.getFit(fitID).ship
cont = sFit.getFit(fitID).ship.itemModifiedAttributes
elif srcContext == "fittingCharge":
@@ -99,4 +101,5 @@ class ChangeAffectingSkills(ContextMenu):
wx.PostEvent(self.mainFrame, GE.CharListUpdated())
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
ChangeAffectingSkills.register()

View File

@@ -1,15 +1,17 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import gui.globalEvents as GE
import wx
from gui.bitmapLoader import BitmapLoader
from service.fit import Fit
from service.damagePattern import DamagePattern as import_DamagePattern
try:
from collections import OrderedDict
except ImportError:
from gui.utils.compat import OrderedDict
class DamagePattern(ContextMenu):
def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
@@ -18,8 +20,8 @@ class DamagePattern(ContextMenu):
return srcContext == "resistancesViewFull" and self.mainFrame.getActiveFit() is not None
def getText(self, itmContext, selection):
sDP = service.DamagePattern.getInstance()
sFit = service.Fit.getInstance()
sDP = import_DamagePattern.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
self.fit = sFit.getFit(fitID)
@@ -34,9 +36,9 @@ class DamagePattern(ContextMenu):
for pattern in self.patterns:
start, end = pattern.name.find('['), pattern.name.find(']')
if start is not -1 and end is not -1:
currBase = pattern.name[start+1:end]
currBase = pattern.name[start + 1:end]
# set helper attr
setattr(pattern, "_name", pattern.name[end+1:].strip())
setattr(pattern, "_name", pattern.name[end + 1:].strip())
if currBase not in self.subMenus:
self.subMenus[currBase] = []
self.subMenus[currBase].append(pattern)
@@ -59,7 +61,7 @@ class DamagePattern(ContextMenu):
menuItem.pattern = pattern
# determine active pattern
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
f = sFit.getFit(fitID)
dp = f.damagePattern
@@ -98,10 +100,11 @@ class DamagePattern(ContextMenu):
event.Skip()
return
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.setDamagePattern(fitID, pattern)
setattr(self.mainFrame,"_activeDmgPattern", pattern)
setattr(self.mainFrame, "_activeDmgPattern", pattern)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
DamagePattern.register()

View File

@@ -1,8 +1,9 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import wx
import gui.globalEvents as GE
from service.fit import Fit
class ItemRemove(ContextMenu):
def __init__(self):
@@ -15,7 +16,7 @@ class ItemRemove(ContextMenu):
return "Remove {0} Stack".format(itmContext)
def activate(self, fullContext, selection, i):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
@@ -24,4 +25,5 @@ class ItemRemove(ContextMenu):
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
ItemRemove.register()

View File

@@ -1,59 +1,59 @@
from gui.contextMenu import ContextMenu
from gui.itemStats import ItemStatsDialog
import gui.mainFrame
import gui.globalEvents as GE
import service
import wx
class DroneSplit(ContextMenu):
def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
def display(self, srcContext, selection):
return srcContext in ("droneItem", "projectedDrone") and selection[0].amount > 1
def getText(self, itmContext, selection):
return "Split {0} Stack".format(itmContext)
def activate(self, fullContext, selection, i):
srcContext = fullContext[0]
dlg = DroneSpinner(self.mainFrame, selection[0], srcContext)
dlg.ShowModal()
dlg.Destroy()
DroneSplit.register()
class DroneSpinner(wx.Dialog):
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)
self.spinner = wx.SpinCtrl(self)
self.spinner.SetRange(1, drone.amount - 1)
self.spinner.SetValue(1)
bSizer1.Add(self.spinner, 0, wx.ALL, 5)
self.button = wx.Button(self, wx.ID_OK, u"Split")
bSizer1.Add(self.button, 0, wx.ALL, 5)
self.SetSizer(bSizer1)
self.Layout()
self.Centre(wx.BOTH)
self.button.Bind(wx.EVT_BUTTON, self.split)
def split(self, event):
sFit = service.Fit.getInstance()
mainFrame = gui.mainFrame.MainFrame.getInstance()
fitID = mainFrame.getActiveFit()
if self.context == "droneItem":
sFit.splitDroneStack(fitID, self.drone, self.spinner.GetValue())
else:
sFit.splitProjectedDroneStack(fitID, self.drone, self.spinner.GetValue())
wx.PostEvent(mainFrame, GE.FitChanged(fitID=fitID))
event.Skip()
from gui.contextMenu import ContextMenu
import gui.mainFrame
import gui.globalEvents as GE
from service.fit import Fit
import wx
class DroneSplit(ContextMenu):
def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
def display(self, srcContext, selection):
return srcContext in ("droneItem", "projectedDrone") and selection[0].amount > 1
def getText(self, itmContext, selection):
return "Split {0} Stack".format(itmContext)
def activate(self, fullContext, selection, i):
srcContext = fullContext[0]
dlg = DroneSpinner(self.mainFrame, selection[0], srcContext)
dlg.ShowModal()
dlg.Destroy()
DroneSplit.register()
class DroneSpinner(wx.Dialog):
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)
self.spinner = wx.SpinCtrl(self)
self.spinner.SetRange(1, drone.amount - 1)
self.spinner.SetValue(1)
bSizer1.Add(self.spinner, 0, wx.ALL, 5)
self.button = wx.Button(self, wx.ID_OK, u"Split")
bSizer1.Add(self.button, 0, wx.ALL, 5)
self.SetSizer(bSizer1)
self.Layout()
self.Centre(wx.BOTH)
self.button.Bind(wx.EVT_BUTTON, self.split)
def split(self, event):
sFit = Fit.getInstance()
mainFrame = gui.mainFrame.MainFrame.getInstance()
fitID = mainFrame.getActiveFit()
if self.context == "droneItem":
sFit.splitDroneStack(fitID, self.drone, self.spinner.GetValue())
else:
sFit.splitProjectedDroneStack(fitID, self.drone, self.spinner.GetValue())
wx.PostEvent(mainFrame, GE.FitChanged(fitID=fitID))
event.Skip()

View File

@@ -1,35 +1,36 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import gui.globalEvents as GE
import wx
from gui.bitmapLoader import BitmapLoader
class FactorReload(ContextMenu):
def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
def display(self, srcContext, selection):
return srcContext == "firepowerViewFull" and self.mainFrame.getActiveFit() is not None
def getText(self, itmContext, selection):
return "Factor in Reload Time"
def activate(self, fullContext, selection, i):
sFit = service.Fit.getInstance()
sFit.serviceFittingOptions["useGlobalForceReload"] = not sFit.serviceFittingOptions["useGlobalForceReload"]
fitID = self.mainFrame.getActiveFit()
sFit.refreshFit(fitID)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def getBitmap(self, context, selection):
sFit = service.Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
if fit.factorReload:
return BitmapLoader.getBitmap("state_active_small", "gui")
else:
return None
FactorReload.register()
from gui.contextMenu import ContextMenu
import gui.mainFrame
import gui.globalEvents as GE
import wx
from gui.bitmapLoader import BitmapLoader
from service.fit import Fit
class FactorReload(ContextMenu):
def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
def display(self, srcContext, selection):
return srcContext == "firepowerViewFull" and self.mainFrame.getActiveFit() is not None
def getText(self, itmContext, selection):
return "Factor in Reload Time"
def activate(self, fullContext, selection, i):
sFit = Fit.getInstance()
sFit.serviceFittingOptions["useGlobalForceReload"] = not sFit.serviceFittingOptions["useGlobalForceReload"]
fitID = self.mainFrame.getActiveFit()
sFit.refreshFit(fitID)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def getBitmap(self, context, selection):
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
if fit.factorReload:
return BitmapLoader.getBitmap("state_active_small", "gui")
else:
return None
FactorReload.register()

View File

@@ -1,8 +1,9 @@
import wx
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import gui.globalEvents as GE
from service.fit import Fit
class FighterAbility(ContextMenu):
def __init__(self):
@@ -48,9 +49,10 @@ class FighterAbility(ContextMenu):
event.Skip()
return
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.toggleFighterAbility(fitID, ability)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
FighterAbility.register()

View File

@@ -1,8 +1,11 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import gui.globalEvents as GE
import wx
from service.implantSet import ImplantSets as s_ImplantSets
from service.character import Character
from service.fit import Fit
class ImplantSets(ContextMenu):
def __init__(self):
@@ -32,7 +35,7 @@ class ImplantSets(ContextMenu):
m = wx.Menu()
bindmenu = rootMenu if "wxMSW" in wx.PlatformInfo else m
sIS = service.ImplantSets.getInstance()
sIS = s_ImplantSets.getInstance()
implantSets = sIS.getImplantSetList()
self.context = context
@@ -59,7 +62,7 @@ class ImplantSets(ContextMenu):
if self.context == "implantEditor":
# we are calling from character editor, the implant source is different
sChar = service.Character.getInstance()
sChar = Character.getInstance()
charID = self.selection.getActiveCharacter()
for implant in set.implants:
@@ -67,7 +70,7 @@ class ImplantSets(ContextMenu):
wx.PostEvent(self.selection, GE.CharChanged())
else:
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
for implant in set.implants:
sFit.addImplant(fitID, implant.item.ID, recalc=implant == set.implants[-1])

View File

@@ -1,8 +1,9 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import wx
import gui.globalEvents as GE
from service.fit import Fit
class ItemRemove(ContextMenu):
def __init__(self):
@@ -21,15 +22,15 @@ class ItemRemove(ContextMenu):
def activate(self, fullContext, selection, i):
srcContext = fullContext[0]
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
if srcContext == "fittingModule":
for module in selection:
if module is not None:
sFit.removeModule(fitID,fit.modules.index(module))
elif srcContext in ("fittingCharge" , "projectedCharge"):
sFit.removeModule(fitID, fit.modules.index(module))
elif srcContext in ("fittingCharge", "projectedCharge"):
sFit.setAmmo(fitID, None, selection)
elif srcContext == "droneItem":
sFit.removeDrone(fitID, fit.drones.index(selection[0]))
@@ -47,6 +48,4 @@ class ItemRemove(ContextMenu):
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
ItemRemove.register()

View File

@@ -1,65 +1,67 @@
from gui.contextMenu import ContextMenu
from gui.itemStats import ItemStatsDialog
import gui.mainFrame
import service
import wx
class ItemStats(ContextMenu):
def __init__(self):
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",
"itemStats", "fighterItem",
"implantItemChar", "projectedFighter",
"fittingMode")
def getText(self, itmContext, selection):
return "{0} Stats".format(itmContext if itmContext is not None else "Item")
def activate(self, fullContext, selection, i):
srcContext = fullContext[0]
if srcContext == "fittingShip":
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
stuff = sFit.getFit(fitID).ship
elif srcContext == "fittingMode":
stuff = selection[0].item
else:
stuff = selection[0]
if srcContext == "fittingModule" and stuff.isEmpty:
return
mstate = wx.GetMouseState()
reuse = False
if mstate.CmdDown():
reuse = True
if self.mainFrame.GetActiveStatsWindow() is None and reuse:
ItemStatsDialog(stuff, fullContext)
elif reuse:
lastWnd = self.mainFrame.GetActiveStatsWindow()
pos = lastWnd.GetPosition()
maximized = lastWnd.IsMaximized()
if not maximized:
size = lastWnd.GetSize()
else:
size = wx.DefaultSize
pos = wx.DefaultPosition
ItemStatsDialog(stuff, fullContext, pos, size, maximized)
lastWnd.closeEvent(None)
else:
ItemStatsDialog(stuff, fullContext)
ItemStats.register()
from gui.contextMenu import ContextMenu
from gui.itemStats import ItemStatsDialog
import gui.mainFrame
import wx
from service.fit import Fit
class ItemStats(ContextMenu):
def __init__(self):
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",
"itemStats", "fighterItem",
"implantItemChar", "projectedFighter",
"fittingMode")
def getText(self, itmContext, selection):
return "{0} Stats".format(itmContext if itmContext is not None else "Item")
def activate(self, fullContext, selection, i):
srcContext = fullContext[0]
if srcContext == "fittingShip":
fitID = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
stuff = sFit.getFit(fitID).ship
elif srcContext == "fittingMode":
stuff = selection[0].item
else:
stuff = selection[0]
if srcContext == "fittingModule" and stuff.isEmpty:
return
mstate = wx.GetMouseState()
reuse = False
if mstate.CmdDown():
reuse = True
if self.mainFrame.GetActiveStatsWindow() is None and reuse:
ItemStatsDialog(stuff, fullContext)
elif reuse:
lastWnd = self.mainFrame.GetActiveStatsWindow()
pos = lastWnd.GetPosition()
maximized = lastWnd.IsMaximized()
if not maximized:
size = lastWnd.GetSize()
else:
size = wx.DefaultSize
pos = wx.DefaultPosition
ItemStatsDialog(stuff, fullContext, pos, size, maximized)
lastWnd.closeEvent(None)
else:
ItemStatsDialog(stuff, fullContext)
ItemStats.register()

View File

@@ -1,48 +1,49 @@
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, srcContext, selection):
validContexts = ("marketItemMisc", "fittingModule",
"fittingCharge", "droneItem",
"implantItem", "boosterItem",
"projectedModule", "projectedDrone",
"projectedCharge", "cargoItem",
"implantItemChar", "fighterItem",
"projectedDrone")
if not srcContext in validContexts or selection is None or len(selection) < 1:
return False
sMkt = service.Market.getInstance()
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
return doit
def getText(self, itmContext, selection):
return "{0} Market Group".format(itmContext if itmContext is not None else "Item")
def activate(self, fullContext, selection, i):
srcContext = fullContext[0]
if srcContext in ("fittingCharge", "projectedCharge"):
item = selection[0].charge
elif hasattr(selection[0], "item"):
item = selection[0].item
else:
item = selection[0]
self.mainFrame.notebookBrowsers.SetSelection(0)
self.mainFrame.marketBrowser.jump(item)
MarketJump.register()
from gui.contextMenu import ContextMenu
import gui.mainFrame
from service.market import Market
class MarketJump(ContextMenu):
def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
def display(self, srcContext, selection):
validContexts = ("marketItemMisc", "fittingModule",
"fittingCharge", "droneItem",
"implantItem", "boosterItem",
"projectedModule", "projectedDrone",
"projectedCharge", "cargoItem",
"implantItemChar", "fighterItem",
"projectedDrone")
if srcContext not in validContexts or selection is None or len(selection) < 1:
return False
sMkt = Market.getInstance()
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
return doit
def getText(self, itmContext, selection):
return "{0} Market Group".format(itmContext if itmContext is not None else "Item")
def activate(self, fullContext, selection, i):
srcContext = fullContext[0]
if srcContext in ("fittingCharge", "projectedCharge"):
item = selection[0].charge
elif hasattr(selection[0], "item"):
item = selection[0].item
else:
item = selection[0]
self.mainFrame.notebookBrowsers.SetSelection(0)
self.mainFrame.marketBrowser.jump(item)
MarketJump.register()

View File

@@ -1,10 +1,13 @@
# -*- coding: utf-8 -*-
from gui.contextMenu import ContextMenu
from gui.itemStats import ItemStatsDialog
import gui.mainFrame
import service
# coding: utf-8
import wx
from service.fit import Fit
from service.market import Market
import gui.mainFrame
import gui.globalEvents as GE
from gui.contextMenu import ContextMenu
class MetaSwap(ContextMenu):
def __init__(self):
@@ -17,7 +20,7 @@ class MetaSwap(ContextMenu):
# Check if list of variations is same for all of selection
# If not - don't show the menu
mkt = service.Market.getInstance()
mkt = Market.getInstance()
self.variations = None
for i in selection:
variations = mkt.getVariationsByItems([i.item])
@@ -41,7 +44,8 @@ class MetaSwap(ContextMenu):
self.moduleLookup = {}
def get_metalevel(x):
if "metaLevel" not in x.attributes: return 0
if "metaLevel" not in x.attributes:
return 0
return x.attributes["metaLevel"].value
def get_metagroup(x):
@@ -88,14 +92,15 @@ class MetaSwap(ContextMenu):
event.Skip()
return
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
for mod in self.selection:
pos = fit.modules.index(mod)
sFit.changeModule(fitID, pos, item.ID)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
MetaSwap.register()

View File

@@ -1,223 +1,230 @@
# -*- coding: utf-8 -*-
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import wx
from gui.bitmapLoader import BitmapLoader
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()
def display(self, srcContext, selection):
if self.mainFrame.getActiveFit() is None or srcContext not in ("fittingModule", "projectedModule"):
return False
modules = selection if srcContext == "fittingModule" else (selection[0],)
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)
currCharges = mod.getValidCharges()
if len(currCharges) > 0:
if validCharges is not None and validCharges != currCharges:
return False
validCharges = currCharges
self.module = mod
if validCharges is None:
return False
self.modules = modules
self.charges = list(filter(lambda charge: service.Market.getInstance().getPublicityByItem(charge), validCharges))
return len(self.charges) > 0
def getText(self, itmContext, selection):
return "Charge"
def turretSorter(self, charge):
damage = 0
range = (self.module.getModifiedItemAttr("maxRange") or 0) * (charge.getAttribute("weaponRangeMultiplier") or 1)
falloff = (self.module.getModifiedItemAttr("falloff") or 0) * (charge.getAttribute("fallofMultiplier") or 1)
for type in self.DAMAGE_TYPES:
d = charge.getAttribute("%sDamage" % type)
if d > 0:
damage += d
# Take optimal and half falloff as range factor
rangeFactor = range + falloff / 2
return - rangeFactor, charge.name.rsplit()[-2:], damage, charge.name
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
def damageInfo(self, charge):
# Set up data storage for missile damage stuff
damageMap = {}
totalDamage = 0
# Fill them with the data about charge
for damageType in self.DAMAGE_TYPES:
currentDamage = charge.getAttribute("{0}Damage".format(damageType)) or 0
damageMap[damageType] = currentDamage
totalDamage += currentDamage
# Detect type of ammo
chargeDamageType = None
for damageType in damageMap:
# If all damage belongs to certain type purely, set appropriate
# ammoType
if damageMap[damageType] == totalDamage:
chargeDamageType = damageType
break
# Else consider ammo as mixed damage
if chargeDamageType is None:
chargeDamageType = "mixed"
return chargeDamageType, totalDamage
def numericConverter(self, string):
return int(string) if string.isdigit() else string
def nameSorter(self, charge):
parts = charge.name.split(" ")
return map(self.numericConverter, parts)
def addCharge(self, menu, charge):
id = ContextMenu.nextID()
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, "icons")
if bitmap is not None:
item.SetBitmap(bitmap)
return item
def addSeperator(self, m, text):
id = ContextMenu.nextID()
m.Append(id, u'%s' % text)
m.Enable(id, False)
def getSubMenu(self, context, selection, rootMenu, i, pitem):
msw = True if "wxMSW" in wx.PlatformInfo else False
m = wx.Menu()
self.chargeIds = {}
hardpoint = self.module.hardpoint
moduleName = self.module.item.name
# Make sure we do not consider mining turrets as combat turrets
if hardpoint == Hardpoint.TURRET and self.module.getModifiedItemAttr("miningAmount") is None:
self.addSeperator(m, "Long Range")
items = []
range = None
nameBase = None
sub = None
self.charges.sort(key=self.turretSorter)
for charge in self.charges:
# fix issue 71 - will probably have to change if CCP adds more Orbital ammo
if "Orbital" in charge.name:
# uncomment if we ever want to include Oribital ammo in ammo picker - see issue #71
# This allows us to hide the ammo, but it's still loadable from the market
#item = self.addCharge(m, charge)
#items.append(item)
continue
currBase = charge.name.rsplit()[-2:]
currRange = charge.getAttribute("weaponRangeMultiplier")
if nameBase is None or range != currRange or nameBase != currBase:
if sub is not None:
self.addSeperator(sub, "More Damage")
sub = None
base = charge
nameBase = currBase
range = currRange
item = self.addCharge(rootMenu if msw else m, charge)
items.append(item)
else:
if sub is None:
sub = wx.Menu()
sub.Bind(wx.EVT_MENU, self.handleAmmoSwitch)
self.addSeperator(sub, "Less Damage")
item.SetSubMenu(sub)
sub.AppendItem(self.addCharge(rootMenu if msw else sub, base))
sub.AppendItem(self.addCharge(rootMenu if msw else sub, charge))
if sub is not None:
self.addSeperator(sub, "More Damage")
for item in items:
m.AppendItem(item)
self.addSeperator(m, "Short Range")
elif hardpoint == Hardpoint.MISSILE and moduleName != 'Festival Launcher':
self.charges.sort(key=self.missileSorter)
type = None
sub = None
defender = None
for charge in self.charges:
currType = self.damageInfo(charge)[0]
if currType != type or type is None:
if sub is not None:
self.addSeperator(sub, "More Damage")
type = currType
item = wx.MenuItem(m, wx.ID_ANY, type.capitalize())
bitmap = BitmapLoader.getBitmap("%s_small" % type, "gui")
if bitmap is not None:
item.SetBitmap(bitmap)
sub = wx.Menu()
sub.Bind(wx.EVT_MENU, self.handleAmmoSwitch)
self.addSeperator(sub, "Less Damage")
item.SetSubMenu(sub)
m.AppendItem(item)
if charge.name not in ("Light Defender Missile I", "Heavy Defender Missile I"):
sub.AppendItem(self.addCharge(rootMenu if msw else sub, charge))
else:
defender = charge
if defender is not None:
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(rootMenu if msw else m, charge))
m.AppendItem(self.addCharge(rootMenu if msw else m, None))
return m
def handleAmmoSwitch(self, event):
charge = self.chargeIds.get(event.Id, False)
if charge is False:
event.Skip()
return
sFit = service.Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.setAmmo(fitID, charge.ID if charge is not None else None, self.modules)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
ModuleAmmoPicker.register()
# coding: utf-8
import wx
from service.fit import Fit
from service.market import Market
from eos.types import Hardpoint
import gui.mainFrame
import gui.globalEvents as GE
from gui.contextMenu import ContextMenu
from gui.bitmapLoader import BitmapLoader
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()
def display(self, srcContext, selection):
if self.mainFrame.getActiveFit() is None or srcContext not in ("fittingModule", "projectedModule"):
return False
modules = selection if srcContext == "fittingModule" else (selection[0],)
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)
currCharges = mod.getValidCharges()
if len(currCharges) > 0:
if validCharges is not None and validCharges != currCharges:
return False
validCharges = currCharges
self.module = mod
if validCharges is None:
return False
self.modules = modules
self.charges = list(filter(lambda charge: Market.getInstance().getPublicityByItem(charge), validCharges))
return len(self.charges) > 0
def getText(self, itmContext, selection):
return "Charge"
def turretSorter(self, charge):
damage = 0
range_ = (self.module.getModifiedItemAttr("maxRange") or 0) * \
(charge.getAttribute("weaponRangeMultiplier") or 1)
falloff = (self.module.getModifiedItemAttr("falloff") or 0) * \
(charge.getAttribute("fallofMultiplier") or 1)
for type_ in self.DAMAGE_TYPES:
d = charge.getAttribute("%sDamage" % type_)
if d > 0:
damage += d
# Take optimal and half falloff as range factor
rangeFactor = range_ + falloff / 2
return - rangeFactor, charge.name.rsplit()[-2:], damage, charge.name
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
def damageInfo(self, charge):
# Set up data storage for missile damage stuff
damageMap = {}
totalDamage = 0
# Fill them with the data about charge
for damageType in self.DAMAGE_TYPES:
currentDamage = charge.getAttribute("{0}Damage".format(damageType)) or 0
damageMap[damageType] = currentDamage
totalDamage += currentDamage
# Detect type of ammo
chargeDamageType = None
for damageType in damageMap:
# If all damage belongs to certain type purely, set appropriate
# ammoType
if damageMap[damageType] == totalDamage:
chargeDamageType = damageType
break
# Else consider ammo as mixed damage
if chargeDamageType is None:
chargeDamageType = "mixed"
return chargeDamageType, totalDamage
def numericConverter(self, string):
return int(string) if string.isdigit() else string
def nameSorter(self, charge):
parts = charge.name.split(" ")
return map(self.numericConverter, parts)
def addCharge(self, menu, charge):
id_ = ContextMenu.nextID()
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, "icons")
if bitmap is not None:
item.SetBitmap(bitmap)
return item
def addSeperator(self, m, text):
id_ = ContextMenu.nextID()
m.Append(id_, u'%s' % text)
m.Enable(id_, False)
def getSubMenu(self, context, selection, rootMenu, i, pitem):
msw = True if "wxMSW" in wx.PlatformInfo else False
m = wx.Menu()
self.chargeIds = {}
hardpoint = self.module.hardpoint
moduleName = self.module.item.name
# Make sure we do not consider mining turrets as combat turrets
if hardpoint == Hardpoint.TURRET and self.module.getModifiedItemAttr("miningAmount") is None:
self.addSeperator(m, "Long Range")
items = []
range_ = None
nameBase = None
sub = None
self.charges.sort(key=self.turretSorter)
for charge in self.charges:
# fix issue 71 - will probably have to change if CCP adds more Orbital ammo
if "Orbital" in charge.name:
# uncomment if we ever want to include Oribital ammo in ammo picker - see issue #71
# This allows us to hide the ammo, but it's still loadable from the market
# item = self.addCharge(m, charge)
# items.append(item)
continue
currBase = charge.name.rsplit()[-2:]
currRange = charge.getAttribute("weaponRangeMultiplier")
if nameBase is None or range_ != currRange or nameBase != currBase:
if sub is not None:
self.addSeperator(sub, "More Damage")
sub = None
base = charge
nameBase = currBase
range_ = currRange
item = self.addCharge(rootMenu if msw else m, charge)
items.append(item)
else:
if sub is None:
sub = wx.Menu()
sub.Bind(wx.EVT_MENU, self.handleAmmoSwitch)
self.addSeperator(sub, "Less Damage")
item.SetSubMenu(sub)
sub.AppendItem(self.addCharge(rootMenu if msw else sub, base))
sub.AppendItem(self.addCharge(rootMenu if msw else sub, charge))
if sub is not None:
self.addSeperator(sub, "More Damage")
for item in items:
m.AppendItem(item)
self.addSeperator(m, "Short Range")
elif hardpoint == Hardpoint.MISSILE and moduleName != 'Festival Launcher':
self.charges.sort(key=self.missileSorter)
type_ = None
sub = None
defender = None
for charge in self.charges:
currType = self.damageInfo(charge)[0]
if currType != type_ or type_ is None:
if sub is not None:
self.addSeperator(sub, "More Damage")
type_ = currType
item = wx.MenuItem(m, wx.ID_ANY, type_.capitalize())
bitmap = BitmapLoader.getBitmap("%s_small" % type, "gui")
if bitmap is not None:
item.SetBitmap(bitmap)
sub = wx.Menu()
sub.Bind(wx.EVT_MENU, self.handleAmmoSwitch)
self.addSeperator(sub, "Less Damage")
item.SetSubMenu(sub)
m.AppendItem(item)
if charge.name not in ("Light Defender Missile I", "Heavy Defender Missile I"):
sub.AppendItem(self.addCharge(rootMenu if msw else sub, charge))
else:
defender = charge
if defender is not None:
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(rootMenu if msw else m, charge))
m.AppendItem(self.addCharge(rootMenu if msw else m, None))
return m
def handleAmmoSwitch(self, event):
charge = self.chargeIds.get(event.Id, False)
if charge is False:
event.Skip()
return
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.setAmmo(fitID, charge.ID if charge is not None else None, self.modules)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
ModuleAmmoPicker.register()

View File

@@ -1,13 +1,11 @@
# -*- coding: utf-8 -*-
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import wx
from gui.bitmapLoader import BitmapLoader
from eos.types import Hardpoint
import gui.globalEvents as GE
from gui.builtinContextMenus.moduleAmmoPicker import ModuleAmmoPicker
import eos.db
from service.fit import Fit
class ModuleGlobalAmmoPicker(ModuleAmmoPicker):
def __init__(self):
@@ -26,7 +24,7 @@ class ModuleGlobalAmmoPicker(ModuleAmmoPicker):
event.Skip()
return
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = eos.db.getFit(fitID)

View File

@@ -3,6 +3,7 @@ import gui.mainFrame
import wx
from gui.shipBrowser import FitSelected
class OpenFit(ContextMenu):
def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
@@ -17,4 +18,5 @@ class OpenFit(ContextMenu):
fit = selection[0]
wx.PostEvent(self.mainFrame, FitSelected(fitID=fit.ID, startup=2))
OpenFit.register()

View File

@@ -2,7 +2,8 @@ from gui.contextMenu import ContextMenu
import gui.mainFrame
import wx
import gui.globalEvents as GE
import service
from service.market import Market
class PriceClear(ContextMenu):
def __init__(self):
@@ -15,8 +16,9 @@ class PriceClear(ContextMenu):
return "Reset Price Cache"
def activate(self, fullContext, selection, i):
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
sMkt.clearPriceCache()
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
PriceClear.register()

View File

@@ -1,37 +1,38 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import gui.globalEvents as GE
import wx
import eos.db
class Project(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
sFit = service.Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
if fit.isStructure:
return False
item = selection[0]
return item.isType("projected")
def getText(self, itmContext, selection):
return "Project {0} onto Fit".format(itmContext)
def activate(self, fullContext, selection, i):
sFit = service.Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
trigger = sFit.project(fitID, selection[0])
if trigger:
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.additionsPane.select("Projected")
Project.register()
from gui.contextMenu import ContextMenu
import gui.mainFrame
import gui.globalEvents as GE
import wx
from service.fit import Fit
class Project(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
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
if fit.isStructure:
return False
item = selection[0]
return item.isType("projected")
def getText(self, itmContext, selection):
return "Project {0} onto Fit".format(itmContext)
def activate(self, fullContext, selection, i):
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
trigger = sFit.project(fitID, selection[0])
if trigger:
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.additionsPane.select("Projected")
Project.register()

View File

@@ -1,8 +1,9 @@
import wx
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
from gui.shipBrowser import Stage3Selected
from service.fit import Fit
class ShipJump(ContextMenu):
def __init__(self):
@@ -16,11 +17,12 @@ class ShipJump(ContextMenu):
def activate(self, fullContext, selection, i):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
stuff = sFit.getFit(fitID).ship
groupID = stuff.item.group.ID
self.mainFrame.notebookBrowsers.SetSelection(1)
wx.PostEvent(self.mainFrame.shipBrowser,Stage3Selected(shipID=stuff.item.ID, back=groupID))
wx.PostEvent(self.mainFrame.shipBrowser, Stage3Selected(shipID=stuff.item.ID, back=groupID))
ShipJump.register()

View File

@@ -1,8 +1,10 @@
import wx
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import gui.globalEvents as GE
from service.fit import Fit
class TacticalMode(ContextMenu):
def __init__(self):
@@ -12,7 +14,7 @@ class TacticalMode(ContextMenu):
if self.mainFrame.getActiveFit() is None or srcContext != "fittingShip":
return False
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
@@ -52,9 +54,10 @@ class TacticalMode(ContextMenu):
event.Skip()
return
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.setMode(fitID, self.modeIds[event.Id])
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
TacticalMode.register()

View File

@@ -1,15 +1,17 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import gui.globalEvents as GE
import wx
from gui.bitmapLoader import BitmapLoader
from service.targetResists import TargetResists as svc_TargetResists
from service.fit import Fit
try:
from collections import OrderedDict
except ImportError:
from gui.utils.compat import OrderedDict
class TargetResists(ContextMenu):
def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
@@ -18,7 +20,7 @@ class TargetResists(ContextMenu):
if self.mainFrame.getActiveFit() is None or srcContext != "firepowerViewFull":
return False
sTR = service.TargetResists.getInstance()
sTR = svc_TargetResists.getInstance()
self.patterns = sTR.getTargetResistsList()
self.patterns.sort(key=lambda p: (p.name in ["None"], p.name))
@@ -33,7 +35,7 @@ class TargetResists(ContextMenu):
event.Skip()
return
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.setTargetResists(fitID, pattern)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -50,7 +52,7 @@ class TargetResists(ContextMenu):
item.pattern = pattern
# determine active pattern
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
f = sFit.getFit(fitID)
tr = f.targetResists
@@ -64,15 +66,15 @@ class TargetResists(ContextMenu):
msw = True if "wxMSW" in wx.PlatformInfo else False
self.patternIds = {}
self.subMenus = OrderedDict()
self.singles = []
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:
currBase = pattern.name[start+1:end]
currBase = pattern.name[start + 1:end]
# set helper attr
setattr(pattern, "_name", pattern.name[end+1:].strip())
setattr(pattern, "_name", pattern.name[end + 1:].strip())
if currBase not in self.subMenus:
self.subMenus[currBase] = []
self.subMenus[currBase].append(pattern)
@@ -93,7 +95,7 @@ class TargetResists(ContextMenu):
# Create menu for child items
grandSub = wx.Menu()
#sub.Bind(wx.EVT_MENU, self.handleResistSwitch)
# sub.Bind(wx.EVT_MENU, self.handleResistSwitch)
# Apply child menu to parent item
item.SetSubMenu(grandSub)
@@ -101,8 +103,9 @@ class TargetResists(ContextMenu):
# Append child items to child menu
for pattern in patterns:
grandSub.AppendItem(self.addPattern(rootMenu if msw else grandSub, pattern))
sub.AppendItem(item) #finally, append parent item to root menu
sub.AppendItem(item) # finally, append parent item to root menu
return sub
TargetResists.register()

View File

@@ -1,8 +1,10 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
import gui.globalEvents as GE
import service
import wx
from service.market import Market
from service.fit import Fit
class WhProjector(ContextMenu):
def __init__(self):
@@ -16,7 +18,7 @@ class WhProjector(ContextMenu):
def getSubMenu(self, context, selection, rootMenu, i, pitem):
msw = True if "wxMSW" in wx.PlatformInfo else False
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
effdata = sMkt.getSystemWideEffects()
self.idmap = {}
@@ -41,16 +43,17 @@ class WhProjector(ContextMenu):
return sub
def handleSelection(self, event):
#Skip events ids that aren't mapped
# Skip events ids that aren't mapped
swObj, swName = self.idmap.get(event.Id, (False, False))
if not swObj and not swName:
event.Skip()
return
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.project(fitID, swObj)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
WhProjector.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,15 +15,15 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
from gui.graph import Graph
import service
from gui.bitmapLoader import BitmapLoader
from eos.graph.fitDps import FitDpsGraph as FitDps
from eos.graph import Data
import gui.mainFrame
import service
from service.attribute import Attribute
class FitDpsGraph(Graph):
propertyAttributeMap = {"angle": "maxVelocity",
@@ -53,7 +53,7 @@ class FitDpsGraph(Graph):
def getIcons(self):
icons = {}
sAttr = service.Attribute.getInstance()
sAttr = Attribute.getInstance()
for key, attrName in self.propertyAttributeMap.iteritems():
iconFile = sAttr.getAttributeInfo(attrName).icon.iconFile
bitmap = BitmapLoader.getBitmap(iconFile, "icons")
@@ -75,7 +75,7 @@ class FitDpsGraph(Graph):
if variable is None:
variable = fieldName
else:
#We can't handle more then one variable atm, OOPS FUCK OUT
# We can't handle more then one variable atm, OOPS FUCK OUT
return False, "Can only handle 1 variable"
fitDps.setData(d)
@@ -91,4 +91,5 @@ class FitDpsGraph(Graph):
return x, y
FitDpsGraph.register()

View File

@@ -1,6 +1,7 @@
__all__ = ["pyfaGeneralPreferences","pyfaHTMLExportPreferences","pyfaUpdatePreferences","pyfaNetworkPreferences"]
import wx
if not 'wxMac' in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3,0)):
__all__ = ["pyfaGeneralPreferences", "pyfaHTMLExportPreferences", "pyfaUpdatePreferences",
"pyfaNetworkPreferences"] # noqa
if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0)):
__all__.append("pyfaCrestPreferences")

View File

@@ -1,94 +1,94 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
import wx
from gui.preferenceView import PreferenceView
from gui.bitmapLoader import BitmapLoader
class DummyView(PreferenceView):
title = "Dummy"
def populatePanel(self, panel):
mainSizer = wx.BoxSizer( wx.VERTICAL )
headerSizer = self.initHeader(panel)
mainSizer.Add( headerSizer, 0, wx.EXPAND, 5 )
self.stline1 = wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
mainSizer.Add( self.stline1, 0, wx.EXPAND, 5 )
contentSizer = self.initContent(panel)
mainSizer.Add( contentSizer, 1, wx.EXPAND|wx.TOP|wx.BOTTOM|wx.LEFT, 10 )
self.stline2 = wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
mainSizer.Add( self.stline2, 0, wx.EXPAND, 5 )
footerSizer = self.initFooter(panel)
mainSizer.Add( footerSizer, 0, wx.EXPAND, 5 )
panel.SetSizer( mainSizer )
panel.Layout()
def refreshPanel(self, fit):
pass
def initHeader(self, panel):
headerSizer = wx.BoxSizer( wx.VERTICAL )
self.stTitle = wx.StaticText( panel, wx.ID_ANY, u"Dummy", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stTitle.Wrap( -1 )
self.stTitle.SetFont( wx.Font( 14, 70, 90, 90, False, wx.EmptyString ) )
headerSizer.Add( self.stTitle, 0, wx.ALL, 5)
return headerSizer
def initContent(self, panel):
contentSizer = wx.BoxSizer( wx.VERTICAL )
self.m_checkBox2 = wx.CheckBox( panel, wx.ID_ANY, u"Check Me!", wx.DefaultPosition, wx.DefaultSize, 0 )
contentSizer.Add( self.m_checkBox2, 0, wx.ALL, 5 )
self.m_radioBtn2 = wx.RadioButton( panel, wx.ID_ANY, u"RadioBtn", wx.DefaultPosition, wx.DefaultSize, 0 )
contentSizer.Add( self.m_radioBtn2, 0, wx.ALL, 5 )
self.m_slider2 = wx.Slider( panel, wx.ID_ANY, 50, 0, 100, wx.DefaultPosition, wx.DefaultSize, wx.SL_HORIZONTAL )
contentSizer.Add( self.m_slider2, 0, wx.ALL, 5 )
self.m_gauge1 = wx.Gauge( panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, wx.GA_HORIZONTAL )
contentSizer.Add( self.m_gauge1, 0, wx.ALL, 5 )
self.m_textCtrl2 = wx.TextCtrl( panel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
contentSizer.Add( self.m_textCtrl2, 0, wx.ALL, 5 )
return contentSizer
def initFooter(self, panel):
footerSizer = wx.BoxSizer( wx.HORIZONTAL )
footerSizer.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 )
self.btnRestore = wx.Button( panel, wx.ID_ANY, u"Restore", wx.DefaultPosition, wx.DefaultSize, 0 )
self.btnRestore.Enable( False )
footerSizer.Add( self.btnRestore, 0, wx.ALL, 5 )
self.btnApply = wx.Button( panel, wx.ID_ANY, u"Apply", wx.DefaultPosition, wx.DefaultSize, 0 )
footerSizer.Add( self.btnApply, 0, wx.ALL, 5 )
return footerSizer
DummyView.register()
# =============================================================================
# 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 <http://www.gnu.org/licenses/>.
# =============================================================================
import wx
from gui.preferenceView import PreferenceView
class DummyView(PreferenceView):
title = "Dummy"
def populatePanel(self, panel):
mainSizer = wx.BoxSizer(wx.VERTICAL)
headerSizer = self.initHeader(panel)
mainSizer.Add(headerSizer, 0, wx.EXPAND, 5)
self.stline1 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
mainSizer.Add(self.stline1, 0, wx.EXPAND, 5)
contentSizer = self.initContent(panel)
mainSizer.Add(contentSizer, 1, wx.EXPAND | wx.TOP | wx.BOTTOM | wx.LEFT, 10)
self.stline2 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
mainSizer.Add(self.stline2, 0, wx.EXPAND, 5)
footerSizer = self.initFooter(panel)
mainSizer.Add(footerSizer, 0, wx.EXPAND, 5)
panel.SetSizer(mainSizer)
panel.Layout()
def refreshPanel(self, fit):
pass
def initHeader(self, panel):
headerSizer = wx.BoxSizer(wx.VERTICAL)
self.stTitle = wx.StaticText(panel, wx.ID_ANY, u"Dummy", wx.DefaultPosition, wx.DefaultSize, 0)
self.stTitle.Wrap(-1)
self.stTitle.SetFont(wx.Font(14, 70, 90, 90, False, wx.EmptyString))
headerSizer.Add(self.stTitle, 0, wx.ALL, 5)
return headerSizer
def initContent(self, panel):
contentSizer = wx.BoxSizer(wx.VERTICAL)
self.m_checkBox2 = wx.CheckBox(panel, wx.ID_ANY, u"Check Me!", wx.DefaultPosition, wx.DefaultSize, 0)
contentSizer.Add(self.m_checkBox2, 0, wx.ALL, 5)
self.m_radioBtn2 = wx.RadioButton(panel, wx.ID_ANY, u"RadioBtn", wx.DefaultPosition, wx.DefaultSize, 0)
contentSizer.Add(self.m_radioBtn2, 0, wx.ALL, 5)
self.m_slider2 = wx.Slider(panel, wx.ID_ANY, 50, 0, 100, wx.DefaultPosition, wx.DefaultSize, wx.SL_HORIZONTAL)
contentSizer.Add(self.m_slider2, 0, wx.ALL, 5)
self.m_gauge1 = wx.Gauge(panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, wx.GA_HORIZONTAL)
contentSizer.Add(self.m_gauge1, 0, wx.ALL, 5)
self.m_textCtrl2 = wx.TextCtrl(panel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0)
contentSizer.Add(self.m_textCtrl2, 0, wx.ALL, 5)
return contentSizer
def initFooter(self, panel):
footerSizer = wx.BoxSizer(wx.HORIZONTAL)
footerSizer.AddSpacer((0, 0), 1, wx.EXPAND, 5)
self.btnRestore = wx.Button(panel, wx.ID_ANY, u"Restore", wx.DefaultPosition, wx.DefaultSize, 0)
self.btnRestore.Enable(False)
footerSizer.Add(self.btnRestore, 0, wx.ALL, 5)
self.btnApply = wx.Button(panel, wx.ID_ANY, u"Apply", wx.DefaultPosition, wx.DefaultSize, 0)
footerSizer.Add(self.btnApply, 0, wx.ALL, 5)
return footerSizer
DummyView.register()

View File

@@ -4,101 +4,109 @@ from gui.preferenceView import PreferenceView
from gui.bitmapLoader import BitmapLoader
import gui.mainFrame
import service
from service.crest import CrestModes
from service.crest import Crest
from service.settings import CRESTSettings
from wx.lib.intctrl import IntCtrl
class PFCrestPref ( PreferenceView):
class PFCrestPref(PreferenceView):
title = "CREST"
def populatePanel( self, panel ):
def populatePanel(self, panel):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.settings = service.settings.CRESTSettings.getInstance()
self.settings = CRESTSettings.getInstance()
self.dirtySettings = False
dlgWidth = panel.GetParent().GetParent().ClientSize.width
mainSizer = wx.BoxSizer( wx.VERTICAL )
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.stTitle = wx.StaticText( panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0 )
self.stTitle.Wrap( -1 )
self.stTitle.SetFont( wx.Font( 12, 70, 90, 90, False, wx.EmptyString ) )
self.stTitle = wx.StaticText(panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0)
self.stTitle.Wrap(-1)
self.stTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString))
mainSizer.Add( self.stTitle, 0, wx.ALL, 5 )
mainSizer.Add(self.stTitle, 0, wx.ALL, 5)
self.m_staticline1 = wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
mainSizer.Add( self.m_staticline1, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5 )
self.m_staticline1 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
mainSizer.Add(self.m_staticline1, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)
self.stInfo = wx.StaticText( panel, wx.ID_ANY, u"Please see the pyfa wiki on GitHub for information regarding these options.", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stInfo = wx.StaticText(panel, wx.ID_ANY,
u"Please see the pyfa wiki on GitHub for information regarding these options.",
wx.DefaultPosition, wx.DefaultSize, 0)
self.stInfo.Wrap(dlgWidth - 50)
mainSizer.Add( self.stInfo, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5 )
mainSizer.Add(self.stInfo, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)
rbSizer = wx.BoxSizer(wx.HORIZONTAL)
self.rbMode = wx.RadioBox(panel, -1, "Mode", wx.DefaultPosition, wx.DefaultSize, ['Implicit', 'User-supplied details'], 1, wx.RA_SPECIFY_COLS)
self.rbServer = wx.RadioBox(panel, -1, "Server", wx.DefaultPosition, wx.DefaultSize, ['Tranquility', 'Singularity'], 1, wx.RA_SPECIFY_COLS)
self.rbMode = wx.RadioBox(panel, -1, "Mode", wx.DefaultPosition, wx.DefaultSize,
['Implicit', 'User-supplied details'], 1, wx.RA_SPECIFY_COLS)
self.rbServer = wx.RadioBox(panel, -1, "Server", wx.DefaultPosition, wx.DefaultSize,
['Tranquility', 'Singularity'], 1, wx.RA_SPECIFY_COLS)
self.rbMode.SetSelection(self.settings.get('mode'))
self.rbServer.SetSelection(self.settings.get('server'))
rbSizer.Add(self.rbMode, 1, wx.TOP | wx.RIGHT, 5 )
rbSizer.Add(self.rbServer, 1, wx.ALL, 5 )
rbSizer.Add(self.rbMode, 1, wx.TOP | wx.RIGHT, 5)
rbSizer.Add(self.rbServer, 1, wx.ALL, 5)
self.rbMode.Bind(wx.EVT_RADIOBOX, self.OnModeChange)
self.rbServer.Bind(wx.EVT_RADIOBOX, self.OnServerChange)
mainSizer.Add(rbSizer, 1, wx.ALL|wx.EXPAND, 0)
mainSizer.Add(rbSizer, 1, wx.ALL | wx.EXPAND, 0)
timeoutSizer = wx.BoxSizer(wx.HORIZONTAL)
self.stTimout = wx.StaticText( panel, wx.ID_ANY, u"Timeout (seconds):", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stTimout.Wrap( -1 )
self.stTimout = wx.StaticText(panel, wx.ID_ANY, u"Timeout (seconds):", wx.DefaultPosition, wx.DefaultSize, 0)
self.stTimout.Wrap(-1)
timeoutSizer.Add( self.stTimout, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5 )
timeoutSizer.Add(self.stTimout, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.intTimeout = IntCtrl(panel, max=300000, limited=True, value=self.settings.get('timeout'))
timeoutSizer.Add(self.intTimeout, 0, wx.ALL, 5 )
timeoutSizer.Add(self.intTimeout, 0, wx.ALL, 5)
self.intTimeout.Bind(wx.lib.intctrl.EVT_INT, self.OnTimeoutChange)
mainSizer.Add(timeoutSizer, 0, wx.ALL|wx.EXPAND, 0)
mainSizer.Add(timeoutSizer, 0, wx.ALL | wx.EXPAND, 0)
detailsTitle = wx.StaticText( panel, wx.ID_ANY, "CREST client details", wx.DefaultPosition, wx.DefaultSize, 0 )
detailsTitle.Wrap( -1 )
detailsTitle.SetFont( wx.Font( 12, 70, 90, 90, False, wx.EmptyString ) )
detailsTitle = wx.StaticText(panel, wx.ID_ANY, "CREST client details", wx.DefaultPosition, wx.DefaultSize, 0)
detailsTitle.Wrap(-1)
detailsTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString))
mainSizer.Add( detailsTitle, 0, wx.ALL, 5 )
mainSizer.Add( wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ), 0, wx.EXPAND, 5 )
mainSizer.Add(detailsTitle, 0, wx.ALL, 5)
mainSizer.Add(wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0,
wx.EXPAND, 5)
fgAddrSizer = wx.FlexGridSizer( 2, 2, 0, 0 )
fgAddrSizer.AddGrowableCol( 1 )
fgAddrSizer.SetFlexibleDirection( wx.BOTH )
fgAddrSizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
fgAddrSizer = wx.FlexGridSizer(2, 2, 0, 0)
fgAddrSizer.AddGrowableCol(1)
fgAddrSizer.SetFlexibleDirection(wx.BOTH)
fgAddrSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
self.stSetID = wx.StaticText( panel, wx.ID_ANY, u"Client ID:", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stSetID.Wrap( -1 )
fgAddrSizer.Add( self.stSetID, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.stSetID = wx.StaticText(panel, wx.ID_ANY, u"Client ID:", wx.DefaultPosition, wx.DefaultSize, 0)
self.stSetID.Wrap(-1)
fgAddrSizer.Add(self.stSetID, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.inputClientID = wx.TextCtrl( panel, wx.ID_ANY, self.settings.get('clientID'), wx.DefaultPosition, wx.DefaultSize, 0 )
self.inputClientID = wx.TextCtrl(panel, wx.ID_ANY, self.settings.get('clientID'), wx.DefaultPosition,
wx.DefaultSize, 0)
fgAddrSizer.Add( self.inputClientID, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5 )
fgAddrSizer.Add(self.inputClientID, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5)
self.stSetSecret = wx.StaticText( panel, wx.ID_ANY, u"Client Secret:", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stSetSecret.Wrap( -1 )
self.stSetSecret = wx.StaticText(panel, wx.ID_ANY, u"Client Secret:", wx.DefaultPosition, wx.DefaultSize, 0)
self.stSetSecret.Wrap(-1)
fgAddrSizer.Add( self.stSetSecret, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
fgAddrSizer.Add(self.stSetSecret, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.inputClientSecret = wx.TextCtrl( panel, wx.ID_ANY, self.settings.get('clientSecret'), wx.DefaultPosition, wx.DefaultSize, 0 )
self.inputClientSecret = wx.TextCtrl(panel, wx.ID_ANY, self.settings.get('clientSecret'), wx.DefaultPosition,
wx.DefaultSize, 0)
fgAddrSizer.Add( self.inputClientSecret, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5 )
fgAddrSizer.Add(self.inputClientSecret, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5)
self.btnApply = wx.Button( panel, wx.ID_ANY, u"Save Client Settings", wx.DefaultPosition, wx.DefaultSize, 0 )
self.btnApply = wx.Button(panel, wx.ID_ANY, u"Save Client Settings", wx.DefaultPosition, wx.DefaultSize, 0)
self.btnApply.Bind(wx.EVT_BUTTON, self.OnBtnApply)
mainSizer.Add( fgAddrSizer, 0, wx.EXPAND, 5)
mainSizer.Add( self.btnApply, 0, wx.ALIGN_RIGHT, 5)
mainSizer.Add(fgAddrSizer, 0, wx.EXPAND, 5)
mainSizer.Add(self.btnApply, 0, wx.ALIGN_RIGHT, 5)
self.ToggleProxySettings(self.settings.get('mode'))
panel.SetSizer( mainSizer )
panel.SetSizer(mainSizer)
panel.Layout()
def OnTimeoutChange(self, event):
@@ -107,16 +115,16 @@ class PFCrestPref ( PreferenceView):
def OnModeChange(self, event):
self.settings.set('mode', event.GetInt())
self.ToggleProxySettings(self.settings.get('mode'))
service.Crest.restartService()
Crest.restartService()
def OnServerChange(self, event):
self.settings.set('server', event.GetInt())
service.Crest.restartService()
Crest.restartService()
def OnBtnApply(self, event):
self.settings.set('clientID', self.inputClientID.GetValue().strip())
self.settings.set('clientSecret', self.inputClientSecret.GetValue().strip())
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
sCrest.delAllCharacters()
def ToggleProxySettings(self, mode):
@@ -134,4 +142,5 @@ class PFCrestPref ( PreferenceView):
def getImage(self):
return BitmapLoader.getBitmap("eve", "gui")
PFCrestPref.register()

View File

@@ -10,13 +10,15 @@ from gui.bitmapLoader import BitmapLoader
from gui.utils import colorUtils
import gui.utils.drawUtils as drawUtils
###########################################################################
## Class PFGaugePref
# Class PFGaugePref
###########################################################################
class PFGaugePreview(wx.Window):
def __init__ (self, parent, id = wx.ID_ANY, value = 0, pos = wx.DefaultPosition, size = wx.DefaultSize, style = 0):
wx.Window.__init__(self, parent, id, pos = pos, size = size, style = style)
def __init__(self, parent, id=wx.ID_ANY, value=0, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0):
wx.Window.__init__(self, parent, id, pos=pos, size=size, style=style)
self.value = float(value)
self.oldValue = self.value
@@ -28,14 +30,14 @@ class PFGaugePreview(wx.Window):
self.animDir = 1
self._fractionDigits = 2
self.colorS = wx.Colour(0,0,0,255)
self.colorE = wx.Colour(0,0,0,255)
self.colorS = wx.Colour(0, 0, 0, 255)
self.colorE = wx.Colour(0, 0, 0, 255)
self.gradientStart = 0
self.bkColor = wx.Colour(0,0,0,255)
self.SetMinSize((100,-1))
self.bkColor = wx.Colour(0, 0, 0, 255)
self.SetMinSize((100, -1))
self.font = wx.FontFromPixelSize((0,13),wx.SWISS, wx.NORMAL, wx.NORMAL, False)
self.font = wx.FontFromPixelSize((0, 13), wx.SWISS, wx.NORMAL, wx.NORMAL, False)
self.timerID = wx.NewId()
self.timer = wx.Timer(self, self.timerID)
@@ -56,7 +58,7 @@ class PFGaugePreview(wx.Window):
if self.value > 100:
self.value = 100
self.animDir = -1
if self.value <0:
if self.value < 0:
self.value = 0
self.animDir = 1
self.Refresh()
@@ -79,7 +81,7 @@ class PFGaugePreview(wx.Window):
self.Refresh()
event.Skip()
def CanAnimate(self, anim = True):
def CanAnimate(self, anim=True):
self.animate = anim
if self.timer.IsRunning():
self.timer.Stop()
@@ -97,7 +99,7 @@ class PFGaugePreview(wx.Window):
self.Refresh()
def SetValue(self, value):
self.value = min(max(value,0),100)
self.value = min(max(value, 0), 100)
self.Refresh()
def SetPercentages(self, start, end):
@@ -119,198 +121,210 @@ class PFGaugePreview(wx.Window):
r = copy.copy(rect)
r.width = w
color = colorUtils.CalculateTransitionColor(self.colorS, self.colorE, float(value)/100)
color = colorUtils.CalculateTransitionColor(self.colorS, self.colorE, float(value) / 100)
if self.gradientStart > 0:
gcolor = colorUtils.BrightenColor(color, float(self.gradientStart) / 100)
gMid = colorUtils.BrightenColor(color, float(self.gradientStart/2) / 100)
gcolor = colorUtils.BrightenColor(color, float(self.gradientStart) / 100)
gMid = colorUtils.BrightenColor(color, float(self.gradientStart / 2) / 100)
else:
gcolor = colorUtils.DarkenColor(color, float(-self.gradientStart) / 100)
gMid = colorUtils.DarkenColor(color, float(-self.gradientStart/2) / 100)
gcolor = colorUtils.DarkenColor(color, float(-self.gradientStart) / 100)
gMid = colorUtils.DarkenColor(color, float(-self.gradientStart / 2) / 100)
gBmp = drawUtils.DrawGradientBar(r.width, r.height, gMid, color, gcolor)
dc.DrawBitmap(gBmp,0,0)
dc.DrawBitmap(gBmp, 0, 0)
dc.SetFont(self.font)
r = copy.copy(rect)
r.left +=1
r.top +=1
r.left += 1
r.top += 1
formatStr = "{0:." + str(self._fractionDigits) + "f}%"
value = (self.percE - self.percS) * value / (self.percE - self.percS)
value = self.percS + (self.percE - self.percS) * value / 100
dc.SetTextForeground(wx.Colour(80,80,80))
dc.SetTextForeground(wx.Colour(80, 80, 80))
dc.DrawLabel(formatStr.format(value), r, wx.ALIGN_CENTER)
dc.SetTextForeground(wx.Colour(255,255,255))
dc.SetTextForeground(wx.Colour(255, 255, 255))
dc.DrawLabel(formatStr.format(value), rect, wx.ALIGN_CENTER)
class PFGaugePref ( PreferenceView):
class PFGaugePref(PreferenceView):
title = "Pyfa Gauge Theme"
def populatePanel( self, panel ):
def populatePanel(self, panel):
self.InitDefaultColours()
mainSizer = wx.BoxSizer( wx.VERTICAL )
mainSizer = wx.BoxSizer(wx.VERTICAL)
gSizer1 = wx.BoxSizer( wx.HORIZONTAL )
gSizer1 = wx.BoxSizer(wx.HORIZONTAL)
self.st0100 = wx.StaticText( panel, wx.ID_ANY, u"0 - 100", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT )
self.st0100.Wrap( -1 )
gSizer1.Add( self.st0100, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.st0100 = wx.StaticText(panel, wx.ID_ANY, u"0 - 100", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT)
self.st0100.Wrap(-1)
gSizer1.Add(self.st0100, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.cp0100S = wx.ColourPickerCtrl( panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize, wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL )
gSizer1.Add( self.cp0100S, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.cp0100S = wx.ColourPickerCtrl(panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize,
wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL)
gSizer1.Add(self.cp0100S, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.cp0100E = wx.ColourPickerCtrl( panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize, wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL )
gSizer1.Add( self.cp0100E, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.cp0100E = wx.ColourPickerCtrl(panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize,
wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL)
gSizer1.Add(self.cp0100E, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.gauge0100S = PFGaugePreview( panel, wx.ID_ANY, 33, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER )
gSizer1.Add( self.gauge0100S, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5 )
self.gauge0100S = PFGaugePreview(panel, wx.ID_ANY, 33, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
gSizer1.Add(self.gauge0100S, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5)
self.gauge0100M = PFGaugePreview( panel, wx.ID_ANY, 66, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER )
gSizer1.Add( self.gauge0100M, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5 )
self.gauge0100M = PFGaugePreview(panel, wx.ID_ANY, 66, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
gSizer1.Add(self.gauge0100M, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5)
self.gauge0100E = PFGaugePreview( panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER )
gSizer1.Add( self.gauge0100E, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.LEFT, 5 )
self.gauge0100E = PFGaugePreview(panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
gSizer1.Add(self.gauge0100E, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 5)
mainSizer.Add( gSizer1, 0, wx.EXPAND, 5 )
mainSizer.Add(gSizer1, 0, wx.EXPAND, 5)
gSizer2 = wx.BoxSizer( wx.HORIZONTAL )
gSizer2 = wx.BoxSizer(wx.HORIZONTAL)
self.st100101 = wx.StaticText( panel, wx.ID_ANY, u"100 - 101", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT )
self.st100101.Wrap( -1 )
gSizer2.Add( self.st100101, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.st100101 = wx.StaticText(panel, wx.ID_ANY, u"100 - 101", wx.DefaultPosition, wx.DefaultSize,
wx.ALIGN_RIGHT)
self.st100101.Wrap(-1)
gSizer2.Add(self.st100101, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.cp100101S = wx.ColourPickerCtrl( panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize, wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL )
gSizer2.Add( self.cp100101S, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.cp100101S = wx.ColourPickerCtrl(panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize,
wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL)
gSizer2.Add(self.cp100101S, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.cp100101E = wx.ColourPickerCtrl( panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize, wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL )
gSizer2.Add( self.cp100101E, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.cp100101E = wx.ColourPickerCtrl(panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize,
wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL)
gSizer2.Add(self.cp100101E, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.gauge100101S = PFGaugePreview( panel, wx.ID_ANY, 33, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER )
gSizer2.Add( self.gauge100101S, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5 )
self.gauge100101S = PFGaugePreview(panel, wx.ID_ANY, 33, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
gSizer2.Add(self.gauge100101S, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5)
self.gauge100101M = PFGaugePreview( panel, wx.ID_ANY, 66, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER )
gSizer2.Add( self.gauge100101M, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5 )
self.gauge100101M = PFGaugePreview(panel, wx.ID_ANY, 66, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
gSizer2.Add(self.gauge100101M, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5)
self.gauge100101E = PFGaugePreview( panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER )
gSizer2.Add( self.gauge100101E, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.LEFT, 5 )
self.gauge100101E = PFGaugePreview(panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
gSizer2.Add(self.gauge100101E, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 5)
mainSizer.Add( gSizer2, 0, wx.EXPAND, 5 )
mainSizer.Add(gSizer2, 0, wx.EXPAND, 5)
gSizer3 = wx.BoxSizer( wx.HORIZONTAL )
gSizer3 = wx.BoxSizer(wx.HORIZONTAL)
self.st101103 = wx.StaticText( panel, wx.ID_ANY, u"101 - 103", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT )
self.st101103.Wrap( -1 )
gSizer3.Add( self.st101103, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.st101103 = wx.StaticText(panel, wx.ID_ANY, u"101 - 103", wx.DefaultPosition, wx.DefaultSize,
wx.ALIGN_RIGHT)
self.st101103.Wrap(-1)
gSizer3.Add(self.st101103, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.cp101103S = wx.ColourPickerCtrl( panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize, wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL )
gSizer3.Add( self.cp101103S, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.cp101103S = wx.ColourPickerCtrl(panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize,
wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL)
gSizer3.Add(self.cp101103S, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.cp101103E = wx.ColourPickerCtrl( panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize, wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL )
gSizer3.Add( self.cp101103E, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.cp101103E = wx.ColourPickerCtrl(panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize,
wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL)
gSizer3.Add(self.cp101103E, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.gauge101103S = PFGaugePreview( panel, wx.ID_ANY, 33, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER )
gSizer3.Add( self.gauge101103S, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5 )
self.gauge101103S = PFGaugePreview(panel, wx.ID_ANY, 33, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
gSizer3.Add(self.gauge101103S, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5)
self.gauge101103M = PFGaugePreview( panel, wx.ID_ANY, 66, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER )
gSizer3.Add( self.gauge101103M, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5 )
self.gauge101103M = PFGaugePreview(panel, wx.ID_ANY, 66, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
gSizer3.Add(self.gauge101103M, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5)
self.gauge101103E = PFGaugePreview( panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER )
gSizer3.Add( self.gauge101103E, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.LEFT, 5 )
self.gauge101103E = PFGaugePreview(panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
gSizer3.Add(self.gauge101103E, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 5)
mainSizer.Add( gSizer3, 0, wx.EXPAND, 5 )
mainSizer.Add(gSizer3, 0, wx.EXPAND, 5)
gSizer4 = wx.BoxSizer( wx.HORIZONTAL )
gSizer4 = wx.BoxSizer(wx.HORIZONTAL)
self.st103105 = wx.StaticText( panel, wx.ID_ANY, u"103 - 105", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT )
self.st103105.Wrap( -1 )
gSizer4.Add( self.st103105, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.st103105 = wx.StaticText(panel, wx.ID_ANY, u"103 - 105", wx.DefaultPosition, wx.DefaultSize,
wx.ALIGN_RIGHT)
self.st103105.Wrap(-1)
gSizer4.Add(self.st103105, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.cp103105S = wx.ColourPickerCtrl( panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize, wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL )
gSizer4.Add( self.cp103105S, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.cp103105S = wx.ColourPickerCtrl(panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize,
wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL)
gSizer4.Add(self.cp103105S, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.cp103105E = wx.ColourPickerCtrl( panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize, wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL )
gSizer4.Add( self.cp103105E, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.cp103105E = wx.ColourPickerCtrl(panel, wx.ID_ANY, wx.BLACK, wx.DefaultPosition, wx.DefaultSize,
wx.CLRP_DEFAULT_STYLE | wx.CLRP_SHOW_LABEL)
gSizer4.Add(self.cp103105E, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.gauge103105S = PFGaugePreview( panel, wx.ID_ANY, 33, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER )
gSizer4.Add( self.gauge103105S, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5 )
self.gauge103105S = PFGaugePreview(panel, wx.ID_ANY, 33, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
gSizer4.Add(self.gauge103105S, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5)
self.gauge103105M = PFGaugePreview( panel, wx.ID_ANY, 66, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER )
gSizer4.Add( self.gauge103105M, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5 )
self.gauge103105M = PFGaugePreview(panel, wx.ID_ANY, 66, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
gSizer4.Add(self.gauge103105M, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5)
self.gauge103105E = PFGaugePreview( panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER )
gSizer4.Add( self.gauge103105E, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.LEFT, 5 )
self.gauge103105E = PFGaugePreview(panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
gSizer4.Add(self.gauge103105E, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 5)
mainSizer.Add( gSizer4, 0, wx.EXPAND, 5 )
mainSizer.Add(gSizer4, 0, wx.EXPAND, 5)
footerSizer = wx.BoxSizer( wx.VERTICAL )
footerSizer = wx.BoxSizer(wx.VERTICAL)
self.sl1 = wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
footerSizer.Add( self.sl1, 0, wx.EXPAND |wx.ALL, 5 )
self.sl1 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
footerSizer.Add(self.sl1, 0, wx.EXPAND | wx.ALL, 5)
previewSizer = wx.BoxSizer( wx.HORIZONTAL )
previewSizer = wx.BoxSizer(wx.HORIZONTAL)
self.wndPreview0100 = PFGaugePreview( panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, 0)
previewSizer.Add( self.wndPreview0100, 1, wx.ALIGN_CENTER_VERTICAL, 5 )
self.wndPreview0100 = PFGaugePreview(panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, 0)
previewSizer.Add(self.wndPreview0100, 1, wx.ALIGN_CENTER_VERTICAL, 5)
self.wndPreview100101 = PFGaugePreview( panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, 0)
previewSizer.Add( self.wndPreview100101, 1, wx.ALIGN_CENTER_VERTICAL, 5 )
self.wndPreview100101 = PFGaugePreview(panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, 0)
previewSizer.Add(self.wndPreview100101, 1, wx.ALIGN_CENTER_VERTICAL, 5)
self.wndPreview101103 = PFGaugePreview( panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, 0)
previewSizer.Add( self.wndPreview101103, 1, wx.ALIGN_CENTER_VERTICAL, 5 )
self.wndPreview101103 = PFGaugePreview(panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, 0)
previewSizer.Add(self.wndPreview101103, 1, wx.ALIGN_CENTER_VERTICAL, 5)
self.wndPreview103105 = PFGaugePreview( panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, 0)
previewSizer.Add( self.wndPreview103105, 1, wx.ALIGN_CENTER_VERTICAL, 5 )
self.wndPreview103105 = PFGaugePreview(panel, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, 0)
previewSizer.Add(self.wndPreview103105, 1, wx.ALIGN_CENTER_VERTICAL, 5)
footerSizer.Add( previewSizer, 1, wx.EXPAND | wx.ALL, 5 )
footerSizer.Add(previewSizer, 1, wx.EXPAND | wx.ALL, 5)
buttonsSizer = wx.BoxSizer( wx.HORIZONTAL )
buttonsSizer = wx.BoxSizer(wx.HORIZONTAL)
self.cbLink = wx.CheckBox( panel, wx.ID_ANY, u"Link Colors", wx.DefaultPosition, wx.DefaultSize, 0 )
buttonsSizer.Add( self.cbLink, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 5 )
self.cbLink = wx.CheckBox(panel, wx.ID_ANY, u"Link Colors", wx.DefaultPosition, wx.DefaultSize, 0)
buttonsSizer.Add(self.cbLink, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 5)
self.sliderGradientStart = wx.Slider( panel, wx.ID_ANY, self.gradientStart, -100, 100, wx.DefaultPosition, (127,-1), wx.SL_HORIZONTAL|wx.SL_LABELS )
buttonsSizer.Add( self.sliderGradientStart, 1, wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5 )
self.sliderGradientStart = wx.Slider(panel, wx.ID_ANY, self.gradientStart, -100, 100, wx.DefaultPosition,
(127, -1), wx.SL_HORIZONTAL | wx.SL_LABELS)
buttonsSizer.Add(self.sliderGradientStart, 1, wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.btnRestore = wx.Button( panel, wx.ID_ANY, u"Restore Defaults", wx.DefaultPosition, wx.DefaultSize, 0 )
buttonsSizer.Add( self.btnRestore, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5 )
self.btnRestore = wx.Button(panel, wx.ID_ANY, u"Restore Defaults", wx.DefaultPosition, wx.DefaultSize, 0)
buttonsSizer.Add(self.btnRestore, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.btnDump = wx.Button( panel, wx.ID_ANY, u"Dump Colors", wx.DefaultPosition, wx.DefaultSize, 0 )
buttonsSizer.Add( self.btnDump, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5 )
self.btnDump = wx.Button(panel, wx.ID_ANY, u"Dump Colors", wx.DefaultPosition, wx.DefaultSize, 0)
buttonsSizer.Add(self.btnDump, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.btnOk = wx.Button( panel, wx.ID_ANY, u"Apply", wx.DefaultPosition, wx.DefaultSize, 0 )
buttonsSizer.Add( self.btnOk, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5 )
self.btnOk = wx.Button(panel, wx.ID_ANY, u"Apply", wx.DefaultPosition, wx.DefaultSize, 0)
buttonsSizer.Add(self.btnOk, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
footerSizer.Add( buttonsSizer, 1, wx.ALIGN_RIGHT, 5 )
mainSizer.Add( footerSizer, 0, wx.EXPAND, 5 )
footerSizer.Add(buttonsSizer, 1, wx.ALIGN_RIGHT, 5)
mainSizer.Add(footerSizer, 0, wx.EXPAND, 5)
panel.SetSizer( mainSizer )
panel.SetSizer(mainSizer)
self.SetColours()
# self.Fit()
# self.Layout()
# self.Fit()
# self.Layout()
self.sliderGradientStart.Bind(wx.EVT_SCROLL, self.OnGradientStartScroll)
self.btnRestore.Bind(wx.EVT_BUTTON, self.RestoreDefaults)
self.btnDump.Bind(wx.EVT_BUTTON, self.DumpColours)
self.btnOk.Bind(wx.EVT_BUTTON, self.OnOk)
self.cp0100S.Bind( wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged )
self.cp0100E.Bind( wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged )
self.cp0100S.Bind(wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged)
self.cp0100E.Bind(wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged)
self.cp100101S.Bind( wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged )
self.cp100101E.Bind( wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged )
self.cp100101S.Bind(wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged)
self.cp100101E.Bind(wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged)
self.cp101103S.Bind( wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged )
self.cp101103E.Bind( wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged )
self.cp101103S.Bind(wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged)
self.cp101103E.Bind(wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged)
self.cp103105S.Bind( wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged )
self.cp103105E.Bind( wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged )
self.cp103105S.Bind(wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged)
self.cp103105E.Bind(wx.EVT_COLOURPICKER_CHANGED, self.OnColourChanged)
def getImage(self):
return BitmapLoader.getBitmap("pref-gauges_big", "gui")
@@ -344,7 +358,6 @@ class PFGaugePref ( PreferenceView):
self.gauge0100M.SetGradientStart(self.sliderGradientStart.GetValue())
self.gauge0100E.SetGradientStart(self.sliderGradientStart.GetValue())
self.cp100101S.SetColour(self.c100101S)
self.cp100101E.SetColour(self.c100101E)
self.gauge100101S.SetColour(self.c100101S, self.c100101E)
@@ -363,7 +376,6 @@ class PFGaugePref ( PreferenceView):
self.gauge100101M.SetGradientStart(self.sliderGradientStart.GetValue())
self.gauge100101E.SetGradientStart(self.sliderGradientStart.GetValue())
self.cp101103S.SetColour(self.c101103S)
self.cp101103E.SetColour(self.c101103E)
self.gauge101103S.SetColour(self.c101103S, self.c101103E)
@@ -378,7 +390,6 @@ class PFGaugePref ( PreferenceView):
self.gauge101103M.SetGradientStart(self.sliderGradientStart.GetValue())
self.gauge101103E.SetGradientStart(self.sliderGradientStart.GetValue())
self.cp103105S.SetColour(self.c103105S)
self.cp103105E.SetColour(self.c103105E)
self.gauge103105S.SetColour(self.c103105S, self.c103105E)
@@ -406,7 +417,7 @@ class PFGaugePref ( PreferenceView):
self.wndPreview101103.SetGradientStart(self.sliderGradientStart.GetValue())
self.wndPreview103105.SetColour(self.c103105S, self.c103105E)
self.wndPreview103105.SetPercentages(103,104.99)
self.wndPreview103105.SetPercentages(103, 104.99)
self.wndPreview103105.SetGradientStart(self.sliderGradientStart.GetValue())
def OnGradientStartScroll(self, event):
@@ -415,15 +426,15 @@ class PFGaugePref ( PreferenceView):
event.Skip()
def OnOk(self, event):
#Apply New Settings
# Apply New Settings
event.Skip()
def DumpColours(self, event):
print "Gradient start: %d" % self.sliderGradientStart.GetValue()
print " 0 <-> 100 Start: ", self.c0100S, " End: ", self.c0100E
print "100 <-> 101 Start: ", self.c100101S, " End: ", self.c100101E
print "101 <-> 103 Start: ", self.c101103S, " End: ", self.c101103E
print "103 <-> 105 Start: ", self.c103105S, " End: ", self.c103105E
print("Gradient start: %d" % self.sliderGradientStart.GetValue())
print(" 0 <-> 100 Start: ", self.c0100S, " End: ", self.c0100E)
print("100 <-> 101 Start: ", self.c100101S, " End: ", self.c100101E)
print("101 <-> 103 Start: ", self.c101103S, " End: ", self.c101103E)
print("103 <-> 105 Start: ", self.c103105S, " End: ", self.c103105E)
event.Skip()
@@ -478,7 +489,8 @@ class PFGaugePref ( PreferenceView):
self.SetColours()
event.Skip()
def __del__( self ):
def __del__(self):
pass
PFGaugePref.register()

View File

@@ -4,73 +4,84 @@ from gui.preferenceView import PreferenceView
from gui.bitmapLoader import BitmapLoader
import gui.mainFrame
import service
import gui.globalEvents as GE
from service.settings import SettingsProvider
from service.fit import Fit
class PFGeneralPref ( PreferenceView):
class PFGeneralPref(PreferenceView):
title = "General"
def populatePanel( self, panel ):
def populatePanel(self, panel):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.dirtySettings = False
self.openFitsSettings = service.SettingsProvider.getInstance().getSettings("pyfaPrevOpenFits", {"enabled": False, "pyfaOpenFits": []})
self.openFitsSettings = SettingsProvider.getInstance().getSettings("pyfaPrevOpenFits",
{"enabled": False, "pyfaOpenFits": []})
mainSizer = wx.BoxSizer( wx.VERTICAL )
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.stTitle = wx.StaticText( panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0 )
self.stTitle.Wrap( -1 )
self.stTitle.SetFont( wx.Font( 12, 70, 90, 90, False, wx.EmptyString ) )
self.stTitle = wx.StaticText(panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0)
self.stTitle.Wrap(-1)
self.stTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString))
mainSizer.Add( self.stTitle, 0, wx.ALL, 5 )
mainSizer.Add(self.stTitle, 0, wx.ALL, 5)
self.m_staticline1 = wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
mainSizer.Add( self.m_staticline1, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5 )
self.m_staticline1 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
mainSizer.Add(self.m_staticline1, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)
self.cbGlobalChar = wx.CheckBox( panel, wx.ID_ANY, u"Use global character", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.cbGlobalChar, 0, wx.ALL|wx.EXPAND, 5 )
self.cbGlobalChar = wx.CheckBox(panel, wx.ID_ANY, u"Use global character", wx.DefaultPosition, wx.DefaultSize,
0)
mainSizer.Add(self.cbGlobalChar, 0, wx.ALL | wx.EXPAND, 5)
self.cbGlobalDmgPattern = wx.CheckBox( panel, wx.ID_ANY, u"Use global damage pattern", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.cbGlobalDmgPattern, 0, wx.ALL|wx.EXPAND, 5 )
self.cbGlobalDmgPattern = wx.CheckBox(panel, wx.ID_ANY, u"Use global damage pattern", wx.DefaultPosition,
wx.DefaultSize, 0)
mainSizer.Add(self.cbGlobalDmgPattern, 0, wx.ALL | wx.EXPAND, 5)
self.cbGlobalForceReload = wx.CheckBox( panel, wx.ID_ANY, u"Factor in reload time", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.cbGlobalForceReload, 0, wx.ALL|wx.EXPAND, 5 )
self.cbGlobalForceReload = wx.CheckBox(panel, wx.ID_ANY, u"Factor in reload time", wx.DefaultPosition,
wx.DefaultSize, 0)
mainSizer.Add(self.cbGlobalForceReload, 0, wx.ALL | wx.EXPAND, 5)
self.cbCompactSkills = wx.CheckBox( panel, wx.ID_ANY, u"Compact skills needed tooltip", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.cbCompactSkills, 0, wx.ALL|wx.EXPAND, 5 )
self.cbCompactSkills = wx.CheckBox(panel, wx.ID_ANY, u"Compact skills needed tooltip", wx.DefaultPosition,
wx.DefaultSize, 0)
mainSizer.Add(self.cbCompactSkills, 0, wx.ALL | wx.EXPAND, 5)
self.cbFitColorSlots = wx.CheckBox( panel, wx.ID_ANY, u"Color fitting view by slot", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.cbFitColorSlots, 0, wx.ALL|wx.EXPAND, 5 )
self.cbFitColorSlots = wx.CheckBox(panel, wx.ID_ANY, u"Color fitting view by slot", wx.DefaultPosition,
wx.DefaultSize, 0)
mainSizer.Add(self.cbFitColorSlots, 0, wx.ALL | wx.EXPAND, 5)
self.cbReopenFits = wx.CheckBox( panel, wx.ID_ANY, u"Reopen previous fits on startup", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.cbReopenFits, 0, wx.ALL|wx.EXPAND, 5 )
self.cbReopenFits = wx.CheckBox(panel, wx.ID_ANY, u"Reopen previous fits on startup", wx.DefaultPosition,
wx.DefaultSize, 0)
mainSizer.Add(self.cbReopenFits, 0, wx.ALL | wx.EXPAND, 5)
self.cbRackSlots = wx.CheckBox( panel, wx.ID_ANY, u"Separate Racks", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.cbRackSlots, 0, wx.ALL|wx.EXPAND, 5 )
self.cbRackSlots = wx.CheckBox(panel, wx.ID_ANY, u"Separate Racks", wx.DefaultPosition, wx.DefaultSize, 0)
mainSizer.Add(self.cbRackSlots, 0, wx.ALL | wx.EXPAND, 5)
labelSizer = wx.BoxSizer( wx.VERTICAL )
self.cbRackLabels = wx.CheckBox( panel, wx.ID_ANY, u"Show Rack Labels", wx.DefaultPosition, wx.DefaultSize, 0 )
labelSizer.Add( self.cbRackLabels, 0, wx.ALL|wx.EXPAND, 5 )
mainSizer.Add( labelSizer, 0, wx.LEFT|wx.EXPAND, 30 )
labelSizer = wx.BoxSizer(wx.VERTICAL)
self.cbRackLabels = wx.CheckBox(panel, wx.ID_ANY, u"Show Rack Labels", wx.DefaultPosition, wx.DefaultSize, 0)
labelSizer.Add(self.cbRackLabels, 0, wx.ALL | wx.EXPAND, 5)
mainSizer.Add(labelSizer, 0, wx.LEFT | wx.EXPAND, 30)
self.cbShowTooltip = wx.CheckBox( panel, wx.ID_ANY, u"Show tab tooltips", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.cbShowTooltip, 0, wx.ALL|wx.EXPAND, 5 )
self.cbShowTooltip = wx.CheckBox(panel, wx.ID_ANY, u"Show tab tooltips", wx.DefaultPosition, wx.DefaultSize, 0)
mainSizer.Add(self.cbShowTooltip, 0, wx.ALL | wx.EXPAND, 5)
self.cbMarketShortcuts = wx.CheckBox( panel, wx.ID_ANY, u"Show market shortcuts", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.cbMarketShortcuts, 0, wx.ALL|wx.EXPAND, 5 )
self.cbMarketShortcuts = wx.CheckBox(panel, wx.ID_ANY, u"Show market shortcuts", wx.DefaultPosition,
wx.DefaultSize, 0)
mainSizer.Add(self.cbMarketShortcuts, 0, wx.ALL | wx.EXPAND, 5)
self.cbGaugeAnimation = wx.CheckBox( panel, wx.ID_ANY, u"Animate gauges", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.cbGaugeAnimation, 0, wx.ALL|wx.EXPAND, 5 )
self.cbGaugeAnimation = wx.CheckBox(panel, wx.ID_ANY, u"Animate gauges", wx.DefaultPosition, wx.DefaultSize, 0)
mainSizer.Add(self.cbGaugeAnimation, 0, wx.ALL | wx.EXPAND, 5)
self.cbExportCharges = wx.CheckBox( panel, wx.ID_ANY, u"Export loaded charges", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.cbExportCharges, 0, wx.ALL|wx.EXPAND, 5 )
self.cbOpenFitInNew = wx.CheckBox( panel, wx.ID_ANY, u"Open fittings in a new page by default", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.cbOpenFitInNew, 0, wx.ALL|wx.EXPAND, 5 )
self.cbExportCharges = wx.CheckBox(panel, wx.ID_ANY, u"Export loaded charges", wx.DefaultPosition,
wx.DefaultSize, 0)
mainSizer.Add(self.cbExportCharges, 0, wx.ALL | wx.EXPAND, 5)
defCharSizer = wx.BoxSizer( wx.HORIZONTAL )
self.cbOpenFitInNew = wx.CheckBox(panel, wx.ID_ANY, u"Open fittings in a new page by default",
wx.DefaultPosition, wx.DefaultSize, 0)
mainSizer.Add(self.cbOpenFitInNew, 0, wx.ALL | wx.EXPAND, 5)
self.sFit = service.Fit.getInstance()
wx.BoxSizer(wx.HORIZONTAL)
self.sFit = Fit.getInstance()
self.cbGlobalChar.SetValue(self.sFit.serviceFittingOptions["useGlobalCharacter"])
self.cbGlobalDmgPattern.SetValue(self.sFit.serviceFittingOptions["useGlobalDamagePattern"])
@@ -102,7 +113,7 @@ class PFGeneralPref ( PreferenceView):
self.cbRackLabels.Enable(self.sFit.serviceFittingOptions["rackSlots"] or False)
panel.SetSizer( mainSizer )
panel.SetSizer(mainSizer)
panel.Layout()
def onCBGlobalColorBySlot(self, event):
@@ -163,11 +174,12 @@ class PFGeneralPref ( PreferenceView):
def onCBExportCharges(self, event):
self.sFit.serviceFittingOptions["exportCharges"] = self.cbExportCharges.GetValue()
def onCBOpenFitInNew(self, event):
self.sFit.serviceFittingOptions["openFitInNew"] = self.cbOpenFitInNew.GetValue()
def getImage(self):
return BitmapLoader.getBitmap("prefs_settings", "gui")
PFGeneralPref.register()
PFGeneralPref.register()

View File

@@ -5,78 +5,82 @@ from gui.preferenceView import PreferenceView
from gui.bitmapLoader import BitmapLoader
import gui.mainFrame
import service
import gui.globalEvents as GE
from service.settings import HTMLExportSettings
class PFHTMLExportPref ( PreferenceView):
class PFHTMLExportPref(PreferenceView):
title = "HTML Export"
desc = "HTML Export (File > Export HTML) allows you to export your entire fitting "+\
"database into an HTML file at the specified location. This file can be "+\
"used in the in-game browser to easily open and import your fits, or used "+\
"in a regular web browser to open them at NULL-SEC.com or Osmium."
desc2 = "Enabling automatic exporting will update the HTML file after any change "+\
"to a fit is made. Under certain circumstance, this may cause performance issues."
desc4 = "Export Fittings in a minmal HTML Version, just containing the Fittingslinks " +\
"without any visual styling or javscript features"
desc = ("HTML Export (File > Export HTML) allows you to export your entire fitting "
"database into an HTML file at the specified location. This file can be "
"used in the in-game browser to easily open and import your fits, or used "
"in a regular web browser to open them at NULL-SEC.com or Osmium.")
desc2 = ("Enabling automatic exporting will update the HTML file after any change "
"to a fit is made. Under certain circumstance, this may cause performance issues.")
desc4 = ("Export Fittings in a minmal HTML Version, just containing the Fittingslinks "
"without any visual styling or javscript features")
def populatePanel( self, panel ):
def populatePanel(self, panel):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.HTMLExportSettings = service.settings.HTMLExportSettings.getInstance()
self.HTMLExportSettings = HTMLExportSettings.getInstance()
self.dirtySettings = False
dlgWidth = panel.GetParent().GetParent().ClientSize.width
mainSizer = wx.BoxSizer( wx.VERTICAL )
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.stTitle = wx.StaticText( panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0 )
self.stTitle.Wrap( -1 )
self.stTitle.SetFont( wx.Font( 12, 70, 90, 90, False, wx.EmptyString ) )
mainSizer.Add( self.stTitle, 0, wx.ALL, 5 )
self.stTitle = wx.StaticText(panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0)
self.stTitle.Wrap(-1)
self.stTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString))
mainSizer.Add(self.stTitle, 0, wx.ALL, 5)
self.m_staticline1 = wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
mainSizer.Add( self.m_staticline1, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5 )
self.m_staticline1 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
mainSizer.Add(self.m_staticline1, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)
self.stDesc = wx.StaticText( panel, wx.ID_ANY, self.desc, wx.DefaultPosition, wx.DefaultSize, 0 )
self.stDesc = wx.StaticText(panel, wx.ID_ANY, self.desc, wx.DefaultPosition, wx.DefaultSize, 0)
self.stDesc.Wrap(dlgWidth - 50)
mainSizer.Add( self.stDesc, 0, wx.ALL, 5 )
mainSizer.Add(self.stDesc, 0, wx.ALL, 5)
self.PathLinkCtrl = wx.HyperlinkCtrl( panel, wx.ID_ANY, self.HTMLExportSettings.getPath(), u'file:///{}'.format(self.HTMLExportSettings.getPath()), wx.DefaultPosition, wx.DefaultSize, wx.HL_ALIGN_LEFT|wx.NO_BORDER|wx.HL_CONTEXTMENU )
mainSizer.Add( self.PathLinkCtrl, 0, wx.ALL|wx.EXPAND, 5)
self.PathLinkCtrl = wx.HyperlinkCtrl(panel, wx.ID_ANY, self.HTMLExportSettings.getPath(),
u'file:///{}'.format(self.HTMLExportSettings.getPath()),
wx.DefaultPosition, wx.DefaultSize,
wx.HL_ALIGN_LEFT | wx.NO_BORDER | wx.HL_CONTEXTMENU)
mainSizer.Add(self.PathLinkCtrl, 0, wx.ALL | wx.EXPAND, 5)
self.fileSelectDialog = wx.FileDialog(None, "Save Fitting As...", wildcard = "EVE IGB HTML fitting file (*.html)|*.html", style = wx.FD_SAVE)
self.fileSelectDialog = wx.FileDialog(None, "Save Fitting As...",
wildcard="EVE IGB HTML fitting file (*.html)|*.html", style=wx.FD_SAVE)
self.fileSelectDialog.SetPath(self.HTMLExportSettings.getPath())
self.fileSelectDialog.SetFilename(os.path.basename(self.HTMLExportSettings.getPath()));
self.fileSelectDialog.SetFilename(os.path.basename(self.HTMLExportSettings.getPath()))
self.fileSelectButton = wx.Button(panel, -1, "Set export destination", pos=(0,0))
self.fileSelectButton = wx.Button(panel, -1, "Set export destination", pos=(0, 0))
self.fileSelectButton.Bind(wx.EVT_BUTTON, self.selectHTMLExportFilePath)
mainSizer.Add( self.fileSelectButton, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
mainSizer.Add(self.fileSelectButton, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.stDesc2 = wx.StaticText( panel, wx.ID_ANY, self.desc2, wx.DefaultPosition, wx.DefaultSize, 0 )
self.stDesc2 = wx.StaticText(panel, wx.ID_ANY, self.desc2, wx.DefaultPosition, wx.DefaultSize, 0)
self.stDesc2.Wrap(dlgWidth - 50)
mainSizer.Add( self.stDesc2, 0, wx.ALL, 5 )
mainSizer.Add(self.stDesc2, 0, wx.ALL, 5)
self.exportEnabled = wx.CheckBox( panel, wx.ID_ANY, u"Enable automatic HTML export", wx.DefaultPosition, wx.DefaultSize, 0 )
self.exportEnabled = wx.CheckBox(panel, wx.ID_ANY, u"Enable automatic HTML export", wx.DefaultPosition,
wx.DefaultSize, 0)
self.exportEnabled.SetValue(self.HTMLExportSettings.getEnabled())
self.exportEnabled.Bind(wx.EVT_CHECKBOX, self.OnExportEnabledChange)
mainSizer.Add( self.exportEnabled, 0, wx.ALL|wx.EXPAND, 5 )
mainSizer.Add(self.exportEnabled, 0, wx.ALL | wx.EXPAND, 5)
self.stDesc4 = wx.StaticText( panel, wx.ID_ANY, self.desc4, wx.DefaultPosition, wx.DefaultSize, 0 )
self.stDesc4 = wx.StaticText(panel, wx.ID_ANY, self.desc4, wx.DefaultPosition, wx.DefaultSize, 0)
self.stDesc4.Wrap(dlgWidth - 50)
mainSizer.Add( self.stDesc4, 0, wx.ALL, 5 )
mainSizer.Add(self.stDesc4, 0, wx.ALL, 5)
self.exportMinimal = wx.CheckBox( panel, wx.ID_ANY, u"Enable minimal export Format", wx.DefaultPosition, wx.DefaultSize, 0 )
self.exportMinimal = wx.CheckBox(panel, wx.ID_ANY, u"Enable minimal export Format", wx.DefaultPosition,
wx.DefaultSize, 0)
self.exportMinimal.SetValue(self.HTMLExportSettings.getMinimalEnabled())
self.exportMinimal.Bind(wx.EVT_CHECKBOX, self.OnMinimalEnabledChange)
mainSizer.Add( self.exportMinimal, 0, wx.ALL|wx.EXPAND, 5 )
mainSizer.Add(self.exportMinimal, 0, wx.ALL | wx.EXPAND, 5)
panel.SetSizer( mainSizer )
panel.SetSizer(mainSizer)
panel.Layout()
def setPathLinkCtrlValues(self, path):
self.PathLinkCtrl.SetLabel(self.HTMLExportSettings.getPath())
self.PathLinkCtrl.SetURL(u'file:///{}'.format(self.HTMLExportSettings.getPath()))
self.PathLinkCtrl.SetSize(wx.DefaultSize);
self.PathLinkCtrl.SetSize(wx.DefaultSize)
self.PathLinkCtrl.Refresh()
def selectHTMLExportFilePath(self, event):
@@ -94,4 +98,5 @@ class PFHTMLExportPref ( PreferenceView):
def getImage(self):
return BitmapLoader.getBitmap("prefs_html", "gui")
PFHTMLExportPref.register()

View File

@@ -4,50 +4,54 @@ from gui.preferenceView import PreferenceView
from gui.bitmapLoader import BitmapLoader
import gui.mainFrame
import service
from service.settings import NetworkSettings
from service.network import Network
class PFNetworkPref ( PreferenceView):
class PFNetworkPref(PreferenceView):
title = "Network"
def populatePanel( self, panel ):
def populatePanel(self, panel):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.settings = service.settings.NetworkSettings.getInstance()
self.network = service.Network.getInstance()
self.settings = NetworkSettings.getInstance()
self.network = Network.getInstance()
self.dirtySettings = False
mainSizer = wx.BoxSizer( wx.VERTICAL )
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.stTitle = wx.StaticText( panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0 )
self.stTitle.Wrap( -1 )
self.stTitle.SetFont( wx.Font( 12, 70, 90, 90, False, wx.EmptyString ) )
self.stTitle = wx.StaticText(panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0)
self.stTitle.Wrap(-1)
self.stTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString))
mainSizer.Add( self.stTitle, 0, wx.ALL, 5 )
mainSizer.Add(self.stTitle, 0, wx.ALL, 5)
self.m_staticline1 = wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
mainSizer.Add( self.m_staticline1, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5 )
self.m_staticline1 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
mainSizer.Add(self.m_staticline1, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)
self.cbEnableNetwork = wx.CheckBox( panel, wx.ID_ANY, u"Enable Network", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.cbEnableNetwork, 0, wx.ALL|wx.EXPAND, 5 )
self.cbEnableNetwork = wx.CheckBox(panel, wx.ID_ANY, u"Enable Network", wx.DefaultPosition, wx.DefaultSize, 0)
mainSizer.Add(self.cbEnableNetwork, 0, wx.ALL | wx.EXPAND, 5)
subSizer = wx.BoxSizer( wx.VERTICAL )
self.cbEve = wx.CheckBox( panel, wx.ID_ANY, u"EVE Servers (API && CREST import)", wx.DefaultPosition, wx.DefaultSize, 0 )
subSizer.Add( self.cbEve, 0, wx.ALL|wx.EXPAND, 5 )
subSizer = wx.BoxSizer(wx.VERTICAL)
self.cbEve = wx.CheckBox(panel, wx.ID_ANY, u"EVE Servers (API && CREST import)", wx.DefaultPosition,
wx.DefaultSize, 0)
subSizer.Add(self.cbEve, 0, wx.ALL | wx.EXPAND, 5)
self.cbPricing = wx.CheckBox( panel, wx.ID_ANY, u"Pricing updates", wx.DefaultPosition, wx.DefaultSize, 0 )
subSizer.Add( self.cbPricing, 0, wx.ALL|wx.EXPAND, 5 )
self.cbPricing = wx.CheckBox(panel, wx.ID_ANY, u"Pricing updates", wx.DefaultPosition, wx.DefaultSize, 0)
subSizer.Add(self.cbPricing, 0, wx.ALL | wx.EXPAND, 5)
self.cbPyfaUpdate = wx.CheckBox( panel, wx.ID_ANY, u"Pyfa Update checks", wx.DefaultPosition, wx.DefaultSize, 0 )
subSizer.Add( self.cbPyfaUpdate, 0, wx.ALL|wx.EXPAND, 5 )
self.cbPyfaUpdate = wx.CheckBox(panel, wx.ID_ANY, u"Pyfa Update checks", wx.DefaultPosition, wx.DefaultSize, 0)
subSizer.Add(self.cbPyfaUpdate, 0, wx.ALL | wx.EXPAND, 5)
mainSizer.Add( subSizer, 0, wx.LEFT|wx.EXPAND, 30 )
mainSizer.Add(subSizer, 0, wx.LEFT | wx.EXPAND, 30)
proxyTitle = wx.StaticText( panel, wx.ID_ANY, "Proxy settings", wx.DefaultPosition, wx.DefaultSize, 0 )
proxyTitle.Wrap( -1 )
proxyTitle.SetFont( wx.Font( 12, 70, 90, 90, False, wx.EmptyString ) )
proxyTitle = wx.StaticText(panel, wx.ID_ANY, "Proxy settings", wx.DefaultPosition, wx.DefaultSize, 0)
proxyTitle.Wrap(-1)
proxyTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString))
mainSizer.Add( proxyTitle, 0, wx.ALL, 5 )
mainSizer.Add( wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ), 0, wx.EXPAND, 5 )
mainSizer.Add(proxyTitle, 0, wx.ALL, 5)
mainSizer.Add(wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0,
wx.EXPAND, 5)
self.cbEnableNetwork.SetValue(self.settings.isEnabled(self.network.ENABLED))
self.cbEve.SetValue(self.settings.isEnabled(self.network.EVE))
@@ -61,9 +65,9 @@ class PFNetworkPref ( PreferenceView):
self.toggleNetworks(self.cbEnableNetwork.GetValue())
#---------------
# ---------------
# Proxy
#---------------
# ---------------
self.nMode = self.settings.getMode()
self.nAddr = self.settings.getAddress()
@@ -73,51 +77,50 @@ class PFNetworkPref ( PreferenceView):
if self.nAuth is None:
self.nAuth = ("", "") # we don't want None here, it should be a tuple
ptypeSizer = wx.BoxSizer( wx.HORIZONTAL )
ptypeSizer = wx.BoxSizer(wx.HORIZONTAL)
self.stPType = wx.StaticText( panel, wx.ID_ANY, u"Mode:", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stPType.Wrap( -1 )
ptypeSizer.Add( self.stPType, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.stPType = wx.StaticText(panel, wx.ID_ANY, u"Mode:", wx.DefaultPosition, wx.DefaultSize, 0)
self.stPType.Wrap(-1)
ptypeSizer.Add(self.stPType, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.chProxyTypeChoices = [ u"No proxy", u"Auto-detected proxy settings", u"Manual proxy settings" ]
self.chProxyType = wx.Choice( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, self.chProxyTypeChoices, 0 )
self.chProxyTypeChoices = [u"No proxy", u"Auto-detected proxy settings", u"Manual proxy settings"]
self.chProxyType = wx.Choice(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, self.chProxyTypeChoices, 0)
self.chProxyType.SetSelection(self.nMode)
self.chProxyType.SetSelection( self.nMode )
ptypeSizer.Add(self.chProxyType, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
ptypeSizer.Add( self.chProxyType, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
mainSizer.Add(ptypeSizer, 0, wx.EXPAND, 5)
mainSizer.Add( ptypeSizer, 0, wx.EXPAND, 5 )
fgAddrSizer = wx.FlexGridSizer(2, 2, 0, 0)
fgAddrSizer.AddGrowableCol(1)
fgAddrSizer.SetFlexibleDirection(wx.BOTH)
fgAddrSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
fgAddrSizer = wx.FlexGridSizer( 2, 2, 0, 0 )
fgAddrSizer.AddGrowableCol( 1 )
fgAddrSizer.SetFlexibleDirection( wx.BOTH )
fgAddrSizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
self.stPSetAddr = wx.StaticText(panel, wx.ID_ANY, u"Addr:", wx.DefaultPosition, wx.DefaultSize, 0)
self.stPSetAddr.Wrap(-1)
fgAddrSizer.Add(self.stPSetAddr, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.editProxySettingsAddr = wx.TextCtrl(panel, wx.ID_ANY, self.nAddr, wx.DefaultPosition, wx.DefaultSize, 0)
self.stPSetAddr = wx.StaticText( panel, wx.ID_ANY, u"Addr:", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stPSetAddr.Wrap( -1 )
fgAddrSizer.Add( self.stPSetAddr, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
fgAddrSizer.Add(self.editProxySettingsAddr, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5)
self.editProxySettingsAddr = wx.TextCtrl( panel, wx.ID_ANY, self.nAddr, wx.DefaultPosition, wx.DefaultSize, 0 )
self.stPSetPort = wx.StaticText(panel, wx.ID_ANY, u"Port:", wx.DefaultPosition, wx.DefaultSize, 0)
self.stPSetPort.Wrap(-1)
fgAddrSizer.Add( self.editProxySettingsAddr, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5 )
fgAddrSizer.Add(self.stPSetPort, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.stPSetPort = wx.StaticText( panel, wx.ID_ANY, u"Port:", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stPSetPort.Wrap( -1 )
self.editProxySettingsPort = wx.TextCtrl(panel, wx.ID_ANY, self.nPort, wx.DefaultPosition, wx.DefaultSize, 0)
fgAddrSizer.Add( self.stPSetPort, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
fgAddrSizer.Add(self.editProxySettingsPort, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5)
self.editProxySettingsPort = wx.TextCtrl( panel, wx.ID_ANY, self.nPort, wx.DefaultPosition, wx.DefaultSize, 0 )
fgAddrSizer.Add( self.editProxySettingsPort, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5 )
mainSizer.Add( fgAddrSizer, 0, wx.EXPAND, 5)
mainSizer.Add(fgAddrSizer, 0, wx.EXPAND, 5)
# proxy auth information: login and pass
self.stPSetLogin = wx.StaticText(panel, wx.ID_ANY, u"Username:", wx.DefaultPosition, wx.DefaultSize, 0)
self.stPSetLogin.Wrap(-1)
self.editProxySettingsLogin = wx.TextCtrl(panel, wx.ID_ANY, self.nAuth[0], wx.DefaultPosition, wx.DefaultSize, 0)
self.editProxySettingsLogin = wx.TextCtrl(panel, wx.ID_ANY, self.nAuth[0], wx.DefaultPosition, wx.DefaultSize,
0)
self.stPSetPassword = wx.StaticText(panel, wx.ID_ANY, u"Password:", wx.DefaultPosition, wx.DefaultSize, 0)
self.stPSetPassword.Wrap(-1)
self.editProxySettingsPassword = wx.TextCtrl(panel, wx.ID_ANY, self.nAuth[1], wx.DefaultPosition,
@@ -129,23 +132,24 @@ class PFNetworkPref ( PreferenceView):
pAuthSizer.Add(self.editProxySettingsPassword, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
mainSizer.Add(pAuthSizer, 0, wx.EXPAND, 5)
self.stPSAutoDetected = wx.StaticText( panel, wx.ID_ANY, u"Auto-detected: ", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stPSAutoDetected.Wrap( -1 )
mainSizer.Add( self.stPSAutoDetected, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.stPSAutoDetected = wx.StaticText(panel, wx.ID_ANY, u"Auto-detected: ", wx.DefaultPosition, wx.DefaultSize,
0)
self.stPSAutoDetected.Wrap(-1)
mainSizer.Add(self.stPSAutoDetected, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
btnSizer = wx.BoxSizer( wx.HORIZONTAL )
btnSizer.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 )
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
btnSizer.AddSpacer((0, 0), 1, wx.EXPAND, 5)
self.btnApply = wx.Button( panel, wx.ID_ANY, u"Apply Proxy Settings", wx.DefaultPosition, wx.DefaultSize, 0 )
self.btnApply = wx.Button(panel, wx.ID_ANY, u"Apply Proxy Settings", wx.DefaultPosition, wx.DefaultSize, 0)
btnSizer.Add( self.btnApply, 0, wx.ALL, 5 )
btnSizer.Add(self.btnApply, 0, wx.ALL, 5)
mainSizer.Add(btnSizer, 0, wx.EXPAND,5)
mainSizer.Add(btnSizer, 0, wx.EXPAND, 5)
proxy = self.settings.autodetect()
if proxy is not None:
addr,port = proxy
addr, port = proxy
txt = addr + ":" + str(port)
else:
txt = "None"
@@ -159,17 +163,16 @@ class PFNetworkPref ( PreferenceView):
self.editProxySettingsLogin.Bind(wx.EVT_TEXT, self.OnEditPSLoginText)
self.editProxySettingsPassword.Bind(wx.EVT_TEXT, self.OnEditPSPasswordText)
self.btnApply.Bind(wx.EVT_BUTTON, self.OnBtnApply)
self.UpdateApplyButtonState()
if self.nMode is not service.settings.NetworkSettings.PROXY_MODE_MANUAL: # == 2
if self.nMode is not NetworkSettings.PROXY_MODE_MANUAL: # == 2
self.ToggleProxySettings(False)
else:
self.ToggleProxySettings(True)
panel.SetSizer( mainSizer )
panel.SetSizer(mainSizer)
panel.Layout()
def toggleNetworks(self, toggle):
@@ -236,7 +239,7 @@ class PFNetworkPref ( PreferenceView):
self.UpdateApplyButtonState()
if choice is not service.settings.NetworkSettings.PROXY_MODE_MANUAL:
if choice is not NetworkSettings.PROXY_MODE_MANUAL:
self.ToggleProxySettings(False)
else:
self.ToggleProxySettings(True)
@@ -264,4 +267,5 @@ class PFNetworkPref ( PreferenceView):
def getImage(self):
return BitmapLoader.getBitmap("prefs_proxy", "gui")
PFNetworkPref.register()

View File

@@ -1,84 +1,82 @@
import wx
import service
import os
from gui.preferenceView import PreferenceView
from gui.bitmapLoader import BitmapLoader
import service
import gui.globalEvents as GE
from service.settings import UpdateSettings
class PFUpdatePref (PreferenceView):
class PFUpdatePref(PreferenceView):
title = "Updates"
desc = "Pyfa can automatically check and notify you of new releases. "+\
"This feature is toggled in the Network settings. "+\
"Here, you may allow pre-release notifications and view "+\
"suppressed release notifications, if any."
desc = ("Pyfa can automatically check and notify you of new releases. "
"This feature is toggled in the Network settings. "
"Here, you may allow pre-release notifications and view "
"suppressed release notifications, if any.")
def populatePanel( self, panel ):
self.UpdateSettings = service.settings.UpdateSettings.getInstance()
def populatePanel(self, panel):
self.UpdateSettings = UpdateSettings.getInstance()
self.dirtySettings = False
dlgWidth = panel.GetParent().GetParent().ClientSize.width
mainSizer = wx.BoxSizer( wx.VERTICAL )
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.stTitle = wx.StaticText( panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0 )
self.stTitle.Wrap( -1 )
self.stTitle.SetFont( wx.Font( 12, 70, 90, 90, False, wx.EmptyString ) )
mainSizer.Add( self.stTitle, 0, wx.ALL, 5 )
self.stTitle = wx.StaticText(panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0)
self.stTitle.Wrap(-1)
self.stTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString))
mainSizer.Add(self.stTitle, 0, wx.ALL, 5)
self.m_staticline1 = wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
mainSizer.Add( self.m_staticline1, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5 )
self.m_staticline1 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
mainSizer.Add(self.m_staticline1, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)
self.stDesc = wx.StaticText( panel, wx.ID_ANY, self.desc, wx.DefaultPosition, wx.DefaultSize, 0 )
self.stDesc = wx.StaticText(panel, wx.ID_ANY, self.desc, wx.DefaultPosition, wx.DefaultSize, 0)
self.stDesc.Wrap(dlgWidth - 50)
mainSizer.Add( self.stDesc, 0, wx.ALL, 5 )
mainSizer.Add(self.stDesc, 0, wx.ALL, 5)
self.suppressPrerelease = wx.CheckBox( panel, wx.ID_ANY, u"Allow pre-release notifications", wx.DefaultPosition, wx.DefaultSize, 0 )
self.suppressPrerelease = wx.CheckBox(panel, wx.ID_ANY, u"Allow pre-release notifications", wx.DefaultPosition,
wx.DefaultSize, 0)
self.suppressPrerelease.Bind(wx.EVT_CHECKBOX, self.OnPrereleaseStateChange)
self.suppressPrerelease.SetValue(not self.UpdateSettings.get('prerelease'))
mainSizer.Add( self.suppressPrerelease, 0, wx.ALL|wx.EXPAND, 5 )
mainSizer.Add(self.suppressPrerelease, 0, wx.ALL | wx.EXPAND, 5)
if (self.UpdateSettings.get('version')):
self.versionSizer = wx.BoxSizer( wx.VERTICAL )
self.versionSizer = wx.BoxSizer(wx.VERTICAL)
self.versionTitle = wx.StaticText(panel, wx.ID_ANY, "Suppressing {0} Notifications".format(
self.UpdateSettings.get('version')), wx.DefaultPosition, wx.DefaultSize, 0)
self.versionTitle.Wrap(-1)
self.versionTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString))
self.versionTitle = wx.StaticText( panel, wx.ID_ANY, "Suppressing "+self.UpdateSettings.get('version')+" Notifications", wx.DefaultPosition, wx.DefaultSize, 0 )
self.versionTitle.Wrap( -1 )
self.versionTitle.SetFont( wx.Font( 12, 70, 90, 90, False, wx.EmptyString ) )
self.versionInfo = ("There is a release available which you have chosen to suppress. "
"You can choose to reset notification suppression for this release, "
"or download the new release from GitHub.")
self.versionInfo = "There is a release available which you have chosen to suppress. "+\
"You can choose to reset notification suppression for this release, "+\
"or download the new release from GitHub."
self.versionSizer.AddSpacer((5, 5), 0, wx.EXPAND, 5)
self.versionSizer.AddSpacer( ( 5, 5), 0, wx.EXPAND, 5 )
self.versionSizer.Add(wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL),
0, wx.EXPAND, 5)
self.versionSizer.AddSpacer((5, 5), 0, wx.EXPAND, 5)
self.versionSizer.Add( wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ), 0, wx.EXPAND, 5 )
self.versionSizer.AddSpacer( ( 5, 5), 0, wx.EXPAND, 5 )
self.versionSizer.Add( self.versionTitle, 0, wx.EXPAND, 5 )
self.versionDesc = wx.StaticText( panel, wx.ID_ANY, self.versionInfo, wx.DefaultPosition, wx.DefaultSize, 0 )
self.versionSizer.Add(self.versionTitle, 0, wx.EXPAND, 5)
self.versionDesc = wx.StaticText(panel, wx.ID_ANY, self.versionInfo, wx.DefaultPosition, wx.DefaultSize, 0)
self.versionDesc.Wrap(dlgWidth - 50)
self.versionSizer.Add( self.versionDesc, 0, wx.ALL, 5 )
self.versionSizer.Add(self.versionDesc, 0, wx.ALL, 5)
actionSizer = wx.BoxSizer( wx.HORIZONTAL )
resetSizer = wx.BoxSizer( wx.VERTICAL )
actionSizer = wx.BoxSizer(wx.HORIZONTAL)
resetSizer = wx.BoxSizer(wx.VERTICAL)
self.downloadButton = wx.Button( panel, wx.ID_ANY, "Download", wx.DefaultPosition, wx.DefaultSize, 0 )
self.downloadButton = wx.Button(panel, wx.ID_ANY, "Download", wx.DefaultPosition, wx.DefaultSize, 0)
self.downloadButton.Bind(wx.EVT_BUTTON, self.OnDownload)
resetSizer.Add( self.downloadButton, 0, wx.ALL, 5 )
actionSizer.Add( resetSizer, 1, wx.EXPAND, 5 )
resetSizer.Add(self.downloadButton, 0, wx.ALL, 5)
actionSizer.Add(resetSizer, 1, wx.EXPAND, 5)
self.resetButton = wx.Button( panel, wx.ID_ANY, "Reset Suppression", wx.DefaultPosition, wx.DefaultSize, 0 )
self.resetButton = wx.Button(panel, wx.ID_ANY, "Reset Suppression", wx.DefaultPosition, wx.DefaultSize, 0)
self.resetButton.Bind(wx.EVT_BUTTON, self.ResetSuppression)
actionSizer.Add( self.resetButton, 0, wx.ALL, 5 )
self.versionSizer.Add( actionSizer, 0, wx.EXPAND, 5 )
mainSizer.Add( self.versionSizer, 0, wx.EXPAND, 5 )
actionSizer.Add(self.resetButton, 0, wx.ALL, 5)
self.versionSizer.Add(actionSizer, 0, wx.EXPAND, 5)
mainSizer.Add(self.versionSizer, 0, wx.EXPAND, 5)
panel.SetSizer( mainSizer )
panel.SetSizer(mainSizer)
panel.Layout()
def OnPrereleaseStateChange(self, event):
@@ -96,9 +94,10 @@ class PFUpdatePref (PreferenceView):
self.resetButton.Hide()
def OnDownload(self, event):
wx.LaunchDefaultBrowser('https://github.com/pyfa-org/Pyfa/releases/tag/'+self.UpdateSettings.get('version'))
wx.LaunchDefaultBrowser('https://github.com/pyfa-org/Pyfa/releases/tag/' + self.UpdateSettings.get('version'))
def getImage(self):
return BitmapLoader.getBitmap("prefs_update", "gui")
PFUpdatePref.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,24 +15,26 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from gui.statsView import StatsView
from gui import builtinStatsViews
from gui.bitmapLoader import BitmapLoader
from gui.utils.numberFormatter import formatAmount
class CapacitorViewFull(StatsView):
name = "capacitorViewFull"
def __init__(self, parent):
StatsView.__init__(self)
self.parent = parent
def getHeaderText(self, fit):
return "Capacitor"
def getTextExtentW(self, text):
width, height = self.parent.GetTextExtent( text )
width, height = self.parent.GetTextExtent(text)
return width
def populatePanel(self, contentPanel, headerPanel):
@@ -104,12 +106,13 @@ class CapacitorViewFull(StatsView):
chargeSizer.Add(lbl, 0, wx.ALIGN_CENTER)
chargeSizer.Add(wx.StaticText(parent, wx.ID_ANY, " GJ/s"), 0, wx.ALIGN_CENTER)
def refreshPanel(self, fit):
#If we did anything intresting, we'd update our labels to reflect the new fit's stats here
stats= (("label%sCapacitorCapacity", lambda: fit.ship.getModifiedItemAttr("capacitorCapacity"), 3, 0, 9),
("label%sCapacitorRecharge", lambda: fit.capRecharge, 3, 0, 0),
("label%sCapacitorDischarge", lambda: fit.capUsed, 3, 0, 0))
# If we did anything intresting, we'd update our labels to reflect the new fit's stats here
stats = (
("label%sCapacitorCapacity", lambda: fit.ship.getModifiedItemAttr("capacitorCapacity"), 3, 0, 9),
("label%sCapacitorRecharge", lambda: fit.capRecharge, 3, 0, 0),
("label%sCapacitorDischarge", lambda: fit.capUsed, 3, 0, 0),
)
panel = "Full"
for labelName, value, prec, lowest, highest in stats:
@@ -147,4 +150,5 @@ class CapacitorViewFull(StatsView):
self.panel.Layout()
self.headerPanel.Layout()
CapacitorViewFull.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,17 +15,19 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import service
import gui.mainFrame
from gui.statsView import StatsView
from gui.bitmapLoader import BitmapLoader
from gui.utils.numberFormatter import formatAmount
from service.fit import Fit
class FirepowerViewFull(StatsView):
name = "firepowerViewFull"
def __init__(self, parent):
StatsView.__init__(self)
self.parent = parent
@@ -35,7 +37,7 @@ class FirepowerViewFull(StatsView):
return "Firepower"
def getTextExtentW(self, text):
width, height = self.parent.GetTextExtent( text )
width, height = self.parent.GetTextExtent(text)
return width
def populatePanel(self, contentPanel, headerPanel):
@@ -84,7 +86,7 @@ class FirepowerViewFull(StatsView):
baseBox.Add(BitmapLoader.getStaticBitmap("volley_big", parent, "gui"), 0, wx.ALIGN_CENTER)
gridS = wx.GridSizer(2,2,0,0)
gridS = wx.GridSizer(2, 2, 0, 0)
baseBox.Add(gridS, 0)
@@ -114,7 +116,7 @@ class FirepowerViewFull(StatsView):
def switchToMiningYieldView(self, event):
# Getting the active fit
mainFrame = gui.mainFrame.MainFrame.getInstance()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(mainFrame.getActiveFit())
# Remove ourselves from statsPane's view list
self.parent.views.remove(self)
@@ -139,20 +141,20 @@ class FirepowerViewFull(StatsView):
view.refreshPanel(fit)
def refreshPanel(self, fit):
#If we did anything intresting, we'd update our labels to reflect the new fit's stats here
# If we did anything intresting, we'd update our labels to reflect the new fit's stats here
if fit is not None and fit.targetResists is not None:
self.stEff.Show()
else:
self.stEff.Hide()
stats = (("labelFullDpsWeapon", lambda: fit.weaponDPS, 3, 0, 0, "%s DPS",None),
stats = (("labelFullDpsWeapon", lambda: fit.weaponDPS, 3, 0, 0, "%s DPS", None),
("labelFullDpsDrone", lambda: fit.droneDPS, 3, 0, 0, "%s DPS", None),
("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:
# if fit is not None and fit.totalYield > 0:
# self.miningyield.Show()
#else:
# else:
# self.miningyield.Hide()
counter = 0
@@ -166,9 +168,10 @@ class FirepowerViewFull(StatsView):
tipStr = valueFormat % valueStr if altFormat is None else altFormat % value
label.SetToolTip(wx.ToolTip(tipStr))
self._cachedValues[counter] = value
counter +=1
counter += 1
self.panel.Layout()
self.headerPanel.Layout()
FirepowerViewFull.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2014 Alexandros Kosiaris
#
# This file is part of pyfa.
@@ -15,26 +15,29 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import service
import gui.mainFrame
from gui.statsView import StatsView
from gui.bitmapLoader import BitmapLoader
from gui.utils.numberFormatter import formatAmount
from service.fit import Fit
class MiningYieldViewFull(StatsView):
name = "miningyieldViewFull"
def __init__(self, parent):
StatsView.__init__(self)
self.parent = parent
self._cachedValues = []
def getHeaderText(self, fit):
return "Mining Yield"
def getTextExtentW(self, text):
width, height = self.parent.GetTextExtent( text )
width, height = self.parent.GetTextExtent(text)
return width
def populatePanel(self, contentPanel, headerPanel):
@@ -47,11 +50,11 @@ class MiningYieldViewFull(StatsView):
sizerMiningYield = wx.FlexGridSizer(1, 4)
sizerMiningYield.AddGrowableCol(1)
contentSizer.Add( sizerMiningYield, 0, wx.EXPAND, 0)
contentSizer.Add(sizerMiningYield, 0, wx.EXPAND, 0)
counter = 0
for miningType, image in (("miner", "mining") , ("drone", "drones")):
for miningType, image in (("miner", "mining"), ("drone", "drones")):
baseBox = wx.BoxSizer(wx.HORIZONTAL)
sizerMiningYield.Add(baseBox, 1, wx.ALIGN_LEFT if counter == 0 else wx.ALIGN_CENTER_HORIZONTAL)
@@ -66,7 +69,7 @@ class MiningYieldViewFull(StatsView):
box.Add(hbox, 1, wx.ALIGN_CENTER)
lbl = wx.StaticText(parent, wx.ID_ANY, u"0.0 m\u00B3/s")
setattr(self, "label%sminingyield%s" % (panel.capitalize() ,miningType.capitalize()), lbl)
setattr(self, "label%sminingyield%s" % (panel.capitalize(), miningType.capitalize()), lbl)
hbox.Add(lbl, 0, wx.ALIGN_CENTER)
self._cachedValues.append(0)
@@ -103,7 +106,7 @@ class MiningYieldViewFull(StatsView):
def switchToFirepowerView(self, event):
# Getting the active fit
mainFrame = gui.mainFrame.MainFrame.getInstance()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(mainFrame.getActiveFit())
# Remove ourselves from statsPane's view list
self.parent.views.remove(self)
@@ -122,7 +125,7 @@ class MiningYieldViewFull(StatsView):
view.refreshPanel(fit)
def refreshPanel(self, fit):
#If we did anything intresting, we'd update our labels to reflect the new fit's stats here
# If we did anything intresting, we'd update our labels to reflect the new fit's stats here
stats = (("labelFullminingyieldMiner", lambda: fit.minerYield, 3, 0, 0, u"%s m\u00B3/s",None),
("labelFullminingyieldDrone", lambda: fit.droneYield, 3, 0, 0, u"%s m\u00B3/s", None),
@@ -139,8 +142,9 @@ class MiningYieldViewFull(StatsView):
tipStr = "Mining Yield per second ({0} per hour)".format(formatAmount(value * 3600, 3, 0, 3))
label.SetToolTip(wx.ToolTip(tipStr))
self._cachedValues[counter] = value
counter +=1
counter += 1
self.panel.Layout()
self.headerPanel.Layout()
MiningYieldViewFull.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,17 +15,18 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from gui.statsView import StatsView
from gui import builtinStatsViews
from gui.bitmapLoader import BitmapLoader
from gui.utils.numberFormatter import formatAmount
import service
from service.market import Market
class PriceViewFull(StatsView):
name = "priceViewFull"
def __init__(self, parent):
StatsView.__init__(self)
self.parent = parent
@@ -81,18 +82,18 @@ class PriceViewFull(StatsView):
typeIDs.append(mod.itemID)
for drone in fit.drones:
for _ in xrange(drone.amount):
for _ in range(drone.amount):
typeIDs.append(drone.itemID)
for fighter in fit.fighters:
for _ in xrange(fighter.amountActive):
for _ in range(fighter.amountActive):
typeIDs.append(fighter.itemID)
for cargo in fit.cargo:
for _ in xrange(cargo.amount):
for _ in range(cargo.amount):
typeIDs.append(cargo.itemID)
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
sMkt.getPrices(typeIDs, self.processPrices)
self.labelEMStatus.SetLabel("Updating prices...")
else:
@@ -117,10 +118,11 @@ class PriceViewFull(StatsView):
self.labelPriceFittings.SetLabel("%s ISK" % formatAmount(modPrice, 3, 3, 9, currency=True))
self.labelPriceFittings.SetToolTip(wx.ToolTip('{:,.2f}'.format(modPrice)))
self._cachedFittings = modPrice
if self._cachedTotal != (shipPrice+modPrice):
if self._cachedTotal != (shipPrice + modPrice):
self.labelPriceTotal.SetLabel("%s ISK" % formatAmount(shipPrice + modPrice, 3, 3, 9, currency=True))
self.labelPriceTotal.SetToolTip(wx.ToolTip('{:,.2f}'.format(shipPrice + modPrice)))
self._cachedTotal = shipPrice + modPrice
self.panel.Layout()
PriceViewFull.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from gui.statsView import StatsView
@@ -23,10 +23,12 @@ from gui.bitmapLoader import BitmapLoader
from gui.utils.numberFormatter import formatAmount
import gui.mainFrame
import gui.builtinStatsViews.resistancesViewFull as rvf
import service
from service.fit import Fit
class RechargeViewFull(StatsView):
name = "rechargeViewFull"
def __init__(self, parent):
StatsView.__init__(self)
self.parent = parent
@@ -38,12 +40,12 @@ class RechargeViewFull(StatsView):
return "Recharge rates"
def getTextExtentW(self, text):
width, height = self.parent.GetTextExtent( text )
width, height = self.parent.GetTextExtent(text)
return width
def toggleEffective(self, event):
self.effective = event.effective
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
self.refreshPanel(sFit.getFit(self.mainFrame.getActiveFit()))
event.Skip()
@@ -53,21 +55,22 @@ class RechargeViewFull(StatsView):
self.panel = contentPanel
self.headerPanel = headerPanel
sizerTankStats = wx.FlexGridSizer(3, 5)
for i in xrange(4):
for i in range(4):
sizerTankStats.AddGrowableCol(i + 1)
contentSizer.Add(sizerTankStats, 0, wx.EXPAND, 0)
#Add an empty label first for correct alignment.
# Add an empty label first for correct alignment.
sizerTankStats.Add(wx.StaticText(contentPanel, wx.ID_ANY, ""), 0)
toolTipText = {"shieldPassive" : "Passive shield recharge", "shieldActive" : "Active shield boost", "armorActive" : "Armor repair amount", "hullActive" : "Hull repair amount"}
toolTipText = {"shieldPassive": "Passive shield recharge", "shieldActive": "Active shield boost",
"armorActive": "Armor repair amount", "hullActive": "Hull repair amount"}
for tankType in ("shieldPassive", "shieldActive", "armorActive", "hullActive"):
bitmap = BitmapLoader.getStaticBitmap("%s_big" % tankType, contentPanel, "gui")
tooltip = wx.ToolTip(toolTipText[tankType])
bitmap.SetToolTip(tooltip)
sizerTankStats.Add(bitmap, 0, wx.ALIGN_CENTER)
toolTipText = {"reinforced" : "Reinforced", "sustained" : "Sustained"}
toolTipText = {"reinforced": "Reinforced", "sustained": "Sustained"}
for stability in ("reinforced", "sustained"):
bitmap = BitmapLoader.getStaticBitmap("regen%s_big" % stability.capitalize(), contentPanel, "gui")
tooltip = wx.ToolTip(toolTipText[stability])
@@ -79,7 +82,7 @@ class RechargeViewFull(StatsView):
continue
tankTypeCap = tankType[0].capitalize() + tankType[1:]
lbl = wx.StaticText(contentPanel, wx.ID_ANY, "0.0", style = wx.ALIGN_RIGHT)
lbl = wx.StaticText(contentPanel, wx.ID_ANY, "0.0", style=wx.ALIGN_RIGHT)
setattr(self, "labelTank%s%s" % (stability.capitalize(), tankTypeCap), lbl)
box = wx.BoxSizer(wx.HORIZONTAL)
@@ -91,12 +94,12 @@ class RechargeViewFull(StatsView):
contentPanel.Layout()
def refreshPanel(self, fit):
#If we did anything intresting, we'd update our labels to reflect the new fit's stats here
# If we did anything intresting, we'd update our labels to reflect the new fit's stats here
for stability in ("reinforced", "sustained"):
if stability == "reinforced" and fit != None:
if stability == "reinforced" and fit is not None:
tank = fit.effectiveTank if self.effective else fit.tank
elif stability == "sustained" and fit != None:
elif stability == "sustained" and fit is not None:
tank = fit.effectiveSustainableTank if self.effective else fit.sustainableTank
else:
tank = None
@@ -122,4 +125,5 @@ class RechargeViewFull(StatsView):
self.panel.Layout()
self.headerPanel.Layout()
RechargeViewFull.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,23 +15,22 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from gui.statsView import StatsView
from gui import builtinStatsViews
from gui.bitmapLoader import BitmapLoader
from gui import pygauge as PG
from gui.utils.numberFormatter import formatAmount
import service
import gui.mainFrame
import gui.builtinViews.fittingView as fv
import gui.globalEvents as GE
EffectiveHpToggled, EFFECTIVE_HP_TOGGLED = wx.lib.newevent.NewEvent()
class ResistancesViewFull(StatsView):
name = "resistancesViewFull"
def __init__(self, parent):
StatsView.__init__(self)
self.parent = parent
@@ -45,7 +44,7 @@ class ResistancesViewFull(StatsView):
return "Resistances"
def getTextExtentW(self, text):
width, height = self.parent.GetTextExtent( text )
width, height = self.parent.GetTextExtent(text)
return width
def populatePanel(self, contentPanel, headerPanel):
@@ -56,7 +55,7 @@ class ResistancesViewFull(StatsView):
# Custom header EHP
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 HP: ")
headerContentSizer.Add(self.stEff)
headerPanel.GetParent().AddToggleItem(self.stEff)
@@ -67,81 +66,83 @@ class ResistancesViewFull(StatsView):
stCls = wx.StaticText(headerPanel, wx.ID_ANY, " )")
headerPanel.GetParent().AddToggleItem( stCls )
headerContentSizer.Add( stCls )
# headerContentSizer.Add(wx.StaticLine(headerPanel, wx.ID_ANY), 1, wx.ALIGN_CENTER)
headerPanel.GetParent().AddToggleItem(stCls)
headerContentSizer.Add(stCls)
# headerContentSizer.Add(wx.StaticLine(headerPanel, wx.ID_ANY), 1, wx.ALIGN_CENTER)
# Display table
col = 0
row = 0
sizerResistances = wx.GridBagSizer()
contentSizer.Add( sizerResistances, 0, wx.EXPAND , 0)
contentSizer.Add(sizerResistances, 0, wx.EXPAND, 0)
# Add an empty label, then the rest.
sizerResistances.Add(wx.StaticText(contentPanel, wx.ID_ANY), wx.GBPosition( row, col ), wx.GBSpan( 1, 1 ))
col+=1
toolTipText = {"em" : "Electromagnetic resistance", "thermal" : "Thermal resistance", "kinetic" : "Kinetic resistance", "explosive" : "Explosive resistance"}
sizerResistances.Add(wx.StaticText(contentPanel, wx.ID_ANY), wx.GBPosition(row, col), wx.GBSpan(1, 1))
col += 1
toolTipText = {"em": "Electromagnetic resistance", "thermal": "Thermal resistance",
"kinetic": "Kinetic resistance", "explosive": "Explosive resistance"}
for damageType in ("em", "thermal", "kinetic", "explosive"):
bitmap = BitmapLoader.getStaticBitmap("%s_big" % damageType, contentPanel, "gui")
tooltip = wx.ToolTip(toolTipText[damageType])
bitmap.SetToolTip(tooltip)
sizerResistances.Add(bitmap, wx.GBPosition( row, col ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER)
col+=1
self.stEHPs = wx.Button(contentPanel, style = wx.BU_EXACTFIT, label = "EHP")
sizerResistances.Add(bitmap, wx.GBPosition(row, col), wx.GBSpan(1, 1), wx.ALIGN_CENTER)
col += 1
self.stEHPs = wx.Button(contentPanel, style=wx.BU_EXACTFIT, label="EHP")
self.stEHPs.SetToolTip(wx.ToolTip("Click to toggle between effective HP and raw HP"))
self.stEHPs.Bind(wx.EVT_BUTTON, self.toggleEHP)
for i in xrange(4):
sizerResistances.AddGrowableCol(i+1)
sizerResistances.AddGrowableCol(i + 1)
sizerResistances.Add(self.stEHPs, wx.GBPosition( row, col ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER)
col=0
row+=1
sizerResistances.Add(self.stEHPs, wx.GBPosition(row, col), wx.GBSpan(1, 1), wx.ALIGN_CENTER)
col = 0
row += 1
gaugeColours=( ((38,133,198),(52,86,98)), ((198,38,38),(83,65,67)), ((163,163,163),(74,90,93)), ((198,133,38),(81,83,67)) )
gaugeColours = (((38, 133, 198), (52, 86, 98)), ((198, 38, 38), (83, 65, 67)), ((163, 163, 163), (74, 90, 93)),
((198, 133, 38), (81, 83, 67)))
toolTipText = {"shield" : "Shield resistance", "armor" : "Armor resistance", "hull" : "Hull resistance", "damagePattern" : "Incoming damage pattern"}
toolTipText = {"shield": "Shield resistance", "armor": "Armor resistance", "hull": "Hull resistance",
"damagePattern": "Incoming damage pattern"}
for tankType in ("shield", "armor", "hull", "separator", "damagePattern"):
if tankType != "separator":
bitmap = BitmapLoader.getStaticBitmap("%s_big" % tankType, contentPanel, "gui")
tooltip = wx.ToolTip(toolTipText[tankType])
bitmap.SetToolTip(tooltip)
sizerResistances.Add(bitmap, wx.GBPosition( row, col ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER)
col+=1
sizerResistances.Add(bitmap, wx.GBPosition(row, col), wx.GBSpan(1, 1), wx.ALIGN_CENTER)
col += 1
else:
sizerResistances.Add(wx.StaticLine(contentPanel, wx.ID_ANY), wx.GBPosition( row, col ), wx.GBSpan( 1, 6 ), wx.EXPAND|wx.ALIGN_CENTER)
row+=1
col=0
sizerResistances.Add(wx.StaticLine(contentPanel, wx.ID_ANY), wx.GBPosition(row, col), wx.GBSpan(1, 6),
wx.EXPAND | wx.ALIGN_CENTER)
row += 1
col = 0
continue
currGColour=0
currGColour = 0
for damageType in ("em", "thermal", "kinetic", "explosive"):
box = wx.BoxSizer(wx.HORIZONTAL)
sizerResistances.Add(box, wx.GBPosition( row, col ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER)
sizerResistances.Add(box, wx.GBPosition(row, col), wx.GBSpan(1, 1), wx.ALIGN_CENTER)
# Fancy gauges addon
#Fancy gauges addon
pgColour= gaugeColours[currGColour]
pgColour = gaugeColours[currGColour]
fc = pgColour[0]
bc = pgColour[1]
currGColour+=1
currGColour += 1
lbl = PG.PyGauge(contentPanel, wx.ID_ANY, 100)
lbl.SetMinSize((48, 16))
lbl.SetBackgroundColour(wx.Colour(bc[0],bc[1],bc[2]))
lbl.SetBarColour(wx.Colour(fc[0],fc[1],fc[2]))
lbl.SetBackgroundColour(wx.Colour(bc[0], bc[1], bc[2]))
lbl.SetBarColour(wx.Colour(fc[0], fc[1], fc[2]))
lbl.SetBarGradient()
lbl.SetFractionDigits(1)
setattr(self, "gaugeResistance%s%s" % (tankType.capitalize(), damageType.capitalize()), lbl)
box.Add(lbl, 0, wx.ALIGN_CENTER)
col+=1
col += 1
box = wx.BoxSizer(wx.VERTICAL)
box.SetMinSize(wx.Size(self.getTextExtentW("WWWWk"), -1))
@@ -149,9 +150,9 @@ class ResistancesViewFull(StatsView):
box.Add(lbl, 0, wx.ALIGN_CENTER)
setattr(self, "labelResistance%sEhp" % tankType.capitalize(), lbl)
sizerResistances.Add(box, wx.GBPosition( row, col ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER)
row+=1
col=0
sizerResistances.Add(box, wx.GBPosition(row, col), wx.GBSpan(1, 1), wx.ALIGN_CENTER)
row += 1
col = 0
self.stEHPs.SetToolTip(wx.ToolTip("Click to toggle between effective HP and raw HP"))
@@ -163,7 +164,7 @@ class ResistancesViewFull(StatsView):
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
def refreshPanel(self, fit):
#If we did anything intresting, we'd update our labels to reflect the new fit's stats here
# If we did anything intresting, we'd update our labels to reflect the new fit's stats here
if fit is None and not self.showEffective:
self.showEffective = True
wx.PostEvent(self.mainFrame, EffectiveHpToggled(effective=True))
@@ -194,11 +195,11 @@ class ResistancesViewFull(StatsView):
total += ehp[tankType]
rrFactor = fit.ehp[tankType] / fit.hp[tankType]
lbl.SetLabel(formatAmount(ehp[tankType], 3, 0, 9))
lbl.SetToolTip(wx.ToolTip("%s: %d\nResist Multiplier: x%.2f" % (tankType.capitalize(), ehp[tankType], rrFactor)))
lbl.SetToolTip(
wx.ToolTip("%s: %d\nResist Multiplier: x%.2f" % (tankType.capitalize(), ehp[tankType], rrFactor)))
else:
lbl.SetLabel("0")
self.labelEhp.SetLabel("%s" % formatAmount(total, 3, 0, 9))
if self.showEffective:
self.stEff.SetLabel("( Effective HP: ")
@@ -207,10 +208,9 @@ class ResistancesViewFull(StatsView):
self.stEff.SetLabel("( Raw HP: ")
self.labelEhp.SetToolTip(wx.ToolTip("Raw: %d HP" % total))
damagePattern = fit.damagePattern if fit is not None and self.showEffective else None
damagePattern = fit.damagePattern if fit is not None and self.showEffective else None
total = sum((damagePattern.emAmount, damagePattern.thermalAmount,
damagePattern.kineticAmount, damagePattern.explosiveAmount)) if damagePattern is not None else 0
damagePattern.kineticAmount, damagePattern.explosiveAmount)) if damagePattern is not None else 0
for damageType in ("em", "thermal", "kinetic", "explosive"):
lbl = getattr(self, "gaugeResistanceDamagepattern%s" % damageType.capitalize())
@@ -223,5 +223,5 @@ class ResistancesViewFull(StatsView):
self.panel.Layout()
self.headerPanel.Layout()
ResistancesViewFull.register()
ResistancesViewFull.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,11 +15,10 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from gui.statsView import StatsView
from gui import builtinStatsViews
from gui.bitmapLoader import BitmapLoader
from gui import pygauge as PG
import gui.mainFrame
@@ -29,6 +28,7 @@ from eos.types import Hardpoint
from gui.utils.numberFormatter import formatAmount
class ResourcesViewFull(StatsView):
name = "resourcesViewFull"
contexts = ["drone", "fighter", "cargo"]
@@ -79,7 +79,7 @@ class ResourcesViewFull(StatsView):
return "Resources"
def getTextExtentW(self, text):
width, height = self.parent.GetTextExtent( text )
width, height = self.parent.GetTextExtent(text)
return width
def populatePanel(self, contentPanel, headerPanel):
@@ -99,54 +99,56 @@ class ResourcesViewFull(StatsView):
self.headerPanel = headerPanel
panel = "full"
base = sizerResources
sizer.AddSpacer((0, 0), 1, wx.EXPAND, 5)
#Turrets & launcher hardslots display
tooltipText = {"turret":"Turret hardpoints", "launcher":"Launcher hardpoints", "drones":"Drones active", "fighter": "Fighter squadrons active", "calibration":"Calibration"}
for type in ("turret", "launcher", "drones", "fighter", "calibration"):
# Turrets & launcher hardslots display
tooltipText = {"turret": "Turret hardpoints", "launcher": "Launcher hardpoints", "drones": "Drones active",
"fighter": "Fighter squadrons active", "calibration": "Calibration"}
for type_ in ("turret", "launcher", "drones", "fighter", "calibration"):
box = wx.BoxSizer(wx.HORIZONTAL)
bitmap = BitmapLoader.getStaticBitmap("%s_big" % type, parent, "gui")
tooltip = wx.ToolTip(tooltipText[type])
bitmap = BitmapLoader.getStaticBitmap("%s_big" % type_, parent, "gui")
tooltip = wx.ToolTip(tooltipText[type_])
bitmap.SetToolTip(tooltip)
box.Add(bitmap, 0, wx.ALIGN_CENTER)
sizer.Add(box, 0, wx.ALIGN_CENTER)
suffix = {'turret':'Hardpoints', 'launcher':'Hardpoints', 'drones':'Active', 'fighter':'Tubes', 'calibration':'Points'}
suffix = {'turret': 'Hardpoints', 'launcher': 'Hardpoints', 'drones': 'Active', 'fighter': 'Tubes',
'calibration': 'Points'}
lbl = wx.StaticText(parent, wx.ID_ANY, "0")
setattr(self, "label%sUsed%s%s" % (panel.capitalize(), type.capitalize(), suffix[type].capitalize()), lbl)
setattr(self, "label%sUsed%s%s" % (panel.capitalize(), type_.capitalize(), suffix[type_].capitalize()), lbl)
box.Add(lbl, 0, wx.ALIGN_CENTER | wx.LEFT, 5)
box.Add(wx.StaticText(parent, wx.ID_ANY, "/"), 0, wx.ALIGN_CENTER)
lbl = wx.StaticText(parent, wx.ID_ANY, "0")
setattr(self, "label%sTotal%s%s" % (panel.capitalize(), type.capitalize(), suffix[type].capitalize()), lbl)
setattr(self, "label%sTotal%s%s" % (panel.capitalize(), type_.capitalize(), suffix[type_].capitalize()),
lbl)
box.Add(lbl, 0, wx.ALIGN_CENTER)
setattr(self, "boxSizer{}".format(type.capitalize()), box)
setattr(self, "boxSizer{}".format(type_.capitalize()), box)
# Hack - We add a spacer after each thing, but we are always hiding something. The spacer is stil there.
# This way, we only have one space after the drones/fighters
if type != "drones":
if type_ != "drones":
sizer.AddSpacer((0, 0), 1, wx.EXPAND, 5)
#PG, Cpu & drone stuff
tooltipText = {"cpu":"CPU", "pg":"PowerGrid", "droneBay":"Drone bay", "fighterBay": "Fighter bay", "droneBandwidth":"Drone bandwidth", "cargoBay":"Cargo bay"}
# PG, Cpu & drone stuff
tooltipText = {"cpu": "CPU", "pg": "PowerGrid", "droneBay": "Drone bay", "fighterBay": "Fighter bay",
"droneBandwidth": "Drone bandwidth", "cargoBay": "Cargo bay"}
for i, group in enumerate((("cpu", "pg"), ("cargoBay", "droneBay", "fighterBay", "droneBandwidth"))):
main = wx.BoxSizer(wx.VERTICAL)
base.Add(main, 1 , wx.ALIGN_CENTER)
base.Add(main, 1, wx.ALIGN_CENTER)
for type in group:
capitalizedType = type[0].capitalize() + type[1:]
bitmap = BitmapLoader.getStaticBitmap(type + "_big", parent, "gui")
tooltip = wx.ToolTip(tooltipText[type])
for type_ in group:
capitalizedType = type_[0].capitalize() + type_[1:]
bitmap = BitmapLoader.getStaticBitmap(type_ + "_big", parent, "gui")
tooltip = wx.ToolTip(tooltipText[type_])
bitmap.SetToolTip(tooltip)
stats = wx.BoxSizer(wx.VERTICAL)
absolute = wx.BoxSizer(wx.HORIZONTAL)
absolute = wx.BoxSizer(wx.HORIZONTAL)
stats.Add(absolute, 0, wx.EXPAND)
b = wx.BoxSizer(wx.HORIZONTAL)
@@ -166,8 +168,9 @@ class ResourcesViewFull(StatsView):
setattr(self, "label%sTotal%s" % (panel.capitalize(), capitalizedType), lbl)
absolute.Add(lbl, 0, wx.ALIGN_LEFT)
units = {"cpu":" tf", "pg":" MW", "droneBandwidth":" mbit/s", "droneBay":u" m\u00B3", "fighterBay":u" m\u00B3", "cargoBay":u" m\u00B3"}
lbl = wx.StaticText(parent, wx.ID_ANY, "%s" % units[type])
units = {"cpu": " tf", "pg": " MW", "droneBandwidth": " mbit/s", "droneBay": u" m\u00B3",
"fighterBay": u" m\u00B3", "cargoBay": u" m\u00B3"}
lbl = wx.StaticText(parent, wx.ID_ANY, "%s" % units[type_])
absolute.Add(lbl, 0, wx.ALIGN_LEFT)
# Gauges modif. - Darriele
@@ -177,7 +180,7 @@ class ResourcesViewFull(StatsView):
gauge.SetMinSize((self.getTextExtentW("1.999M/1.99M MW"), 23))
gauge.SetFractionDigits(2)
setattr(self, "gauge%s%s" % (panel.capitalize(),capitalizedType), gauge)
setattr(self, "gauge%s%s" % (panel.capitalize(), capitalizedType), gauge)
stats.Add(gauge, 0, wx.ALIGN_CENTER)
setattr(self, "base%s%s" % (panel.capitalize(), capitalizedType), b)
@@ -186,30 +189,32 @@ class ResourcesViewFull(StatsView):
self.toggleContext("drone")
def refreshPanel(self, fit):
#If we did anything intresting, we'd update our labels to reflect the new fit's stats here
# If we did anything intresting, we'd update our labels to reflect the new fit's stats here
stats = (("label%sUsedTurretHardpoints", lambda: fit.getHardpointsUsed(Hardpoint.TURRET), 0, 0, 0),
("label%sTotalTurretHardpoints", lambda: fit.ship.getModifiedItemAttr('turretSlotsLeft'), 0, 0, 0),
("label%sUsedLauncherHardpoints", lambda: fit.getHardpointsUsed(Hardpoint.MISSILE), 0, 0, 0),
("label%sTotalLauncherHardpoints", lambda: fit.ship.getModifiedItemAttr('launcherSlotsLeft'), 0, 0, 0),
("label%sUsedDronesActive", lambda: fit.activeDrones, 0, 0, 0),
("label%sTotalDronesActive", lambda: fit.extraAttributes["maxActiveDrones"], 0, 0, 0),
("label%sUsedFighterTubes", lambda: fit.fighterTubesUsed, 3, 0, 9),
("label%sTotalFighterTubes", lambda: fit.ship.getModifiedItemAttr("fighterTubes"), 3, 0, 9),
("label%sUsedCalibrationPoints", lambda: fit.calibrationUsed, 0, 0, 0),
("label%sTotalCalibrationPoints", lambda: fit.ship.getModifiedItemAttr('upgradeCapacity'), 0, 0, 0),
("label%sUsedPg", lambda: fit.pgUsed, 4, 0, 9),
("label%sUsedCpu", lambda: fit.cpuUsed, 4, 0, 9),
("label%sTotalPg", lambda: fit.ship.getModifiedItemAttr("powerOutput"), 4, 0, 9),
("label%sTotalCpu", lambda: fit.ship.getModifiedItemAttr("cpuOutput"), 4, 0, 9),
("label%sUsedDroneBay", lambda: fit.droneBayUsed, 3, 0, 9),
("label%sUsedFighterBay", lambda: fit.fighterBayUsed, 3, 0, 9),
("label%sUsedDroneBandwidth", lambda: fit.droneBandwidthUsed, 3, 0, 9),
("label%sTotalDroneBay", lambda: fit.ship.getModifiedItemAttr("droneCapacity"), 3, 0, 9),
("label%sTotalDroneBandwidth", lambda: fit.ship.getModifiedItemAttr("droneBandwidth"), 3, 0, 9),
("label%sTotalFighterBay", lambda: fit.ship.getModifiedItemAttr("fighterCapacity"), 3, 0, 9),
("label%sUsedCargoBay", lambda: fit.cargoBayUsed, 3, 0, 9),
("label%sTotalCargoBay", lambda: fit.ship.getModifiedItemAttr("capacity"), 3, 0, 9))
stats = (
("label%sUsedTurretHardpoints", lambda: fit.getHardpointsUsed(Hardpoint.TURRET), 0, 0, 0),
("label%sTotalTurretHardpoints", lambda: fit.ship.getModifiedItemAttr('turretSlotsLeft'), 0, 0, 0),
("label%sUsedLauncherHardpoints", lambda: fit.getHardpointsUsed(Hardpoint.MISSILE), 0, 0, 0),
("label%sTotalLauncherHardpoints", lambda: fit.ship.getModifiedItemAttr('launcherSlotsLeft'), 0, 0, 0),
("label%sUsedDronesActive", lambda: fit.activeDrones, 0, 0, 0),
("label%sTotalDronesActive", lambda: fit.extraAttributes["maxActiveDrones"], 0, 0, 0),
("label%sUsedFighterTubes", lambda: fit.fighterTubesUsed, 3, 0, 9),
("label%sTotalFighterTubes", lambda: fit.ship.getModifiedItemAttr("fighterTubes"), 3, 0, 9),
("label%sUsedCalibrationPoints", lambda: fit.calibrationUsed, 0, 0, 0),
("label%sTotalCalibrationPoints", lambda: fit.ship.getModifiedItemAttr('upgradeCapacity'), 0, 0, 0),
("label%sUsedPg", lambda: fit.pgUsed, 4, 0, 9),
("label%sUsedCpu", lambda: fit.cpuUsed, 4, 0, 9),
("label%sTotalPg", lambda: fit.ship.getModifiedItemAttr("powerOutput"), 4, 0, 9),
("label%sTotalCpu", lambda: fit.ship.getModifiedItemAttr("cpuOutput"), 4, 0, 9),
("label%sUsedDroneBay", lambda: fit.droneBayUsed, 3, 0, 9),
("label%sUsedFighterBay", lambda: fit.fighterBayUsed, 3, 0, 9),
("label%sUsedDroneBandwidth", lambda: fit.droneBandwidthUsed, 3, 0, 9),
("label%sTotalDroneBay", lambda: fit.ship.getModifiedItemAttr("droneCapacity"), 3, 0, 9),
("label%sTotalDroneBandwidth", lambda: fit.ship.getModifiedItemAttr("droneBandwidth"), 3, 0, 9),
("label%sTotalFighterBay", lambda: fit.ship.getModifiedItemAttr("fighterCapacity"), 3, 0, 9),
("label%sUsedCargoBay", lambda: fit.cargoBayUsed, 3, 0, 9),
("label%sTotalCargoBay", lambda: fit.ship.getModifiedItemAttr("capacity"), 3, 0, 9),
)
panel = "Full"
usedTurretHardpoints = 0
totalTurretHardpoints = 0
@@ -303,12 +308,14 @@ class ResourcesViewFull(StatsView):
labelTCP.SetForegroundColour(colorC)
if fit is not None:
resMax = (lambda: fit.ship.getModifiedItemAttr("cpuOutput"),
lambda: fit.ship.getModifiedItemAttr("powerOutput"),
lambda: fit.ship.getModifiedItemAttr("droneCapacity"),
lambda: fit.ship.getModifiedItemAttr("fighterCapacity"),
lambda: fit.ship.getModifiedItemAttr("droneBandwidth"),
lambda: fit.ship.getModifiedItemAttr("capacity"))
resMax = (
lambda: fit.ship.getModifiedItemAttr("cpuOutput"),
lambda: fit.ship.getModifiedItemAttr("powerOutput"),
lambda: fit.ship.getModifiedItemAttr("droneCapacity"),
lambda: fit.ship.getModifiedItemAttr("fighterCapacity"),
lambda: fit.ship.getModifiedItemAttr("droneBandwidth"),
lambda: fit.ship.getModifiedItemAttr("capacity"),
)
i = 0
for resourceType in ("cpu", "pg", "droneBay", "fighterBay", "droneBandwidth", "cargoBay"):
@@ -316,11 +323,11 @@ class ResourcesViewFull(StatsView):
capitalizedType = resourceType[0].capitalize() + resourceType[1:]
gauge = getattr(self, "gauge%s%s" % (panel, capitalizedType))
resUsed = getattr(fit,"%sUsed" % resourceType)
resUsed = getattr(fit, "%sUsed" % resourceType)
gauge.SetValueRange(resUsed or 0, resMax[i]() or 0)
i+=1
i += 1
else:
capitalizedType = resourceType[0].capitalize() + resourceType[1:]
@@ -328,9 +335,10 @@ class ResourcesViewFull(StatsView):
gauge.SetValueRange(0, 0)
i+=1
i += 1
self.panel.Layout()
self.headerPanel.Layout()
ResourcesViewFull.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,29 +15,31 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from gui.statsView import StatsView
from gui import builtinStatsViews
from gui.utils.numberFormatter import formatAmount
import locale
try:
from collections import OrderedDict
except ImportError:
from utils.compat import OrderedDict
class TargetingMiscViewFull(StatsView):
name = "targetingmiscViewFull"
def __init__(self, parent):
StatsView.__init__(self)
self.parent = parent
self._cachedValues = []
def getHeaderText(self, fit):
return "Targeting && Misc"
def getTextExtentW(self, text):
width, height = self.parent.GetTextExtent( text )
width, height = self.parent.GetTextExtent(text)
return width
def populatePanel(self, contentPanel, headerPanel):
@@ -46,7 +48,7 @@ class TargetingMiscViewFull(StatsView):
self.panel = contentPanel
self.headerPanel = headerPanel
gridTargetingMisc = wx.FlexGridSizer(1, 3)
contentSizer.Add( gridTargetingMisc, 0, wx.EXPAND | wx.ALL, 0)
contentSizer.Add(gridTargetingMisc, 0, wx.EXPAND | wx.ALL, 0)
gridTargetingMisc.AddGrowableCol(0)
gridTargetingMisc.AddGrowableCol(2)
# Targeting
@@ -68,17 +70,17 @@ class TargetingMiscViewFull(StatsView):
box = wx.BoxSizer(wx.HORIZONTAL)
gridTargeting.Add(box, 0, wx.ALIGN_LEFT)
lbl = wx.StaticText(contentPanel, wx.ID_ANY, "0 %s" %unit)
lbl = wx.StaticText(contentPanel, wx.ID_ANY, "0 %s" % unit)
setattr(self, "label%s" % labelShort, lbl)
box.Add(lbl, 0, wx.ALIGN_LEFT)
self._cachedValues.append({"main": 0})
# Misc
gridTargetingMisc.Add( wx.StaticLine( contentPanel, wx.ID_ANY, style = wx.VERTICAL),0, wx.EXPAND, 3 )
gridTargetingMisc.Add(wx.StaticLine(contentPanel, wx.ID_ANY, style=wx.VERTICAL), 0, wx.EXPAND, 3)
gridMisc = wx.FlexGridSizer(5, 2)
gridMisc.AddGrowableCol(1)
gridTargetingMisc.Add(gridMisc,0 , wx.ALIGN_LEFT | wx.ALL, 5)
gridTargetingMisc.Add(gridMisc, 0, wx.ALIGN_LEFT | wx.ALL, 5)
labels = (("Speed", "Speed", "m/s"),
("Align time", "AlignTime", "s"),
@@ -98,9 +100,8 @@ class TargetingMiscViewFull(StatsView):
self._cachedValues.append({"main": 0})
def refreshPanel(self, fit):
#If we did anything interesting, we'd update our labels to reflect the new fit's stats here
# If we did anything interesting, we'd update our labels to reflect the new fit's stats here
cargoNamesOrder = OrderedDict((
("fleetHangarCapacity", "Fleet hangar"),
@@ -132,14 +133,17 @@ class TargetingMiscViewFull(StatsView):
"specialSmallShipHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialSmallShipHoldCapacity"),
"specialMediumShipHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialMediumShipHoldCapacity"),
"specialLargeShipHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialLargeShipHoldCapacity"),
"specialIndustrialShipHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialIndustrialShipHoldCapacity"),
"specialIndustrialShipHoldCapacity": lambda: fit.ship.getModifiedItemAttr(
"specialIndustrialShipHoldCapacity"),
"specialOreHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialOreHoldCapacity"),
"specialMineralHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialMineralHoldCapacity"),
"specialMaterialBayCapacity": lambda: fit.ship.getModifiedItemAttr("specialMaterialBayCapacity"),
"specialGasHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialGasHoldCapacity"),
"specialSalvageHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialSalvageHoldCapacity"),
"specialCommandCenterHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialCommandCenterHoldCapacity"),
"specialPlanetaryCommoditiesHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialPlanetaryCommoditiesHoldCapacity"),
"specialCommandCenterHoldCapacity": lambda: fit.ship.getModifiedItemAttr(
"specialCommandCenterHoldCapacity"),
"specialPlanetaryCommoditiesHoldCapacity": lambda: fit.ship.getModifiedItemAttr(
"specialPlanetaryCommoditiesHoldCapacity"),
"specialQuafeHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialQuafeHoldCapacity")
}
@@ -155,9 +159,9 @@ class TargetingMiscViewFull(StatsView):
("labelFullCargo", cargoValues, 4, 0, 9, u"m\u00B3"))
counter = 0
RADII = [("Pod",25), ("Interceptor",33), ("Frigate",38),
RADII = [("Pod", 25), ("Interceptor", 33), ("Frigate", 38),
("Destroyer", 83), ("Cruiser", 130),
("Battlecruiser", 265), ("Battleship",420),
("Battlecruiser", 265), ("Battleship", 420),
("Carrier", 3000)]
for labelName, valueDict, prec, lowest, highest, unit in stats:
label = getattr(self, labelName)
@@ -173,13 +177,13 @@ class TargetingMiscViewFull(StatsView):
# Get sum of all cargoholds except for maintenance bay
additionalCargo = sum(otherValues.values())
if additionalCargo > 0:
label.SetLabel("%s+%s %s" %(formatAmount(mainValue, prec, lowest, highest),
formatAmount(additionalCargo, prec, lowest, highest),
unit))
label.SetLabel("%s+%s %s" % (formatAmount(mainValue, prec, lowest, highest),
formatAmount(additionalCargo, prec, lowest, highest),
unit))
else:
label.SetLabel("%s %s" %(formatAmount(mainValue, prec, lowest, highest), unit))
label.SetLabel("%s %s" % (formatAmount(mainValue, prec, lowest, highest), unit))
else:
label.SetLabel("%s %s" %(formatAmount(mainValue, prec, lowest, highest), unit))
label.SetLabel("%s %s" % (formatAmount(mainValue, prec, lowest, highest), unit))
# Tooltip stuff
if fit:
if labelName == "labelScanRes":
@@ -187,25 +191,27 @@ class TargetingMiscViewFull(StatsView):
for size, radius in RADII:
left = "%.1fs" % fit.calculateLockTime(radius)
right = "%s [%d]" % (size, radius)
lockTime += "%5s\t%s\n" % (left,right)
lockTime += "%5s\t%s\n" % (left, right)
label.SetToolTip(wx.ToolTip(lockTime))
elif labelName == "labelFullSigRadius":
label.SetToolTip(wx.ToolTip("Probe Size: %.3f" % (fit.probeSize or 0) ))
label.SetToolTip(wx.ToolTip("Probe Size: %.3f" % (fit.probeSize or 0)))
elif labelName == "labelFullWarpSpeed":
label.SetToolTip(wx.ToolTip("Max Warp Distance: %.1f AU" % fit.maxWarpDistance))
elif labelName == "labelSensorStr":
if fit.jamChance > 0:
label.SetToolTip(wx.ToolTip("Type: %s\n%.1f%% Chance of Jam" % (fit.scanType, fit.jamChance)))
label.SetToolTip(
wx.ToolTip("Type: %s\n%.1f%% Chance of Jam" % (fit.scanType, fit.jamChance)))
else:
label.SetToolTip(wx.ToolTip("Type: %s" % (fit.scanType)))
label.SetToolTip(wx.ToolTip("Type: %s" % (fit.scanType)))
elif labelName == "labelFullAlignTime":
alignTime = "Align:\t%.3fs"%mainValue
alignTime = "Align:\t%.3fs" % mainValue
mass = 'Mass:\t{:,.0f}kg'.format(fit.ship.getModifiedItemAttr("mass"))
agility = "Agility:\t%.3fx"%(fit.ship.getModifiedItemAttr("agility") or 0)
agility = "Agility:\t%.3fx" % (fit.ship.getModifiedItemAttr("agility") or 0)
label.SetToolTip(wx.ToolTip("%s\n%s\n%s" % (alignTime, mass, agility)))
elif labelName == "labelFullCargo":
tipLines = []
tipLines.append(u"Cargohold: {:,.2f}m\u00B3 / {:,.2f}m\u00B3".format(fit.cargoBayUsed, newValues["main"]))
tipLines.append(
u"Cargohold: {:,.2f}m\u00B3 / {:,.2f}m\u00B3".format(fit.cargoBayUsed, newValues["main"]))
for attrName, tipAlias in cargoNamesOrder.items():
if newValues[attrName] > 0:
tipLines.append(u"{}: {:,.2f}m\u00B3".format(tipAlias, newValues[attrName]))
@@ -234,7 +240,8 @@ class TargetingMiscViewFull(StatsView):
# if you add stuff to cargo, the capacity doesn't change and thus it is still cached
# This assures us that we force refresh of cargo tooltip
tipLines = []
tipLines.append(u"Cargohold: {:,.2f}m\u00B3 / {:,.2f}m\u00B3".format(fit.cargoBayUsed, cachedCargo["main"]))
tipLines.append(
u"Cargohold: {:,.2f}m\u00B3 / {:,.2f}m\u00B3".format(fit.cargoBayUsed, cachedCargo["main"]))
for attrName, tipAlias in cargoNamesOrder.items():
if cachedCargo[attrName] > 0:
tipLines.append(u"{}: {:,.2f}m\u00B3".format(tipAlias, cachedCargo[attrName]))
@@ -247,4 +254,5 @@ class TargetingMiscViewFull(StatsView):
self.panel.Layout()
self.headerPanel.Layout()
TargetingMiscViewFull.register()

View File

@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -16,17 +15,18 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
from gui.viewColumn import ViewColumn
import gui.mainFrame
import wx
from eos.types import Fighter
from gui.viewColumn import ViewColumn
import gui.mainFrame
class Abilities(ViewColumn):
name = "Fighter Abilities"
def __init__(self, fittingView, params):
ViewColumn.__init__(self, fittingView)
@@ -41,4 +41,5 @@ class Abilities(ViewColumn):
return "None"
return ", ".join(active)
Abilities.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,17 +15,17 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
from gui import builtinViewColumns
from gui.viewColumn import ViewColumn
from gui.bitmapLoader import BitmapLoader
import wx
from eos.types import Fighter
from gui.viewColumn import ViewColumn
from gui.bitmapLoader import BitmapLoader
class Ammo(ViewColumn):
name = "Ammo"
def __init__(self, fittingView, params):
ViewColumn.__init__(self, fittingView)
self.mask = wx.LIST_MASK_IMAGE
@@ -43,7 +43,7 @@ class Ammo(ViewColumn):
charges = stuff.numCharges
if charges > 0:
cycles = stuff.numShots
if cycles !=0 and charges != cycles:
if cycles != 0 and charges != cycles:
return "%s (%d, %d cycles)" % (stuff.charge.name, charges, cycles)
else:
return "%s (%d)" % (stuff.charge.name, charges)
@@ -54,5 +54,5 @@ class Ammo(ViewColumn):
def getImageId(self, mod):
return -1
Ammo.register()
Ammo.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,16 +15,16 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
from gui import builtinViewColumns
from gui.viewColumn import ViewColumn
from gui.bitmapLoader import BitmapLoader
import wx
from eos.types import Module
class AmmoIcon(ViewColumn):
name = "Ammo Icon"
def __init__(self, fittingView, params):
ViewColumn.__init__(self, fittingView)
self.size = 24
@@ -52,4 +52,5 @@ class AmmoIcon(ViewColumn):
if isinstance(mod, Module) and mod.charge is not None:
return mod.charge.name
AmmoIcon.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,21 +15,24 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from gui import builtinViewColumns
from gui.viewColumn import ViewColumn
from gui.bitmapLoader import BitmapLoader
from gui.utils.numberFormatter import formatAmount
import service
import wx
from service.attribute import Attribute
from service.market import Market
class AttributeDisplay(ViewColumn):
name = "attr"
def __init__(self, fittingView, params):
ViewColumn.__init__(self, fittingView)
sAttr = service.Attribute.getInstance()
sAttr = Attribute.getInstance()
info = sAttr.getAttributeInfo(params["attribute"])
self.info = info
if params["showIcon"]:
@@ -57,9 +60,10 @@ class AttributeDisplay(ViewColumn):
self.direct = True
self.view = fittingView
originalRefresh = fittingView.refresh
sMkt = service.Market.getInstance()
#Hack into our master view and add a callback for ourselves to know when to query
sMkt = Market.getInstance()
def refresh(stuff):
# Hack into our master view and add a callback for ourselves to know when to query
self.directInfo = sMkt.directAttrRequest(stuff, info) if stuff else None
originalRefresh(stuff)
@@ -76,10 +80,10 @@ class AttributeDisplay(ViewColumn):
attr = mod.getAttribute(self.info.name)
if self.info.name == "volume":
str = (formatAmount(attr, 3, 0, 3))
str_ = (formatAmount(attr, 3, 0, 3))
if hasattr(mod, "amount"):
str = str + u"m\u00B3 (%s m\u00B3)"%(formatAmount(attr*mod.amount, 3, 0, 3))
attr = str
str_ = str_ + u"m\u00B3 (%s m\u00B3)" % (formatAmount(attr * mod.amount, 3, 0, 3))
attr = str_
if isinstance(attr, (float, int)):
attr = (formatAmount(attr, 3, 0, 3))
@@ -102,4 +106,5 @@ class AttributeDisplay(ViewColumn):
("showIcon", bool, True),
("direct", bool, False))
AttributeDisplay.register()

View File

@@ -1,44 +1,46 @@
from gui import builtinViewColumns
from gui.viewColumn import ViewColumn
from gui.bitmapLoader import BitmapLoader
import wx
from eos.types import Drone, Fit, Module, Slot, Rack, Implant
class BaseIcon(ViewColumn):
name = "Base Icon"
def __init__(self, fittingView, params):
ViewColumn.__init__(self, fittingView)
self.size = 24
self.maxsize = self.size
self.mask = wx.LIST_MASK_IMAGE
self.columnText = ""
self.shipImage = fittingView.imageList.GetImageIndex("ship_small", "gui")
def getImageId(self, stuff):
if isinstance(stuff, Drone):
return -1
if isinstance(stuff, Fit):
return self.shipImage
if isinstance(stuff, Rack):
return -1
if isinstance(stuff, Implant):
if stuff.character: # if it has a character as it's parent
return self.fittingView.imageList.GetImageIndex("character_small", "gui")
else:
return self.shipImage
if isinstance(stuff, Module):
if stuff.isEmpty:
return self.fittingView.imageList.GetImageIndex("slot_%s_small" % Slot.getName(stuff.slot).lower(), "gui")
else:
return self.loadIconFile(stuff.item.icon.iconFile if stuff.item.icon else "")
item = getattr(stuff, "item", stuff)
return self.loadIconFile(item.icon.iconFile if item.icon else "")
def loadIconFile(self, iconFile):
if iconFile:
return self.fittingView.imageList.GetImageIndex(iconFile, "icons")
else:
return -1
BaseIcon.register()
import wx
from eos.types import Drone, Fit, Module, Slot, Rack, Implant
from gui.viewColumn import ViewColumn
class BaseIcon(ViewColumn):
name = "Base Icon"
def __init__(self, fittingView, params):
ViewColumn.__init__(self, fittingView)
self.size = 24
self.maxsize = self.size
self.mask = wx.LIST_MASK_IMAGE
self.columnText = ""
self.shipImage = fittingView.imageList.GetImageIndex("ship_small", "gui")
def getImageId(self, stuff):
if isinstance(stuff, Drone):
return -1
elif isinstance(stuff, Fit):
return self.shipImage
elif isinstance(stuff, Rack):
return -1
elif isinstance(stuff, Implant):
if stuff.character: # if it has a character as it's parent
return self.fittingView.imageList.GetImageIndex("character_small", "gui")
else:
return self.shipImage
elif isinstance(stuff, Module):
if stuff.isEmpty:
return self.fittingView.imageList.GetImageIndex("slot_%s_small" % Slot.getName(stuff.slot).lower(),
"gui")
else:
return self.loadIconFile(stuff.item.icon.iconFile if stuff.item.icon else "")
item = getattr(stuff, "item", stuff)
return self.loadIconFile(item.icon.iconFile if item.icon else "")
def loadIconFile(self, iconFile):
if iconFile:
return self.fittingView.imageList.GetImageIndex(iconFile, "icons")
else:
return -1
BaseIcon.register()

View File

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
#===============================================================================
# coding: utf-8
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -16,17 +16,18 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from eos.types import Drone, Cargo, Module, Slot, Rack, Implant, Fighter
from service.fit import Fit
from gui.viewColumn import ViewColumn
import gui.mainFrame
import wx
from eos.types import Drone, Cargo, Fit, Module, Slot, Rack, Implant, Fighter
import service
class BaseName(ViewColumn):
name = "Base Name"
def __init__(self, fittingView, params):
ViewColumn.__init__(self, fittingView)
@@ -39,8 +40,9 @@ class BaseName(ViewColumn):
def getText(self, stuff):
if isinstance(stuff, Drone):
return "%dx %s" % (stuff.amount, stuff.item.name)
if isinstance(stuff, Fighter):
return "%d/%d %s" % (stuff.amountActive, stuff.getModifiedItemAttr("fighterSquadronMaxSize"), stuff.item.name)
elif isinstance(stuff, Fighter):
return "%d/%d %s" % \
(stuff.amountActive, stuff.getModifiedItemAttr("fighterSquadronMaxSize"), stuff.item.name)
elif isinstance(stuff, Cargo):
return "%dx %s" % (stuff.amount, stuff.item.name)
elif isinstance(stuff, Fit):
@@ -51,7 +53,7 @@ class BaseName(ViewColumn):
else:
return "%s (%s)" % (stuff.name, stuff.ship.item.name)
elif isinstance(stuff, Rack):
if service.Fit.getInstance().serviceFittingOptions["rackLabels"]:
if Fit.getInstance().serviceFittingOptions["rackLabels"]:
if stuff.slot == Slot.MODE:
return u'─ Tactical Mode ─'
else:
@@ -68,15 +70,16 @@ class BaseName(ViewColumn):
else:
item = getattr(stuff, "item", stuff)
if service.Fit.getInstance().serviceFittingOptions["showMarketShortcuts"]:
if Fit.getInstance().serviceFittingOptions["showMarketShortcuts"]:
marketShortcut = getattr(item, "marketShortcut", None)
if marketShortcut:
# use unicode subscript to display shortcut value
shortcut = unichr(marketShortcut+8320)+u" "
shortcut = unichr(marketShortcut + 8320) + u" "
del item.marketShortcut
return shortcut+item.name
return shortcut + item.name
return item.name
BaseName.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,25 +15,26 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import service
from eos.types import Mode
from service.attribute import Attribute
from gui.utils.numberFormatter import formatAmount
from gui.viewColumn import ViewColumn
from gui.bitmapLoader import BitmapLoader
from eos.types import Mode
class CapacitorUse(ViewColumn):
name = "Capacitor Usage"
def __init__(self, fittingView, params):
ViewColumn.__init__(self, fittingView)
self.mask = wx.LIST_MASK_IMAGE
sAttr = service.Attribute.getInstance()
info = sAttr.getAttributeInfo("capacitorNeed")
Attribute.getInstance().getAttributeInfo("capacitorNeed")
self.imageId = fittingView.imageList.GetImageIndex("capacitorRecharge_small", "gui")
self.bitmap = BitmapLoader.getBitmap("capacitorRecharge_small", "gui")
@@ -53,4 +54,5 @@ class CapacitorUse(ViewColumn):
def getToolTip(self, mod):
return self.name
CapacitorUse.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,25 +15,27 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
from gui import builtinViewColumns
import wx
from eos.types import Mode
from service.attribute import Attribute
from gui.viewColumn import ViewColumn
from gui.bitmapLoader import BitmapLoader
import service
from gui.utils.numberFormatter import formatAmount
import wx
from eos.types import Mode
class MaxRange(ViewColumn):
name = "Max Range"
def __init__(self, fittingView, params = None):
if params == None:
params = {"showIcon": True,
"displayName": False}
def __init__(self, fittingView, params=None):
if params is None:
params = {"showIcon": True, "displayName": False}
ViewColumn.__init__(self, fittingView)
sAttr = service.Attribute.getInstance()
sAttr = Attribute.getInstance()
info = sAttr.getAttributeInfo("maxRange")
self.info = info
if params["showIcon"]:
@@ -71,10 +73,10 @@ class MaxRange(ViewColumn):
return -1
def getParameters(self):
return (("displayName", bool, False),
("showIcon", bool, True))
return (("displayName", bool, False), ("showIcon", bool, True))
def getToolTip(self, mod):
return "Optimal + Falloff"
MaxRange.register()

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos, Lucas Thode
#
# This file is part of pyfa.
@@ -15,17 +15,20 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from eos.types import Drone, Cargo
from service.market import Market
from gui.viewColumn import ViewColumn
from gui.bitmapLoader import BitmapLoader
from gui.utils.numberFormatter import formatAmount
from eos.types import Drone, Cargo
import wx
import service
class Price(ViewColumn):
name = "Price"
def __init__(self, fittingView, params):
ViewColumn.__init__(self, fittingView)
self.mask = wx.LIST_MASK_IMAGE
@@ -36,7 +39,7 @@ class Price(ViewColumn):
if stuff.item is None or stuff.item.group.name == "Ship Modifiers":
return ""
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
price = sMkt.getPriceNow(stuff.item.ID)
if not price or not price.price or not price.isValid:
@@ -45,21 +48,22 @@ class Price(ViewColumn):
price = price.price # Set new price variable with what we need
if isinstance(stuff, Drone) or isinstance(stuff, Cargo):
price *= stuff.amount
price *= stuff.amount
return formatAmount(price, 3, 3, 9, currency=True)
def delayedText(self, mod, display, colItem):
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
def callback(item):
price = sMkt.getPriceNow(item.ID)
text = formatAmount(price.price, 3, 3, 9, currency=True) if price.price else ""
if price.failed: text += " (!)"
if price.failed:
text += " (!)"
colItem.SetText(text)
display.SetItem(colItem)
sMkt.waitForPrice(mod.item, callback)
def getImageId(self, mod):
@@ -68,4 +72,5 @@ class Price(ViewColumn):
def getToolTip(self, mod):
return self.name
Price.register()

View File

@@ -1,70 +1,71 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from gui.viewColumn import ViewColumn
from gui.bitmapLoader import BitmapLoader
from gui.utils.numberFormatter import formatAmount
import wx
import service
class PropertyDisplay(ViewColumn):
name = "prop"
def __init__(self, fittingView, params):
ViewColumn.__init__(self, fittingView)
sAttr = service.Attribute.getInstance()
attributeSlave = params["attributeSlave"] or params["property"]
# This function can throw an exception if the database isn't sane
# We need to do a sanity check before this runs
info = sAttr.getAttributeInfo(attributeSlave)
self.mask = 0
self.propertyName = params["property"]
self.info = info
if params["showIcon"]:
if info.name == "power":
iconFile = "pg_small"
iconType = "gui"
else:
iconFile = info.icon.iconFile if info.icon else None
iconType = "icons"
if iconFile:
self.imageId = fittingView.imageList.GetImageIndex(iconFile, iconType)
else:
self.imageId = -1
else:
self.imageId = -1
if params["displayName"] or self.imageId == -1:
self.columnText = info.displayName if info.displayName != "" else info.name
def getText(self, stuff):
attr = getattr(stuff, self.propertyName, None)
if attr:
return (formatAmount(attr, 3, 0, 3))
else:
return ""
@staticmethod
def getParameters():
return (("property", str, None),
("attributeSlave", str, None),
("displayName", bool, False),
("showIcon", bool, True))
PropertyDisplay.register()
# =============================================================================
# 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 <http://www.gnu.org/licenses/>.
# =============================================================================
from gui.viewColumn import ViewColumn
from gui.utils.numberFormatter import formatAmount
from service.attribute import Attribute
class PropertyDisplay(ViewColumn):
name = "prop"
def __init__(self, fittingView, params):
ViewColumn.__init__(self, fittingView)
sAttr = Attribute.getInstance()
attributeSlave = params["attributeSlave"] or params["property"]
# This function can throw an exception if the database isn't sane
# We need to do a sanity check before this runs
info = sAttr.getAttributeInfo(attributeSlave)
self.mask = 0
self.propertyName = params["property"]
self.info = info
if params["showIcon"]:
if info.name == "power":
iconFile = "pg_small"
iconType = "gui"
else:
iconFile = info.icon.iconFile if info.icon else None
iconType = "icons"
if iconFile:
self.imageId = fittingView.imageList.GetImageIndex(iconFile, iconType)
else:
self.imageId = -1
else:
self.imageId = -1
if params["displayName"] or self.imageId == -1:
self.columnText = info.displayName if info.displayName != "" else info.name
def getText(self, stuff):
attr = getattr(stuff, self.propertyName, None)
if attr:
return (formatAmount(attr, 3, 0, 3))
else:
return ""
@staticmethod
def getParameters():
return (("property", str, None),
("attributeSlave", str, None),
("displayName", bool, False),
("showIcon", bool, True))
PropertyDisplay.register()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,18 +15,21 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
from gui.viewColumn import ViewColumn
from gui.bitmapLoader import BitmapLoader
import gui.mainFrame
import wx
from eos.types import Drone, Module, Rack, Fit, Implant
from eos.types import State as State_
from gui.viewColumn import ViewColumn
import gui.mainFrame
class State(ViewColumn):
name = "State"
def __init__(self, fittingView, params):
ViewColumn.__init__(self, fittingView)
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
@@ -44,7 +47,8 @@ class State(ViewColumn):
def getImageId(self, stuff):
generic_active = self.fittingView.imageList.GetImageIndex("state_%s_small" % State_.getName(1).lower(), "gui")
generic_inactive = self.fittingView.imageList.GetImageIndex("state_%s_small" % State_.getName(-1).lower(), "gui")
generic_inactive = self.fittingView.imageList.GetImageIndex("state_%s_small" % State_.getName(-1).lower(),
"gui")
if isinstance(stuff, Drone):
if stuff.amountActive > 0:
@@ -57,7 +61,8 @@ class State(ViewColumn):
if stuff.isEmpty:
return -1
else:
return self.fittingView.imageList.GetImageIndex("state_%s_small" % State_.getName(stuff.state).lower(), "gui")
return self.fittingView.imageList.GetImageIndex("state_%s_small" % State_.getName(stuff.state).lower(),
"gui")
elif isinstance(stuff, Fit):
fitID = self.mainFrame.getActiveFit()
projectionInfo = stuff.getProjectionInfo(fitID)
@@ -78,4 +83,5 @@ class State(ViewColumn):
return generic_active
return generic_inactive
State.register()

View File

@@ -1 +1 @@
__all__ = ["fittingView", "implantEditor"]
__all__ = ["fittingView", "implantEditor"]

View File

@@ -2,7 +2,7 @@ import wx
import gui.globalEvents as GE
import gui.chromeTabs
import gui.mainFrame
import service
class BlankPage(wx.Panel):
def __init__(self, parent):
@@ -23,8 +23,8 @@ class BlankPage(wx.Panel):
def pageChanged(self, event):
if self.parent.IsActive(self):
fitID = None
# sFit = service.Fit.getInstance()
# sFit.switchFit(fitID)
# sFit = Fit.getInstance()
# sFit.switchFit(fitID)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
event.Skip()
event.Skip()

View File

@@ -1,6 +1,6 @@
import wx
from gui.bitmapLoader import BitmapLoader
import service
class BaseValidator(wx.PyValidator):
def __init__(self):
@@ -15,6 +15,7 @@ class BaseValidator(wx.PyValidator):
def TransferFromWindow(self):
return True
class TextEntryValidatedDialog(wx.TextEntryDialog):
def __init__(self, parent, validator=None, *args, **kargs):
wx.TextEntryDialog.__init__(self, parent, *args, **kargs)
@@ -24,7 +25,8 @@ class TextEntryValidatedDialog(wx.TextEntryDialog):
if validator:
self.txtctrl.SetValidator(validator())
class EntityEditor (wx.Panel):
class EntityEditor(wx.Panel):
"""
Entity Editor is a panel that takes some sort of list as a source and populates a drop down with options to add/
rename/clone/delete an entity. Comes with dialogs that take user input. Classes that derive this class must override
@@ -52,7 +54,7 @@ class EntityEditor (wx.Panel):
bitmap = wx.ArtProvider.GetBitmap(art, wx.ART_BUTTON) if name != "rename" else art
btn = wx.BitmapButton(self, wx.ID_ANY, bitmap)
if size is None:
size = btn.GetSize()
size = btn.GetSize()
btn.SetMinSize(size)
btn.SetMaxSize(size)
@@ -135,8 +137,9 @@ class EntityEditor (wx.Panel):
def OnDelete(self, event):
dlg = wx.MessageDialog(self,
"Do you really want to delete the {} {}?".format(self.getActiveEntity().name, self.entityName),
"Confirm Delete", wx.YES | wx.NO | wx.ICON_QUESTION)
"Do you really want to delete the {} {}?".format(self.getActiveEntity().name,
self.entityName),
"Confirm Delete", wx.YES | wx.NO | wx.ICON_QUESTION)
dlg.CenterOnParent()
if dlg.ShowModal() == wx.ID_YES:
@@ -171,4 +174,4 @@ class EntityEditor (wx.Panel):
return False
self.Parent.Show()
return True
return True

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,11 +15,10 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import wx.lib.newevent
import service
import gui.mainFrame
import gui.marketBrowser
import gui.display as d
@@ -33,11 +32,15 @@ import gui.builtinViews.emptyView
from gui.utils.exportHtml import exportHtml
from logging import getLogger, Formatter
from service.fit import Fit
from service.market import Market
import gui.globalEvents as GE
logger = getLogger(__name__)
#Tab spawning handler
# Tab spawning handler
class FitSpawner(gui.multiSwitch.TabSpawner):
def __init__(self, multiSwitch):
self.multiSwitch = multiSwitch
@@ -58,7 +61,7 @@ class FitSpawner(gui.multiSwitch.TabSpawner):
pass
if count < 0:
startup = getattr(event, "startup", False) # see OpenFitsThread in gui.mainFrame
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
openFitInNew = sFit.serviceFittingOptions["openFitInNew"]
mstate = wx.GetMouseState()
@@ -87,22 +90,25 @@ class FitSpawner(gui.multiSwitch.TabSpawner):
self.multiSwitch.AddPage(view)
view.handleDrag(type, fitID)
FitSpawner.register()
#Drag'n'drop handler
class FittingViewDrop(wx.PyDropTarget):
def __init__(self, dropFn):
wx.PyDropTarget.__init__(self)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
if self.GetData():
data = self.dropData.GetText().split(':')
self.dropFn(x, y, data)
return t
# Drag'n'drop handler
class FittingViewDrop(wx.PyDropTarget):
def __init__(self, dropFn):
wx.PyDropTarget.__init__(self)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
if self.GetData():
data = self.dropData.GetText().split(':')
self.dropFn(x, y, data)
return t
class FittingView(d.Display):
DEFAULT_COLS = ["State",
@@ -119,7 +125,7 @@ class FittingView(d.Display):
]
def __init__(self, parent):
d.Display.__init__(self, parent, size = (0,0), style = wx.BORDER_NONE)
d.Display.__init__(self, parent, size=(0, 0), style=wx.BORDER_NONE)
self.Show(False)
self.parent = parent
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
@@ -129,7 +135,7 @@ class FittingView(d.Display):
self.Bind(wx.EVT_LEFT_DCLICK, self.removeItem)
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.startDrag)
if "__WXGTK__" in wx.PlatformInfo:
if "__WXGTK__" in wx.PlatformInfo:
self.Bind(wx.EVT_RIGHT_UP, self.scheduleMenu)
else:
self.Bind(wx.EVT_RIGHT_DOWN, self.scheduleMenu)
@@ -194,7 +200,7 @@ class FittingView(d.Display):
self.addModule(x, y, int(data[1]))
def handleDrag(self, type, fitID):
#Those are drags coming from pyfa sources, NOT builtin wx drags
# Those are drags coming from pyfa sources, NOT builtin wx drags
if type == "fit":
wx.PostEvent(self.mainFrame, gui.shipBrowser.FitSelected(fitID=fitID))
@@ -210,7 +216,7 @@ class FittingView(d.Display):
def pageChanged(self, event):
if self.parent.IsActive(self):
fitID = self.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.switchFit(fitID)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -228,7 +234,7 @@ class FittingView(d.Display):
dropSource = wx.DropSource(self)
dropSource.SetData(data)
res = dropSource.DoDragDrop()
dropSource.DoDragDrop()
def getSelectedMods(self):
sel = []
@@ -239,15 +245,14 @@ class FittingView(d.Display):
return sel
def kbEvent(self,event):
def kbEvent(self, event):
keycode = event.GetKeyCode()
if keycode == wx.WXK_DELETE or keycode == wx.WXK_NUMPAD_DELETE:
row = self.GetFirstSelected()
firstSel = row
while row != -1:
if row not in self.blanks:
self.removeModule(self.mods[row])
self.Select(row,0)
self.Select(row, 0)
row = self.GetNextSelected(row)
event.Skip()
@@ -265,7 +270,7 @@ class FittingView(d.Display):
try:
# Sometimes there is no active page after deletion, hence the try block
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.refreshFit(self.getActiveFit())
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.activeFitID))
except wx._core.PyDeadObjectError:
@@ -285,7 +290,7 @@ class FittingView(d.Display):
fitID = event.fitID
startup = getattr(event, "startup", False)
self.activeFitID = fitID
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
self.updateTab()
if not startup or startup == 2: # see OpenFitsThread in gui.mainFrame
self.Show(fitID is not None)
@@ -296,7 +301,7 @@ class FittingView(d.Display):
event.Skip()
def updateTab(self):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(self.getActiveFit(), basic=True)
bitmap = BitmapLoader.getImage("race_%s_small" % fit.ship.item.race, "gui")
@@ -310,8 +315,8 @@ class FittingView(d.Display):
if self.parent.IsActive(self):
itemID = event.itemID
fitID = self.activeFitID
if fitID != None:
sFit = service.Fit.getInstance()
if fitID is not None:
sFit = Fit.getInstance()
if sFit.isAmmo(itemID):
modules = []
sel = self.GetFirstSelected()
@@ -340,7 +345,7 @@ class FittingView(d.Display):
self.click(event)
def removeModule(self, module):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(self.activeFitID)
populate = sFit.removeModule(self.activeFitID, fit.modules.index(module))
@@ -350,11 +355,10 @@ class FittingView(d.Display):
def addModule(self, x, y, srcIdx):
'''Add a module from the market browser'''
mstate = wx.GetMouseState()
dstRow, _ = self.HitTest((x, y))
if dstRow != -1 and dstRow not in self.blanks:
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
moduleChanged = sFit.changeModule(fitID, self.mods[dstRow].modPosition, srcIdx)
if moduleChanged is None:
@@ -370,15 +374,16 @@ class FittingView(d.Display):
if dstRow != -1 and dstRow not in self.blanks:
module = self.mods[dstRow]
sFit = service.Fit.getInstance()
sFit.moveCargoToModule(self.mainFrame.getActiveFit(), module.modPosition, srcIdx, mstate.CmdDown() and module.isEmpty)
sFit = Fit.getInstance()
sFit.moveCargoToModule(self.mainFrame.getActiveFit(), module.modPosition, srcIdx,
mstate.CmdDown() and module.isEmpty)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
def swapItems(self, x, y, srcIdx):
'''Swap two modules in fitting window'''
mstate = wx.GetMouseState()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(self.activeFitID)
if mstate.CmdDown():
@@ -412,7 +417,7 @@ class FittingView(d.Display):
known to the display, and not the backend, so it's safe.
'''
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(self.activeFitID)
slotOrder = [Slot.SUBSYSTEM, Slot.HIGH, Slot.MED, Slot.LOW, Slot.RIG, Slot.SERVICE]
@@ -425,7 +430,7 @@ class FittingView(d.Display):
# 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
self.blanks = [] # preliminary markers where blanks will be inserted
if sFit.serviceFittingOptions["rackSlots"]:
# flag to know when to add blanks, based on previous slot
@@ -435,12 +440,12 @@ class FittingView(d.Display):
for i, mod in enumerate(self.mods):
if mod.slot != slotDivider:
slotDivider = mod.slot
self.blanks.append((i, slotDivider)) # where and what
self.blanks.append((i, slotDivider)) # where and what
# second loop modifies self.mods, rewrites self.blanks to represent actual index of blanks
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))
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
@@ -484,7 +489,7 @@ class FittingView(d.Display):
if self.activeFitID is None:
return
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
selection = []
sel = self.GetFirstSelected()
contexts = []
@@ -507,22 +512,21 @@ class FittingView(d.Display):
srcContext = "fittingModule"
itemContext = sMkt.getCategoryByItem(mod.item).name
fullContext = (srcContext, itemContext)
if not srcContext in tuple(fCtxt[0] for fCtxt in contexts):
if srcContext not in tuple(fCtxt[0] for fCtxt in contexts):
contexts.append(fullContext)
if mod.charge is not None:
srcContext = "fittingCharge"
itemContext = sMkt.getCategoryByItem(mod.charge).name
fullContext = (srcContext, itemContext)
if not srcContext in tuple(fCtxt[0] for fCtxt in contexts):
if srcContext not in tuple(fCtxt[0] for fCtxt in contexts):
contexts.append(fullContext)
selection.append(mod)
sel = self.GetNextSelected(sel)
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(self.activeFitID)
contexts.append(("fittingShip", "Ship" if not fit.isStructure else "Citadel"))
@@ -545,7 +549,7 @@ class FittingView(d.Display):
sel = []
curr = self.GetFirstSelected()
while curr != -1 and row not in self.blanks :
while curr != -1 and row not in self.blanks:
sel.append(curr)
curr = self.GetNextSelected(curr)
@@ -554,7 +558,7 @@ class FittingView(d.Display):
else:
mods = self.getSelectedMods()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
ctrl = wx.GetMouseState().CmdDown() or wx.GetMouseState().MiddleDown()
click = "ctrl" if ctrl is True else "right" if event.GetButton() == 3 else "left"
@@ -588,7 +592,7 @@ class FittingView(d.Display):
self.Freeze()
d.Display.refresh(self, stuff)
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(self.activeFitID)
slotMap = {}
@@ -626,7 +630,7 @@ class FittingView(d.Display):
try:
self.MakeSnapshot()
except:
pass
pass
def OnShow(self, event):
if event.GetShow():
@@ -639,22 +643,22 @@ class FittingView(d.Display):
def Snapshot(self):
return self.FVsnapshot
def MakeSnapshot(self, maxColumns = 1337):
def MakeSnapshot(self, maxColumns=1337):
if self.FVsnapshot:
del self.FVsnapshot
tbmp = wx.EmptyBitmap(16,16)
tbmp = wx.EmptyBitmap(16, 16)
tdc = wx.MemoryDC()
tdc.SelectObject(tbmp)
font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
tdc.SetFont(font)
columnsWidths = []
for i in xrange(len(self.DEFAULT_COLS)):
for i in range(len(self.DEFAULT_COLS)):
columnsWidths.append(0)
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
try:
fit = sFit.getFit(self.activeFitID)
except:
@@ -675,25 +679,25 @@ class FittingView(d.Display):
maxWidth = 0
maxRowHeight = isize
rows = 0
for id,st in enumerate(self.mods):
for st in self.mods:
for i, col in enumerate(self.activeColumns):
if i>maxColumns:
if i > maxColumns:
break
name = col.getText(st)
if not isinstance(name, basestring):
name = ""
nx,ny = tdc.GetTextExtent(name)
nx, ny = tdc.GetTextExtent(name)
imgId = col.getImageId(st)
cw = 0
if imgId != -1:
cw += isize + padding
if name != "":
cw += nx + 4*padding
cw += nx + 4 * padding
if imgId == -1 and name == "":
cw += isize +padding
cw += isize + padding
maxRowHeight = max(ny, maxRowHeight)
columnsWidths[i] = max(columnsWidths[i], cw)
@@ -702,7 +706,7 @@ class FittingView(d.Display):
render = wx.RendererNative.Get()
#Fix column widths (use biggest between header or items)
# Fix column widths (use biggest between header or items)
for i, col in enumerate(self.activeColumns):
if i > maxColumns:
@@ -720,26 +724,23 @@ class FittingView(d.Display):
opts.m_labelText = name
if imgId != -1:
opts.m_labelBitmap = wx.EmptyBitmap(isize,isize)
opts.m_labelBitmap = wx.EmptyBitmap(isize, isize)
width = render.DrawHeaderButton(self, tdc, (0, 0, 16, 16),
sortArrow = wx.HDR_SORT_ICON_NONE, params = opts)
width = render.DrawHeaderButton(self, tdc, (0, 0, 16, 16), sortArrow=wx.HDR_SORT_ICON_NONE, params=opts)
columnsWidths[i] = max(columnsWidths[i], width)
tdc.SelectObject(wx.NullBitmap)
maxWidth = padding * 2
for i in xrange(len(self.DEFAULT_COLS)):
for i in range(len(self.DEFAULT_COLS)):
if i > maxColumns:
break
maxWidth += columnsWidths[i]
mdc = wx.MemoryDC()
mbmp = wx.EmptyBitmap(maxWidth, (maxRowHeight) * rows + padding*4 + headerSize)
mbmp = wx.EmptyBitmap(maxWidth, (maxRowHeight) * rows + padding * 4 + headerSize)
mdc.SelectObject(mbmp)
@@ -769,8 +770,8 @@ class FittingView(d.Display):
bmp = col.bitmap
opts.m_labelBitmap = bmp
width = render.DrawHeaderButton (self, mdc, (cx, padding, columnsWidths[i], headerSize), wx.CONTROL_CURRENT,
sortArrow = wx.HDR_SORT_ICON_NONE, params = opts)
width = render.DrawHeaderButton(self, mdc, (cx, padding, columnsWidths[i], headerSize), wx.CONTROL_CURRENT,
sortArrow=wx.HDR_SORT_ICON_NONE, params=opts)
cx += columnsWidths[i]
@@ -780,15 +781,15 @@ class FittingView(d.Display):
mdc.SetPen(pen)
mdc.SetBrush(brush)
cy = padding*2 + headerSize
for id,st in enumerate(self.mods):
cy = padding * 2 + headerSize
for st in self.mods:
cx = padding
if slotMap[st.slot]:
mdc.DrawRectangle(cx,cy,maxWidth - cx,maxRowHeight)
mdc.DrawRectangle(cx, cy, maxWidth - cx, maxRowHeight)
for i, col in enumerate(self.activeColumns):
if i>maxColumns:
if i > maxColumns:
break
name = col.getText(st)
@@ -799,14 +800,14 @@ class FittingView(d.Display):
tcx = cx
if imgId != -1:
self.imageList.Draw(imgId,mdc,cx,cy,wx.IMAGELIST_DRAW_TRANSPARENT,False)
self.imageList.Draw(imgId, mdc, cx, cy, wx.IMAGELIST_DRAW_TRANSPARENT, False)
tcx += isize + padding
if name != "":
nx,ny = mdc.GetTextExtent(name)
nx, ny = mdc.GetTextExtent(name)
rect = wx.Rect()
rect.top = cy
rect.left = cx + 2*padding
rect.left = cx + 2 * padding
rect.width = nx
rect.height = maxRowHeight + padding
mdc.DrawLabel(name, rect, wx.ALIGN_CENTER_VERTICAL)
@@ -818,4 +819,4 @@ class FittingView(d.Display):
mdc.SelectObject(wx.NullBitmap)
self.FVsnapshot = mbmp
self.FVsnapshot = mbmp

View File

@@ -1,12 +1,14 @@
import wx
import service
import gui.display as d
from gui.bitmapLoader import BitmapLoader
import gui.PFSearchBox as SBox
from gui.marketBrowser import SearchBox
from wx.lib.buttons import GenBitmapButton
class BaseImplantEditorView (wx.Panel):
from service.market import Market
import gui.display as d
import gui.PFSearchBox as SBox
from gui.bitmapLoader import BitmapLoader
from gui.marketBrowser import SearchBox
class BaseImplantEditorView(wx.Panel):
def addMarketViewImage(self, iconFile):
if iconFile is None:
return -1
@@ -17,7 +19,8 @@ class BaseImplantEditorView (wx.Panel):
return self.availableImplantsImageList.Add(bitmap)
def __init__(self, parent):
wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TAB_TRAVERSAL)
wx.Panel.__init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize,
style=wx.TAB_TRAVERSAL)
self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
pmainSizer = wx.BoxSizer(wx.HORIZONTAL)
@@ -46,32 +49,32 @@ class BaseImplantEditorView (wx.Panel):
availableSizer.Add(self.availableImplantsTree, 1, wx.EXPAND)
pmainSizer.Add(availableSizer, 1, wx.ALL | wx.EXPAND, 5)
buttonSizer = wx.BoxSizer(wx.VERTICAL)
buttonSizer.AddSpacer(( 0, 0), 1)
buttonSizer.AddSpacer((0, 0), 1)
self.btnAdd = GenBitmapButton(self, wx.ID_ADD, BitmapLoader.getBitmap("fit_add_small", "gui"), style = wx.BORDER_NONE)
self.btnAdd = GenBitmapButton(self, wx.ID_ADD, BitmapLoader.getBitmap("fit_add_small", "gui"),
style=wx.BORDER_NONE)
buttonSizer.Add(self.btnAdd, 0)
self.btnRemove = GenBitmapButton(self, wx.ID_REMOVE, BitmapLoader.getBitmap("fit_delete_small", "gui"), style = wx.BORDER_NONE)
self.btnRemove = GenBitmapButton(self, wx.ID_REMOVE, BitmapLoader.getBitmap("fit_delete_small", "gui"),
style=wx.BORDER_NONE)
buttonSizer.Add(self.btnRemove, 0)
buttonSizer.AddSpacer(( 0, 0), 1)
buttonSizer.AddSpacer((0, 0), 1)
pmainSizer.Add(buttonSizer, 0, wx.EXPAND, 0)
characterImplantSizer = wx.BoxSizer(wx.VERTICAL)
self.pluggedImplantsTree = AvailableImplantsView(self)
characterImplantSizer.Add(self.pluggedImplantsTree, 1, wx.ALL|wx.EXPAND, 5)
characterImplantSizer.Add(self.pluggedImplantsTree, 1, wx.ALL | wx.EXPAND, 5)
pmainSizer.Add(characterImplantSizer, 1, wx.EXPAND, 5)
self.SetSizer(pmainSizer)
# Populate the market tree
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
for mktGrp in sMkt.getImplantTree():
iconId = self.addMarketViewImage(sMkt.getIconByMarketGroup(mktGrp))
childId = self.availableImplantsTree.AppendItem(root, mktGrp.name, iconId, data=wx.TreeItemData(mktGrp.ID))
@@ -80,13 +83,13 @@ class BaseImplantEditorView (wx.Panel):
self.availableImplantsTree.SortChildren(self.availableRoot)
#Bind the event to replace dummies by real data
# Bind the event to replace dummies by real data
self.availableImplantsTree.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.expandLookup)
self.availableImplantsTree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.itemSelected)
self.itemView.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.itemSelected)
#Bind add & remove buttons
# Bind add & remove buttons
self.btnAdd.Bind(wx.EVT_BUTTON, self.itemSelected)
self.btnRemove.Bind(wx.EVT_BUTTON, self.removeItem)
@@ -126,7 +129,7 @@ class BaseImplantEditorView (wx.Panel):
def expandLookup(self, event):
tree = self.availableImplantsTree
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
parent = event.Item
child, _ = tree.GetFirstChild(parent)
text = tree.GetItemText(child)
@@ -136,7 +139,7 @@ class BaseImplantEditorView (wx.Panel):
# if the dummy item is a market group, replace with actual market groups
if text == "dummy":
#Add 'real stoof!' instead
# Add 'real stoof!' instead
currentMktGrp = sMkt.getMarketGroup(tree.GetPyData(parent), eager="children")
for childMktGrp in sMkt.getMarketGroupChildren(currentMktGrp):
iconId = self.addMarketViewImage(sMkt.getIconByMarketGroup(childMktGrp))
@@ -194,6 +197,7 @@ class BaseImplantEditorView (wx.Panel):
self.removeImplantFromContext(self.implants[pos])
self.update()
class AvailableImplantsView(d.Display):
DEFAULT_COLS = ["attr:implantness",
"Base Icon",
@@ -203,6 +207,7 @@ class AvailableImplantsView(d.Display):
d.Display.__init__(self, parent, style=wx.LC_SINGLE_SEL)
self.Bind(wx.EVT_LEFT_DCLICK, parent.removeItem)
class ItemView(d.Display):
DEFAULT_COLS = ["Base Icon",
"Base Name",
@@ -235,7 +240,7 @@ class ItemView(d.Display):
self.update(self.items)
def scheduleSearch(self, event=None):
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
search = self.searchBox.GetLineText(0)
# Make sure we do not count wildcard as search symbol
@@ -255,4 +260,4 @@ class ItemView(d.Display):
self.items = sorted(list(items), key=lambda i: i.name)
self.update(self.items)
self.update(self.items)

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,21 +15,23 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from gui.bitmapLoader import BitmapLoader
class CachingImageList(wx.ImageList):
def __init__(self, width, height):
wx.ImageList.__init__(self, width, height)
self.map = {}
def GetImageIndex(self, *loaderArgs):
id = self.map.get(loaderArgs)
if id is None:
id_ = self.map.get(loaderArgs)
if id_ is None:
bitmap = BitmapLoader.getBitmap(*loaderArgs)
if bitmap is None:
return -1
id = self.map[loaderArgs] = wx.ImageList.Add(self,bitmap)
return id
id_ = self.map[loaderArgs] = wx.ImageList.Add(self, bitmap)
return id_

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,31 +15,33 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import service
import gui.display as d
import gui.marketBrowser as mb
from gui.builtinViewColumns.state import State
from gui.contextMenu import ContextMenu
import globalEvents as GE
from service.fit import Fit
from service.market import Market
class CargoViewDrop(wx.PyDropTarget):
def __init__(self, dropFn):
wx.PyDropTarget.__init__(self)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.SetDataObject(self.dropData)
def __init__(self, dropFn):
wx.PyDropTarget.__init__(self)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
if self.GetData():
data = self.dropData.GetText().split(':')
self.dropFn(x, y, data)
return t
def OnData(self, x, y, t):
if self.GetData():
data = self.dropData.GetText().split(':')
self.dropFn(x, y, data)
return t
# @todo: Was copied form another class and modified. Look through entire file, refine
# @todo: Was copied form another class and modified. Look through entire file, refine
class CargoView(d.Display):
DEFAULT_COLS = ["Base Icon",
"Base Name",
@@ -58,7 +60,7 @@ class CargoView(d.Display):
self.SetDropTarget(CargoViewDrop(self.handleListDrag))
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.startDrag)
if "__WXGTK__" in wx.PlatformInfo:
if "__WXGTK__" in wx.PlatformInfo:
self.Bind(wx.EVT_RIGHT_UP, self.scheduleMenu)
else:
self.Bind(wx.EVT_RIGHT_DOWN, self.scheduleMenu)
@@ -75,7 +77,7 @@ class CargoView(d.Display):
if data[0] == "fitting":
self.swapModule(x, y, int(data[1]))
elif data[0] == "market":
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.addCargo(self.mainFrame.getActiveFit(), int(data[1]), 1)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
@@ -84,17 +86,17 @@ class CargoView(d.Display):
if row != -1:
data = wx.PyTextDataObject()
data.SetText("cargo:"+str(row))
data.SetText("cargo:" + str(row))
dropSource = wx.DropSource(self)
dropSource.SetData(data)
res = dropSource.DoDragDrop()
dropSource.DoDragDrop()
def kbEvent(self,event):
def kbEvent(self, event):
keycode = event.GetKeyCode()
if keycode == wx.WXK_DELETE or keycode == wx.WXK_NUMPAD_DELETE:
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
row = self.GetFirstSelected()
if row != -1:
sFit.removeCargo(fitID, self.GetItemData(row))
@@ -103,7 +105,7 @@ class CargoView(d.Display):
def swapModule(self, x, y, modIdx):
'''Swap a module from fitting window with cargo'''
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(self.mainFrame.getActiveFit())
dstRow, _ = self.HitTest((x, y))
mstate = wx.GetMouseState()
@@ -111,26 +113,26 @@ class CargoView(d.Display):
# Gather module information to get position
module = fit.modules[modIdx]
if dstRow != -1: # we're swapping with cargo
if mstate.CmdDown(): # if copying, append to cargo
if dstRow != -1: # we're swapping with cargo
if mstate.CmdDown(): # if copying, append to cargo
sFit.addCargo(self.mainFrame.getActiveFit(), module.item.ID)
else: # else, move / swap
else: # else, move / swap
sFit.moveCargoToModule(self.mainFrame.getActiveFit(), module.position, dstRow)
else: # dragging to blank spot, append
else: # dragging to blank spot, append
sFit.addCargo(self.mainFrame.getActiveFit(), module.item.ID)
if not mstate.CmdDown(): # if not copying, remove module
sFit.removeModule(self.mainFrame.getActiveFit(), module.position)
if not mstate.CmdDown(): # if not copying, remove module
sFit.removeModule(self.mainFrame.getActiveFit(), module.position)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
def fitChanged(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(event.fitID)
self.Parent.Parent.DisablePage(self, not fit or fit.isStructure)
#Clear list and get out if current fitId is None
# Clear list and get out if current fitId is None
if event.fitID is None and self.lastFitId is not None:
self.DeleteAllItems()
self.lastFitId = None
@@ -139,7 +141,8 @@ class CargoView(d.Display):
self.original = fit.cargo if fit is not None else None
self.cargo = stuff = fit.cargo if fit is not None else None
if stuff is not None: stuff.sort(key=lambda cargo: cargo.itemID)
if stuff is not None:
stuff.sort(key=lambda cargo: cargo.itemID)
if event.fitID != self.lastFitId:
self.lastFitId = event.fitID
@@ -161,7 +164,7 @@ class CargoView(d.Display):
col = self.getColumn(event.Position)
if col != self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
cargo = self.cargo[self.GetItemData(row)]
sFit.removeCargo(fitID, self.original.index(cargo))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -174,11 +177,11 @@ class CargoView(d.Display):
def spawnMenu(self):
sel = self.GetFirstSelected()
if sel != -1:
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(self.mainFrame.getActiveFit())
cargo = fit.cargo[sel]
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
sourceContext = "cargoItem"
itemContext = sMkt.getCategoryByItem(cargo.item).name

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,18 +15,21 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import wx.lib.newevent
import wx.gizmos
from gui.bitmapLoader import BitmapLoader
import service
from gui.contextMenu import ContextMenu
import gui.globalEvents as GE
from gui.builtinViews.implantEditor import BaseImplantEditorView
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator
from service.fit import Fit
from service.character import Character
from service.network import AuthenticationError, TimeoutError
from service.market import Market
class CharacterTextValidor(BaseValidator):
@@ -60,7 +63,7 @@ class CharacterEntityEditor(EntityEditor):
self.SetEditorValidator(CharacterTextValidor)
def getEntitiesFromContext(self):
sChar = service.Character.getInstance()
sChar = Character.getInstance()
charList = sorted(sChar.getCharacterList(), key=lambda c: c.name)
# Do some processing to ensure that we have All 0 and All 5 at the top
@@ -76,35 +79,35 @@ class CharacterEntityEditor(EntityEditor):
return charList
def DoNew(self, name):
sChar = service.Character.getInstance()
sChar = Character.getInstance()
return sChar.new(name)
def DoRename(self, entity, name):
sChar = service.Character.getInstance()
sChar = Character.getInstance()
sChar.rename(entity, name)
def DoCopy(self, entity, name):
sChar = service.Character.getInstance()
sChar = Character.getInstance()
copy = sChar.copy(entity)
sChar.rename(copy, name)
return copy
def DoDelete(self, entity):
sChar = service.Character.getInstance()
sChar = Character.getInstance()
sChar.delete(entity)
class CharacterEditor(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__ (self, parent, id=wx.ID_ANY, title=u"pyfa: Character Editor", pos=wx.DefaultPosition,
size=wx.Size(640, 600), style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER)
wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=u"pyfa: Character Editor", pos=wx.DefaultPosition,
size=wx.Size(640, 600), style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER)
i = wx.IconFromBitmap(BitmapLoader.getBitmap("character_small", "gui"))
self.SetIcon(i)
self.mainFrame = parent
#self.disableWin = wx.WindowDisabler(self)
sFit = service.Fit.getInstance()
# self.disableWin = wx.WindowDisabler(self)
sFit = Fit.getInstance()
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))
@@ -176,12 +179,12 @@ class CharacterEditor(wx.Frame):
event.Skip()
def editingFinished(self, event):
#del self.disableWin
# del self.disableWin
wx.PostEvent(self.mainFrame, GE.CharListUpdated())
self.Destroy()
def saveChar(self, event):
sChr = service.Character.getInstance()
sChr = Character.getInstance()
char = self.entityEditor.getActiveEntity()
sChr.saveCharacter(char.ID)
wx.PostEvent(self, GE.CharListUpdated())
@@ -192,13 +195,13 @@ class CharacterEditor(wx.Frame):
dlg.ShowModal()
def revertChar(self, event):
sChr = service.Character.getInstance()
sChr = Character.getInstance()
char = self.entityEditor.getActiveEntity()
sChr.revertCharacter(char.ID)
wx.PostEvent(self, GE.CharListUpdated())
def closeEvent(self, event):
#del self.disableWin
# del self.disableWin
wx.PostEvent(self.mainFrame, GE.CharListUpdated())
self.Destroy()
@@ -223,7 +226,7 @@ class CharacterEditor(wx.Frame):
event.Skip()
def Destroy(self):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
if fitID is not None:
sFit.clearFit(fitID)
@@ -231,18 +234,20 @@ class CharacterEditor(wx.Frame):
wx.Frame.Destroy(self)
class SkillTreeView (wx.Panel):
class SkillTreeView(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TAB_TRAVERSAL)
wx.Panel.__init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize,
style=wx.TAB_TRAVERSAL)
self.charEditor = self.Parent.Parent # first parent is Notebook, second is Character Editor
self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
pmainSizer = wx.BoxSizer(wx.VERTICAL)
tree = self.skillTreeListCtrl = wx.gizmos.TreeListCtrl(self, wx.ID_ANY, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT)
tree = self.skillTreeListCtrl = wx.gizmos.TreeListCtrl(self, wx.ID_ANY,
style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT)
pmainSizer.Add(tree, 1, wx.EXPAND | wx.ALL, 5)
self.imageList = wx.ImageList(16, 16)
tree.SetImageList(self.imageList)
self.skillBookImageId = self.imageList.Add(BitmapLoader.getBitmap("skill_small", "gui"))
@@ -286,7 +291,6 @@ class SkillTreeView (wx.Panel):
self.revertID = wx.NewId()
self.levelChangeMenu.Append(self.revertID, "Revert")
self.saveID = wx.NewId()
self.levelChangeMenu.Append(self.saveID, "Save")
@@ -296,7 +300,7 @@ class SkillTreeView (wx.Panel):
self.Layout()
def populateSkillTree(self, event=None):
sChar = service.Character.getInstance()
sChar = Character.getInstance()
char = self.charEditor.entityEditor.getActiveEntity()
dirtyGroups = set([skill.item.group.ID for skill in char.dirtySkills])
@@ -325,8 +329,8 @@ class SkillTreeView (wx.Panel):
if tree.GetItemText(child) == "dummy":
tree.Delete(child)
#Get the real intrestin' stuff
sChar = service.Character.getInstance()
# Get the real intrestin' stuff
sChar = Character.getInstance()
char = self.charEditor.entityEditor.getActiveEntity()
for id, name in sChar.getSkills(tree.GetPyData(root)):
iconId = self.skillBookImageId
@@ -348,7 +352,7 @@ class SkillTreeView (wx.Panel):
return
char = self.charEditor.entityEditor.getActiveEntity()
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
if char.name not in ("All 0", "All 5"):
self.levelChangeMenu.selection = sMkt.getItem(self.skillTreeListCtrl.GetPyData(item))
self.PopupMenu(self.levelChangeMenu)
@@ -359,7 +363,7 @@ class SkillTreeView (wx.Panel):
def changeLevel(self, event):
level = self.levelIds.get(event.Id)
sChar = service.Character.getInstance()
sChar = Character.getInstance()
char = self.charEditor.entityEditor.getActiveEntity()
selection = self.skillTreeListCtrl.GetSelection()
skillID = self.skillTreeListCtrl.GetPyData(selection)
@@ -388,7 +392,7 @@ class SkillTreeView (wx.Panel):
class ImplantEditorView(BaseImplantEditorView):
def __init__(self, parent):
BaseImplantEditorView.__init__ (self, parent)
BaseImplantEditorView.__init__(self, parent)
self.determineEnabled()
@@ -405,19 +409,19 @@ class ImplantEditorView(BaseImplantEditorView):
self.determineEnabled()
def getImplantsFromContext(self):
sChar = service.Character.getInstance()
sChar = Character.getInstance()
char = self.Parent.Parent.entityEditor.getActiveEntity()
return sChar.getImplants(char.ID)
def addImplantToContext(self, item):
sChar = service.Character.getInstance()
sChar = Character.getInstance()
char = self.Parent.Parent.entityEditor.getActiveEntity()
sChar.addImplant(char.ID, item.ID)
def removeImplantFromContext(self, implant):
sChar = service.Character.getInstance()
sChar = Character.getInstance()
char = self.Parent.Parent.entityEditor.getActiveEntity()
sChar.removeImplant(char.ID, implant)
@@ -442,9 +446,10 @@ class ImplantEditorView(BaseImplantEditorView):
self.Enable()
class APIView (wx.Panel):
class APIView(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(500, 300), style=wx.TAB_TRAVERSAL)
wx.Panel.__init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(500, 300),
style=wx.TAB_TRAVERSAL)
self.charEditor = self.Parent.Parent # first parent is Notebook, second is Character Editor
self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
@@ -453,17 +458,17 @@ class APIView (wx.Panel):
pmainSizer = wx.BoxSizer(wx.VERTICAL)
hintSizer = wx.BoxSizer( wx.HORIZONTAL )
hintSizer = wx.BoxSizer(wx.HORIZONTAL)
hintSizer.AddStretchSpacer()
self.stDisabledTip = wx.StaticText( self, wx.ID_ANY, u"You cannot add API Details for All 0 and All 5 characters.\n"
u"Please select another character or make a new one.", style=wx.ALIGN_CENTER )
self.stDisabledTip.Wrap( -1 )
hintSizer.Add( self.stDisabledTip, 0, wx.TOP | wx.BOTTOM, 10 )
self.stDisabledTip = wx.StaticText(self, wx.ID_ANY,
u"You cannot add API Details for All 0 and All 5 characters.\n"
u"Please select another character or make a new one.", style=wx.ALIGN_CENTER)
self.stDisabledTip.Wrap(-1)
hintSizer.Add(self.stDisabledTip, 0, wx.TOP | wx.BOTTOM, 10)
self.stDisabledTip.Hide()
hintSizer.AddStretchSpacer()
pmainSizer.Add(hintSizer, 0, wx.EXPAND, 5)
fgSizerInput = wx.FlexGridSizer(3, 2, 0, 0)
fgSizerInput.AddGrowableCol(1)
fgSizerInput.SetFlexibleDirection(wx.BOTH)
@@ -495,39 +500,44 @@ class APIView (wx.Panel):
pmainSizer.Add(fgSizerInput, 0, wx.EXPAND, 5)
btnSizer = wx.BoxSizer( wx.HORIZONTAL )
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
btnSizer.AddStretchSpacer()
self.btnFetchCharList = wx.Button(self, wx.ID_ANY, u"Get Characters")
btnSizer.Add(self.btnFetchCharList, 0, wx.ALL, 2)
self.btnFetchCharList.Bind(wx.EVT_BUTTON, self.fetchCharList)
self.btnFetchSkills = wx.Button(self, wx.ID_ANY, u"Fetch Skills")
btnSizer.Add(self.btnFetchSkills, 0, wx.ALL, 2)
self.btnFetchSkills = wx.Button(self, wx.ID_ANY, u"Fetch Skills")
btnSizer.Add(self.btnFetchSkills, 0, wx.ALL, 2)
self.btnFetchSkills.Bind(wx.EVT_BUTTON, self.fetchSkills)
self.btnFetchSkills.Enable(False)
btnSizer.AddStretchSpacer()
pmainSizer.Add(btnSizer, 0, wx.EXPAND, 5)
self.stStatus = wx.StaticText(self, wx.ID_ANY, wx.EmptyString)
self.stStatus = wx.StaticText(self, wx.ID_ANY, wx.EmptyString)
pmainSizer.Add(self.stStatus, 0, wx.ALL, 5)
pmainSizer.AddStretchSpacer()
self.stAPITip = wx.StaticText( self, wx.ID_ANY, u"You can create a pre-defined key here (only CharacterSheet is required):", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stAPITip.Wrap( -1 )
self.stAPITip = wx.StaticText(self, wx.ID_ANY,
u"You can create a pre-defined key here (only CharacterSheet is required):",
wx.DefaultPosition, wx.DefaultSize, 0)
self.stAPITip.Wrap(-1)
pmainSizer.Add( self.stAPITip, 0, wx.ALL, 2 )
pmainSizer.Add(self.stAPITip, 0, wx.ALL, 2)
self.hlEveAPI = wx.HyperlinkCtrl( self, wx.ID_ANY, self.apiUrlCreatePredefined, self.apiUrlCreatePredefined, wx.DefaultPosition, wx.DefaultSize, wx.HL_DEFAULT_STYLE )
pmainSizer.Add( self.hlEveAPI, 0, wx.ALL, 2 )
self.hlEveAPI = wx.HyperlinkCtrl(self, wx.ID_ANY, self.apiUrlCreatePredefined, self.apiUrlCreatePredefined,
wx.DefaultPosition, wx.DefaultSize, wx.HL_DEFAULT_STYLE)
pmainSizer.Add(self.hlEveAPI, 0, wx.ALL, 2)
self.stAPITip2 = wx.StaticText( self, wx.ID_ANY, u"Or, you can choose an existing key from:", wx.DefaultPosition, wx.DefaultSize, 0 )
self.stAPITip2.Wrap( -1 )
pmainSizer.Add( self.stAPITip2, 0, wx.ALL, 2 )
self.stAPITip2 = wx.StaticText(self, wx.ID_ANY, u"Or, you can choose an existing key from:", wx.DefaultPosition,
wx.DefaultSize, 0)
self.stAPITip2.Wrap(-1)
pmainSizer.Add(self.stAPITip2, 0, wx.ALL, 2)
self.hlEveAPI2 = wx.HyperlinkCtrl( self, wx.ID_ANY, self.apiUrlKeyList, self.apiUrlKeyList, wx.DefaultPosition, wx.DefaultSize, wx.HL_DEFAULT_STYLE )
pmainSizer.Add( self.hlEveAPI2, 0, wx.ALL, 2 )
self.hlEveAPI2 = wx.HyperlinkCtrl(self, wx.ID_ANY, self.apiUrlKeyList, self.apiUrlKeyList, wx.DefaultPosition,
wx.DefaultSize, wx.HL_DEFAULT_STYLE)
pmainSizer.Add(self.hlEveAPI2, 0, wx.ALL, 2)
self.charEditor.entityEditor.Bind(wx.EVT_CHOICE, self.charChanged)
@@ -536,7 +546,7 @@ class APIView (wx.Panel):
self.charChanged(None)
def charChanged(self, event):
sChar = service.Character.getInstance()
sChar = Character.getInstance()
activeChar = self.charEditor.entityEditor.getActiveEntity()
ID, key, char, chars = sChar.getApiDetails(activeChar.ID)
@@ -547,7 +557,7 @@ class APIView (wx.Panel):
if chars:
for charName in chars:
i = self.charChoice.Append(charName)
self.charChoice.Append(charName)
self.charChoice.SetStringSelection(char)
self.charChoice.Enable(True)
self.btnFetchSkills.Enable(True)
@@ -575,20 +585,20 @@ class APIView (wx.Panel):
self.stStatus.SetLabel("Invalid keyID or vCode!")
return
sChar = service.Character.getInstance()
sChar = Character.getInstance()
try:
activeChar = self.charEditor.entityEditor.getActiveEntity()
list = sChar.apiCharList(activeChar.ID, self.inputID.GetLineText(0), self.inputKey.GetLineText(0))
except service.network.AuthenticationError, e:
except AuthenticationError, e:
self.stStatus.SetLabel("Authentication failure. Please check keyID and vCode combination.")
except service.network.TimeoutError, e:
except TimeoutError, e:
self.stStatus.SetLabel("Request timed out. Please check network connectivity and/or proxy settings.")
except Exception, e:
self.stStatus.SetLabel("Error:\n%s"%e.message)
self.stStatus.SetLabel("Error:\n%s" % e.message)
else:
self.charChoice.Clear()
for charName in list:
i = self.charChoice.Append(charName)
self.charChoice.Append(charName)
self.btnFetchSkills.Enable(True)
self.charChoice.Enable(True)
@@ -601,20 +611,20 @@ class APIView (wx.Panel):
charName = self.charChoice.GetString(self.charChoice.GetSelection())
if charName:
try:
sChar = service.Character.getInstance()
sChar = Character.getInstance()
activeChar = self.charEditor.entityEditor.getActiveEntity()
sChar.apiFetch(activeChar.ID, charName)
self.stStatus.SetLabel("Successfully fetched %s\'s skills from EVE API." % charName)
except Exception, e:
self.stStatus.SetLabel("Unable to retrieve %s\'s skills. Error message:\n%s" % (charName, e))
class SaveCharacterAs(wx.Dialog):
class SaveCharacterAs(wx.Dialog):
def __init__(self, parent, charID):
wx.Dialog.__init__(self, parent, title="Save Character As...", size=wx.Size(300, 60))
self.charID = charID
self.parent = parent
sChar = service.Character.getInstance()
sChar = Character.getInstance()
name = sChar.getCharName(charID)
bSizer1 = wx.BoxSizer(wx.HORIZONTAL)
@@ -631,10 +641,9 @@ class SaveCharacterAs(wx.Dialog):
self.button.Bind(wx.EVT_BUTTON, self.change)
def change(self, event):
sChar = service.Character.getInstance()
sChar = Character.getInstance()
sChar.saveCharacterAs(self.charID, self.input.GetLineText(0))
wx.PostEvent(self.parent, GE.CharListUpdated())
event.Skip()
self.Close()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,13 +15,15 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import service
from gui.bitmapLoader import BitmapLoader
import gui.globalEvents as GE
import gui.mainFrame
from service.character import Character
from service.fit import Fit
class CharacterSelection(wx.Panel):
def __init__(self, parent):
@@ -42,9 +44,9 @@ class CharacterSelection(wx.Panel):
self.refreshCharacterList()
self.cleanSkills = BitmapLoader.getBitmap("skill_big", "gui")
self.redSkills = BitmapLoader.getBitmap("skillRed_big", "gui")
self.redSkills = BitmapLoader.getBitmap("skillRed_big", "gui")
self.greenSkills = BitmapLoader.getBitmap("skillGreen_big", "gui")
self.refresh = BitmapLoader.getBitmap("refresh", "gui")
self.refresh = BitmapLoader.getBitmap("refresh", "gui")
self.btnRefresh = wx.BitmapButton(self, wx.ID_ANY, self.refresh)
size = self.btnRefresh.GetSize()
@@ -66,7 +68,7 @@ class CharacterSelection(wx.Panel):
self.mainFrame.Bind(GE.CHAR_LIST_UPDATED, self.refreshCharacterList)
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
self.SetMinSize(wx.Size(25,-1))
self.SetMinSize(wx.Size(25, -1))
self.charChoice.Enable(False)
@@ -76,7 +78,7 @@ class CharacterSelection(wx.Panel):
def refreshCharacterList(self, event=None):
choice = self.charChoice
sChar = service.Character.getInstance()
sChar = Character.getInstance()
activeChar = self.getActiveCharacter()
choice.Clear()
@@ -94,7 +96,7 @@ class CharacterSelection(wx.Panel):
charID = sChar.all5ID()
self.selectChar(charID)
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.changeChar(fitID, charID)
choice.Append(u"\u2015 Open Character Editor \u2015", -1)
@@ -104,7 +106,7 @@ class CharacterSelection(wx.Panel):
event.Skip()
def refreshApi(self, event):
sChar = service.Character.getInstance()
sChar = Character.getInstance()
ID, key, charName, chars = sChar.getApiDetails(self.getActiveCharacter())
if charName:
try:
@@ -117,7 +119,7 @@ class CharacterSelection(wx.Panel):
def charChanged(self, event):
fitID = self.mainFrame.getActiveFit()
charID = self.getActiveCharacter()
sChar = service.Character.getInstance()
sChar = Character.getInstance()
if charID == -1:
# revert to previous character
@@ -129,7 +131,7 @@ class CharacterSelection(wx.Panel):
else:
self.btnRefresh.Enable(False)
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.changeChar(fitID, charID)
self.charCache = self.charChoice.GetCurrentSelection()
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -137,18 +139,18 @@ class CharacterSelection(wx.Panel):
def selectChar(self, charID):
choice = self.charChoice
numItems = len(choice.GetItems())
for i in xrange(numItems):
id = choice.GetClientData(i)
if id == charID:
for i in range(numItems):
id_ = choice.GetClientData(i)
if id_ == charID:
choice.SetSelection(i)
return True
return False
def fitChanged(self, event):
self.charChoice.Enable(event.fitID != None)
self.charChoice.Enable(event.fitID is not None)
choice = self.charChoice
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
currCharID = choice.GetClientData(choice.GetCurrentSelection())
fit = sFit.getFit(event.fitID)
newCharID = fit.character.ID if fit is not None else None
@@ -156,38 +158,37 @@ class CharacterSelection(wx.Panel):
self.skillReqsStaticBitmap.SetBitmap(self.cleanSkills)
self.skillReqsStaticBitmap.SetToolTipString("No active fit")
else:
sCharacter = service.Character.getInstance()
sCharacter = Character.getInstance()
reqs = sCharacter.checkRequirements(fit)
sCharacter.skillReqsDict = {'charname':fit.character.name, 'skills':[]}
sCharacter.skillReqsDict = {'charname': fit.character.name, 'skills': []}
if len(reqs) == 0:
tip = "All skill prerequisites have been met"
self.skillReqsStaticBitmap.SetBitmap(self.greenSkills)
else:
tip = "Skills required:\n"
tip = "Skills required:\n"
condensed = sFit.serviceFittingOptions["compactSkills"]
if condensed:
dict = self._buildSkillsTooltipCondensed(reqs, skillsMap = {})
for key in sorted(dict):
tip += "%s: %d\n" % (key, dict[key])
dict_ = self._buildSkillsTooltipCondensed(reqs, skillsMap={})
for key in sorted(dict_):
tip += "%s: %d\n" % (key, dict_[key])
else:
tip += self._buildSkillsTooltip(reqs)
self.skillReqsStaticBitmap.SetBitmap(self.redSkills)
self.skillReqsStaticBitmap.SetToolTipString(tip.strip())
if newCharID == None:
sChar = service.Character.getInstance()
if newCharID is None:
sChar = Character.getInstance()
self.selectChar(sChar.all5ID())
elif currCharID != newCharID:
self.selectChar(newCharID)
self.charChanged(None)
event.Skip()
def _buildSkillsTooltip(self, reqs, currItem = "", tabulationLevel = 0):
def _buildSkillsTooltip(self, reqs, currItem="", tabulationLevel=0):
tip = ""
sCharacter = service.Character.getInstance()
sCharacter = Character.getInstance()
if tabulationLevel == 0:
for item, subReqs in reqs.iteritems():
@@ -197,11 +198,11 @@ class CharacterSelection(wx.Panel):
for name, info in reqs.iteritems():
level, ID, more = info
sCharacter.skillReqsDict['skills'].append({
'item' : currItem,
'skillID' : ID,
'skill' : name,
'level' : level,
'indent' : tabulationLevel
'item': currItem,
'skillID': ID,
'skill': name,
'level': level,
'indent': tabulationLevel,
})
tip += "%s%s: %d\n" % (" " * tabulationLevel, name, level)
@@ -209,8 +210,11 @@ class CharacterSelection(wx.Panel):
return tip
def _buildSkillsTooltipCondensed(self, reqs, currItem = "", tabulationLevel = 0, skillsMap = {}):
sCharacter = service.Character.getInstance()
def _buildSkillsTooltipCondensed(self, reqs, currItem="", tabulationLevel=0, skillsMap=None):
if skillsMap is None:
skillsMap = {}
sCharacter = Character.getInstance()
if tabulationLevel == 0:
for item, subReqs in reqs.iteritems():
@@ -220,11 +224,11 @@ class CharacterSelection(wx.Panel):
for name, info in reqs.iteritems():
level, ID, more = info
sCharacter.skillReqsDict['skills'].append({
'item' : currItem,
'skillID' : ID,
'skill' : name,
'level' : level,
'indent' : tabulationLevel
'item': currItem,
'skillID': ID,
'skill': name,
'level': level,
'indent': tabulationLevel,
})
if name not in skillsMap:
@@ -232,6 +236,6 @@ class CharacterSelection(wx.Panel):
elif skillsMap[name] < level:
skillsMap[name] = level
skillMap = self._buildSkillsTooltipCondensed(more, currItem, tabulationLevel + 1, skillsMap)
skillsMap = self._buildSkillsTooltipCondensed(more, currItem, tabulationLevel + 1, skillsMap)
return skillsMap

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Darriele
#
# This file is part of pyfa.
@@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import wx.lib.newevent
@@ -23,9 +23,8 @@ import gui.utils.colorUtils as colorUtils
import gui.utils.drawUtils as drawUtils
import gui.utils.fonts as fonts
from gui.bitmapLoader import BitmapLoader
import gui.utils.fonts as fonts
import service
from service.fit import Fit
_PageChanging, EVT_NOTEBOOK_PAGE_CHANGING = wx.lib.newevent.NewEvent()
_PageChanged, EVT_NOTEBOOK_PAGE_CHANGED = wx.lib.newevent.NewEvent()
@@ -34,6 +33,7 @@ _PageClosing, EVT_NOTEBOOK_PAGE_CLOSING = wx.lib.newevent.NewEvent()
PageAdded, EVT_NOTEBOOK_PAGE_ADDED = wx.lib.newevent.NewEvent()
PageClosed, EVT_NOTEBOOK_PAGE_CLOSED = wx.lib.newevent.NewEvent()
class VetoAble():
def __init__(self):
self.__vetoed = False
@@ -91,7 +91,6 @@ class PageAdding(_PageAdding, VetoAble):
class PFNotebook(wx.Panel):
def __init__(self, parent, canAdd=True):
"""
Instance of Pyfa Notebook. Initializes general layout, includes methods
@@ -100,8 +99,8 @@ class PFNotebook(wx.Panel):
parent - wx parent element
canAdd - True if tabs be deleted and added, passed directly to
PFTabsContainer
"""
wx.Panel.__init__(self, parent, wx.ID_ANY, size=(-1, -1))
self.pages = []
@@ -234,7 +233,7 @@ class PFNotebook(wx.Panel):
try:
# Set page to the first non-disabled page
self.SetSelection(next(i for i, _ in enumerate(self.pages) if not self.tabsContainer.tabs[i].disabled))
except StopIteration, ex:
except StopIteration:
self.SetSelection(0)
self.tabsContainer.DisableTab(idx, toggle)
@@ -337,7 +336,7 @@ class PFNotebook(wx.Panel):
class PFTabRenderer:
def __init__(self, size=(36, 24), text=wx.EmptyString, img=None, inclination=6 , closeButton=True):
def __init__(self, size=(36, 24), text=wx.EmptyString, img=None, inclination=6, closeButton=True):
"""
Renders a new tab
@@ -432,7 +431,7 @@ class PFTabRenderer:
mdc.SelectObject(ebmp)
mdc.SetFont(self.font)
textSizeX, textSizeY = mdc.GetTextExtent(self.text)
totalSize = self.leftWidth + self.rightWidth + textSizeX + self.closeBtnWidth/2 + 16 + self.padding*2
totalSize = self.leftWidth + self.rightWidth + textSizeX + self.closeBtnWidth / 2 + 16 + self.padding * 2
mdc.SelectObject(wx.NullBitmap)
return totalSize, self.tabHeight
@@ -497,7 +496,7 @@ class PFTabRenderer:
mdc = wx.MemoryDC()
mdc.SelectObject(bkbmp)
#mdc.SetBackground(wx.Brush((0x12, 0x23, 0x32)))
# mdc.SetBackground(wx.Brush((0x12, 0x23, 0x32)))
mdc.Clear()
mdc.DrawBitmap(self.ctabLeftBmp, 0, 0) # set the left bitmap
@@ -506,14 +505,14 @@ class PFTabRenderer:
cm = self.ctabMiddleBmp.ConvertToImage()
mimg = cm.Scale(self.contentWidth, self.ctabMiddle.GetHeight(), wx.IMAGE_QUALITY_NORMAL)
mbmp = wx.BitmapFromImage(mimg)
mdc.DrawBitmap(mbmp, self.leftWidth, 0 ) # set middle bitmap, offset by left
mdc.DrawBitmap(mbmp, self.leftWidth, 0) # set middle bitmap, offset by left
# set right bitmap offset by left + middle
mdc.DrawBitmap(self.ctabRightBmp, self.contentWidth + self.leftWidth, 0)
mdc.SelectObject(wx.NullBitmap)
#bkbmp.SetMaskColour((0x12, 0x23, 0x32))
# bkbmp.SetMaskColour((0x12, 0x23, 0x32))
if self.tabBackBitmap:
del self.tabBackBitmap
@@ -527,7 +526,10 @@ class PFTabRenderer:
"""
self.tabRegion = wx.RegionFromBitmap(self.tabBackBitmap)
self.closeBtnRegion = wx.RegionFromBitmap(self.ctabCloseBmp)
self.closeBtnRegion.Offset(self.contentWidth + self.leftWidth - self.ctabCloseBmp.GetWidth()/2, (self.tabHeight - self.ctabCloseBmp.GetHeight())/2)
self.closeBtnRegion.Offset(
self.contentWidth + self.leftWidth - self.ctabCloseBmp.GetWidth() / 2,
(self.tabHeight - self.ctabCloseBmp.GetHeight()) / 2
)
def InitColors(self):
"""Determines colors used for tab, based on system settings"""
@@ -545,33 +547,33 @@ class PFTabRenderer:
height = self.tabHeight
#rect = wx.Rect(0, 0, self.tabWidth, self.tabHeight)
# rect = wx.Rect(0, 0, self.tabWidth, self.tabHeight)
canvas = wx.EmptyBitmap(self.tabWidth, self.tabHeight, 24)
mdc = wx.MemoryDC()
mdc.SelectObject(canvas)
#mdc.SetBackground(wx.Brush ((0x12,0x23,0x32)))
# mdc.SetBackground(wx.Brush ((0x12,0x23,0x32)))
mdc.Clear()
#r = copy.copy(rect)
#r.top = r.left = 0
#r.height = height
# r = copy.copy(rect)
# r.top = r.left = 0
# r.height = height
mdc.DrawBitmap(self.tabBackBitmap, 0, 0, True)
if self.tabImg:
bmp = wx.BitmapFromImage(self.tabImg.ConvertToGreyscale() if self.disabled else self.tabImg)
if self.contentWidth > 16: # @todo: is this conditional relevant anymore?
# Draw tab icon
mdc.DrawBitmap(bmp, self.leftWidth + self.padding - bmp.GetWidth()/2, (height - bmp.GetHeight())/2)
textStart = self.leftWidth + self.padding + bmp.GetWidth()/2
mdc.DrawBitmap(bmp, self.leftWidth + self.padding - bmp.GetWidth() / 2, (height - bmp.GetHeight()) / 2)
textStart = self.leftWidth + self.padding + bmp.GetWidth() / 2
else:
textStart = self.leftWidth
mdc.SetFont(self.font)
maxsize = self.tabWidth - textStart - self.rightWidth - self.padding*4
maxsize = self.tabWidth - textStart - self.rightWidth - self.padding * 4
color = self.selectedColor if self.selected else self.inactiveColor
mdc.SetTextForeground(colorUtils.GetSuitableColor(color, 1))
@@ -589,9 +591,10 @@ class PFTabRenderer:
cbmp = wx.BitmapFromImage(cimg)
mdc.DrawBitmap(
cbmp,
self.contentWidth + self.leftWidth - self.ctabCloseBmp.GetWidth()/2,
(height - self.ctabCloseBmp.GetHeight())/2)
cbmp,
self.contentWidth + self.leftWidth - self.ctabCloseBmp.GetWidth() / 2,
(height - self.ctabCloseBmp.GetHeight()) / 2,
)
mdc.SelectObject(wx.NullBitmap)
@@ -609,6 +612,7 @@ class PFTabRenderer:
self.text, self.disabled, hex(id(self))
)
class PFAddRenderer:
def __init__(self):
"""Renders the add tab button"""
@@ -628,7 +632,7 @@ class PFAddRenderer:
def GetPosition(self):
return self.position
def SetPosition(self,pos):
def SetPosition(self, pos):
self.position = pos
def GetSize(self):
@@ -689,7 +693,7 @@ class PFTabsContainer(wx.Panel):
"""
wx.Panel.__init__(self, parent, id, pos, size)
if wx.VERSION >= (3,0):
if wx.VERSION >= (3, 0):
self.SetBackgroundStyle(wx.BG_STYLE_PAINT)
self.tabs = []
@@ -699,7 +703,7 @@ class PFTabsContainer(wx.Panel):
self.containerHeight = height
self.startDrag = False
self.dragging = False
self.sFit = service.Fit.getInstance()
self.sFit = Fit.getInstance()
self.inclination = 7
if canAdd:
@@ -865,7 +869,8 @@ class PFTabsContainer(wx.Panel):
return True
if self.TabHitTest(tab, x, y):
if tab.disabled: return
if tab.disabled:
return
tab.SetSelected(True)
oldSelTab.SetSelected(False)
@@ -942,7 +947,7 @@ class PFTabsContainer(wx.Panel):
closeBtnReg = tab.GetCloseButtonRegion()
tabPos = tab.GetPosition()
tabPosX, tabPosY = tabPos
closeBtnReg.Offset(tabPosX,tabPosY)
closeBtnReg.Offset(tabPosX, tabPosY)
if closeBtnReg.Contains(x, y):
if not tab.GetCloseButtonHoverStatus():
@@ -985,7 +990,6 @@ class PFTabsContainer(wx.Panel):
def GetTabAtRight(self, tabIndex):
return self.tabs[tabIndex + 1] if tabIndex < self.GetTabsCount() - 1 else None
def SwitchTabs(self, src, dest, draggedTab=None):
self.tabs[src], self.tabs[dest] = self.tabs[dest], self.tabs[src]
self.UpdateTabsPosition(draggedTab)
@@ -1110,14 +1114,12 @@ class PFTabsContainer(wx.Panel):
def OnPaint(self, event):
if "wxGTK" in wx.PlatformInfo:
mdc = wx.AutoBufferedPaintDC(self)
else:
rect = self.GetRect()
mdc = wx.BufferedPaintDC(self)
selected = 0
if 'wxMac' in wx.PlatformInfo and wx.VERSION < (3,0):
if 'wxMac' in wx.PlatformInfo and wx.VERSION < (3, 0):
color = wx.Colour(0, 0, 0)
brush = wx.Brush(color)
@@ -1128,7 +1130,7 @@ class PFTabsContainer(wx.Panel):
brush = wx.Brush(color)
if "wxGTK" not in wx.PlatformInfo:
mdc.SetBackground (brush)
mdc.SetBackground(brush)
mdc.Clear()
selected = None
@@ -1136,21 +1138,18 @@ class PFTabsContainer(wx.Panel):
tabsWidth = 0
for tab in self.tabs:
tabsWidth += tab.tabWidth - self.inclination*2
pos = tabsWidth
tabsWidth += tab.tabWidth - self.inclination * 2
if self.showAddButton:
ax,ay = self.addButton.GetPosition()
ax, ay = self.addButton.GetPosition()
mdc.DrawBitmap(self.addButton.Render(), ax, ay, True)
for i in xrange(len(self.tabs) - 1, -1, -1):
for i in range(len(self.tabs) - 1, -1, -1):
tab = self.tabs[i]
width = tab.tabWidth - 6
posx, posy = tab.GetPosition()
if not tab.IsSelected():
mdc.DrawBitmap(self.efxBmp, posx, posy, True )
mdc.DrawBitmap(self.efxBmp, posx, posy, True)
bmp = tab.Render()
img = bmp.ConvertToImage()
img = img.AdjustChannels(1, 1, 1, 0.85)
@@ -1265,13 +1264,13 @@ class PFTabsContainer(wx.Panel):
def UpdateTabsPosition(self, skipTab=None):
tabsWidth = 0
for tab in self.tabs:
tabsWidth += tab.tabWidth - self.inclination*2
tabsWidth += tab.tabWidth - self.inclination * 2
pos = tabsWidth
selected = None
for i in xrange(len(self.tabs) - 1, -1, -1):
for i in range(len(self.tabs) - 1, -1, -1):
tab = self.tabs[i]
width = tab.tabWidth - self.inclination*2
width = tab.tabWidth - self.inclination * 2
pos -= width
if not tab.IsSelected():
tab.SetPosition((pos, self.containerHeight - self.height))
@@ -1280,7 +1279,12 @@ class PFTabsContainer(wx.Panel):
selpos = pos
if selected is not skipTab:
selected.SetPosition((selpos, self.containerHeight - self.height))
self.addButton.SetPosition((round(tabsWidth) + self.inclination*2, self.containerHeight - self.height/2 - self.addButton.GetHeight()/3))
self.addButton.SetPosition(
(
round(tabsWidth) + self.inclination * 2,
self.containerHeight - self.height / 2 - self.addButton.GetHeight() / 3
)
)
def OnLeaveWindow(self, event):
@@ -1305,17 +1309,28 @@ class PFTabsContainer(wx.Panel):
if not self.previewTab.GetSelected():
page = self.Parent.GetPage(self.GetTabIndex(self.previewTab))
if page.Snapshot():
self.previewWnd = PFNotebookPagePreview(self, (mposx+3, mposy+3), page.Snapshot(), self.previewTab.text)
self.previewWnd = PFNotebookPagePreview(
self,
(mposx + 3, mposy + 3),
page.Snapshot(),
self.previewTab.text
)
self.previewWnd.Show()
event.Skip()
class PFNotebookPagePreview(wx.Frame):
def __init__ (self,parent, pos, bitmap, title):
wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString, pos=pos, size=wx.DefaultSize, style=
wx.NO_BORDER
| wx.FRAME_NO_TASKBAR
| wx.STAY_ON_TOP)
def __init__(self, parent, pos, bitmap, title):
wx.Frame.__init__(
self,
parent,
id=wx.ID_ANY,
title=wx.EmptyString,
pos=pos,
size=wx.DefaultSize,
style=wx.NO_BORDER | wx.FRAME_NO_TASKBAR | wx.STAY_ON_TOP
)
self.title = title
self.bitmap = bitmap
@@ -1342,13 +1357,13 @@ class PFNotebookPagePreview(wx.Frame):
else:
width = bitmap.GetWidth()
self.SetSize((width, bitmap.GetHeight()+16))
self.SetSize((width, bitmap.GetHeight() + 16))
self.SetTransparent(0)
self.Refresh()
def OnTimer(self, event):
self.transp += 20*self.direction
self.transp += 20 * self.direction
if self.transp > 220:
self.transp = 220
@@ -1357,7 +1372,7 @@ class PFNotebookPagePreview(wx.Frame):
if self.transp < 0:
self.transp = 0
self.timer.Stop()
wx.Frame.Show(self,False)
wx.Frame.Show(self, False)
self.Destroy()
return
self.SetTransparent(self.transp)
@@ -1381,8 +1396,7 @@ class PFNotebookPagePreview(wx.Frame):
self.direction = -1
self.timer.Start(10)
def OnWindowEraseBk(self,event):
def OnWindowEraseBk(self, event):
pass
def OnWindowPaint(self, event):
@@ -1394,17 +1408,17 @@ class PFNotebookPagePreview(wx.Frame):
mdc.SetBackground(wx.Brush(color))
mdc.Clear()
font = wx.Font(fonts.NORMAL, wx.SWISS, wx.NORMAL,wx.NORMAL, False)
font = wx.Font(fonts.NORMAL, wx.SWISS, wx.NORMAL, wx.NORMAL, False)
mdc.SetFont(font)
x,y = mdc.GetTextExtent(self.title)
x, y = mdc.GetTextExtent(self.title)
mdc.SetBrush(wx.Brush(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOWTEXT)))
mdc.DrawRectangle(0, 0, rect.width, 16)
mdc.SetTextForeground(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
mdc.DrawText(self.title, (rect.width - x)/2, (16 - y)/2)
mdc.DrawText(self.title, (rect.width - x) / 2, (16 - y) / 2)
mdc.DrawBitmap(self.bitmap, 0, 16)

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,16 +15,17 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import gui.display as d
import gui.globalEvents as GE
import service
import gui.droneView
from gui.builtinViewColumns.state import State
from gui.contextMenu import ContextMenu
import eos.types
from service.fit import Fit
from eos.saveddata.drone import Drone as es_Drone
class DummyItem:
@@ -32,29 +33,32 @@ class DummyItem:
self.name = txt
self.icon = None
class DummyEntry:
def __init__(self, txt):
self.item = DummyItem(txt)
class CommandViewDrop(wx.PyDropTarget):
def __init__(self, dropFn):
wx.PyDropTarget.__init__(self)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
if self.GetData():
data = self.dropData.GetText().split(':')
self.dropFn(x, y, data)
return t
class CommandViewDrop(wx.PyDropTarget):
def __init__(self, dropFn):
wx.PyDropTarget.__init__(self)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
if self.GetData():
data = self.dropData.GetText().split(':')
self.dropFn(x, y, data)
return t
class CommandView(d.Display):
DEFAULT_COLS = ["Base Name",]
DEFAULT_COLS = ["Base Name"]
def __init__(self, parent):
d.Display.__init__(self, parent, style = wx.LC_SINGLE_SEL | wx.BORDER_NONE)
d.Display.__init__(self, parent, style=wx.LC_SINGLE_SEL | wx.BORDER_NONE)
self.lastFitId = None
@@ -66,7 +70,7 @@ class CommandView(d.Display):
self.droneView = gui.droneView.DroneView
if "__WXGTK__" in wx.PlatformInfo:
if "__WXGTK__" in wx.PlatformInfo:
self.Bind(wx.EVT_RIGHT_UP, self.scheduleMenu)
else:
self.Bind(wx.EVT_RIGHT_DOWN, self.scheduleMenu)
@@ -84,31 +88,31 @@ class CommandView(d.Display):
'''
pass
def kbEvent(self,event):
def kbEvent(self, event):
keycode = event.GetKeyCode()
if keycode == wx.WXK_DELETE or keycode == wx.WXK_NUMPAD_DELETE:
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
row = self.GetFirstSelected()
if row != -1:
sFit.removeCommand(fitID, self.get(row))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def handleDrag(self, type, fitID):
#Those are drags coming from pyfa sources, NOT builtin wx drags
# Those are drags coming from pyfa sources, NOT builtin wx drags
if type == "fit":
activeFit = self.mainFrame.getActiveFit()
if activeFit:
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
draggedFit = sFit.getFit(fitID)
sFit.addCommandFit(activeFit, draggedFit)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFit))
def startDrag(self, event):
row = event.GetIndex()
if row != -1 and isinstance(self.get(row), eos.types.Drone):
if row != -1 and isinstance(self.get(row), es_Drone):
data = wx.PyTextDataObject()
data.SetText("command:"+str(self.GetItemData(row)))
data.SetText("command:" + str(self.GetItemData(row)))
dropSource = wx.DropSource(self)
dropSource.SetData(data)
@@ -118,12 +122,12 @@ class CommandView(d.Display):
return fit.name
def fitChanged(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(event.fitID)
self.Parent.Parent.DisablePage(self, not fit or fit.isStructure)
#Clear list and get out if current fitId is None
# Clear list and get out if current fitId is None
if event.fitID is None and self.lastFitId is not None:
self.DeleteAllItems()
self.lastFitId = None
@@ -168,7 +172,7 @@ class CommandView(d.Display):
col = self.getColumn(event.Position)
if col == self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.toggleCommandFit(fitID, item)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -182,11 +186,11 @@ class CommandView(d.Display):
menu = None
if sel != -1:
item = self.get(sel)
if item is None: return
sMkt = service.Market.getInstance()
if item is None:
return
fitSrcContext = "commandFit"
fitItemContext = item.name
context = ((fitSrcContext,fitItemContext),)
context = ((fitSrcContext, fitItemContext),)
context = context + (("command",),)
menu = ContextMenu.getMenu((item,), *context)
elif sel == -1:
@@ -204,6 +208,6 @@ class CommandView(d.Display):
col = self.getColumn(event.Position)
if col != self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.removeCommand(fitID, self.get(row))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))

View File

@@ -1,179 +1,180 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
import wx
import logging
logger = logging.getLogger(__name__)
class ContextMenu(object):
menus = []
_ids = [] #[wx.NewId() for x in xrange(200)] # init with decent amount
_idxid = -1
@classmethod
def register(cls):
ContextMenu.menus.append(cls)
@classmethod
def getMenu(cls, selection, *fullContexts):
"""
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'),)
"""
cls._idxid = -1
debug_start = len(cls._ids)
rootMenu = wx.Menu()
rootMenu.info = {}
rootMenu.selection = (selection,) if not hasattr(selection, "__iter__") else selection
empty = True
for i, fullContext in enumerate(fullContexts):
amount = 0
srcContext = fullContext[0]
try:
itemContext = fullContext[1]
except IndexError:
itemContext = None
for menuHandler in cls.menus:
# loop through registered menus
m = menuHandler()
if m.display(srcContext, selection):
amount += 1
texts = m.getText(itemContext, selection)
if isinstance(texts, basestring):
texts = (texts,)
bitmap = m.getBitmap(srcContext, selection)
multiple = not isinstance(bitmap, wx.Bitmap)
for it, text in enumerate(texts):
id = cls.nextID()
rootItem = wx.MenuItem(rootMenu, id, text)
rootMenu.info[id] = (m, fullContext, it)
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)
elif sub:
# If sub exists and is not False, set submenu.
# Sub might return False when we have a mix of
# single menu items and submenus (see: damage profile
# context menu)
#
# If there is a submenu, it is expected that the sub
# logic take care of it's own bindings, including for
# any single root items. No binding is done here
#
# It is important to remember that when binding sub
# menu items, the menu to bind to depends on platform.
# Windows should bind to rootMenu, and all other
# platforms should bind to sub menu. See existing
# implementations for examples.
rootItem.SetSubMenu(sub)
if bitmap is not None:
if multiple:
bp = bitmap[it]
if bp:
rootItem.SetBitmap(bp)
else:
rootItem.SetBitmap(bitmap)
rootMenu.AppendItem(rootItem)
empty = False
if amount > 0 and i != len(fullContexts) - 1:
rootMenu.AppendSeparator()
debug_end = len(cls._ids)
if (debug_end - debug_start):
logger.debug("%d new IDs created for this menu" % (debug_end - debug_start))
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:
menuHandler, context, i = stuff
selection = menu.selection
if not hasattr(selection, "__iter__"):
selection = (selection,)
menuHandler.activate(context, selection, i)
else:
event.Skip()
def display(self, context, selection):
raise NotImplementedError()
def activate(self, fullContext, selection, i):
return None
def getSubMenu(self, context, selection, rootMenu, i, pitem):
return None
@classmethod
def nextID(cls):
"""
Fetches an ID from the pool of IDs allocated to Context Menu.
If we don't have enough ID's to fulfill request, create new
ID and add it to the pool.
See GH Issue #589
"""
cls._idxid += 1
if cls._idxid >= len(cls._ids): # We don't ahve an ID for this index, create one
cls._ids.append(wx.NewId())
return cls._ids[cls._idxid]
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):
return None
from gui.builtinContextMenus import *
# =============================================================================
# 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 <http://www.gnu.org/licenses/>.
# =============================================================================
import wx
import logging
logger = logging.getLogger(__name__)
class ContextMenu(object):
menus = []
_ids = [] # [wx.NewId() for x in xrange(200)] # init with decent amount
_idxid = -1
@classmethod
def register(cls):
ContextMenu.menus.append(cls)
@classmethod
def getMenu(cls, selection, *fullContexts):
"""
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'),)
"""
cls._idxid = -1
debug_start = len(cls._ids)
rootMenu = wx.Menu()
rootMenu.info = {}
rootMenu.selection = (selection,) if not hasattr(selection, "__iter__") else selection
empty = True
for i, fullContext in enumerate(fullContexts):
amount = 0
srcContext = fullContext[0]
try:
itemContext = fullContext[1]
except IndexError:
itemContext = None
for menuHandler in cls.menus:
# loop through registered menus
m = menuHandler()
if m.display(srcContext, selection):
amount += 1
texts = m.getText(itemContext, selection)
if isinstance(texts, basestring):
texts = (texts,)
bitmap = m.getBitmap(srcContext, selection)
multiple = not isinstance(bitmap, wx.Bitmap)
for it, text in enumerate(texts):
id = cls.nextID()
rootItem = wx.MenuItem(rootMenu, id, text)
rootMenu.info[id] = (m, fullContext, it)
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)
elif sub:
# If sub exists and is not False, set submenu.
# Sub might return False when we have a mix of
# single menu items and submenus (see: damage profile
# context menu)
#
# If there is a submenu, it is expected that the sub
# logic take care of it's own bindings, including for
# any single root items. No binding is done here
#
# It is important to remember that when binding sub
# menu items, the menu to bind to depends on platform.
# Windows should bind to rootMenu, and all other
# platforms should bind to sub menu. See existing
# implementations for examples.
rootItem.SetSubMenu(sub)
if bitmap is not None:
if multiple:
bp = bitmap[it]
if bp:
rootItem.SetBitmap(bp)
else:
rootItem.SetBitmap(bitmap)
rootMenu.AppendItem(rootItem)
empty = False
if amount > 0 and i != len(fullContexts) - 1:
rootMenu.AppendSeparator()
debug_end = len(cls._ids)
if (debug_end - debug_start):
logger.debug("%d new IDs created for this menu" % (debug_end - debug_start))
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:
menuHandler, context, i = stuff
selection = menu.selection
if not hasattr(selection, "__iter__"):
selection = (selection,)
menuHandler.activate(context, selection, i)
else:
event.Skip()
def display(self, context, selection):
raise NotImplementedError()
def activate(self, fullContext, selection, i):
return None
def getSubMenu(self, context, selection, rootMenu, i, pitem):
return None
@classmethod
def nextID(cls):
"""
Fetches an ID from the pool of IDs allocated to Context Menu.
If we don't have enough ID's to fulfill request, create new
ID and add it to the pool.
See GH Issue #589
"""
cls._idxid += 1
if cls._idxid >= len(cls._ids): # We don't ahve an ID for this index, create one
cls._ids.append(wx.NewId())
return cls._ids[cls._idxid]
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):
return None
from gui.builtinContextMenus import * # noqa

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Lucas Thode
#
# This file is part of pyfa.
@@ -15,11 +15,12 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
class CopySelectDialog(wx.Dialog):
copyFormatEft = 0
copyFormatEftImps = 1
@@ -29,7 +30,8 @@ class CopySelectDialog(wx.Dialog):
copyFormatMultiBuy = 5
def __init__(self, parent):
wx.Dialog.__init__(self, parent, id = wx.ID_ANY, title = u"Select a format", size = (-1,-1), style = wx.DEFAULT_DIALOG_STYLE)
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title=u"Select a format", size=(-1, -1),
style=wx.DEFAULT_DIALOG_STYLE)
mainSizer = wx.BoxSizer(wx.VERTICAL)
copyFormats = [u"EFT", u"EFT (Implants)", u"XML", u"DNA", u"CREST", u"MultiBuy"]
@@ -39,7 +41,8 @@ class CopySelectDialog(wx.Dialog):
CopySelectDialog.copyFormatDna: u"A one-line text format",
CopySelectDialog.copyFormatCrest: u"A JSON format used for EVE CREST",
CopySelectDialog.copyFormatMultiBuy: u"MultiBuy text format"}
selector = wx.RadioBox(self, wx.ID_ANY, label = u"Copy to the clipboard using:", choices = copyFormats, style = wx.RA_SPECIFY_ROWS)
selector = wx.RadioBox(self, wx.ID_ANY, label=u"Copy to the clipboard using:", choices=copyFormats,
style=wx.RA_SPECIFY_ROWS)
selector.Bind(wx.EVT_RADIOBOX, self.Selected)
for format, tooltip in copyFormatTooltips.iteritems():
selector.SetItemToolTip(format, tooltip)
@@ -47,21 +50,18 @@ class CopySelectDialog(wx.Dialog):
self.copyFormat = CopySelectDialog.copyFormatEft
selector.SetSelection(self.copyFormat)
mainSizer.Add(selector,0,wx.EXPAND | wx.ALL, 5)
mainSizer.Add(selector, 0, wx.EXPAND | wx.ALL, 5)
buttonSizer = self.CreateButtonSizer(wx.OK | wx.CANCEL)
if (buttonSizer):
mainSizer.Add(buttonSizer,0, wx.EXPAND | wx.ALL, 5)
mainSizer.Add(buttonSizer, 0, wx.EXPAND | wx.ALL, 5)
self.SetSizer(mainSizer)
self.Fit()
self.Center()
def Selected(self, event):
self.copyFormat = event.GetSelection()
def GetSelected(self):
return self.copyFormat

View File

@@ -4,8 +4,9 @@ import json
import wx
import requests
import service
from service.crest import CrestModes
from service.crest import Crest
from service.fit import Fit
from eos.types import Cargo
from eos.db import getItem
@@ -15,52 +16,53 @@ import gui.globalEvents as GE
class CrestFittings(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, id=wx.ID_ANY, title="Browse EVE Fittings", pos=wx.DefaultPosition, size=wx.Size( 550,450 ), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
wx.Frame.__init__(self, parent, id=wx.ID_ANY, title="Browse EVE Fittings", pos=wx.DefaultPosition,
size=wx.Size(550, 450), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))
self.mainFrame = parent
mainSizer = wx.BoxSizer(wx.VERTICAL)
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
characterSelectSizer = wx.BoxSizer( wx.HORIZONTAL )
characterSelectSizer = wx.BoxSizer(wx.HORIZONTAL)
if sCrest.settings.get('mode') == CrestModes.IMPLICIT:
self.stLogged = wx.StaticText(self, wx.ID_ANY, "Currently logged in as %s"%sCrest.implicitCharacter.name, wx.DefaultPosition, wx.DefaultSize)
self.stLogged.Wrap( -1 )
self.stLogged = wx.StaticText(self, wx.ID_ANY, "Currently logged in as %s" % sCrest.implicitCharacter.name,
wx.DefaultPosition, wx.DefaultSize)
self.stLogged.Wrap(-1)
characterSelectSizer.Add( self.stLogged, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
characterSelectSizer.Add(self.stLogged, 1, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
else:
self.charChoice = wx.Choice(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, [])
characterSelectSizer.Add( self.charChoice, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
characterSelectSizer.Add(self.charChoice, 1, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
self.updateCharList()
self.fetchBtn = wx.Button( self, wx.ID_ANY, u"Fetch Fits", wx.DefaultPosition, wx.DefaultSize, 5 )
characterSelectSizer.Add( self.fetchBtn, 0, wx.ALL, 5 )
mainSizer.Add( characterSelectSizer, 0, wx.EXPAND, 5 )
self.fetchBtn = wx.Button(self, wx.ID_ANY, u"Fetch Fits", wx.DefaultPosition, wx.DefaultSize, 5)
characterSelectSizer.Add(self.fetchBtn, 0, wx.ALL, 5)
mainSizer.Add(characterSelectSizer, 0, wx.EXPAND, 5)
self.sl = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
mainSizer.Add( self.sl, 0, wx.EXPAND |wx.ALL, 5 )
self.sl = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
mainSizer.Add(self.sl, 0, wx.EXPAND | wx.ALL, 5)
contentSizer = wx.BoxSizer( wx.HORIZONTAL )
browserSizer = wx.BoxSizer( wx.VERTICAL )
contentSizer = wx.BoxSizer(wx.HORIZONTAL)
browserSizer = wx.BoxSizer(wx.VERTICAL)
self.fitTree = FittingsTreeView(self)
browserSizer.Add( self.fitTree, 1, wx.ALL|wx.EXPAND, 5 )
contentSizer.Add( browserSizer, 1, wx.EXPAND, 0 )
fitSizer = wx.BoxSizer( wx.VERTICAL )
browserSizer.Add(self.fitTree, 1, wx.ALL | wx.EXPAND, 5)
contentSizer.Add(browserSizer, 1, wx.EXPAND, 0)
fitSizer = wx.BoxSizer(wx.VERTICAL)
self.fitView = FitView(self)
fitSizer.Add( self.fitView, 1, wx.ALL|wx.EXPAND, 5 )
fitSizer.Add(self.fitView, 1, wx.ALL | wx.EXPAND, 5)
btnSizer = wx.BoxSizer( wx.HORIZONTAL )
self.importBtn = wx.Button( self, wx.ID_ANY, u"Import to pyfa", wx.DefaultPosition, wx.DefaultSize, 5 )
self.deleteBtn = wx.Button( self, wx.ID_ANY, u"Delete from EVE", wx.DefaultPosition, wx.DefaultSize, 5 )
btnSizer.Add( self.importBtn, 1, wx.ALL, 5 )
btnSizer.Add( self.deleteBtn, 1, wx.ALL, 5 )
fitSizer.Add( btnSizer, 0, wx.EXPAND )
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
self.importBtn = wx.Button(self, wx.ID_ANY, u"Import to pyfa", wx.DefaultPosition, wx.DefaultSize, 5)
self.deleteBtn = wx.Button(self, wx.ID_ANY, u"Delete from EVE", wx.DefaultPosition, wx.DefaultSize, 5)
btnSizer.Add(self.importBtn, 1, wx.ALL, 5)
btnSizer.Add(self.deleteBtn, 1, wx.ALL, 5)
fitSizer.Add(btnSizer, 0, wx.EXPAND)
contentSizer.Add(fitSizer, 1, wx.EXPAND, 0)
mainSizer.Add(contentSizer, 1, wx.EXPAND, 5)
@@ -90,7 +92,7 @@ class CrestFittings(wx.Frame):
event.Skip()
def updateCharList(self):
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
chars = sCrest.getCrestCharacters()
if len(chars) == 0:
@@ -103,12 +105,12 @@ class CrestFittings(wx.Frame):
self.charChoice.SetSelection(0)
def updateCacheStatus(self, event):
t = time.gmtime(self.cacheTime-time.time())
t = time.gmtime(self.cacheTime - time.time())
if t < 0:
self.cacheTimer.Stop()
else:
sTime = time.strftime("%H:%M:%S", t)
self.statusbar.SetStatusText("Cached for %s"%sTime, 0)
self.statusbar.SetStatusText("Cached for %s" % sTime, 0)
def ssoLogout(self, event):
if event.type == CrestModes.IMPLICIT:
@@ -123,7 +125,7 @@ class CrestFittings(wx.Frame):
event.Skip()
def getActiveCharacter(self):
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
if sCrest.settings.get('mode') == CrestModes.IMPLICIT:
return sCrest.implicitCharacter.ID
@@ -132,7 +134,7 @@ class CrestFittings(wx.Frame):
return self.charChoice.GetClientData(selection) if selection is not None else None
def fetchFittings(self, event):
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
try:
waitDialog = wx.BusyInfo("Fetching fits, please wait...", parent=self)
fittings = sCrest.getFittings(self.getActiveCharacter())
@@ -150,20 +152,20 @@ class CrestFittings(wx.Frame):
if not selection:
return
data = self.fitTree.fittingsTreeCtrl.GetPyData(selection)
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fits = sFit.importFitFromBuffer(data)
self.mainFrame._openAfterImport(fits)
def deleteFitting(self, event):
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
selection = self.fitView.fitSelection
if not selection:
return
data = json.loads(self.fitTree.fittingsTreeCtrl.GetPyData(selection))
dlg = wx.MessageDialog(self,
"Do you really want to delete %s (%s) from EVE?"%(data['name'], data['ship']['name']),
"Confirm Delete", wx.YES | wx.NO | wx.ICON_QUESTION)
"Do you really want to delete %s (%s) from EVE?" % (data['name'], data['ship']['name']),
"Confirm Delete", wx.YES | wx.NO | wx.ICON_QUESTION)
if dlg.ShowModal() == wx.ID_YES:
try:
@@ -173,32 +175,33 @@ class CrestFittings(wx.Frame):
class ExportToEve(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, id=wx.ID_ANY, title="Export fit to EVE", pos=wx.DefaultPosition, size=(wx.Size(350,100)), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
wx.Frame.__init__(self, parent, id=wx.ID_ANY, title="Export fit to EVE", pos=wx.DefaultPosition,
size=(wx.Size(350, 100)), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
self.mainFrame = parent
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
mainSizer = wx.BoxSizer(wx.VERTICAL)
hSizer = wx.BoxSizer(wx.HORIZONTAL)
if sCrest.settings.get('mode') == CrestModes.IMPLICIT:
self.stLogged = wx.StaticText(self, wx.ID_ANY, "Currently logged in as %s"%sCrest.implicitCharacter.name, wx.DefaultPosition, wx.DefaultSize)
self.stLogged.Wrap( -1 )
self.stLogged = wx.StaticText(self, wx.ID_ANY, "Currently logged in as %s" % sCrest.implicitCharacter.name,
wx.DefaultPosition, wx.DefaultSize)
self.stLogged.Wrap(-1)
hSizer.Add( self.stLogged, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
hSizer.Add(self.stLogged, 1, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
else:
self.charChoice = wx.Choice(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, [])
hSizer.Add( self.charChoice, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
hSizer.Add(self.charChoice, 1, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
self.updateCharList()
self.charChoice.SetSelection(0)
self.exportBtn = wx.Button( self, wx.ID_ANY, u"Export Fit", wx.DefaultPosition, wx.DefaultSize, 5 )
hSizer.Add( self.exportBtn, 0, wx.ALL, 5 )
self.exportBtn = wx.Button(self, wx.ID_ANY, u"Export Fit", wx.DefaultPosition, wx.DefaultSize, 5)
hSizer.Add(self.exportBtn, 0, wx.ALL, 5)
mainSizer.Add( hSizer, 0, wx.EXPAND, 5 )
mainSizer.Add(hSizer, 0, wx.EXPAND, 5)
self.exportBtn.Bind(wx.EVT_BUTTON, self.exportFitting)
@@ -217,7 +220,7 @@ class ExportToEve(wx.Frame):
self.Centre(wx.BOTH)
def updateCharList(self):
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
chars = sCrest.getCrestCharacters()
if len(chars) == 0:
@@ -245,7 +248,7 @@ class ExportToEve(wx.Frame):
event.Skip()
def getActiveCharacter(self):
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
if sCrest.settings.get('mode') == CrestModes.IMPLICIT:
return sCrest.implicitCharacter.ID
@@ -254,7 +257,7 @@ class ExportToEve(wx.Frame):
return self.charChoice.GetClientData(selection) if selection is not None else None
def exportFitting(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
self.statusbar.SetStatusText("", 0)
@@ -264,13 +267,13 @@ class ExportToEve(wx.Frame):
return
self.statusbar.SetStatusText("Sending request and awaiting response", 1)
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
try:
data = sFit.exportCrest(fitID)
res = sCrest.postFitting(self.getActiveCharacter(), data)
self.statusbar.SetStatusText("%d: %s"%(res.status_code, res.reason), 0)
self.statusbar.SetStatusText("%d: %s" % (res.status_code, res.reason), 0)
try:
text = json.loads(res.text)
self.statusbar.SetStatusText(text['message'], 1)
@@ -281,47 +284,47 @@ class ExportToEve(wx.Frame):
class CrestMgmt(wx.Dialog):
def __init__( self, parent ):
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = "CREST Character Management", pos = wx.DefaultPosition, size = wx.Size( 550,250 ), style = wx.DEFAULT_DIALOG_STYLE )
def __init__(self, parent):
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title="CREST Character Management", pos=wx.DefaultPosition,
size=wx.Size(550, 250), style=wx.DEFAULT_DIALOG_STYLE)
self.mainFrame = parent
mainSizer = wx.BoxSizer( wx.HORIZONTAL )
mainSizer = wx.BoxSizer(wx.HORIZONTAL)
self.lcCharacters = wx.ListCtrl( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LC_REPORT)
self.lcCharacters = wx.ListCtrl(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LC_REPORT)
self.lcCharacters.InsertColumn(0, heading='Character')
self.lcCharacters.InsertColumn(1, heading='Refresh Token')
self.popCharList()
mainSizer.Add( self.lcCharacters, 1, wx.ALL|wx.EXPAND, 5 )
mainSizer.Add(self.lcCharacters, 1, wx.ALL | wx.EXPAND, 5)
btnSizer = wx.BoxSizer( wx.VERTICAL )
btnSizer = wx.BoxSizer(wx.VERTICAL)
self.addBtn = wx.Button( self, wx.ID_ANY, u"Add Character", wx.DefaultPosition, wx.DefaultSize, 0 )
btnSizer.Add( self.addBtn, 0, wx.ALL | wx.EXPAND, 5 )
self.addBtn = wx.Button(self, wx.ID_ANY, u"Add Character", wx.DefaultPosition, wx.DefaultSize, 0)
btnSizer.Add(self.addBtn, 0, wx.ALL | wx.EXPAND, 5)
self.deleteBtn = wx.Button( self, wx.ID_ANY, u"Revoke Character", wx.DefaultPosition, wx.DefaultSize, 0 )
btnSizer.Add( self.deleteBtn, 0, wx.ALL | wx.EXPAND, 5 )
self.deleteBtn = wx.Button(self, wx.ID_ANY, u"Revoke Character", wx.DefaultPosition, wx.DefaultSize, 0)
btnSizer.Add(self.deleteBtn, 0, wx.ALL | wx.EXPAND, 5)
mainSizer.Add( btnSizer, 0, wx.EXPAND, 5 )
mainSizer.Add(btnSizer, 0, wx.EXPAND, 5)
self.addBtn.Bind(wx.EVT_BUTTON, self.addChar)
self.deleteBtn.Bind(wx.EVT_BUTTON, self.delChar)
self.mainFrame.Bind(GE.EVT_SSO_LOGIN, self.ssoLogin)
self.SetSizer( mainSizer )
self.SetSizer(mainSizer)
self.Layout()
self.Centre( wx.BOTH )
self.Centre(wx.BOTH)
def ssoLogin(self, event):
self.popCharList()
event.Skip()
def popCharList(self):
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
chars = sCrest.getCrestCharacters()
self.lcCharacters.DeleteAllItems()
@@ -335,7 +338,7 @@ class CrestMgmt(wx.Dialog):
self.lcCharacters.SetColumnWidth(1, wx.LIST_AUTOSIZE)
def addChar(self, event):
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
uri = sCrest.startServer()
webbrowser.open(uri)
@@ -343,7 +346,7 @@ class CrestMgmt(wx.Dialog):
item = self.lcCharacters.GetFirstSelected()
if item > -1:
charID = self.lcCharacters.GetItemData(item)
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
sCrest.delCrestCharacter(charID)
self.popCharList()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,19 +15,19 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import sys
import wx
import gui.mainFrame
from gui.viewColumn import ViewColumn
from gui.cachingImageList import CachingImageList
class Display(wx.ListCtrl):
def __init__(self, parent, size = wx.DefaultSize, style = 0):
wx.ListCtrl.__init__(self, parent,size = size, style=wx.LC_REPORT | style )
class Display(wx.ListCtrl):
def __init__(self, parent, size=wx.DefaultSize, style=0):
wx.ListCtrl.__init__(self, parent, size=size, style=wx.LC_REPORT | style)
self.imageList = CachingImageList(16, 16)
self.SetImageList(self.imageList, wx.IMAGE_LIST_SMALL)
self.activeColumns = []
@@ -70,9 +70,8 @@ class Display(wx.ListCtrl):
self.imageListBase = self.imageList.ImageCount
# Override native HitTestSubItem (doesn't work as it should on GTK)
# Source: ObjectListView
# Override native HitTestSubItem (doesn't work as it should on GTK)
# Source: ObjectListView
def HitTestSubItem(self, pt):
"""
@@ -110,15 +109,14 @@ class Display(wx.ListCtrl):
return (rowIndex, 0, -1)
def OnEraseBk(self,event):
if self.GetItemCount() >0:
def OnEraseBk(self, event):
if self.GetItemCount() > 0:
width, height = self.GetClientSize()
dc = event.GetDC()
dc.DestroyClippingRegion()
dc.SetClippingRegion(0, 0, width, height)
x,y,w,h = dc.GetClippingBox()
x, y, w, h = dc.GetClippingBox()
topItem = self.GetTopItem()
bottomItem = topItem + self.GetCountPerPage()
@@ -129,10 +127,9 @@ class Display(wx.ListCtrl):
topRect = self.GetItemRect(topItem, wx.LIST_RECT_LABEL)
bottomRect = self.GetItemRect(bottomItem, wx.LIST_RECT_BOUNDS)
items_rect = wx.Rect(topRect.left, 0, bottomRect.right - topRect.left, bottomRect.bottom)
items_rect = wx.Rect(topRect.left, 0, bottomRect.right - topRect.left, bottomRect.bottom )
updateRegion = wx.Region(x,y,w,h)
updateRegion = wx.Region(x, y, w, h)
updateRegion.SubtractRect(items_rect)
dc.DestroyClippingRegion()
@@ -171,41 +168,37 @@ class Display(wx.ListCtrl):
# we veto header cell resize by default till we find a way
# to assure a minimal size for the resized header cell
column = event.GetColumn()
wx.CallAfter(self.checkColumnSize,column)
wx.CallAfter(self.checkColumnSize, column)
event.Skip()
def resizeSkip(self, event):
column = event.GetColumn()
if column > len (self.activeColumns)-1:
if column > len(self.activeColumns) - 1:
self.SetColumnWidth(column, 0)
event.Veto()
return
colItem = self.activeColumns[column]
# colItem = self.activeColumns[column]
if self.activeColumns[column].maxsize != -1:
event.Veto()
else:
event.Skip()
def checkColumnSize(self,column):
def checkColumnSize(self, column):
colItem = self.activeColumns[column]
if self.GetColumnWidth(column) < self.columnsMinWidth[column]:
self.SetColumnWidth(column,self.columnsMinWidth[column])
self.SetColumnWidth(column, self.columnsMinWidth[column])
colItem.resized = True
def getLastItem( self, state = wx.LIST_STATE_DONTCARE):
lastFound = -1
while True:
index = self.GetNextItem(
lastFound,
wx.LIST_NEXT_ALL,
state,
)
if index == -1:
break
else:
lastFound = index
def getLastItem(self, state=wx.LIST_STATE_DONTCARE):
lastFound = -1
while True:
index = self.GetNextItem(lastFound, wx.LIST_NEXT_ALL, state)
if index == -1:
break
else:
lastFound = index
return lastFound
return lastFound
def deselectItems(self):
sel = self.GetFirstSelected()
@@ -220,26 +213,25 @@ class Display(wx.ListCtrl):
stuffItemCount = len(stuff)
if listItemCount < stuffItemCount:
for i in xrange(stuffItemCount - listItemCount):
index = self.InsertStringItem(sys.maxint, "")
for i in range(stuffItemCount - listItemCount):
self.InsertStringItem(sys.maxint, "")
if listItemCount > stuffItemCount:
if listItemCount - stuffItemCount > 20 and stuffItemCount < 20:
self.DeleteAllItems()
for i in xrange(stuffItemCount):
index = self.InsertStringItem(sys.maxint, "")
for i in range(stuffItemCount):
self.InsertStringItem(sys.maxint, "")
else:
for i in xrange(listItemCount - stuffItemCount):
for i in range(listItemCount - stuffItemCount):
self.DeleteItem(self.getLastItem())
self.Refresh()
def refresh(self, stuff):
if stuff == None:
if stuff is None:
return
item = -1
for id, st in enumerate(stuff):
for id_, st in enumerate(stuff):
item = self.GetNextItem(item)
@@ -270,11 +262,11 @@ class Display(wx.ListCtrl):
colItem.SetMask(mask)
self.SetItem(colItem)
self.SetItemData(item, id)
self.SetItemData(item, id_)
# self.Freeze()
# self.Freeze()
if 'wxMSW' in wx.PlatformInfo:
for i,col in enumerate(self.activeColumns):
for i, col in enumerate(self.activeColumns):
if not col.resized:
self.SetColumnWidth(i, col.size)
else:
@@ -289,9 +281,7 @@ class Display(wx.ListCtrl):
self.SetColumnWidth(i, headerWidth)
else:
self.SetColumnWidth(i, col.size)
# self.Thaw()
# self.Thaw()
def update(self, stuff):
self.populate(stuff)

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,40 +15,45 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import service
import gui.globalEvents as GE
import gui.marketBrowser as mb
import gui.display as d
from gui.builtinViewColumns.state import State
from gui.contextMenu import ContextMenu
from service.fit import Fit
from service.market import Market
class DroneViewDrop(wx.PyDropTarget):
def __init__(self, dropFn):
wx.PyDropTarget.__init__(self)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.SetDataObject(self.dropData)
def __init__(self, dropFn):
wx.PyDropTarget.__init__(self)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
if self.GetData():
data = self.dropData.GetText().split(':')
self.dropFn(x, y, data)
return t
def OnData(self, x, y, t):
if self.GetData():
data = self.dropData.GetText().split(':')
self.dropFn(x, y, data)
return t
class DroneView(d.Display):
DEFAULT_COLS = ["State",
#"Base Icon",
"Base Name",
# "prop:droneDps,droneBandwidth",
"Max Range",
"Miscellanea",
"attr:maxVelocity",
"Price",]
DEFAULT_COLS = [
"State",
# "Base Icon",
"Base Name",
# "prop:droneDps,droneBandwidth",
"Max Range",
"Miscellanea",
"attr:maxVelocity",
"Price",
]
def __init__(self, parent):
d.Display.__init__(self, parent, style=wx.LC_SINGLE_SEL | wx.BORDER_NONE)
@@ -66,12 +71,11 @@ class DroneView(d.Display):
self.Bind(wx.EVT_MOTION, self.OnMouseMove)
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
if "__WXGTK__" in wx.PlatformInfo:
if "__WXGTK__" in wx.PlatformInfo:
self.Bind(wx.EVT_RIGHT_UP, self.scheduleMenu)
else:
self.Bind(wx.EVT_RIGHT_DOWN, self.scheduleMenu)
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.startDrag)
self.SetDropTarget(DroneViewDrop(self.handleDragDrop))
@@ -107,7 +111,6 @@ class DroneView(d.Display):
keycode = event.GetKeyCode()
if keycode == wx.WXK_DELETE or keycode == wx.WXK_NUMPAD_DELETE:
row = self.GetFirstSelected()
firstSel = row
if row != -1:
drone = self.drones[self.GetItemData(row)]
self.removeDrone(drone)
@@ -118,11 +121,11 @@ class DroneView(d.Display):
row = event.GetIndex()
if row != -1:
data = wx.PyTextDataObject()
data.SetText("drone:"+str(row))
data.SetText("drone:" + str(row))
dropSource = wx.DropSource(self)
dropSource.SetData(data)
res = dropSource.DoDragDrop()
dropSource.DoDragDrop()
def handleDragDrop(self, x, y, data):
'''
@@ -141,7 +144,7 @@ class DroneView(d.Display):
wx.PostEvent(self.mainFrame, mb.ItemSelected(itemID=int(data[1])))
def _merge(self, src, dst):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
if sFit.mergeDrones(fitID, self.drones[src], self.drones[dst]):
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -150,8 +153,9 @@ class DroneView(d.Display):
'Heavy Attack Drones', 'Sentry Drones', 'Fighters',
'Fighter Bombers', 'Combat Utility Drones',
'Electronic Warfare Drones', 'Logistic Drones', 'Mining Drones', 'Salvage Drones')
def droneKey(self, drone):
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
groupName = sMkt.getMarketGroupByItem(drone.item).name
@@ -159,12 +163,12 @@ class DroneView(d.Display):
drone.item.name)
def fitChanged(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(event.fitID)
self.Parent.Parent.DisablePage(self, not fit or fit.isStructure)
#Clear list and get out if current fitId is None
# Clear list and get out if current fitId is None
if event.fitID is None and self.lastFitId is not None:
self.DeleteAllItems()
self.lastFitId = None
@@ -177,7 +181,6 @@ class DroneView(d.Display):
if stuff is not None:
stuff.sort(key=self.droneKey)
if event.fitID != self.lastFitId:
self.lastFitId = event.fitID
@@ -191,9 +194,8 @@ class DroneView(d.Display):
self.update(stuff)
event.Skip()
def addItem(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
@@ -218,7 +220,7 @@ class DroneView(d.Display):
def removeDrone(self, drone):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.removeDrone(fitID, self.original.index(drone))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -229,7 +231,7 @@ class DroneView(d.Display):
col = self.getColumn(event.Position)
if col == self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
drone = self.drones[row]
sFit.toggleDrone(fitID, self.original.index(drone))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -244,7 +246,7 @@ class DroneView(d.Display):
if sel != -1:
drone = self.drones[sel]
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
sourceContext = "droneItem"
itemContext = sMkt.getCategoryByItem(drone.item).name
menu = ContextMenu.getMenu((drone,), (sourceContext, itemContext))

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,11 +15,10 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import service
import gui.globalEvents as GE
import gui.marketBrowser as mb
import gui.mainFrame
@@ -27,25 +26,28 @@ import gui.display as d
from gui.builtinViewColumns.state import State
from eos.types import Slot
from gui.contextMenu import ContextMenu
from service.fit import Fit
from service.market import Market
class FighterViewDrop(wx.PyDropTarget):
def __init__(self, dropFn):
wx.PyDropTarget.__init__(self)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.SetDataObject(self.dropData)
def __init__(self, dropFn):
wx.PyDropTarget.__init__(self)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
if self.GetData():
data = self.dropData.GetText().split(':')
self.dropFn(x, y, data)
return t
def OnData(self, x, y, t):
if self.GetData():
data = self.dropData.GetText().split(':')
self.dropFn(x, y, data)
return t
class FighterView(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, style=wx.TAB_TRAVERSAL )
wx.Panel.__init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, style=wx.TAB_TRAVERSAL)
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.labels = ["Light", "Heavy", "Support"]
@@ -55,7 +57,7 @@ class FighterView(wx.Panel):
mainSizer.Add(self.fighterDisplay, 1, wx.EXPAND, 0)
textSizer = wx.BoxSizer(wx.HORIZONTAL)
textSizer.AddSpacer(( 0, 0), 1, wx.EXPAND, 5)
textSizer.AddSpacer((0, 0), 1, wx.EXPAND, 5)
for x in self.labels:
lbl = wx.StaticText(self, wx.ID_ANY, x.capitalize())
@@ -74,14 +76,13 @@ class FighterView(wx.Panel):
mainSizer.Add(textSizer, 0, wx.EXPAND, 5)
self.SetSizer( mainSizer )
self.SetSizer(mainSizer)
self.SetAutoLayout(True)
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
def fitChanged(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
activeFitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(activeFitID)
@@ -90,7 +91,8 @@ class FighterView(wx.Panel):
slot = getattr(Slot, "F_{}".format(x.upper()))
used = fit.getSlotsUsed(slot)
total = fit.getNumSlots(slot)
color = wx.Colour(204, 51, 51) if used > total else wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOWTEXT)
color = wx.Colour(204, 51, 51) if used > total else wx.SystemSettings_GetColour(
wx.SYS_COLOUR_WINDOWTEXT)
lbl = getattr(self, "label%sUsed" % x.capitalize())
lbl.SetLabel(str(int(used)))
@@ -105,15 +107,15 @@ class FighterView(wx.Panel):
class FighterDisplay(d.Display):
DEFAULT_COLS = ["State",
#"Base Icon",
# "Base Icon",
"Base Name",
# "prop:droneDps,droneBandwidth",
#"Max Range",
#"Miscellanea",
# "Max Range",
# "Miscellanea",
"attr:maxVelocity",
"Fighter Abilities"
#"Price",
]
# "Price",
]
def __init__(self, parent):
d.Display.__init__(self, parent, style=wx.LC_SINGLE_SEL | wx.BORDER_NONE)
@@ -131,12 +133,11 @@ class FighterDisplay(d.Display):
self.Bind(wx.EVT_MOTION, self.OnMouseMove)
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
if "__WXGTK__" in wx.PlatformInfo:
if "__WXGTK__" in wx.PlatformInfo:
self.Bind(wx.EVT_RIGHT_UP, self.scheduleMenu)
else:
self.Bind(wx.EVT_RIGHT_DOWN, self.scheduleMenu)
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.startDrag)
self.SetDropTarget(FighterViewDrop(self.handleDragDrop))
@@ -172,7 +173,6 @@ class FighterDisplay(d.Display):
keycode = event.GetKeyCode()
if keycode == wx.WXK_DELETE or keycode == wx.WXK_NUMPAD_DELETE:
row = self.GetFirstSelected()
firstSel = row
if row != -1:
fighter = self.fighters[self.GetItemData(row)]
self.removeFighter(fighter)
@@ -183,11 +183,11 @@ class FighterDisplay(d.Display):
row = event.GetIndex()
if row != -1:
data = wx.PyTextDataObject()
data.SetText("fighter:"+str(row))
data.SetText("fighter:" + str(row))
dropSource = wx.DropSource(self)
dropSource.SetData(data)
res = dropSource.DoDragDrop()
dropSource.DoDragDrop()
def handleDragDrop(self, x, y, data):
'''
@@ -215,7 +215,7 @@ class FighterDisplay(d.Display):
'Electronic Warfare Drones', 'Logistic Drones', 'Mining Drones', 'Salvage Drones',
'Light Fighters', 'Heavy Fighters', 'Support Fighters')
def droneKey(self, drone):
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
groupName = sMkt.getMarketGroupByItem(drone.item).name
print groupName
@@ -224,12 +224,12 @@ class FighterDisplay(d.Display):
'''
def fitChanged(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(event.fitID)
self.Parent.Parent.Parent.DisablePage(self.Parent, not fit)
#Clear list and get out if current fitId is None
# Clear list and get out if current fitId is None
if event.fitID is None and self.lastFitId is not None:
self.DeleteAllItems()
self.lastFitId = None
@@ -257,9 +257,8 @@ class FighterDisplay(d.Display):
self.update(stuff)
event.Skip()
def addItem(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
trigger = sFit.addFighter(fitID, event.itemID)
if trigger:
@@ -278,7 +277,7 @@ class FighterDisplay(d.Display):
def removeFighter(self, fighter):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.removeFighter(fitID, self.original.index(fighter))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -289,7 +288,7 @@ class FighterDisplay(d.Display):
col = self.getColumn(event.Position)
if col == self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fighter = self.fighters[row]
sFit.toggleFighter(fitID, self.original.index(fighter))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -304,7 +303,7 @@ class FighterDisplay(d.Display):
if sel != -1:
fighter = self.fighters[sel]
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
sourceContext = "fighterItem"
itemContext = sMkt.getCategoryByItem(fighter.item).name
menu = ContextMenu.getMenu((fighter,), (sourceContext, itemContext))

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,7 +15,8 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
class Graph(object):
views = []
@@ -33,4 +34,5 @@ class Graph(object):
def getIcons(self):
return None
from gui.builtinGraphs import *
from gui.builtinGraphs import * # noqa

View File

@@ -1,284 +1,283 @@
# ===============================================================================
# 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 <http://www.gnu.org/licenses/>.
# ===============================================================================
import os
import wx
import gui.display
import gui.globalEvents as GE
import gui.mainFrame
import service
from gui.bitmapLoader import BitmapLoader
from gui.graph import Graph
from config import parsePath
enabled = True
mplImported = False
class GraphFrame(wx.Frame):
def __init__(self, parent, style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE | wx.FRAME_FLOAT_ON_PARENT):
global enabled
global mplImported
self.legendFix = False
if not enabled:
return
try:
import matplotlib as mpl
try:
cache_dir = mpl._get_cachedir()
except:
cache_dir = os.path.expanduser(os.path.join("~", ".matplotlib"))
cache_file = parsePath(cache_dir, 'fontList.cache')
if os.access(cache_dir, os.W_OK | os.X_OK) and os.path.isfile(cache_file):
# remove matplotlib font cache, see #234
os.remove(cache_file)
if not mplImported:
mpl.use('wxagg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
from matplotlib.figure import Figure
enabled = True
if mpl.__version__[0] != "1":
print "pyfa: Found matplotlib version ", mpl.__version__, " - activating OVER9000 workarounds"
print "pyfa: Recommended minimum matplotlib version is 1.0.0"
self.legendFix = True
except:
print "Problems importing matplotlib; continuing without graphs"
enabled = False
return
mplImported = True
wx.Frame.__init__(self, parent, title=u"pyfa: Graph Generator", style=style, size=(520, 390))
i = wx.IconFromBitmap(BitmapLoader.getBitmap("graphs_small", "gui"))
self.SetIcon(i)
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.CreateStatusBar()
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(self.mainSizer)
sFit = service.Fit.getInstance()
fit = sFit.getFit(self.mainFrame.getActiveFit())
self.fits = [fit] if fit is not None else []
self.fitList = FitList(self)
self.fitList.SetMinSize((270, -1))
self.fitList.fitList.update(self.fits)
self.graphSelection = wx.Choice(self, wx.ID_ANY, style=0)
self.mainSizer.Add(self.graphSelection, 0, wx.EXPAND)
self.figure = Figure(figsize=(4, 3))
rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
clr = [c / 255. for c in rgbtuple]
self.figure.set_facecolor(clr)
self.figure.set_edgecolor(clr)
self.canvas = Canvas(self, -1, self.figure)
self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))
self.subplot = self.figure.add_subplot(111)
self.subplot.grid(True)
self.mainSizer.Add(self.canvas, 1, wx.EXPAND)
self.mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0,
wx.EXPAND)
self.gridPanel = wx.Panel(self)
self.mainSizer.Add(self.gridPanel, 0, wx.EXPAND)
dummyBox = wx.BoxSizer(wx.VERTICAL)
self.gridPanel.SetSizer(dummyBox)
self.gridSizer = wx.FlexGridSizer(0, 4)
self.gridSizer.AddGrowableCol(1)
dummyBox.Add(self.gridSizer, 0, wx.EXPAND)
for view in Graph.views:
view = view()
self.graphSelection.Append(view.name, view)
self.graphSelection.SetSelection(0)
self.fields = {}
self.select(0)
self.sl1 = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
self.mainSizer.Add(self.sl1, 0, wx.EXPAND)
self.mainSizer.Add(self.fitList, 0, wx.EXPAND)
self.fitList.fitList.Bind(wx.EVT_LEFT_DCLICK, self.removeItem)
self.mainFrame.Bind(GE.FIT_CHANGED, self.draw)
self.Bind(wx.EVT_CLOSE, self.close)
self.Fit()
self.SetMinSize(self.GetSize())
def handleDrag(self, type, fitID):
if type == "fit":
self.AppendFitToList(fitID)
def close(self, event):
self.fitList.fitList.Unbind(wx.EVT_LEFT_DCLICK, handler=self.removeItem)
self.mainFrame.Unbind(GE.FIT_CHANGED, handler=self.draw)
event.Skip()
def getView(self):
return self.graphSelection.GetClientData(self.graphSelection.GetSelection())
def getValues(self):
values = {}
for fieldName, field in self.fields.iteritems():
values[fieldName] = field.GetValue()
return values
def select(self, index):
view = self.getView()
icons = view.getIcons()
labels = view.getLabels()
sizer = self.gridSizer
self.gridPanel.DestroyChildren()
self.fields.clear()
# Setup textboxes
for field, defaultVal in view.getFields().iteritems():
textBox = wx.TextCtrl(self.gridPanel, wx.ID_ANY, style=0)
self.fields[field] = textBox
textBox.Bind(wx.EVT_TEXT, self.onFieldChanged)
sizer.Add(textBox, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 3)
if defaultVal is not None:
if not isinstance(defaultVal, basestring):
defaultVal = ("%f" % defaultVal).rstrip("0")
if defaultVal[-1:] == ".":
defaultVal += "0"
textBox.ChangeValue(defaultVal)
imgLabelSizer = wx.BoxSizer(wx.HORIZONTAL)
if icons:
icon = icons.get(field)
if icon is not None:
static = wx.StaticBitmap(self.gridPanel)
static.SetBitmap(icon)
imgLabelSizer.Add(static, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
if labels:
label = labels.get(field)
label = label if label is not None else field
else:
label = field
imgLabelSizer.Add(wx.StaticText(self.gridPanel, wx.ID_ANY, label), 0,
wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 3)
sizer.Add(imgLabelSizer, 0, wx.ALIGN_CENTER_VERTICAL)
self.draw()
def draw(self, event=None):
values = self.getValues()
view = self.getView()
self.subplot.clear()
self.subplot.grid(True)
legend = []
for fit in self.fits:
try:
success, status = view.getPoints(fit, values)
if not success:
# TODO: Add a pwetty statys bar to report errors with
self.SetStatusText(status)
return
x, y = success, status
self.subplot.plot(x, y)
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)
for t in leg.get_texts():
t.set_fontsize('small')
for l in leg.get_lines():
l.set_linewidth(1)
elif not self.legendFix and len(legend) > 0:
leg = self.subplot.legend(tuple(legend), "upper right", shadow=False, frameon=False)
for t in leg.get_texts():
t.set_fontsize('small')
for l in leg.get_lines():
l.set_linewidth(1)
self.canvas.draw()
self.SetStatusText("")
if event is not None:
event.Skip()
def onFieldChanged(self, event):
self.draw()
def AppendFitToList(self, fitID):
sFit = service.Fit.getInstance()
fit = sFit.getFit(fitID)
if fit not in self.fits:
self.fits.append(fit)
self.fitList.fitList.update(self.fits)
self.draw()
def removeItem(self, event):
row, _ = self.fitList.fitList.HitTest(event.Position)
if row != -1:
del self.fits[row]
self.fitList.fitList.update(self.fits)
self.draw()
class FitList(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(self.mainSizer)
self.fitList = FitDisplay(self)
self.mainSizer.Add(self.fitList, 1, wx.EXPAND)
fitToolTip = wx.ToolTip("Drag a fit into this list to graph it")
self.fitList.SetToolTip(fitToolTip)
class FitDisplay(gui.display.Display):
DEFAULT_COLS = ["Base Icon",
"Base Name"]
def __init__(self, parent):
gui.display.Display.__init__(self, parent)
# =============================================================================
# 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 <http://www.gnu.org/licenses/>.
# =============================================================================
import os
import wx
from service.fit import Fit
import gui.display
import gui.mainFrame
import gui.globalEvents as GE
from gui.graph import Graph
from gui.bitmapLoader import BitmapLoader
enabled = True
mplImported = False
class GraphFrame(wx.Frame):
def __init__(self, parent, style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE | wx.FRAME_FLOAT_ON_PARENT):
global enabled
global mplImported
self.legendFix = False
if not enabled:
return
try:
import matplotlib as mpl
try:
cache_dir = mpl._get_cachedir()
except:
cache_dir = os.path.expanduser(os.path.join("~", ".matplotlib"))
cache_file = parsePath(cache_dir, 'fontList.cache')
if os.access(cache_dir, os.W_OK | os.X_OK) and os.path.isfile(cache_file):
# remove matplotlib font cache, see #234
os.remove(cache_file)
if not mplImported:
mpl.use('wxagg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
from matplotlib.figure import Figure
enabled = True
if mpl.__version__[0] != "1":
print("pyfa: Found matplotlib version ", mpl.__version__, " - activating OVER9000 workarounds")
print("pyfa: Recommended minimum matplotlib version is 1.0.0")
self.legendFix = True
except:
print("Problems importing matplotlib; continuing without graphs")
enabled = False
return
mplImported = True
wx.Frame.__init__(self, parent, title=u"pyfa: Graph Generator", style=style, size=(520, 390))
i = wx.IconFromBitmap(BitmapLoader.getBitmap("graphs_small", "gui"))
self.SetIcon(i)
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.CreateStatusBar()
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(self.mainSizer)
sFit = Fit.getInstance()
fit = sFit.getFit(self.mainFrame.getActiveFit())
self.fits = [fit] if fit is not None else []
self.fitList = FitList(self)
self.fitList.SetMinSize((270, -1))
self.fitList.fitList.update(self.fits)
self.graphSelection = wx.Choice(self, wx.ID_ANY, style=0)
self.mainSizer.Add(self.graphSelection, 0, wx.EXPAND)
self.figure = Figure(figsize=(4, 3))
rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
clr = [c / 255. for c in rgbtuple]
self.figure.set_facecolor(clr)
self.figure.set_edgecolor(clr)
self.canvas = Canvas(self, -1, self.figure)
self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))
self.subplot = self.figure.add_subplot(111)
self.subplot.grid(True)
self.mainSizer.Add(self.canvas, 1, wx.EXPAND)
self.mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0,
wx.EXPAND)
self.gridPanel = wx.Panel(self)
self.mainSizer.Add(self.gridPanel, 0, wx.EXPAND)
dummyBox = wx.BoxSizer(wx.VERTICAL)
self.gridPanel.SetSizer(dummyBox)
self.gridSizer = wx.FlexGridSizer(0, 4)
self.gridSizer.AddGrowableCol(1)
dummyBox.Add(self.gridSizer, 0, wx.EXPAND)
for view in Graph.views:
view = view()
self.graphSelection.Append(view.name, view)
self.graphSelection.SetSelection(0)
self.fields = {}
self.select(0)
self.sl1 = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
self.mainSizer.Add(self.sl1, 0, wx.EXPAND)
self.mainSizer.Add(self.fitList, 0, wx.EXPAND)
self.fitList.fitList.Bind(wx.EVT_LEFT_DCLICK, self.removeItem)
self.mainFrame.Bind(GE.FIT_CHANGED, self.draw)
self.Bind(wx.EVT_CLOSE, self.close)
self.Fit()
self.SetMinSize(self.GetSize())
def handleDrag(self, type, fitID):
if type == "fit":
self.AppendFitToList(fitID)
def close(self, event):
self.fitList.fitList.Unbind(wx.EVT_LEFT_DCLICK, handler=self.removeItem)
self.mainFrame.Unbind(GE.FIT_CHANGED, handler=self.draw)
event.Skip()
def getView(self):
return self.graphSelection.GetClientData(self.graphSelection.GetSelection())
def getValues(self):
values = {}
for fieldName, field in self.fields.iteritems():
values[fieldName] = field.GetValue()
return values
def select(self, index):
view = self.getView()
icons = view.getIcons()
labels = view.getLabels()
sizer = self.gridSizer
self.gridPanel.DestroyChildren()
self.fields.clear()
# Setup textboxes
for field, defaultVal in view.getFields().iteritems():
textBox = wx.TextCtrl(self.gridPanel, wx.ID_ANY, style=0)
self.fields[field] = textBox
textBox.Bind(wx.EVT_TEXT, self.onFieldChanged)
sizer.Add(textBox, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 3)
if defaultVal is not None:
if not isinstance(defaultVal, basestring):
defaultVal = ("%f" % defaultVal).rstrip("0")
if defaultVal[-1:] == ".":
defaultVal += "0"
textBox.ChangeValue(defaultVal)
imgLabelSizer = wx.BoxSizer(wx.HORIZONTAL)
if icons:
icon = icons.get(field)
if icon is not None:
static = wx.StaticBitmap(self.gridPanel)
static.SetBitmap(icon)
imgLabelSizer.Add(static, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
if labels:
label = labels.get(field)
label = label if label is not None else field
else:
label = field
imgLabelSizer.Add(wx.StaticText(self.gridPanel, wx.ID_ANY, label), 0,
wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 3)
sizer.Add(imgLabelSizer, 0, wx.ALIGN_CENTER_VERTICAL)
self.draw()
def draw(self, event=None):
values = self.getValues()
view = self.getView()
self.subplot.clear()
self.subplot.grid(True)
legend = []
for fit in self.fits:
try:
success, status = view.getPoints(fit, values)
if not success:
# TODO: Add a pwetty statys bar to report errors with
self.SetStatusText(status)
return
x, y = success, status
self.subplot.plot(x, y)
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)
for t in leg.get_texts():
t.set_fontsize('small')
for l in leg.get_lines():
l.set_linewidth(1)
elif not self.legendFix and len(legend) > 0:
leg = self.subplot.legend(tuple(legend), "upper right", shadow=False, frameon=False)
for t in leg.get_texts():
t.set_fontsize('small')
for l in leg.get_lines():
l.set_linewidth(1)
self.canvas.draw()
self.SetStatusText("")
if event is not None:
event.Skip()
def onFieldChanged(self, event):
self.draw()
def AppendFitToList(self, fitID):
sFit = Fit.getInstance()
fit = sFit.getFit(fitID)
if fit not in self.fits:
self.fits.append(fit)
self.fitList.fitList.update(self.fits)
self.draw()
def removeItem(self, event):
row, _ = self.fitList.fitList.HitTest(event.Position)
if row != -1:
del self.fits[row]
self.fitList.fitList.update(self.fits)
self.draw()
class FitList(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(self.mainSizer)
self.fitList = FitDisplay(self)
self.mainSizer.Add(self.fitList, 1, wx.EXPAND)
fitToolTip = wx.ToolTip("Drag a fit into this list to graph it")
self.fitList.SetToolTip(fitToolTip)
class FitDisplay(gui.display.Display):
DEFAULT_COLS = ["Base Icon",
"Base Name"]
def __init__(self, parent):
gui.display.Display.__init__(self, parent)

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,10 +15,9 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import service
import gui.display as d
import gui.marketBrowser as mb
import gui.mainFrame
@@ -26,20 +25,22 @@ from gui.builtinViewColumns.state import State
from gui.contextMenu import ContextMenu
import globalEvents as GE
from eos.types import ImplantLocation
from service.fit import Fit
from service.market import Market
class ImplantView(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, style=wx.TAB_TRAVERSAL )
wx.Panel.__init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, style=wx.TAB_TRAVERSAL)
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.implantDisplay = ImplantDisplay(self)
mainSizer.Add(self.implantDisplay, 1, wx.EXPAND, 0 )
mainSizer.Add(self.implantDisplay, 1, wx.EXPAND, 0)
radioSizer = wx.BoxSizer(wx.HORIZONTAL)
radioSizer.AddSpacer(( 0, 0), 1, wx.EXPAND, 5)
radioSizer.AddSpacer((0, 0), 1, wx.EXPAND, 5)
self.rbFit = wx.RadioButton(self, id=wx.ID_ANY, label="Use Fit-specific Implants", style=wx.RB_GROUP)
self.rbChar = wx.RadioButton(self, id=wx.ID_ANY, label="Use Character Implants")
radioSizer.Add(self.rbFit, 0, wx.ALL, 5)
@@ -48,7 +49,7 @@ class ImplantView(wx.Panel):
mainSizer.Add(radioSizer, 0, wx.EXPAND, 5)
self.SetSizer( mainSizer )
self.SetSizer(mainSizer)
self.SetAutoLayout(True)
self.Bind(wx.EVT_RADIOBUTTON, self.OnRadioSelect, self.rbFit)
@@ -56,7 +57,7 @@ class ImplantView(wx.Panel):
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
def fitChanged(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
activeFitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(activeFitID)
if fit:
@@ -70,7 +71,7 @@ class ImplantView(wx.Panel):
def OnRadioSelect(self, event):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.toggleImplantSource(fitID, ImplantLocation.FIT if self.rbFit.GetValue() else ImplantLocation.CHARACTER)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -93,12 +94,12 @@ class ImplantDisplay(d.Display):
self.Bind(wx.EVT_LEFT_DOWN, self.click)
self.Bind(wx.EVT_KEY_UP, self.kbEvent)
if "__WXGTK__" in wx.PlatformInfo:
if "__WXGTK__" in wx.PlatformInfo:
self.Bind(wx.EVT_RIGHT_UP, self.scheduleMenu)
else:
self.Bind(wx.EVT_RIGHT_DOWN, self.scheduleMenu)
def kbEvent(self,event):
def kbEvent(self, event):
keycode = event.GetKeyCode()
if keycode == wx.WXK_DELETE or keycode == wx.WXK_NUMPAD_DELETE:
row = self.GetFirstSelected()
@@ -107,12 +108,12 @@ class ImplantDisplay(d.Display):
event.Skip()
def fitChanged(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(event.fitID)
self.Parent.Parent.Parent.DisablePage(self.Parent, not fit or fit.isStructure)
#Clear list and get out if current fitId is None
# Clear list and get out if current fitId is None
if event.fitID is None and self.lastFitId is not None:
self.DeleteAllItems()
self.lastFitId = None
@@ -121,7 +122,8 @@ class ImplantDisplay(d.Display):
self.original = fit.implants if fit is not None else None
self.implants = stuff = fit.appliedImplants if fit is not None else None
if stuff is not None: stuff.sort(key=lambda implant: implant.slot)
if stuff is not None:
stuff.sort(key=lambda implant: implant.slot)
if event.fitID != self.lastFitId:
self.lastFitId = event.fitID
@@ -137,7 +139,7 @@ class ImplantDisplay(d.Display):
event.Skip()
def addItem(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
@@ -161,7 +163,7 @@ class ImplantDisplay(d.Display):
def removeImplant(self, implant):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.removeImplant(fitID, self.original.index(implant))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -172,7 +174,7 @@ class ImplantDisplay(d.Display):
col = self.getColumn(event.Position)
if col == self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.toggleImplant(fitID, row)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -185,7 +187,7 @@ class ImplantDisplay(d.Display):
sel = self.GetFirstSelected()
menu = None
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(self.mainFrame.getActiveFit())
if not fit:
@@ -194,7 +196,7 @@ class ImplantDisplay(d.Display):
if sel != -1:
implant = fit.appliedImplants[sel]
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
sourceContext = "implantItem" if fit.implantSource == ImplantLocation.FIT else "implantItemChar"
itemContext = sMkt.getCategoryByItem(implant.item).name

View File

@@ -1,4 +1,4 @@
# ===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,28 +15,26 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
# ===============================================================================
# =============================================================================
import csv
import re
import os
import csv
import sys
import subprocess
import wx
import wx.html
import wx.lib.mixins.listctrl as listmix
import config
import gui.mainFrame
import service
from eos.types import Fit, Ship, Citadel, Module, Skill, Booster, Implant, Drone, Mode, Fighter
from service.market import Market
from service.attribute import Attribute
import gui.mainFrame
from gui.bitmapLoader import BitmapLoader
from gui.contextMenu import ContextMenu
from gui.utils.numberFormatter import formatAmount
try:
from collections import OrderedDict
except ImportError:
from utils.compat import OrderedDict
from gui.contextMenu import ContextMenu
class ItemStatsDialog(wx.Dialog):
@@ -73,9 +71,12 @@ class ItemStatsDialog(wx.Dialog):
itmContext = fullContext[1]
except IndexError:
itmContext = None
item = getattr(victim, "item", None) if srcContext.lower() not in ("projectedcharge", "fittingcharge") else getattr(victim, "charge", None)
item = getattr(victim, "item", None) if srcContext.lower() not in (
"projectedcharge",
"fittingcharge"
) else getattr(victim, "charge", None)
if item is None:
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
item = sMkt.getItem(victim.ID)
victim = None
self.context = itmContext
@@ -149,14 +150,10 @@ class ItemStatsDialog(wx.Dialog):
self.Destroy()
###########################################################################
## Class ItemStatsContainer
###########################################################################
class ItemStatsContainer(wx.Panel):
def __init__(self, parent, stuff, item, context=None):
wx.Panel.__init__(self, parent)
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
mainSizer = wx.BoxSizer(wx.VERTICAL)
@@ -201,33 +198,19 @@ class ItemStatsContainer(wx.Panel):
self.nbContainer.SetSelection(tab)
###########################################################################
## Class AutoListCtrl
###########################################################################
class AutoListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.ListRowHighlighter):
def __init__(self, parent, ID, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=0):
def __init__(self, parent, ID, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0):
wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
listmix.ListCtrlAutoWidthMixin.__init__(self)
listmix.ListRowHighlighter.__init__(self)
###########################################################################
## Class AutoListCtrl
###########################################################################
class AutoListCtrlNoHighlight(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.ListRowHighlighter):
def __init__(self, parent, ID, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=0):
def __init__(self, parent, ID, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0):
wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
listmix.ListCtrlAutoWidthMixin.__init__(self)
###########################################################################
## Class ItemTraits
###########################################################################
class ItemTraits(wx.Panel):
def __init__(self, parent, stuff, item):
wx.Panel.__init__(self, parent)
@@ -241,10 +224,6 @@ class ItemTraits(wx.Panel):
self.Layout()
###########################################################################
## Class ItemDescription
###########################################################################
class ItemDescription(wx.Panel):
def __init__(self, parent, stuff, item):
wx.Panel.__init__(self, parent)
@@ -273,19 +252,13 @@ class ItemDescription(wx.Panel):
self.Layout()
###########################################################################
## Class ItemParams
###########################################################################
class ItemParams(wx.Panel):
def __init__(self, parent, stuff, item, context=None):
wx.Panel.__init__(self, parent)
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.paramList = AutoListCtrl(self, wx.ID_ANY,
style= # wx.LC_HRULES |
# wx.LC_NO_HEADER |
wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES | wx.NO_BORDER)
style=wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES | wx.NO_BORDER)
mainSizer.Add(self.paramList, 1, wx.ALL | wx.EXPAND, 0)
self.SetSizer(mainSizer)
@@ -499,21 +472,21 @@ class ItemParams(wx.Panel):
def TranslateValueUnit(self, value, unitName, unitDisplayName):
def itemIDCallback():
item = service.Market.getInstance().getItem(value)
item = Market.getInstance().getItem(value)
return "%s (%d)" % (item.name, value) if item is not None else str(value)
def groupIDCallback():
group = service.Market.getInstance().getGroup(value)
group = Market.getInstance().getGroup(value)
return "%s (%d)" % (group.name, value) if group is not None else str(value)
def attributeIDCallback():
attribute = service.Attribute.getInstance().getAttributeInfo(value)
attribute = Attribute.getInstance().getAttributeInfo(value)
return "%s (%d)" % (attribute.name.capitalize(), value)
trans = {"Inverse Absolute Percent": (lambda: (1 - value) * 100, unitName),
"Inversed Modifier Percent": (lambda: (1 - value) * 100, unitName),
"Modifier Percent": (
lambda: ("%+.2f" if ((value - 1) * 100) % 1 else "%+d") % ((value - 1) * 100), unitName),
lambda: ("%+.2f" if ((value - 1) * 100) % 1 else "%+d") % ((value - 1) * 100), unitName),
"Volume": (lambda: value, u"m\u00B3"),
"Sizeclass": (lambda: value, ""),
"Absolute Percent": (lambda: (value * 100), unitName),
@@ -524,15 +497,13 @@ class ItemParams(wx.Panel):
override = trans.get(unitDisplayName)
if override is not None:
if type(override[0]()) == type(str()):
fvalue = override[0]()
v = override[0]()
if isinstance(v, str):
fvalue = v
elif isinstance(v, (int, float, long)):
fvalue = formatAmount(v, 3, 0, 0)
else:
v = override[0]()
if isinstance(v, (int, float, long)):
fvalue = formatAmount(v, 3, 0, 0)
else:
fvalue = v
fvalue = v
return "%s %s" % (fvalue, override[1])
else:
return "%s %s" % (formatAmount(value, 3, 0), unitName)
@@ -544,9 +515,7 @@ class ItemCompare(wx.Panel):
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.paramList = AutoListCtrl(self, wx.ID_ANY,
style= # wx.LC_HRULES |
# wx.LC_NO_HEADER |
wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES | wx.NO_BORDER)
style=wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES | wx.NO_BORDER)
mainSizer.Add(self.paramList, 1, wx.ALL | wx.EXPAND, 0)
self.SetSizer(mainSizer)
@@ -611,7 +580,7 @@ class ItemCompare(wx.Panel):
self.toggleViewBtn.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleViewMode)
self.Bind(wx.EVT_LIST_COL_CLICK, self.SortCompareCols)
def SortCompareCols(self,event):
def SortCompareCols(self, event):
self.Freeze()
self.paramList.ClearAll()
self.PopulateList(event.Column)
@@ -672,7 +641,7 @@ class ItemCompare(wx.Panel):
self.paramList.InsertColumn(len(self.attrs) + 1, "Price")
self.paramList.SetColumnWidth(len(self.attrs) + 1, 60)
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
sMkt.getPrices([x.ID for x in self.items], self.processPrices)
for item in self.items:
@@ -695,15 +664,15 @@ class ItemCompare(wx.Panel):
def TranslateValueUnit(self, value, unitName, unitDisplayName):
def itemIDCallback():
item = service.Market.getInstance().getItem(value)
item = Market.getInstance().getItem(value)
return "%s (%d)" % (item.name, value) if item is not None else str(value)
def groupIDCallback():
group = service.Market.getInstance().getGroup(value)
group = Market.getInstance().getGroup(value)
return "%s (%d)" % (group.name, value) if group is not None else str(value)
def attributeIDCallback():
attribute = service.Attribute.getInstance().getAttributeInfo(value)
attribute = Attribute.getInstance().getAttributeInfo(value)
return "%s (%d)" % (attribute.name.capitalize(), value)
trans = {"Inverse Absolute Percent": (lambda: (1 - value) * 100, unitName),
@@ -720,24 +689,18 @@ class ItemCompare(wx.Panel):
override = trans.get(unitDisplayName)
if override is not None:
if type(override[0]()) == type(str()):
fvalue = override[0]()
v = override[0]()
if isinstance(v, str):
fvalue = v
elif isinstance(v, (int, float, long)):
fvalue = formatAmount(v, 3, 0, 0)
else:
v = override[0]()
if isinstance(v, (int, float, long)):
fvalue = formatAmount(v, 3, 0, 0)
else:
fvalue = v
fvalue = v
return "%s %s" % (fvalue, override[1])
else:
return "%s %s" % (formatAmount(value, 3, 0), unitName)
###########################################################################
## Class ItemRequirements
###########################################################################
class ItemRequirements(wx.Panel):
def __init__(self, parent, stuff, item):
wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL)
@@ -773,10 +736,6 @@ class ItemRequirements(wx.Panel):
self.skillIdHistory.append(skill.ID)
###########################################################################
## Class ItemEffects
###########################################################################
class ItemEffects(wx.Panel):
def __init__(self, parent, stuff, item):
wx.Panel.__init__(self, parent)
@@ -785,10 +744,7 @@ class ItemEffects(wx.Panel):
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.effectList = AutoListCtrl(self, wx.ID_ANY,
style=
# wx.LC_HRULES |
# wx.LC_NO_HEADER |
wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES | wx.NO_BORDER)
style=wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES | wx.NO_BORDER)
mainSizer.Add(self.effectList, 1, wx.ALL | wx.EXPAND, 0)
self.SetSizer(mainSizer)
@@ -878,19 +834,17 @@ class ItemEffects(wx.Panel):
If effect file does not exist, create it
"""
import os
file = config.getPyfaPath("eos\\effects\\%s.py" % event.GetText().lower())
file_ = config.getPyfaPath("eos\\effects\\%s.py" % event.GetText().lower())
if not os.path.isfile(file):
open(file, 'a').close()
if not os.path.isfile(file_):
open(file_, 'a').close()
if 'wxMSW' in wx.PlatformInfo:
os.startfile(file)
os.startfile(file_)
elif 'wxMac' in wx.PlatformInfo:
os.system("open " + file)
os.system("open " + file_)
else:
import subprocess
subprocess.call(["xdg-open", file])
subprocess.call(["xdg-open", file_])
def RefreshValues(self, event):
self.Freeze()
@@ -902,11 +856,6 @@ class ItemEffects(wx.Panel):
event.Skip()
###########################################################################
## Class ItemAffectedBy
###########################################################################
class ItemAffectedBy(wx.Panel):
ORDER = [Fit, Ship, Citadel, Mode, Module, Drone, Fighter, Implant, Booster, Skill]
@@ -973,9 +922,9 @@ class ItemAffectedBy(wx.Panel):
# Skills are different in that they don't have itemModifiedAttributes,
# which is needed if we send the container to itemStats dialog. So
# instead, we send the item.
type = stuff.__class__.__name__
contexts.append(("itemStats", type))
menu = ContextMenu.getMenu(stuff if type != "Skill" else stuff.item, *contexts)
type_ = stuff.__class__.__name__
contexts.append(("itemStats", type_))
menu = ContextMenu.getMenu(stuff if type_ != "Skill" else stuff.item, *contexts)
self.PopupMenu(menu)
def ExpandCollapseTree(self):
@@ -1051,20 +1000,22 @@ class ItemAffectedBy(wx.Panel):
return attr
def buildAttributeView(self, root):
# We first build a usable dictionary of items. The key is either a fit
# if the afflictions stem from a projected fit, or self.stuff if they
# are local afflictions (everything else, even gang boosts at this time)
# The value of this is yet another dictionary in the following format:
#
# "attribute name": {
# "Module Name": [
# class of affliction,
# affliction item (required due to GH issue #335)
# modifier type
# amount of modification
# whether this affliction was projected
# ]
# }
"""
We first build a usable dictionary of items. The key is either a fit
if the afflictions stem from a projected fit, or self.stuff if they
are local afflictions (everything else, even gang boosts at this time)
The value of this is yet another dictionary in the following format:
"attribute name": {
"Module Name": [
class of affliction,
affliction item (required due to GH issue #335)
modifier type
amount of modification
whether this affliction was projected
]
}
"""
attributes = self.stuff.itemModifiedAttributes if self.item == self.stuff.item else self.stuff.chargeModifiedAttributes
container = {}
@@ -1178,18 +1129,20 @@ class ItemAffectedBy(wx.Panel):
self.affectedBy.SetPyData(treeItem, afflictor)
def buildModuleView(self, root):
# We first build a usable dictionary of items. The key is either a fit
# if the afflictions stem from a projected fit, or self.stuff if they
# are local afflictions (everything else, even gang boosts at this time)
# The value of this is yet another dictionary in the following format:
#
# "Module Name": [
# class of affliction,
# set of afflictors (such as 2 of the same module),
# info on affliction (attribute name, modifier, and modification amount),
# item that will be used to determine icon (required due to GH issue #335)
# whether this affliction is actually used (unlearned skills are not used)
# ]
"""
We first build a usable dictionary of items. The key is either a fit
if the afflictions stem from a projected fit, or self.stuff if they
are local afflictions (everything else, even gang boosts at this time)
The value of this is yet another dictionary in the following format:
"Module Name": [
class of affliction,
set of afflictors (such as 2 of the same module),
info on affliction (attribute name, modifier, and modification amount),
item that will be used to determine icon (required due to GH issue #335)
whether this affliction is actually used (unlearned skills are not used)
]
"""
attributes = self.stuff.itemModifiedAttributes if self.item == self.stuff.item else self.stuff.chargeModifiedAttributes
container = {}
@@ -1309,9 +1262,19 @@ class ItemAffectedBy(wx.Panel):
if self.showRealNames:
display = "%s %s %.2f %s" % (attrName, attrModifier, attrAmount, penalized)
saved = "%s %s %.2f %s" % ((displayName if displayName != "" else attrName), attrModifier, attrAmount, penalized)
saved = "%s %s %.2f %s" % (
displayName if displayName != "" else attrName,
attrModifier,
attrAmount,
penalized
)
else:
display = "%s %s %.2f %s" % ((displayName if displayName != "" else attrName), attrModifier, attrAmount, penalized)
display = "%s %s %.2f %s" % (
displayName if displayName != "" else attrName,
attrModifier,
attrAmount,
penalized
)
saved = "%s %s %.2f %s" % (attrName, attrModifier, attrAmount, penalized)
treeitem = self.affectedBy.AppendItem(child, display, attrIcon)

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,10 +15,11 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import sys
import os.path
import logging
import sqlalchemy
import wx
@@ -26,17 +27,14 @@ import time
from codecs import open
from wx._core import PyDeadObjectError
from wx.lib.wordwrap import wordwrap
import service
import config
import threading
import webbrowser
from eos.config import gamedata_version
import gui.aboutData
import gui.chromeTabs
import gui.utils.animUtils as animUtils
import gui.globalEvents as GE
from gui.bitmapLoader import BitmapLoader
@@ -56,37 +54,56 @@ from gui.graphFrame import GraphFrame
from gui.copySelectDialog import CopySelectDialog
from gui.utils.clipboard import toClipboard, fromClipboard
from gui.updateDialog import UpdateDialog
from gui.builtinViews import *
from gui.builtinViews import * # TODO: unsure if this is needed here
from gui import graphFrame
from service.settings import SettingsProvider
from service.fit import Fit
from service.character import Character
from service.crest import Crest
from service.update import Update
# import this to access override setting
from eos.modifiedAttributeDict import ModifiedAttributeDict
from eos.db.saveddata.loadDefaultDatabaseValues import DefaultDatabaseValues
from eos import db
from service.port import Port
from service.settings import HTMLExportSettings
from time import gmtime, strftime
if not 'wxMac' in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3,0)):
import threading
import webbrowser
if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0)):
from service.crest import CrestModes
from gui.crestFittings import CrestFittings, ExportToEve, CrestMgmt
try:
from gui.propertyEditor import AttributeEditor
disableOverrideEditor = False
except ImportError, e:
print "Error loading Attribute Editor: %s.\nAccess to Attribute Editor is disabled."%e.message
except ImportError as e:
print("Error loading Attribute Editor: %s.\nAccess to Attribute Editor is disabled." % e.message)
disableOverrideEditor = True
#dummy panel(no paint no erasebk)
logger = logging.getLogger("pyfa.gui.mainFrame")
# dummy panel(no paint no erasebk)
class PFPanel(wx.Panel):
def __init__(self,parent):
wx.Panel.__init__(self,parent)
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnBkErase)
def OnPaint(self, event):
event.Skip()
def OnBkErase(self, event):
pass
class OpenFitsThread(threading.Thread):
def __init__(self, fits, callback):
threading.Thread.__init__(self)
@@ -111,34 +128,36 @@ class OpenFitsThread(threading.Thread):
wx.PostEvent(self.mainFrame, FitSelected(fitID=self.fits[-1], startup=2))
wx.CallAfter(self.callback)
class MainFrame(wx.Frame):
__instance = None
@classmethod
def getInstance(cls):
return cls.__instance if cls.__instance is not None else MainFrame()
def __init__(self, title):
self.title=title
self.title = title
wx.Frame.__init__(self, None, wx.ID_ANY, self.title)
MainFrame.__instance = self
#Load stored settings (width/height/maximized..)
# Load stored settings (width/height/maximized..)
self.LoadMainFrameAttribs()
#Fix for msw (have the frame background color match panel color
# Fix for msw (have the frame background color match panel color
if 'wxMSW' in wx.PlatformInfo:
self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))
#Load and set the icon for pyfa main window
# Load and set the icon for pyfa main window
i = wx.IconFromBitmap(BitmapLoader.getBitmap("pyfa", "gui"))
self.SetIcon(i)
#Create the layout and windows
# Create the layout and windows
mainSizer = wx.BoxSizer(wx.HORIZONTAL)
self.browser_fitting_split = wx.SplitterWindow(self, style = wx.SP_LIVE_UPDATE)
self.fitting_additions_split = wx.SplitterWindow(self.browser_fitting_split, style = wx.SP_LIVE_UPDATE)
self.browser_fitting_split = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE)
self.fitting_additions_split = wx.SplitterWindow(self.browser_fitting_split, style=wx.SP_LIVE_UPDATE)
mainSizer.Add(self.browser_fitting_split, 1, wx.EXPAND | wx.LEFT, 2)
@@ -151,11 +170,11 @@ class MainFrame(wx.Frame):
shipBrowserImg = BitmapLoader.getImage("ship_small", "gui")
self.marketBrowser = MarketBrowser(self.notebookBrowsers)
self.notebookBrowsers.AddPage(self.marketBrowser, "Market", tabImage = marketImg, showClose = False)
self.notebookBrowsers.AddPage(self.marketBrowser, "Market", tabImage=marketImg, showClose=False)
self.marketBrowser.splitter.SetSashPosition(self.marketHeight)
self.shipBrowser = ShipBrowser(self.notebookBrowsers)
self.notebookBrowsers.AddPage(self.shipBrowser, "Fittings", tabImage = shipBrowserImg, showClose = False)
self.notebookBrowsers.AddPage(self.shipBrowser, "Fittings", tabImage=shipBrowserImg, showClose=False)
self.notebookBrowsers.SetSelection(1)
@@ -180,7 +199,7 @@ class MainFrame(wx.Frame):
self.SetSizer(mainSizer)
#Add menu
# Add menu
self.addPageId = wx.NewId()
self.closePageId = wx.NewId()
@@ -188,23 +207,23 @@ class MainFrame(wx.Frame):
self.SetMenuBar(MainMenuBar())
self.registerMenu()
#Internal vars to keep track of other windows (graphing/stats)
# Internal vars to keep track of other windows (graphing/stats)
self.graphFrame = None
self.statsWnds = []
self.activeStatsWnd = None
self.Bind(wx.EVT_CLOSE, self.OnClose)
#Show ourselves
# Show ourselves
self.Show()
self.LoadPreviousOpenFits()
#Check for updates
self.sUpdate = service.Update.getInstance()
# Check for updates
self.sUpdate = Update.getInstance()
self.sUpdate.CheckUpdate(self.ShowUpdateBox)
if not 'wxMac' in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3,0)):
if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0)):
self.Bind(GE.EVT_SSO_LOGIN, self.onSSOLogin)
self.Bind(GE.EVT_SSO_LOGOUT, self.onSSOLogout)
@@ -216,9 +235,10 @@ class MainFrame(wx.Frame):
dlg.ShowModal()
def LoadPreviousOpenFits(self):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
self.prevOpenFits = service.SettingsProvider.getInstance().getSettings("pyfaPrevOpenFits", {"enabled": False, "pyfaOpenFits": []})
self.prevOpenFits = SettingsProvider.getInstance().getSettings("pyfaPrevOpenFits",
{"enabled": False, "pyfaOpenFits": []})
fits = self.prevOpenFits['pyfaOpenFits']
# Remove any fits that cause exception when fetching (non-existent fits)
@@ -237,8 +257,10 @@ class MainFrame(wx.Frame):
OpenFitsThread(fits, self.closeWaitDialog)
def LoadMainFrameAttribs(self):
mainFrameDefaultAttribs = {"wnd_width": 1000, "wnd_height": 700, "wnd_maximized": False, "browser_width": 300, "market_height": 0, "fitting_height": -200}
self.mainFrameAttribs = service.SettingsProvider.getInstance().getSettings("pyfaMainWindowAttribs", mainFrameDefaultAttribs)
mainFrameDefaultAttribs = {"wnd_width": 1000, "wnd_height": 700, "wnd_maximized": False, "browser_width": 300,
"market_height": 0, "fitting_height": -200}
self.mainFrameAttribs = SettingsProvider.getInstance().getSettings("pyfaMainWindowAttribs",
mainFrameDefaultAttribs)
if self.mainFrameAttribs["wnd_maximized"]:
width = mainFrameDefaultAttribs["wnd_width"]
@@ -258,7 +280,7 @@ class MainFrame(wx.Frame):
def UpdateMainFrameAttribs(self):
if self.IsIconized():
return
width,height = self.GetSize()
width, height = self.GetSize()
self.mainFrameAttribs["wnd_width"] = width
self.mainFrameAttribs["wnd_height"] = height
@@ -292,7 +314,7 @@ class MainFrame(wx.Frame):
return m() if m is not None else None
def getActiveView(self):
sel = self.fitMultiSwitch.GetSelectedPage()
self.fitMultiSwitch.GetSelectedPage()
def CloseCurrentPage(self, evt):
ms = self.fitMultiSwitch
@@ -305,14 +327,14 @@ class MainFrame(wx.Frame):
self.UpdateMainFrameAttribs()
# save open fits
self.prevOpenFits['pyfaOpenFits'] = [] # clear old list
self.prevOpenFits['pyfaOpenFits'] = [] # clear old list
for page in self.fitMultiSwitch.pages:
m = getattr(page, "getActiveFit", None)
if m is not None:
self.prevOpenFits['pyfaOpenFits'].append(m())
self.prevOpenFits['pyfaOpenFits'].append(m())
# save all teh settingz
service.SettingsProvider.getInstance().saveAll()
SettingsProvider.getInstance().saveAll()
event.Skip()
def ExitApp(self, event):
@@ -320,43 +342,41 @@ class MainFrame(wx.Frame):
event.Skip()
def ShowAboutBox(self, evt):
import eos.config
v = sys.version_info
info = wx.AboutDialogInfo()
info.Name = "pyfa"
info.Version = gui.aboutData.versionString
info.Description = wordwrap(gui.aboutData.description + "\n\nDevelopers:\n\t" +
"\n\t".join(gui.aboutData.developers) +
"\n\nAdditional credits:\n\t" +
"\n\t".join(gui.aboutData.credits) +
"\n\nLicenses:\n\t" +
"\n\t".join(gui.aboutData.licenses) +
"\n\nEVE Data: \t" + eos.config.gamedata_version +
"\nPython: \t\t" + '{}.{}.{}'.format(v.major, v.minor, v.micro) +
"\nwxPython: \t" + wx.__version__ +
"\nSQLAlchemy: \t" + sqlalchemy.__version__,
500, wx.ClientDC(self))
if "__WXGTK__" in wx.PlatformInfo:
"\n\t".join(gui.aboutData.developers) +
"\n\nAdditional credits:\n\t" +
"\n\t".join(gui.aboutData.credits) +
"\n\nLicenses:\n\t" +
"\n\t".join(gui.aboutData.licenses) +
"\n\nEVE Data: \t" + gamedata_version +
"\nPython: \t\t" + '{}.{}.{}'.format(v.major, v.minor, v.micro) +
"\nwxPython: \t" + wx.__version__ +
"\nSQLAlchemy: \t" + sqlalchemy.__version__,
500, wx.ClientDC(self))
if "__WXGTK__" in wx.PlatformInfo:
forumUrl = "http://forums.eveonline.com/default.aspx?g=posts&amp;t=466425"
else:
forumUrl = "http://forums.eveonline.com/default.aspx?g=posts&t=466425"
info.WebSite = (forumUrl, "pyfa thread at EVE Online forum")
wx.AboutBox(info)
def showCharacterEditor(self, event):
dlg=CharacterEditor(self)
dlg = CharacterEditor(self)
dlg.Show()
def showAttrEditor(self, event):
dlg=AttributeEditor(self)
dlg = AttributeEditor(self)
dlg.Show()
def showTargetResistsEditor(self, event):
ResistsEditorDlg(self)
def showDamagePatternEditor(self, event):
dlg=DmgPatternEditorDlg(self)
dlg = DmgPatternEditorDlg(self)
dlg.ShowModal()
dlg.Destroy()
@@ -365,28 +385,30 @@ class MainFrame(wx.Frame):
def showExportDialog(self, event):
""" Export active fit """
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(self.getActiveFit())
defaultFile = "%s - %s.xml"%(fit.ship.item.name, fit.name) if fit else None
defaultFile = "%s - %s.xml" % (fit.ship.item.name, fit.name) if fit else None
dlg = wx.FileDialog(self, "Save Fitting As...",
wildcard = "EVE XML fitting files (*.xml)|*.xml",
style = wx.FD_SAVE,
wildcard="EVE XML fitting files (*.xml)|*.xml",
style=wx.FD_SAVE,
defaultFile=defaultFile)
if dlg.ShowModal() == wx.ID_OK:
format = dlg.GetFilterIndex()
format_ = dlg.GetFilterIndex()
path = dlg.GetPath()
if format == 0:
if format_ == 0:
output = sFit.exportXml(None, self.getActiveFit())
if '.' not in os.path.basename(path):
path += ".xml"
else:
print "oops, invalid fit format %d" % format
print("oops, invalid fit format %d" % format_)
dlg.Destroy()
return
file = open(path, "w", encoding="utf-8")
file.write(output)
file.close()
with open(path, "w", encoding="utf-8") as openfile:
openfile.write(output)
openfile.close()
dlg.Destroy()
def showPreferenceDialog(self, event):
@@ -415,7 +437,7 @@ class MainFrame(wx.Frame):
self.Bind(wx.EVT_MENU, self.loadDatabaseDefaults, id=menuBar.importDatabaseDefaultsId)
# Widgets Inspector
if config.debug:
self.Bind(wx.EVT_MENU, self.openWXInspectTool, id = self.widgetInspectMenuID)
self.Bind(wx.EVT_MENU, self.openWXInspectTool, id=self.widgetInspectMenuID)
# About
self.Bind(wx.EVT_MENU, self.ShowAboutBox, id=wx.ID_ABOUT)
# Char editor
@@ -443,32 +465,32 @@ class MainFrame(wx.Frame):
# Preference dialog
self.Bind(wx.EVT_MENU, self.showPreferenceDialog, id=wx.ID_PREFERENCES)
# User guide
self.Bind(wx.EVT_MENU, self.goWiki, id = menuBar.wikiId)
self.Bind(wx.EVT_MENU, self.goWiki, id=menuBar.wikiId)
# EVE Forums
self.Bind(wx.EVT_MENU, self.goForums, id = menuBar.forumId)
self.Bind(wx.EVT_MENU, self.goForums, id=menuBar.forumId)
# Save current character
self.Bind(wx.EVT_MENU, self.saveChar, id = menuBar.saveCharId)
self.Bind(wx.EVT_MENU, self.saveChar, id=menuBar.saveCharId)
# Save current character as another character
self.Bind(wx.EVT_MENU, self.saveCharAs, id = menuBar.saveCharAsId)
self.Bind(wx.EVT_MENU, self.saveCharAs, id=menuBar.saveCharAsId)
# Save current character
self.Bind(wx.EVT_MENU, self.revertChar, id = menuBar.revertCharId)
self.Bind(wx.EVT_MENU, self.revertChar, id=menuBar.revertCharId)
# Browse fittings
self.Bind(wx.EVT_MENU, self.eveFittings, id = menuBar.eveFittingsId)
self.Bind(wx.EVT_MENU, self.eveFittings, id=menuBar.eveFittingsId)
# Export to EVE
self.Bind(wx.EVT_MENU, self.exportToEve, id = menuBar.exportToEveId)
self.Bind(wx.EVT_MENU, self.exportToEve, id=menuBar.exportToEveId)
# Handle SSO event (login/logout/manage characters, depending on mode and current state)
self.Bind(wx.EVT_MENU, self.ssoHandler, id = menuBar.ssoLoginId)
self.Bind(wx.EVT_MENU, self.ssoHandler, id=menuBar.ssoLoginId)
# Open attribute editor
self.Bind(wx.EVT_MENU, self.showAttrEditor, id = menuBar.attrEditorId)
self.Bind(wx.EVT_MENU, self.showAttrEditor, id=menuBar.attrEditorId)
# Toggle Overrides
self.Bind(wx.EVT_MENU, self.toggleOverrides, id = menuBar.toggleOverridesId)
self.Bind(wx.EVT_MENU, self.toggleOverrides, id=menuBar.toggleOverridesId)
#Clipboard exports
# Clipboard exports
self.Bind(wx.EVT_MENU, self.exportToClipboard, id=wx.ID_COPY)
#Graphs
# Graphs
self.Bind(wx.EVT_MENU, self.openGraphFrame, id=menuBar.graphFrameId)
toggleSearchBoxId = wx.NewId()
@@ -478,11 +500,11 @@ class MainFrame(wx.Frame):
# Close Page
self.Bind(wx.EVT_MENU, self.CloseCurrentPage, id=self.closePageId)
self.Bind(wx.EVT_MENU, self.HAddPage, id = self.addPageId)
self.Bind(wx.EVT_MENU, self.toggleSearchBox, id = toggleSearchBoxId)
self.Bind(wx.EVT_MENU, self.toggleShipMarket, id = toggleShipMarketId)
self.Bind(wx.EVT_MENU, self.CTabNext, id = ctabnext)
self.Bind(wx.EVT_MENU, self.CTabPrev, id = ctabprev)
self.Bind(wx.EVT_MENU, self.HAddPage, id=self.addPageId)
self.Bind(wx.EVT_MENU, self.toggleSearchBox, id=toggleSearchBoxId)
self.Bind(wx.EVT_MENU, self.toggleShipMarket, id=toggleShipMarketId)
self.Bind(wx.EVT_MENU, self.CTabNext, id=ctabnext)
self.Bind(wx.EVT_MENU, self.CTabPrev, id=ctabprev)
actb = [(wx.ACCEL_CTRL, ord('T'), self.addPageId),
(wx.ACCEL_CMD, ord('T'), self.addPageId),
@@ -515,30 +537,30 @@ class MainFrame(wx.Frame):
for i in range(0, self.additionsPane.notebook.GetPageCount()):
self.additionsSelect.append(wx.NewId())
self.Bind(wx.EVT_MENU, self.AdditionsTabSelect, id=self.additionsSelect[i])
actb.append((wx.ACCEL_CMD, i+49, self.additionsSelect[i]))
actb.append((wx.ACCEL_CTRL, i+49, self.additionsSelect[i]))
actb.append((wx.ACCEL_CMD, i + 49, self.additionsSelect[i]))
actb.append((wx.ACCEL_CTRL, i + 49, self.additionsSelect[i]))
# Alt+1-9 for market item selection
self.itemSelect = []
for i in range(0, 9):
self.itemSelect.append(wx.NewId())
self.Bind(wx.EVT_MENU, self.ItemSelect, id = self.itemSelect[i])
self.Bind(wx.EVT_MENU, self.ItemSelect, id=self.itemSelect[i])
actb.append((wx.ACCEL_ALT, i + 49, self.itemSelect[i]))
atable = wx.AcceleratorTable(actb)
self.SetAcceleratorTable(atable)
def eveFittings(self, event):
dlg=CrestFittings(self)
dlg = CrestFittings(self)
dlg.Show()
def updateTitle(self, event):
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
char = sCrest.implicitCharacter
if char:
t = time.gmtime(char.eve.expires-time.time())
t = time.gmtime(char.eve.expires - time.time())
sTime = time.strftime("%H:%M:%S", t if t >= 0 else 0)
newTitle = "%s | %s - %s"%(self.title, char.name, sTime)
newTitle = "%s | %s - %s" % (self.title, char.name, sTime)
self.SetTitle(newTitle)
def onSSOLogin(self, event):
@@ -568,7 +590,7 @@ class MainFrame(wx.Frame):
self.SetTitle(self.title)
menu = self.GetMenuBar()
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
if type == CrestModes.IMPLICIT:
menu.SetLabel(menu.ssoLoginId, "Login to EVE")
@@ -581,7 +603,7 @@ class MainFrame(wx.Frame):
menu.Enable(menu.exportToEveId, not enable)
def ssoHandler(self, event):
sCrest = service.Crest.getInstance()
sCrest = Crest.getInstance()
if sCrest.settings.get('mode') == CrestModes.IMPLICIT:
if sCrest.implicitCharacter is not None:
sCrest.logout()
@@ -589,21 +611,22 @@ class MainFrame(wx.Frame):
uri = sCrest.startServer()
webbrowser.open(uri)
else:
dlg=CrestMgmt(self)
dlg = CrestMgmt(self)
dlg.Show()
def exportToEve(self, event):
dlg=ExportToEve(self)
dlg = ExportToEve(self)
dlg.Show()
def toggleOverrides(self, event):
ModifiedAttributeDict.OVERRIDES = not ModifiedAttributeDict.OVERRIDES
wx.PostEvent(self, GE.FitChanged(fitID=self.getActiveFit()))
menu = self.GetMenuBar()
menu.SetLabel(menu.toggleOverridesId, "Turn Overrides Off" if ModifiedAttributeDict.OVERRIDES else "Turn Overrides On")
menu.SetLabel(menu.toggleOverridesId,
"Turn Overrides Off" if ModifiedAttributeDict.OVERRIDES else "Turn Overrides On")
def saveChar(self, event):
sChr = service.Character.getInstance()
sChr = Character.getInstance()
charID = self.charSelection.getActiveCharacter()
sChr.saveCharacter(charID)
wx.PostEvent(self, GE.CharListUpdated())
@@ -614,7 +637,7 @@ class MainFrame(wx.Frame):
dlg.ShowModal()
def revertChar(self, event):
sChr = service.Character.getInstance()
sChr = Character.getInstance()
charID = self.charSelection.getActiveCharacter()
sChr.revertCharacter(charID)
wx.PostEvent(self, GE.CharListUpdated())
@@ -637,7 +660,7 @@ class MainFrame(wx.Frame):
def CTabPrev(self, event):
self.fitMultiSwitch.PrevPage()
def HAddPage(self,event):
def HAddPage(self, event):
self.fitMultiSwitch.AddPage()
def toggleShipMarket(self, event):
@@ -652,35 +675,36 @@ class MainFrame(wx.Frame):
self.marketBrowser.search.Focus()
def clipboardEft(self):
sFit = service.Fit.getInstance()
toClipboard(sFit.exportFit(self.getActiveFit()))
fit = db.getFit(self.getActiveFit())
toClipboard(Port.exportEft(fit))
def clipboardEftImps(self):
sFit = service.Fit.getInstance()
toClipboard(sFit.exportEftImps(self.getActiveFit()))
fit = db.getFit(self.getActiveFit())
toClipboard(Port.exportEftImps(fit))
def clipboardDna(self):
sFit = service.Fit.getInstance()
toClipboard(sFit.exportDna(self.getActiveFit()))
fit = db.getFit(self.getActiveFit())
toClipboard(Port.exportDna(fit))
def clipboardCrest(self):
sFit = service.Fit.getInstance()
toClipboard(sFit.exportCrest(self.getActiveFit()))
fit = db.getFit(self.getActiveFit())
toClipboard(Port.exportCrest(fit))
def clipboardXml(self):
sFit = service.Fit.getInstance()
toClipboard(sFit.exportXml(None, self.getActiveFit()))
fitIDs = self.getActiveFit()
fits = map(lambda fitID: db.getFit(fitID), fitIDs)
toClipboard(Port.exportXml(None, *fits))
def clipboardMultiBuy(self):
sFit = service.Fit.getInstance()
toClipboard(sFit.exportMultiBuy(self.getActiveFit()))
fit = db.getFit(self.getActiveFit())
toClipboard(Port.exportMultiBuy(fit))
def importFromClipboard(self, event):
sFit = service.Fit.getInstance()
clipboard = fromClipboard()
try:
fits = sFit.importFitFromBuffer(fromClipboard(), self.getActiveFit())
fits = Port().importFitFromBuffer(clipboard, self.getActiveFit())
except:
pass
logger.error("Attempt to import failed:\n%s", clipboard)
else:
self._openAfterImport(fits)
@@ -697,17 +721,19 @@ class MainFrame(wx.Frame):
CopySelectDict[selected]()
dlg.Destroy()
def exportSkillsNeeded(self, event):
""" Exports skills needed for active fit and active character """
sCharacter = service.Character.getInstance()
saveDialog = wx.FileDialog(self, "Export Skills Needed As...",
wildcard = "EVEMon skills training file (*.emp)|*.emp|" \
"EVEMon skills training XML file (*.xml)|*.xml|" \
"Text skills training file (*.txt)|*.txt",
style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
sCharacter = Character.getInstance()
saveDialog = wx.FileDialog(
self,
"Export Skills Needed As...",
wildcard=("EVEMon skills training file (*.emp)|*.emp|"
"EVEMon skills training XML file (*.xml)|*.xml|"
"Text skills training file (*.txt)|*.txt"),
style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT,
)
if saveDialog.ShowModal() == wx.ID_OK:
saveFmtInt = saveDialog.GetFilterIndex()
@@ -730,17 +756,22 @@ class MainFrame(wx.Frame):
def fileImportDialog(self, event):
"""Handles importing single/multiple EVE XML / EFT cfg fit files"""
sFit = service.Fit.getInstance()
dlg = wx.FileDialog(self, "Open One Or More Fitting Files",
wildcard = "EVE XML fitting files (*.xml)|*.xml|" \
"EFT text fitting files (*.cfg)|*.cfg|" \
"All Files (*)|*",
style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE)
sFit = Fit.getInstance()
dlg = wx.FileDialog(
self,
"Open One Or More Fitting Files",
wildcard=("EVE XML fitting files (*.xml)|*.xml|"
"EFT text fitting files (*.cfg)|*.cfg|"
"All Files (*)|*"),
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE
)
if (dlg.ShowModal() == wx.ID_OK):
self.progressDialog = wx.ProgressDialog(
"Importing fits",
" "*100, # set some arbitrary spacing to create width in window
parent=self, style = wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME)
"Importing fits",
" " * 100, # set some arbitrary spacing to create width in window
parent=self,
style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME
)
self.progressDialog.message = None
sFit.importFitsThreaded(dlg.GetPaths(), self.fileImportCallback)
self.progressDialog.ShowModal()
@@ -748,48 +779,59 @@ class MainFrame(wx.Frame):
def backupToXml(self, event):
""" Back up all fits to EVE XML file """
defaultFile = "pyfa-fits-%s.xml"%strftime("%Y%m%d_%H%M%S", gmtime())
defaultFile = "pyfa-fits-%s.xml" % strftime("%Y%m%d_%H%M%S", gmtime())
saveDialog = wx.FileDialog(self, "Save Backup As...",
wildcard = "EVE XML fitting file (*.xml)|*.xml",
style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT,
defaultFile=defaultFile)
saveDialog = wx.FileDialog(
self,
"Save Backup As...",
wildcard="EVE XML fitting file (*.xml)|*.xml",
style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT,
defaultFile=defaultFile,
)
if saveDialog.ShowModal() == wx.ID_OK:
filePath = saveDialog.GetPath()
if '.' not in os.path.basename(filePath):
filePath += ".xml"
sFit = service.Fit.getInstance()
max = sFit.countAllFits()
sFit = Fit.getInstance()
max_ = sFit.countAllFits()
self.progressDialog = wx.ProgressDialog("Backup fits",
"Backing up %d fits to: %s"%(max, filePath),
maximum=max, parent=self,
style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME)
sFit.backupFits(filePath, self.backupCallback)
self.progressDialog = wx.ProgressDialog(
"Backup fits",
"Backing up %d fits to: %s" % (max_, filePath),
maximum=max_,
parent=self,
style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME,
)
Port().backupFits(filePath, self.backupCallback)
self.progressDialog.ShowModal()
def exportHtml(self, event):
from gui.utils.exportHtml import exportHtml
sFit = service.Fit.getInstance()
settings = service.settings.HTMLExportSettings.getInstance()
sFit = Fit.getInstance()
settings = HTMLExportSettings.getInstance()
max = sFit.countAllFits()
max_ = sFit.countAllFits()
path = settings.getPath()
if not os.path.isdir(os.path.dirname(path)):
dlg = wx.MessageDialog(self,
"Invalid Path\n\nThe following path is invalid or does not exist: \n%s\n\nPlease verify path location pyfa's preferences."%path,
"Error", wx.OK | wx.ICON_ERROR)
dlg = wx.MessageDialog(
self,
"Invalid Path\n\nThe following path is invalid or does not exist: \n%s\n\nPlease verify path location pyfa's preferences." % path,
"Error",
wx.OK | wx.ICON_ERROR
)
if dlg.ShowModal() == wx.ID_OK:
return
self.progressDialog = wx.ProgressDialog("Backup fits",
"Generating HTML file at: %s"%path,
maximum=max, parent=self,
style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME)
self.progressDialog = wx.ProgressDialog(
"Backup fits",
"Generating HTML file at: %s" % path,
maximum=max_, parent=self,
style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME
)
exportHtml.getInstance().refreshFittingHtml(True, self.backupCallback)
self.progressDialog.ShowModal()
@@ -826,7 +868,7 @@ class MainFrame(wx.Frame):
self._openAfterImport(data)
elif action == -2:
dlg = wx.MessageDialog(self,
"The following error was generated\n\n%s\n\nBe aware that already processed fits were not saved"%data,
"The following error was generated\n\n%s\n\nBe aware that already processed fits were not saved" % data,
"Import Error", wx.OK | wx.ICON_ERROR)
if dlg.ShowModal() == wx.ID_OK:
return
@@ -851,14 +893,16 @@ class MainFrame(wx.Frame):
def importCharacter(self, event):
""" Imports character XML file from EVE API """
dlg = wx.FileDialog(self, "Open One Or More Character Files",
wildcard="EVE API XML character files (*.xml)|*.xml|" \
"All Files (*)|*",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE)
dlg = wx.FileDialog(
self,
"Open One Or More Character Files",
wildcard="EVE API XML character files (*.xml)|*.xml|All Files (*)|*",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE
)
if dlg.ShowModal() == wx.ID_OK:
self.waitDialog = wx.BusyInfo("Importing Character...")
sCharacter = service.Character.getInstance()
sCharacter = Character.getInstance()
sCharacter.importCharacter(dlg.GetPaths(), self.importCharacterCallback)
def importCharacterCallback(self):
@@ -871,7 +915,8 @@ class MainFrame(wx.Frame):
def openGraphFrame(self, event):
if not self.graphFrame:
self.graphFrame = GraphFrame(self)
if gui.graphFrame.enabled:
if graphFrame.enabled:
self.graphFrame.Show()
else:
self.graphFrame.SetFocus()
@@ -887,4 +932,3 @@ class MainFrame(wx.Frame):
if not wnd:
wnd = self
InspectionTool().Show(wnd, True)

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,19 +15,22 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import config
from gui.bitmapLoader import BitmapLoader
from service.crest import Crest
from service.character import Character
import gui.mainFrame
import gui.graphFrame
import gui.globalEvents as GE
import service
from gui.bitmapLoader import BitmapLoader
if not 'wxMac' in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3,0)):
if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0)):
from service.crest import CrestModes
class MainMenuBar(wx.MenuBar):
def __init__(self):
self.characterEditorId = wx.NewId()
@@ -51,7 +54,7 @@ class MainMenuBar(wx.MenuBar):
self.toggleOverridesId = wx.NewId()
self.importDatabaseDefaultsId = wx.NewId()
if 'wxMac' in wx.PlatformInfo and wx.VERSION >= (3,0):
if 'wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0):
wx.ID_COPY = wx.NewId()
wx.ID_PASTE = wx.NewId()
@@ -80,8 +83,8 @@ class MainMenuBar(wx.MenuBar):
editMenu = wx.Menu()
self.Append(editMenu, "&Edit")
#editMenu.Append(wx.ID_UNDO)
#editMenu.Append(wx.ID_REDO)
# editMenu.Append(wx.ID_UNDO)
# editMenu.Append(wx.ID_REDO)
editMenu.Append(wx.ID_COPY, "To Clipboard\tCTRL+C", "Export a fit to the clipboard")
editMenu.Append(wx.ID_PASTE, "From Clipboard\tCTRL+V", "Import a fit from the clipboard")
@@ -115,12 +118,12 @@ class MainMenuBar(wx.MenuBar):
windowMenu.AppendItem(graphFrameItem)
preferencesShortCut = "CTRL+," if 'wxMac' in wx.PlatformInfo else "CTRL+P"
preferencesItem = wx.MenuItem(windowMenu, wx.ID_PREFERENCES, "Preferences\t"+preferencesShortCut)
preferencesItem = wx.MenuItem(windowMenu, wx.ID_PREFERENCES, "Preferences\t" + preferencesShortCut)
preferencesItem.SetBitmap(BitmapLoader.getBitmap("preferences_small", "gui"))
windowMenu.AppendItem(preferencesItem)
if not 'wxMac' in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3,0)):
self.sCrest = service.Crest.getInstance()
if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0)):
self.sCrest = Crest.getInstance()
# CREST Menu
crestMenu = wx.Menu()
@@ -154,7 +157,8 @@ class MainMenuBar(wx.MenuBar):
helpMenu.Append(wx.ID_ABOUT)
if config.debug:
helpMenu.Append( self.mainFrame.widgetInspectMenuID, "Open Widgets Inspect tool", "Open Widgets Inspect tool")
helpMenu.Append(self.mainFrame.widgetInspectMenuID, "Open Widgets Inspect tool",
"Open Widgets Inspect tool")
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
@@ -164,7 +168,7 @@ class MainMenuBar(wx.MenuBar):
self.Enable(wx.ID_COPY, enable)
self.Enable(self.exportSkillsNeededId, enable)
sChar = service.Character.getInstance()
sChar = Character.getInstance()
charID = self.mainFrame.charSelection.getActiveCharacter()
char = sChar.getCharacter(charID)
@@ -174,5 +178,3 @@ class MainMenuBar(wx.MenuBar):
self.Enable(self.revertCharId, char.isDirty)
event.Skip()

View File

@@ -1,456 +1,458 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
import wx
import service
import gui.display as d
from gui.cachingImageList import CachingImageList
from gui.contextMenu import ContextMenu
import gui.PFSearchBox as SBox
from gui.bitmapLoader import BitmapLoader
ItemSelected, ITEM_SELECTED = wx.lib.newevent.NewEvent()
RECENTLY_USED_MODULES = -2
MAX_RECENTLY_USED_MODULES = 20
class MetaButton(wx.ToggleButton):
def __init__(self, *args, **kwargs):
super(MetaButton, self).__init__(*args, **kwargs)
self.setUserSelection(True)
def setUserSelection(self, isSelected):
self.userSelected = isSelected
self.SetValue(isSelected)
def setMetaAvailable(self, isAvailable):
self.Enable(isAvailable)
# need to also SetValue(False) for windows because Enabled=False AND SetValue(True) looks enabled.
if not isAvailable:
self.SetValue(False)
def reset(self):
self.Enable(True)
self.SetValue(self.userSelected)
class MarketBrowser(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
vbox = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(vbox)
# Add a search box on top
self.search = SearchBox(self)
vbox.Add(self.search, 0, wx.EXPAND)
self.splitter = wx.SplitterWindow(self, style = wx.SP_LIVE_UPDATE)
vbox.Add(self.splitter, 1, wx.EXPAND)
# Grab market service instance and create child objects
self.sMkt = service.Market.getInstance()
self.searchMode = False
self.marketView = MarketTree(self.splitter, self)
self.itemView = ItemView(self.splitter, self)
self.splitter.SplitHorizontally(self.marketView, self.itemView)
self.splitter.SetMinimumPaneSize(250)
# Setup our buttons for metaGroup selection
# Same fix as for search box on macs,
# need some pixels of extra space or everything clips and is ugly
p = wx.Panel(self)
box = wx.BoxSizer(wx.HORIZONTAL)
p.SetSizer(box)
vbox.Add(p, 0, wx.EXPAND)
self.metaButtons = []
for name in self.sMkt.META_MAP.keys():
btn = MetaButton(p, wx.ID_ANY, name.capitalize(), style=wx.BU_EXACTFIT)
setattr(self, name, btn)
box.Add(btn, 1, wx.ALIGN_CENTER)
btn.Bind(wx.EVT_TOGGLEBUTTON, self.toggleMetaButton)
btn.metaName = name
self.metaButtons.append(btn)
# Make itemview to set toggles according to list contents
self.itemView.setToggles()
p.SetMinSize((wx.SIZE_AUTO_WIDTH, btn.GetSize()[1] + 5))
def toggleMetaButton(self, event):
"""Process clicks on toggle buttons"""
appendMeta = wx.GetMouseState().CmdDown()
clickedBtn = event.EventObject
if appendMeta:
activeBtns = [btn for btn in self.metaButtons if btn.GetValue()]
if activeBtns:
clickedBtn.setUserSelection(clickedBtn.GetValue())
self.itemView.filterItemStore()
else:
# Do 'nothing' if we're trying to turn last active button off
# Keep button in the same state
clickedBtn.setUserSelection(True)
else:
for btn in self.metaButtons:
btn.setUserSelection(btn == clickedBtn)
self.itemView.filterItemStore()
def jump(self, item):
self.marketView.jump(item)
class SearchBox(SBox.PFSearchBox):
def __init__(self, parent, **kwargs):
SBox.PFSearchBox.__init__(self, parent, **kwargs)
cancelBitmap = BitmapLoader.getBitmap("fit_delete_small","gui")
searchBitmap = BitmapLoader.getBitmap("fsearch_small","gui")
self.SetSearchBitmap(searchBitmap)
self.SetCancelBitmap(cancelBitmap)
self.ShowSearchButton()
self.ShowCancelButton()
class MarketTree(wx.TreeCtrl):
def __init__(self, parent, marketBrowser):
wx.TreeCtrl.__init__(self, parent, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT)
self.root = self.AddRoot("root")
self.imageList = CachingImageList(16, 16)
self.SetImageList(self.imageList)
self.sMkt = marketBrowser.sMkt
self.marketBrowser = marketBrowser
# Form market tree root
sMkt = self.sMkt
for mktGrp in sMkt.getMarketRoot():
iconId = self.addImage(sMkt.getIconByMarketGroup(mktGrp))
childId = self.AppendItem(self.root, mktGrp.name, iconId, data=wx.TreeItemData(mktGrp.ID))
# All market groups which were never expanded are dummies, here we assume
# that all root market groups are expandable
self.AppendItem(childId, "dummy")
self.SortChildren(self.root)
# Add recently used modules node
rumIconId = self.addImage("market_small", "gui")
self.AppendItem(self.root, "Recently Used Modules", rumIconId, data = wx.TreeItemData(RECENTLY_USED_MODULES))
# Bind our lookup method to when the tree gets expanded
self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.expandLookup)
def addImage(self, iconFile, location="icons"):
if iconFile is None:
return -1
return self.imageList.GetImageIndex(iconFile, location)
def expandLookup(self, event):
"""Process market tree expands"""
root = event.Item
child = self.GetFirstChild(root)[0]
# If child of given market group is a dummy
if self.GetItemText(child) == "dummy":
# Delete it
self.Delete(child)
# And add real market group contents
sMkt = self.sMkt
currentMktGrp = sMkt.getMarketGroup(self.GetPyData(root), eager="children")
for childMktGrp in sMkt.getMarketGroupChildren(currentMktGrp):
# If market should have items but it doesn't, do not show it
if sMkt.marketGroupValidityCheck(childMktGrp) is False:
continue
iconId = self.addImage(sMkt.getIconByMarketGroup(childMktGrp))
try:
childId = self.AppendItem(root, childMktGrp.name, iconId, data=wx.TreeItemData(childMktGrp.ID))
except:
continue
if sMkt.marketGroupHasTypesCheck(childMktGrp) is False:
self.AppendItem(childId, "dummy")
self.SortChildren(root)
def jump(self, item):
"""Open market group and meta tab of given item"""
self.marketBrowser.searchMode = False
sMkt = self.sMkt
mg = sMkt.getMarketGroupByItem(item)
jumpList = []
while mg is not None:
jumpList.append(mg.ID)
mg = mg.parent
for id in sMkt.ROOT_MARKET_GROUPS:
if id in jumpList:
jumpList = jumpList[:jumpList.index(id)+1]
item = self.root
for i in range(len(jumpList) -1, -1, -1):
target = jumpList[i]
child, cookie = self.GetFirstChild(item)
while self.GetItemPyData(child) != target:
child, cookie = self.GetNextChild(item, cookie)
item = child
self.Expand(item)
self.SelectItem(item)
self.marketBrowser.itemView.selectionMade()
class ItemView(d.Display):
DEFAULT_COLS = ["Base Icon",
"Base Name",
"attr:power,,,True",
"attr:cpu,,,True"]
def __init__(self, parent, marketBrowser):
d.Display.__init__(self, parent)
marketBrowser.Bind(wx.EVT_TREE_SEL_CHANGED, self.selectionMade)
self.unfilteredStore = set()
self.filteredStore = set()
self.recentlyUsedModules = set()
self.sMkt = marketBrowser.sMkt
self.searchMode = marketBrowser.searchMode
self.marketBrowser = marketBrowser
self.marketView = marketBrowser.marketView
# Make sure our search actually does interesting stuff
self.marketBrowser.search.Bind(SBox.EVT_TEXT_ENTER, self.scheduleSearch)
self.marketBrowser.search.Bind(SBox.EVT_SEARCH_BTN, self.scheduleSearch)
self.marketBrowser.search.Bind(SBox.EVT_CANCEL_BTN, self.clearSearch)
self.marketBrowser.search.Bind(SBox.EVT_TEXT, self.scheduleSearch)
# Make sure WE do interesting stuff too
self.Bind(wx.EVT_CONTEXT_MENU, self.contextMenu)
self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.itemActivated)
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.startDrag)
# Make reverse map, used by sorter
self.metaMap = self.makeReverseMetaMap()
# Fill up recently used modules set
for itemID in self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"]:
self.recentlyUsedModules.add(self.sMkt.getItem(itemID))
def startDrag(self, event):
row = self.GetFirstSelected()
if row != -1:
data = wx.PyTextDataObject()
data.SetText("market:"+str(self.active[row].ID))
dropSource = wx.DropSource(self)
dropSource.SetData(data)
res = dropSource.DoDragDrop()
def itemActivated(self, event=None):
# Check if something is selected, if so, spawn the menu for it
sel = self.GetFirstSelected()
if sel == -1:
return
if self.mainFrame.getActiveFit():
self.storeRecentlyUsedMarketItem(self.active[sel].ID)
self.recentlyUsedModules = set()
for itemID in self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"]:
self.recentlyUsedModules.add(self.sMkt.getItem(itemID))
wx.PostEvent(self.mainFrame, ItemSelected(itemID=self.active[sel].ID))
def storeRecentlyUsedMarketItem(self, itemID):
if len(self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"]) > MAX_RECENTLY_USED_MODULES:
self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"].pop(0)
self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"].append(itemID)
def selectionMade(self, event=None):
self.marketBrowser.searchMode = False
# Grab the threeview selection and check if it's fine
sel = self.marketView.GetSelection()
if sel.IsOk():
# Get data field of the selected item (which is a marketGroup ID if anything was selected)
seldata = self.marketView.GetPyData(sel)
if seldata is not None and seldata != RECENTLY_USED_MODULES:
# If market group treeview item doesn't have children (other market groups or dummies),
# then it should have items in it and we want to request them
if self.marketView.ItemHasChildren(sel) is False:
sMkt = self.sMkt
# Get current market group
mg = sMkt.getMarketGroup(seldata, eager=("items", "items.metaGroup"))
# Get all its items
items = sMkt.getItemsByMarketGroup(mg)
else:
items = set()
else:
# If method was called but selection wasn't actually made or we have a hit on recently used modules
if seldata == RECENTLY_USED_MODULES:
items = self.recentlyUsedModules
else:
items = set()
# Fill store
self.updateItemStore(items)
# Set toggle buttons / use search mode flag if recently used modules category is selected (in order to have all modules listed and not filtered)
if seldata is not RECENTLY_USED_MODULES:
self.setToggles()
else:
self.marketBrowser.searchMode = True
self.setToggles()
# Update filtered items
self.filterItemStore()
def updateItemStore(self, items):
self.unfilteredStore = items
def filterItemStore(self):
sMkt = self.sMkt
selectedMetas = set()
for btn in self.marketBrowser.metaButtons:
if btn.GetValue():
selectedMetas.update(sMkt.META_MAP[btn.metaName])
self.filteredStore = sMkt.filterItemsByMeta(self.unfilteredStore, selectedMetas)
self.update(list(self.filteredStore))
def setToggles(self):
metaIDs = set()
sMkt = self.sMkt
for item in self.unfilteredStore:
metaIDs.add(sMkt.getMetaGroupIdByItem(item))
for btn in self.marketBrowser.metaButtons:
btn.reset()
btnMetas = sMkt.META_MAP[btn.metaName]
if len(metaIDs.intersection(btnMetas)) > 0:
btn.setMetaAvailable(True)
else:
btn.setMetaAvailable(False)
def scheduleSearch(self, event=None):
search = self.marketBrowser.search.GetLineText(0)
# Make sure we do not count wildcard as search symbol
realsearch = search.replace("*", "")
# Re-select market group if search query has zero length
if len(realsearch) == 0:
self.selectionMade()
return
# Show nothing if query is too short
elif len(realsearch) < 3:
self.clearSearch()
return
self.marketBrowser.searchMode = True
self.sMkt.searchItems(search, self.populateSearch)
def clearSearch(self, event=None):
# Wipe item store and update everything to accomodate with it
# If clearSearch was generated by SearchCtrl's Cancel button, clear the content also
if event:
self.marketBrowser.search.Clear()
self.marketBrowser.searchMode = False
self.updateItemStore(set())
self.setToggles()
self.filterItemStore()
def populateSearch(self, items):
# If we're no longer searching, dump the results
if self.marketBrowser.searchMode is False:
return
self.updateItemStore(items)
self.setToggles()
self.filterItemStore()
def itemSort(self, item):
sMkt = self.sMkt
catname = sMkt.getCategoryByItem(item).name
try:
mktgrpid = sMkt.getMarketGroupByItem(item).ID
except AttributeError:
mktgrpid = None
print "unable to find market group for", item.name
parentname = sMkt.getParentItemByItem(item).name
# Get position of market group
metagrpid = sMkt.getMetaGroupIdByItem(item)
metatab = self.metaMap.get(metagrpid)
metalvl = self.metalvls.get(item.ID, 0)
return (catname, mktgrpid, parentname, metatab, metalvl, item.name)
def contextMenu(self, event):
# Check if something is selected, if so, spawn the menu for it
sel = self.GetFirstSelected()
if sel == -1:
return
item = self.active[sel]
sMkt = self.sMkt
sourceContext = "marketItemGroup" if self.marketBrowser.searchMode is False else "marketItemMisc"
itemContext = sMkt.getCategoryByItem(item).name
menu = ContextMenu.getMenu((item,), (sourceContext, itemContext))
self.PopupMenu(menu)
def populate(self, items):
if len(items) > 0:
# Get dictionary with meta level attribute
sAttr = service.Attribute.getInstance()
attrs = sAttr.getAttributeInfo("metaLevel")
sMkt = self.sMkt
self.metalvls = sMkt.directAttrRequest(items, attrs)
# Clear selection
self.deselectItems()
# Perform sorting, using item's meta levels besides other stuff
items.sort(key=self.itemSort)
# Mark current item list as active
self.active = items
# Show them
d.Display.populate(self, items)
def refresh(self, items):
if len(items) > 1:
# Get dictionary with meta level attribute
sAttr = service.Attribute.getInstance()
attrs = sAttr.getAttributeInfo("metaLevel")
sMkt = self.sMkt
self.metalvls = sMkt.directAttrRequest(items, attrs)
# Re-sort stuff
items.sort(key=self.itemSort)
for i, item in enumerate(items[:9]):
# set shortcut info for first 9 modules
item.marketShortcut = i+1
d.Display.refresh(self, items)
def makeReverseMetaMap(self):
"""
Form map which tells in which tab items of given metagroup are located
"""
revmap = {}
i = 0
for mgids in self.sMkt.META_MAP.itervalues():
for mgid in mgids:
revmap[mgid] = i
i += 1
return revmap
# =============================================================================
# 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 <http://www.gnu.org/licenses/>.
# =============================================================================
import wx
from service.market import Market
from service.attribute import Attribute
import gui.display as d
import gui.PFSearchBox as SBox
from gui.cachingImageList import CachingImageList
from gui.contextMenu import ContextMenu
from gui.bitmapLoader import BitmapLoader
ItemSelected, ITEM_SELECTED = wx.lib.newevent.NewEvent()
RECENTLY_USED_MODULES = -2
MAX_RECENTLY_USED_MODULES = 20
class MetaButton(wx.ToggleButton):
def __init__(self, *args, **kwargs):
super(MetaButton, self).__init__(*args, **kwargs)
self.setUserSelection(True)
def setUserSelection(self, isSelected):
self.userSelected = isSelected
self.SetValue(isSelected)
def setMetaAvailable(self, isAvailable):
self.Enable(isAvailable)
# need to also SetValue(False) for windows because Enabled=False AND SetValue(True) looks enabled.
if not isAvailable:
self.SetValue(False)
def reset(self):
self.Enable(True)
self.SetValue(self.userSelected)
class MarketBrowser(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
vbox = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(vbox)
# Add a search box on top
self.search = SearchBox(self)
vbox.Add(self.search, 0, wx.EXPAND)
self.splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE)
vbox.Add(self.splitter, 1, wx.EXPAND)
# Grab market service instance and create child objects
self.sMkt = Market.getInstance()
self.searchMode = False
self.marketView = MarketTree(self.splitter, self)
self.itemView = ItemView(self.splitter, self)
self.splitter.SplitHorizontally(self.marketView, self.itemView)
self.splitter.SetMinimumPaneSize(250)
# Setup our buttons for metaGroup selection
# Same fix as for search box on macs,
# need some pixels of extra space or everything clips and is ugly
p = wx.Panel(self)
box = wx.BoxSizer(wx.HORIZONTAL)
p.SetSizer(box)
vbox.Add(p, 0, wx.EXPAND)
self.metaButtons = []
for name in self.sMkt.META_MAP.keys():
btn = MetaButton(p, wx.ID_ANY, name.capitalize(), style=wx.BU_EXACTFIT)
setattr(self, name, btn)
box.Add(btn, 1, wx.ALIGN_CENTER)
btn.Bind(wx.EVT_TOGGLEBUTTON, self.toggleMetaButton)
btn.metaName = name
self.metaButtons.append(btn)
# Make itemview to set toggles according to list contents
self.itemView.setToggles()
p.SetMinSize((wx.SIZE_AUTO_WIDTH, btn.GetSize()[1] + 5))
def toggleMetaButton(self, event):
"""Process clicks on toggle buttons"""
appendMeta = wx.GetMouseState().CmdDown()
clickedBtn = event.EventObject
if appendMeta:
activeBtns = [btn for btn in self.metaButtons if btn.GetValue()]
if activeBtns:
clickedBtn.setUserSelection(clickedBtn.GetValue())
self.itemView.filterItemStore()
else:
# Do 'nothing' if we're trying to turn last active button off
# Keep button in the same state
clickedBtn.setUserSelection(True)
else:
for btn in self.metaButtons:
btn.setUserSelection(btn == clickedBtn)
self.itemView.filterItemStore()
def jump(self, item):
self.marketView.jump(item)
class SearchBox(SBox.PFSearchBox):
def __init__(self, parent, **kwargs):
SBox.PFSearchBox.__init__(self, parent, **kwargs)
cancelBitmap = BitmapLoader.getBitmap("fit_delete_small", "gui")
searchBitmap = BitmapLoader.getBitmap("fsearch_small", "gui")
self.SetSearchBitmap(searchBitmap)
self.SetCancelBitmap(cancelBitmap)
self.ShowSearchButton()
self.ShowCancelButton()
class MarketTree(wx.TreeCtrl):
def __init__(self, parent, marketBrowser):
wx.TreeCtrl.__init__(self, parent, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT)
self.root = self.AddRoot("root")
self.imageList = CachingImageList(16, 16)
self.SetImageList(self.imageList)
self.sMkt = marketBrowser.sMkt
self.marketBrowser = marketBrowser
# Form market tree root
sMkt = self.sMkt
for mktGrp in sMkt.getMarketRoot():
iconId = self.addImage(sMkt.getIconByMarketGroup(mktGrp))
childId = self.AppendItem(self.root, mktGrp.name, iconId, data=wx.TreeItemData(mktGrp.ID))
# All market groups which were never expanded are dummies, here we assume
# that all root market groups are expandable
self.AppendItem(childId, "dummy")
self.SortChildren(self.root)
# Add recently used modules node
rumIconId = self.addImage("market_small", "gui")
self.AppendItem(self.root, "Recently Used Modules", rumIconId, data=wx.TreeItemData(RECENTLY_USED_MODULES))
# Bind our lookup method to when the tree gets expanded
self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.expandLookup)
def addImage(self, iconFile, location="icons"):
if iconFile is None:
return -1
return self.imageList.GetImageIndex(iconFile, location)
def expandLookup(self, event):
"""Process market tree expands"""
root = event.Item
child = self.GetFirstChild(root)[0]
# If child of given market group is a dummy
if self.GetItemText(child) == "dummy":
# Delete it
self.Delete(child)
# And add real market group contents
sMkt = self.sMkt
currentMktGrp = sMkt.getMarketGroup(self.GetPyData(root), eager="children")
for childMktGrp in sMkt.getMarketGroupChildren(currentMktGrp):
# If market should have items but it doesn't, do not show it
if sMkt.marketGroupValidityCheck(childMktGrp) is False:
continue
iconId = self.addImage(sMkt.getIconByMarketGroup(childMktGrp))
try:
childId = self.AppendItem(root, childMktGrp.name, iconId, data=wx.TreeItemData(childMktGrp.ID))
except:
continue
if sMkt.marketGroupHasTypesCheck(childMktGrp) is False:
self.AppendItem(childId, "dummy")
self.SortChildren(root)
def jump(self, item):
"""Open market group and meta tab of given item"""
self.marketBrowser.searchMode = False
sMkt = self.sMkt
mg = sMkt.getMarketGroupByItem(item)
jumpList = []
while mg is not None:
jumpList.append(mg.ID)
mg = mg.parent
for id in sMkt.ROOT_MARKET_GROUPS:
if id in jumpList:
jumpList = jumpList[:jumpList.index(id) + 1]
item = self.root
for i in range(len(jumpList) - 1, -1, -1):
target = jumpList[i]
child, cookie = self.GetFirstChild(item)
while self.GetItemPyData(child) != target:
child, cookie = self.GetNextChild(item, cookie)
item = child
self.Expand(item)
self.SelectItem(item)
self.marketBrowser.itemView.selectionMade()
class ItemView(d.Display):
DEFAULT_COLS = ["Base Icon",
"Base Name",
"attr:power,,,True",
"attr:cpu,,,True"]
def __init__(self, parent, marketBrowser):
d.Display.__init__(self, parent)
marketBrowser.Bind(wx.EVT_TREE_SEL_CHANGED, self.selectionMade)
self.unfilteredStore = set()
self.filteredStore = set()
self.recentlyUsedModules = set()
self.sMkt = marketBrowser.sMkt
self.searchMode = marketBrowser.searchMode
self.marketBrowser = marketBrowser
self.marketView = marketBrowser.marketView
# Make sure our search actually does interesting stuff
self.marketBrowser.search.Bind(SBox.EVT_TEXT_ENTER, self.scheduleSearch)
self.marketBrowser.search.Bind(SBox.EVT_SEARCH_BTN, self.scheduleSearch)
self.marketBrowser.search.Bind(SBox.EVT_CANCEL_BTN, self.clearSearch)
self.marketBrowser.search.Bind(SBox.EVT_TEXT, self.scheduleSearch)
# Make sure WE do interesting stuff too
self.Bind(wx.EVT_CONTEXT_MENU, self.contextMenu)
self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.itemActivated)
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.startDrag)
# Make reverse map, used by sorter
self.metaMap = self.makeReverseMetaMap()
# Fill up recently used modules set
for itemID in self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"]:
self.recentlyUsedModules.add(self.sMkt.getItem(itemID))
def startDrag(self, event):
row = self.GetFirstSelected()
if row != -1:
data = wx.PyTextDataObject()
data.SetText("market:" + str(self.active[row].ID))
dropSource = wx.DropSource(self)
dropSource.SetData(data)
dropSource.DoDragDrop()
def itemActivated(self, event=None):
# Check if something is selected, if so, spawn the menu for it
sel = self.GetFirstSelected()
if sel == -1:
return
if self.mainFrame.getActiveFit():
self.storeRecentlyUsedMarketItem(self.active[sel].ID)
self.recentlyUsedModules = set()
for itemID in self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"]:
self.recentlyUsedModules.add(self.sMkt.getItem(itemID))
wx.PostEvent(self.mainFrame, ItemSelected(itemID=self.active[sel].ID))
def storeRecentlyUsedMarketItem(self, itemID):
if len(self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"]) > MAX_RECENTLY_USED_MODULES:
self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"].pop(0)
self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"].append(itemID)
def selectionMade(self, event=None):
self.marketBrowser.searchMode = False
# Grab the threeview selection and check if it's fine
sel = self.marketView.GetSelection()
if sel.IsOk():
# Get data field of the selected item (which is a marketGroup ID if anything was selected)
seldata = self.marketView.GetPyData(sel)
if seldata is not None and seldata != RECENTLY_USED_MODULES:
# If market group treeview item doesn't have children (other market groups or dummies),
# then it should have items in it and we want to request them
if self.marketView.ItemHasChildren(sel) is False:
sMkt = self.sMkt
# Get current market group
mg = sMkt.getMarketGroup(seldata, eager=("items", "items.metaGroup"))
# Get all its items
items = sMkt.getItemsByMarketGroup(mg)
else:
items = set()
else:
# If method was called but selection wasn't actually made or we have a hit on recently used modules
if seldata == RECENTLY_USED_MODULES:
items = self.recentlyUsedModules
else:
items = set()
# Fill store
self.updateItemStore(items)
# Set toggle buttons / use search mode flag if recently used modules category is selected (in order to have all modules listed and not filtered)
if seldata is not RECENTLY_USED_MODULES:
self.setToggles()
else:
self.marketBrowser.searchMode = True
self.setToggles()
# Update filtered items
self.filterItemStore()
def updateItemStore(self, items):
self.unfilteredStore = items
def filterItemStore(self):
sMkt = self.sMkt
selectedMetas = set()
for btn in self.marketBrowser.metaButtons:
if btn.GetValue():
selectedMetas.update(sMkt.META_MAP[btn.metaName])
self.filteredStore = sMkt.filterItemsByMeta(self.unfilteredStore, selectedMetas)
self.update(list(self.filteredStore))
def setToggles(self):
metaIDs = set()
sMkt = self.sMkt
for item in self.unfilteredStore:
metaIDs.add(sMkt.getMetaGroupIdByItem(item))
for btn in self.marketBrowser.metaButtons:
btn.reset()
btnMetas = sMkt.META_MAP[btn.metaName]
if len(metaIDs.intersection(btnMetas)) > 0:
btn.setMetaAvailable(True)
else:
btn.setMetaAvailable(False)
def scheduleSearch(self, event=None):
search = self.marketBrowser.search.GetLineText(0)
# Make sure we do not count wildcard as search symbol
realsearch = search.replace("*", "")
# Re-select market group if search query has zero length
if len(realsearch) == 0:
self.selectionMade()
return
# Show nothing if query is too short
elif len(realsearch) < 3:
self.clearSearch()
return
self.marketBrowser.searchMode = True
self.sMkt.searchItems(search, self.populateSearch)
def clearSearch(self, event=None):
# Wipe item store and update everything to accomodate with it
# If clearSearch was generated by SearchCtrl's Cancel button, clear the content also
if event:
self.marketBrowser.search.Clear()
self.marketBrowser.searchMode = False
self.updateItemStore(set())
self.setToggles()
self.filterItemStore()
def populateSearch(self, items):
# If we're no longer searching, dump the results
if self.marketBrowser.searchMode is False:
return
self.updateItemStore(items)
self.setToggles()
self.filterItemStore()
def itemSort(self, item):
sMkt = self.sMkt
catname = sMkt.getCategoryByItem(item).name
try:
mktgrpid = sMkt.getMarketGroupByItem(item).ID
except AttributeError:
mktgrpid = None
print("unable to find market group for", item.name)
parentname = sMkt.getParentItemByItem(item).name
# Get position of market group
metagrpid = sMkt.getMetaGroupIdByItem(item)
metatab = self.metaMap.get(metagrpid)
metalvl = self.metalvls.get(item.ID, 0)
return (catname, mktgrpid, parentname, metatab, metalvl, item.name)
def contextMenu(self, event):
# Check if something is selected, if so, spawn the menu for it
sel = self.GetFirstSelected()
if sel == -1:
return
item = self.active[sel]
sMkt = self.sMkt
sourceContext = "marketItemGroup" if self.marketBrowser.searchMode is False else "marketItemMisc"
itemContext = sMkt.getCategoryByItem(item).name
menu = ContextMenu.getMenu((item,), (sourceContext, itemContext))
self.PopupMenu(menu)
def populate(self, items):
if len(items) > 0:
# Get dictionary with meta level attribute
sAttr = Attribute.getInstance()
attrs = sAttr.getAttributeInfo("metaLevel")
sMkt = self.sMkt
self.metalvls = sMkt.directAttrRequest(items, attrs)
# Clear selection
self.deselectItems()
# Perform sorting, using item's meta levels besides other stuff
items.sort(key=self.itemSort)
# Mark current item list as active
self.active = items
# Show them
d.Display.populate(self, items)
def refresh(self, items):
if len(items) > 1:
# Get dictionary with meta level attribute
sAttr = Attribute.getInstance()
attrs = sAttr.getAttributeInfo("metaLevel")
sMkt = self.sMkt
self.metalvls = sMkt.directAttrRequest(items, attrs)
# Re-sort stuff
items.sort(key=self.itemSort)
for i, item in enumerate(items[:9]):
# set shortcut info for first 9 modules
item.marketShortcut = i + 1
d.Display.refresh(self, items)
def makeReverseMetaMap(self):
"""
Form map which tells in which tab items of given metagroup are located
"""
revmap = {}
i = 0
for mgids in self.sMkt.META_MAP.itervalues():
for mgid in mgids:
revmap[mgid] = i
i += 1
return revmap

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import gui.chromeTabs
import gui.builtinViews.emptyView
@@ -24,7 +24,7 @@ import gui.builtinViews.emptyView
class MultiSwitch(gui.chromeTabs.PFNotebook):
def __init__(self, parent):
gui.chromeTabs.PFNotebook.__init__(self, parent)
#self.AddPage() # now handled by mainFrame
# self.AddPage() # now handled by mainFrame
self.handlers = handlers = []
for type in TabSpawner.tabTypes:
handlers.append(type(self))

View File

@@ -1,9 +1,10 @@
import wx
import service
from service.fit import Fit
import gui.globalEvents as GE
import gui.mainFrame
class NotesView(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
@@ -19,7 +20,7 @@ class NotesView(wx.Panel):
self.Bind(wx.EVT_TIMER, self.delayedSave, self.saveTimer)
def fitChanged(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(event.fitID)
self.Parent.Parent.DisablePage(self, not fit or fit.isStructure)
@@ -34,11 +35,11 @@ class NotesView(wx.Panel):
def onText(self, event):
# delay the save so we're not writing to sqlite on every keystroke
self.saveTimer.Stop() # cancel the existing timer
self.saveTimer.Stop() # cancel the existing timer
self.saveTimer.Start(1000, True)
def delayedSave(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(self.lastFitId)
newNotes = self.editNotes.GetValue()
fit.notes = newNotes

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,18 +15,15 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from gui.bitmapLoader import BitmapLoader
import service
from wx.lib.intctrl import IntCtrl
from gui.utils.clipboard import toClipboard, fromClipboard
from service.damagePattern import ImportError
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator
###########################################################################
## Class DmgPatternEditorDlg
###########################################################################
from service.damagePattern import DamagePattern, ImportError
class DmgPatternTextValidor(BaseValidator):
def __init__(self):
@@ -47,7 +44,7 @@ class DmgPatternTextValidor(BaseValidator):
raise ValueError("Damage Profile name already in use, please choose another.")
return True
except ValueError, e:
except ValueError as e:
wx.MessageBox(u"{}".format(e), "Error")
textCtrl.SetFocus()
return False
@@ -59,33 +56,34 @@ class DmgPatternEntityEditor(EntityEditor):
self.SetEditorValidator(DmgPatternTextValidor)
def getEntitiesFromContext(self):
sDP = service.DamagePattern.getInstance()
sDP = DamagePattern.getInstance()
choices = sorted(sDP.getDamagePatternList(), key=lambda p: p.name)
return [c for c in choices if c.name != "Selected Ammo"]
def DoNew(self, name):
sDP = service.DamagePattern.getInstance()
sDP = DamagePattern.getInstance()
return sDP.newPattern(name)
def DoRename(self, entity, name):
sDP = service.DamagePattern.getInstance()
sDP = DamagePattern.getInstance()
sDP.renamePattern(entity, name)
def DoCopy(self, entity, name):
sDP = service.DamagePattern.getInstance()
sDP = DamagePattern.getInstance()
copy = sDP.copyPattern(entity)
sDP.renamePattern(copy, name)
return copy
def DoDelete(self, entity):
sDP = service.DamagePattern.getInstance()
sDP = DamagePattern.getInstance()
sDP.deletePattern(entity)
class DmgPatternEditorDlg(wx.Dialog):
DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive")
def __init__(self, parent):
wx.Dialog.__init__(self, parent, id = wx.ID_ANY, title = u"Damage Pattern Editor", size = wx.Size( 400,240 ))
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title=u"Damage Pattern Editor", size=wx.Size(400, 240))
self.block = False
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
@@ -111,11 +109,11 @@ class DmgPatternEditorDlg(wx.Dialog):
dmgeditSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
width = -1
defSize = wx.Size(width,-1)
defSize = wx.Size(width, -1)
for i, type in enumerate(self.DAMAGE_TYPES):
bmp = wx.StaticBitmap(self, wx.ID_ANY, BitmapLoader.getBitmap("%s_big"%type, "gui"))
if i%2:
for i, type_ in enumerate(self.DAMAGE_TYPES):
bmp = wx.StaticBitmap(self, wx.ID_ANY, BitmapLoader.getBitmap("%s_big" % type_, "gui"))
if i % 2:
style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT
border = 20
else:
@@ -123,13 +121,13 @@ class DmgPatternEditorDlg(wx.Dialog):
border = 5
# set text edit
setattr(self, "%sEdit"%type, IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize))
setattr(self, "%sPerc"%type, wx.StaticText(self, wx.ID_ANY, u"0%"))
editObj = getattr(self, "%sEdit"%type)
setattr(self, "%sEdit" % type_, IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize))
setattr(self, "%sPerc" % type_, wx.StaticText(self, wx.ID_ANY, u"0%"))
editObj = getattr(self, "%sEdit" % type_)
dmgeditSizer.Add(bmp, 0, style, border)
dmgeditSizer.Add(editObj, 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5)
dmgeditSizer.Add(getattr(self, "%sPerc"%type), 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5)
dmgeditSizer.Add(getattr(self, "%sPerc" % type_), 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5)
editObj.Bind(wx.EVT_TEXT, self.ValuesUpdated)
editObj.SetLimited(True)
@@ -147,7 +145,7 @@ class DmgPatternEditorDlg(wx.Dialog):
self.stNotice.Wrap(-1)
perSizer.Add(self.stNotice, 0, wx.BOTTOM | wx.TOP | wx.LEFT, 5)
footerSizer.Add(perSizer, 1, wx.ALIGN_CENTER_VERTICAL, 5)
footerSizer.Add(perSizer, 1, wx.ALIGN_CENTER_VERTICAL, 5)
self.totSizer = wx.BoxSizer(wx.VERTICAL)
@@ -156,8 +154,8 @@ class DmgPatternEditorDlg(wx.Dialog):
mainSizer.Add(contentSizer, 1, wx.EXPAND, 0)
if "wxGTK" in wx.PlatformInfo:
self.closeBtn = wx.Button( self, wx.ID_ANY, u"Close", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.closeBtn, 0, wx.ALL|wx.ALIGN_RIGHT, 5 )
self.closeBtn = wx.Button(self, wx.ID_ANY, u"Close", wx.DefaultPosition, wx.DefaultSize, 0)
mainSizer.Add(self.closeBtn, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
self.closeBtn.Bind(wx.EVT_BUTTON, self.closeEvent)
self.SetSizer(mainSizer)
@@ -166,18 +164,18 @@ class DmgPatternEditorDlg(wx.Dialog):
("Export", wx.ART_FILE_SAVE_AS, "to"))
for name, art, direction in importExport:
bitmap = wx.ArtProvider.GetBitmap(art, wx.ART_BUTTON)
btn = wx.BitmapButton(self, wx.ID_ANY, bitmap)
bitmap = wx.ArtProvider.GetBitmap(art, wx.ART_BUTTON)
btn = wx.BitmapButton(self, wx.ID_ANY, bitmap)
btn.SetMinSize( btn.GetSize() )
btn.SetMaxSize( btn.GetSize() )
btn.SetMinSize(btn.GetSize())
btn.SetMaxSize(btn.GetSize())
btn.Layout()
setattr(self, name, btn)
btn.Enable(True)
btn.SetToolTipString("%s patterns %s clipboard" % (name, direction) )
footerSizer.Add(btn, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_RIGHT)
btn.Bind(wx.EVT_BUTTON, getattr(self, "{}Patterns".format(name.lower())))
btn.Layout()
setattr(self, name, btn)
btn.Enable(True)
btn.SetToolTipString("%s patterns %s clipboard" % (name, direction))
footerSizer.Add(btn, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_RIGHT)
btn.Bind(wx.EVT_BUTTON, getattr(self, "{}Patterns".format(name.lower())))
self.Layout()
bsize = self.GetBestSize()
@@ -196,30 +194,30 @@ class DmgPatternEditorDlg(wx.Dialog):
return
p = self.entityEditor.getActiveEntity()
total = sum(map(lambda attr: getattr(self, "%sEdit"%attr).GetValue(), self.DAMAGE_TYPES))
for type in self.DAMAGE_TYPES:
editObj = getattr(self, "%sEdit"%type)
percObj = getattr(self, "%sPerc"%type)
setattr(p, "%sAmount"%type, editObj.GetValue())
percObj.SetLabel("%.1f%%"%(float(editObj.GetValue())*100/total if total > 0 else 0))
total = sum(map(lambda attr: getattr(self, "%sEdit" % attr).GetValue(), self.DAMAGE_TYPES))
for type_ in self.DAMAGE_TYPES:
editObj = getattr(self, "%sEdit" % type_)
percObj = getattr(self, "%sPerc" % type_)
setattr(p, "%sAmount" % type_, editObj.GetValue())
percObj.SetLabel("%.1f%%" % (float(editObj.GetValue()) * 100 / total if total > 0 else 0))
self.totSizer.Layout()
if event is not None:
event.Skip()
service.DamagePattern.getInstance().saveChanges(p)
DamagePattern.getInstance().saveChanges(p)
def restrict(self):
for type in self.DAMAGE_TYPES:
editObj = getattr(self, "%sEdit"%type)
for type_ in self.DAMAGE_TYPES:
editObj = getattr(self, "%sEdit" % type_)
editObj.Enable(False)
self.entityEditor.btnRename.Enable(False)
self.entityEditor.btnDelete.Enable(False)
def unrestrict(self):
for type in self.DAMAGE_TYPES:
editObj = getattr(self, "%sEdit"%type)
for type_ in self.DAMAGE_TYPES:
editObj = getattr(self, "%sEdit" % type_)
editObj.Enable()
self.entityEditor.btnRename.Enable()
self.entityEditor.btnDelete.Enable()
@@ -251,13 +249,13 @@ class DmgPatternEditorDlg(wx.Dialog):
def importPatterns(self, event):
text = fromClipboard()
if text:
sDP = service.DamagePattern.getInstance()
sDP = DamagePattern.getInstance()
try:
sDP.importPatterns(text)
self.stNotice.SetLabel("Patterns successfully imported from clipboard")
except service.damagePattern.ImportError, e:
except ImportError as e:
self.stNotice.SetLabel(str(e))
except Exception, e:
except Exception:
self.stNotice.SetLabel("Could not import from clipboard: unknown errors")
finally:
self.entityEditor.refreshEntityList()
@@ -265,6 +263,6 @@ class DmgPatternEditorDlg(wx.Dialog):
self.stNotice.SetLabel("Could not import from clipboard")
def exportPatterns(self, event):
sDP = service.DamagePattern.getInstance()
toClipboard( sDP.exportPatterns() )
sDP = DamagePattern.getInstance()
toClipboard(sDP.exportPatterns())
self.stNotice.SetLabel("Patterns exported to clipboard")

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,14 +15,14 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from gui.preferenceView import PreferenceView
from gui.bitmapLoader import BitmapLoader
class PreferenceDialog(wx.Dialog):
class PreferenceDialog(wx.Dialog):
def __init__(self, parent):
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE)
self.SetTitle("pyfa - Preferences")
@@ -33,22 +33,22 @@ class PreferenceDialog(wx.Dialog):
self.listbook = wx.Listbook(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LB_DEFAULT)
self.listview = self.listbook.GetListView()
#self.listview.SetMinSize((500, -1))
#self.listview.SetSize((500, -1))
# self.listview.SetMinSize((500, -1))
# self.listview.SetSize((500, -1))
self.imageList = wx.ImageList(32,32)
self.imageList = wx.ImageList(32, 32)
self.listbook.SetImageList(self.imageList)
mainSizer.Add(self.listbook, 1, wx.EXPAND | wx.TOP|wx.BOTTOM|wx.LEFT, 5)
mainSizer.Add(self.listbook, 1, wx.EXPAND | wx.TOP | wx.BOTTOM | wx.LEFT, 5)
self.m_staticline2 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
mainSizer.Add( self.m_staticline2, 0, wx.EXPAND, 5 )
self.m_staticline2 = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
mainSizer.Add(self.m_staticline2, 0, wx.EXPAND, 5)
btnSizer = wx.BoxSizer( wx.HORIZONTAL )
btnSizer.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 )
self.btnOK = wx.Button( self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.DefaultSize, 0 )
btnSizer.Add( self.btnOK, 0, wx.ALL, 5 )
mainSizer.Add(btnSizer,0 , wx.EXPAND, 5)
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
btnSizer.AddSpacer((0, 0), 1, wx.EXPAND, 5)
self.btnOK = wx.Button(self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.DefaultSize, 0)
btnSizer.Add(self.btnOK, 0, wx.ALL, 5)
mainSizer.Add(btnSizer, 0, wx.EXPAND, 5)
self.SetSizer(mainSizer)
self.Centre(wx.BOTH)
@@ -61,12 +61,12 @@ class PreferenceDialog(wx.Dialog):
else:
imgID = -1
prefView.populatePanel(page)
self.listbook.AddPage(page, prefView.title, imageId = imgID)
self.listbook.AddPage(page, prefView.title, imageId=imgID)
# Set the height based on a condition. Can all the panels fit in the current height?
# If not, use the .GetBestVirtualSize() to ensure that all content is available.
minHeight = 360
bestFit = self.GetBestVirtualSize()
bestFit = self.GetBestVirtualSize()
if minHeight > bestFit[1]:
self.SetSizeWH(450, minHeight)
else:

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,14 +15,13 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
class PreferenceView(object):
views = []
def __init__(self):
pass
@classmethod
def register(cls):
@@ -37,5 +36,5 @@ class PreferenceView(object):
def getImage(self):
return wx.NullBitmap
from gui.builtinPreferenceViews import *
from gui.builtinPreferenceViews import * # noqa

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,16 +15,19 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
import gui.display as d
import gui.globalEvents as GE
import service
import gui.droneView
from gui.builtinViewColumns.state import State
from gui.contextMenu import ContextMenu
import eos.types
from service.fit import Fit
from service.market import Market
from eos.saveddata.drone import Drone as es_Drone
from eos.saveddata.fighter import Fighter as es_Fighter
from eos.saveddata.module import Module as es_Module
class DummyItem:
@@ -32,23 +35,26 @@ class DummyItem:
self.name = txt
self.icon = None
class DummyEntry:
def __init__(self, txt):
self.item = DummyItem(txt)
class ProjectedViewDrop(wx.PyDropTarget):
def __init__(self, dropFn):
wx.PyDropTarget.__init__(self)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
if self.GetData():
data = self.dropData.GetText().split(':')
self.dropFn(x, y, data)
return t
class ProjectedViewDrop(wx.PyDropTarget):
def __init__(self, dropFn):
wx.PyDropTarget.__init__(self)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
if self.GetData():
data = self.dropData.GetText().split(':')
self.dropFn(x, y, data)
return t
class ProjectedView(d.Display):
DEFAULT_COLS = ["State",
@@ -58,7 +64,7 @@ class ProjectedView(d.Display):
"Ammo"]
def __init__(self, parent):
d.Display.__init__(self, parent, style = wx.LC_SINGLE_SEL | wx.BORDER_NONE)
d.Display.__init__(self, parent, style=wx.LC_SINGLE_SEL | wx.BORDER_NONE)
self.lastFitId = None
@@ -70,7 +76,7 @@ class ProjectedView(d.Display):
self.droneView = gui.droneView.DroneView
if "__WXGTK__" in wx.PlatformInfo:
if "__WXGTK__" in wx.PlatformInfo:
self.Bind(wx.EVT_RIGHT_UP, self.scheduleMenu)
else:
self.Bind(wx.EVT_RIGHT_DOWN, self.scheduleMenu)
@@ -91,56 +97,55 @@ class ProjectedView(d.Display):
# if source is coming from projected, we are trying to combine drones.
self.mergeDrones(x, y, int(data[1]))
elif data[0] == "market":
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.project(fitID, int(data[1]))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
def kbEvent(self,event):
def kbEvent(self, event):
keycode = event.GetKeyCode()
if keycode == wx.WXK_DELETE or keycode == wx.WXK_NUMPAD_DELETE:
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
row = self.GetFirstSelected()
if row != -1:
sFit.removeProjected(fitID, self.get(row))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def handleDrag(self, type, fitID):
#Those are drags coming from pyfa sources, NOT builtin wx drags
# Those are drags coming from pyfa sources, NOT builtin wx drags
if type == "fit":
activeFit = self.mainFrame.getActiveFit()
if activeFit:
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
draggedFit = sFit.getFit(fitID)
sFit.project(activeFit, draggedFit)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFit))
def startDrag(self, event):
row = event.GetIndex()
if row != -1 and isinstance(self.get(row), eos.types.Drone):
if row != -1 and isinstance(self.get(row), es_Drone):
data = wx.PyTextDataObject()
data.SetText("projected:"+str(self.GetItemData(row)))
data.SetText("projected:" + str(self.GetItemData(row)))
dropSource = wx.DropSource(self)
dropSource.SetData(data)
dropSource.DoDragDrop()
def mergeDrones(self, x, y, itemID):
srcRow = self.FindItemData(-1,itemID)
srcRow = self.FindItemData(-1, itemID)
dstRow, _ = self.HitTest((x, y))
if srcRow != -1 and dstRow != -1:
self._merge(srcRow, dstRow)
def _merge(self, src, dst):
dstDrone = self.get(dst)
if isinstance(dstDrone, eos.types.Drone):
sFit = service.Fit.getInstance()
if isinstance(dstDrone, es_Drone):
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
if sFit.mergeDrones(fitID, self.get(src), dstDrone, True):
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def moduleSort(self, module):
return module.item.name
@@ -159,12 +164,12 @@ class ProjectedView(d.Display):
return fit.name
def fitChanged(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(event.fitID)
self.Parent.Parent.DisablePage(self, not fit or fit.isStructure)
#Clear list and get out if current fitId is None
# Clear list and get out if current fitId is None
if event.fitID is None and self.lastFitId is not None:
self.DeleteAllItems()
self.lastFitId = None
@@ -231,7 +236,7 @@ class ProjectedView(d.Display):
col = self.getColumn(event.Position)
if col == self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.toggleProjected(fitID, item, "right" if event.Button == 3 else "left")
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
@@ -245,17 +250,18 @@ class ProjectedView(d.Display):
menu = None
if sel != -1:
item = self.get(sel)
if item is None: return
sMkt = service.Market.getInstance()
if isinstance(item, eos.types.Drone):
if item is None:
return
sMkt = Market.getInstance()
if isinstance(item, es_Drone):
srcContext = "projectedDrone"
itemContext = sMkt.getCategoryByItem(item.item).name
context = ((srcContext, itemContext),)
elif isinstance(item, eos.types.Fighter):
elif isinstance(item, es_Fighter):
srcContext = "projectedFighter"
itemContext = sMkt.getCategoryByItem(item.item).name
context = ((srcContext, itemContext),)
elif isinstance(item, eos.types.Module):
elif isinstance(item, es_Module):
modSrcContext = "projectedModule"
modItemContext = sMkt.getCategoryByItem(item.item).name
modFullContext = (modSrcContext, modItemContext)
@@ -269,7 +275,7 @@ class ProjectedView(d.Display):
else:
fitSrcContext = "projectedFit"
fitItemContext = item.name
context = ((fitSrcContext,fitItemContext),)
context = ((fitSrcContext, fitItemContext),)
context = context + (("projected",),)
menu = ContextMenu.getMenu((item,), *context)
elif sel == -1:
@@ -287,6 +293,6 @@ class ProjectedView(d.Display):
col = self.getColumn(event.Position)
if col != self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
sFit.removeProjected(fitID, self.get(row))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))

View File

@@ -1,3 +1,6 @@
import csv
import logging
import wx
try:
@@ -8,24 +11,22 @@ except:
else:
raise
import gui.PFSearchBox as SBox
from gui.marketBrowser import SearchBox
import eos.db
from service.market import Market
import gui.display as d
import gui.globalEvents as GE
import gui.PFSearchBox as SBox
from gui.marketBrowser import SearchBox
from gui.bitmapLoader import BitmapLoader
import service
import csv
import eos.db
import logging
logger = logging.getLogger(__name__)
class AttributeEditor( wx.Frame ):
def __init__( self, parent ):
class AttributeEditor(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, wx.ID_ANY, title="Attribute Editor", pos=wx.DefaultPosition,
size=wx.Size(650, 600), style=wx.DEFAULT_FRAME_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.TAB_TRAVERSAL)
size=wx.Size(650, 600),
style=wx.DEFAULT_FRAME_STYLE | wx.FRAME_FLOAT_ON_PARENT | wx.TAB_TRAVERSAL)
i = wx.IconFromBitmap(BitmapLoader.getBitmap("fit_rename_small", "gui"))
self.SetIcon(i)
@@ -45,7 +46,6 @@ class AttributeEditor( wx.Frame ):
self.Bind(wx.EVT_MENU, self.OnExport, fileExport)
self.Bind(wx.EVT_MENU, self.OnClear, fileClear)
i = wx.IconFromBitmap(BitmapLoader.getBitmap("fit_rename_small", "gui"))
self.SetIcon(i)
@@ -55,7 +55,8 @@ class AttributeEditor( wx.Frame ):
mainSizer = wx.BoxSizer(wx.HORIZONTAL)
leftSizer = wx.BoxSizer(wx.VERTICAL)
leftPanel = wx.Panel(panel, wx.ID_ANY, style=wx.DOUBLE_BORDER if 'wxMSW' in wx.PlatformInfo else wx.SIMPLE_BORDER)
leftPanel = wx.Panel(panel, wx.ID_ANY,
style=wx.DOUBLE_BORDER if 'wxMSW' in wx.PlatformInfo else wx.SIMPLE_BORDER)
self.searchBox = SearchBox(leftPanel)
self.itemView = ItemView(leftPanel)
@@ -67,10 +68,11 @@ class AttributeEditor( wx.Frame ):
mainSizer.Add(leftPanel, 1, wx.ALL | wx.EXPAND, 5)
rightSizer = wx.BoxSizer(wx.VERTICAL)
self.btnRemoveOverrides = wx.Button( panel, wx.ID_ANY, u"Remove Overides for Item", wx.DefaultPosition, wx.DefaultSize, 0 )
self.btnRemoveOverrides = wx.Button(panel, wx.ID_ANY, u"Remove Overides for Item", wx.DefaultPosition,
wx.DefaultSize, 0)
self.pg = AttributeGrid(panel)
rightSizer.Add(self.pg, 1, wx.ALL|wx.EXPAND, 5)
rightSizer.Add(self.btnRemoveOverrides, 0, wx.ALL | wx.EXPAND, 5 )
rightSizer.Add(self.pg, 1, wx.ALL | wx.EXPAND, 5)
rightSizer.Add(self.btnRemoveOverrides, 0, wx.ALL | wx.EXPAND, 5)
self.btnRemoveOverrides.Bind(wx.EVT_BUTTON, self.pg.removeOverrides)
self.btnRemoveOverrides.Enable(False)
@@ -94,8 +96,8 @@ class AttributeEditor( wx.Frame ):
def OnImport(self, event):
dlg = wx.FileDialog(self, "Import pyfa override file",
wildcard = "pyfa override file (*.csv)|*.csv",
style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
wildcard="pyfa override file (*.csv)|*.csv",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if (dlg.ShowModal() == wx.ID_OK):
path = dlg.GetPath()
with open(path, 'rb') as csvfile:
@@ -108,13 +110,13 @@ class AttributeEditor( wx.Frame ):
self.itemView.updateItems(True)
def OnExport(self, event):
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
items = sMkt.getItemsWithOverrides()
defaultFile = "pyfa_overrides.csv"
dlg = wx.FileDialog(self, "Save Overrides As...",
wildcard = "pyfa overrides (*.csv)|*.csv",
style = wx.FD_SAVE,
wildcard="pyfa overrides (*.csv)|*.csv",
style=wx.FD_SAVE,
defaultFile=defaultFile)
if dlg.ShowModal() == wx.ID_OK:
@@ -126,12 +128,15 @@ class AttributeEditor( wx.Frame ):
writer.writerow([item.ID, override.attrID, override.value])
def OnClear(self, event):
dlg = wx.MessageDialog(self,
"Are you sure you want to delete all overrides?",
"Confirm Delete", wx.YES | wx.NO | wx.ICON_EXCLAMATION)
dlg = wx.MessageDialog(
self,
"Are you sure you want to delete all overrides?",
"Confirm Delete",
wx.YES | wx.NO | wx.ICON_EXCLAMATION
)
if dlg.ShowModal() == wx.ID_YES:
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
items = sMkt.getItemsWithOverrides()
# We can't just delete overrides, as loaded items will still have
# them assigned. Deleting them from the database won't propagate
@@ -143,6 +148,7 @@ class AttributeEditor( wx.Frame ):
self.itemView.updateItems(True)
self.pg.Clear()
# This is literally a stripped down version of the market.
class ItemView(d.Display):
DEFAULT_COLS = ["Base Icon",
@@ -152,7 +158,7 @@ class ItemView(d.Display):
def __init__(self, parent):
d.Display.__init__(self, parent)
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
self.things = sMkt.getItemsWithOverrides()
self.items = self.things
@@ -173,14 +179,14 @@ class ItemView(d.Display):
self.update(self.items)
def updateItems(self, updateDisplay=False):
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
self.things = sMkt.getItemsWithOverrides()
self.items = self.things
if updateDisplay:
self.update(self.things)
def scheduleSearch(self, event=None):
sMkt = service.Market.getInstance()
sMkt = Market.getInstance()
search = self.searchBox.GetLineText(0)
# Make sure we do not count wildcard as search symbol
@@ -198,9 +204,9 @@ class ItemView(d.Display):
class AttributeGrid(wxpg.PropertyGrid):
def __init__(self, parent):
wxpg.PropertyGrid.__init__(self, parent, style=wxpg.PG_HIDE_MARGIN|wxpg.PG_HIDE_CATEGORIES|wxpg.PG_BOLD_MODIFIED|wxpg.PG_TOOLTIPS)
wxpg.PropertyGrid.__init__(self, parent,
style=wxpg.PG_HIDE_MARGIN | wxpg.PG_HIDE_CATEGORIES | wxpg.PG_BOLD_MODIFIED | wxpg.PG_TOOLTIPS)
self.SetExtraStyle(wxpg.PG_EX_HELP_AS_TOOLTIPS)
self.item = None
@@ -209,9 +215,9 @@ class AttributeGrid(wxpg.PropertyGrid):
self.btn = parent.Parent.btnRemoveOverrides
self.Bind( wxpg.EVT_PG_CHANGED, self.OnPropGridChange )
self.Bind( wxpg.EVT_PG_SELECTED, self.OnPropGridSelect )
self.Bind( wxpg.EVT_PG_RIGHT_CLICK, self.OnPropGridRightClick )
self.Bind(wxpg.EVT_PG_CHANGED, self.OnPropGridChange)
self.Bind(wxpg.EVT_PG_SELECTED, self.OnPropGridSelect)
self.Bind(wxpg.EVT_PG_RIGHT_CLICK, self.OnPropGridRightClick)
self.itemView.Bind(wx.EVT_LIST_ITEM_SELECTED, self.itemActivated)
self.itemView.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.itemActivated)
@@ -232,14 +238,14 @@ class AttributeGrid(wxpg.PropertyGrid):
prop = wxpg.FloatProperty(key, value=default)
prop.SetClientData(item.attributes[key]) # set this so that we may access it later
prop.SetHelpString("%s\n%s"%(item.attributes[key].displayName or key, "Default Value: %0.3f"%default))
prop.SetHelpString("%s\n%s" % (item.attributes[key].displayName or key, "Default Value: %0.3f" % default))
self.Append(prop)
def removeOverrides(self, event):
if self.item is None:
return
for _, x in self.item.overrides.items():
for x in self.item.overrides.values():
self.item.deleteOverride(x.attr)
self.itemView.updateItems(True)
self.ClearModifiedStatus()

View File

@@ -1,65 +1,55 @@
# -*- coding: utf-8 -*-
###########################################################################
## pyfatogllepanel.py
##
## Author: Darriele - HomeWorld
##
## Project home: https://github.com/pyfa-org/Pyfa - pyfa project
## Some portions of code are based on
## AGW:pycollapsiblepane generic implementation of wx.CollapsiblePane
## AGW:pycollapsiblepane credits ( from the original source file used ):
## Andrea Gavana, @ 09 Aug 2007
## Latest Revision: 12 Apr 2010, 12.00 GMT
##
## Module description:
## TogglePanel class is a wx.collipsablepane like implementation that uses
## some optimization from awg::pycollipsablepane to provide certain
## features tailored for PYFA needs.
##
## This module is part of PYFA (PYthon Fitting Assitant) and it shares the same
## licence ( read PYFA licence notice: gpl.txt )
##
## Notes: leave the commented code as it is, those line will be removed someday
# pyfatogllepanel.py
#
# Author: Darriele - HomeWorld
#
# Project home: https://github.com/pyfa-org/Pyfa - pyfa project
# Some portions of code are based on
# AGW:pycollapsiblepane generic implementation of wx.CollapsiblePane
# AGW:pycollapsiblepane credits ( from the original source file used ):
# Andrea Gavana, @ 09 Aug 2007
# Latest Revision: 12 Apr 2010, 12.00 GMT
#
# Module description:
# TogglePanel class is a wx.collipsablepane like implementation that uses
# some optimization from awg::pycollipsablepane to provide certain
# features tailored for PYFA needs.
#
# This module is part of PYFA (PYthon Fitting Assitant) and it shares the same
# licence ( read PYFA licence notice: gpl.txt )
#
# Notes: leave the commented code as it is, those line will be removed someday
###########################################################################
import wx
from gui.bitmapLoader import BitmapLoader
###########################################################################
## Class TogglePanel
###########################################################################
class TogglePanel ( wx.Panel ):
def __init__( self, parent , forceLayout = -1):
wx.Panel.__init__ ( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( -1,-1 ), style = wx.TAB_TRAVERSAL )
class TogglePanel(wx.Panel):
def __init__(self, parent, forceLayout=-1):
wx.Panel.__init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(-1, -1),
style=wx.TAB_TRAVERSAL)
self._toggle = 1
self.parent = parent
self.forceLayout = forceLayout
self.bkColour = self.GetBackgroundColour()
# Create the main sizer of this panel
self.mainSizer = wx.BoxSizer( wx.VERTICAL )
self.SetSizer( self.mainSizer )
parentSize = parent.GetMinSize()
# Create the header panel
# Create the main sizer of this panel
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(self.mainSizer)
# parentSize = parent.GetMinSize()
# Create the header panel
self.headerPanel = wx.Panel(self)
self.mainSizer.Add(self.headerPanel, 0, wx.EXPAND | wx.TOP | wx.BOTTOM | wx.RIGHT, 1)
self.mainSizer.Add(self.headerPanel,0,wx.EXPAND | wx.TOP|wx.BOTTOM|wx.RIGHT, 1)
# Load expanded/collapsed bitmaps from the icons folder
self.bmpExpanded = BitmapLoader.getBitmap("down-arrow2", "gui")
self.bmpCollapsed = BitmapLoader.getBitmap("up-arrow2", "gui")
# Load expanded/collapsed bitmaps from the icons folder
self.bmpExpanded = BitmapLoader.getBitmap("down-arrow2","gui")
self.bmpCollapsed = BitmapLoader.getBitmap("up-arrow2","gui")
# Make the bitmaps have the same color as window text
sysTextColour = wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOWTEXT )
# Make the bitmaps have the same color as window text
sysTextColour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
img = self.bmpExpanded.ConvertToImage()
img.Replace(0, 0, 0, sysTextColour[0], sysTextColour[1], sysTextColour[2])
@@ -69,55 +59,53 @@ class TogglePanel ( wx.Panel ):
img.Replace(0, 0, 0, sysTextColour[0], sysTextColour[1], sysTextColour[2])
self.bmpCollapsed = wx.BitmapFromImage(img)
self.headerBmp = wx.StaticBitmap(self.headerPanel )
self.headerBmp.SetBitmap( self.bmpExpanded)
self.headerBmp = wx.StaticBitmap(self.headerPanel)
self.headerBmp.SetBitmap(self.bmpExpanded)
# Create the header sizer and add static bitmap and static text controls to it
# Create the header sizer and add static bitmap and static text controls to it
headerSizer = wx.BoxSizer( wx.HORIZONTAL )
self.headerPanel.SetSizer( headerSizer)
headerSizer = wx.BoxSizer(wx.HORIZONTAL)
self.headerPanel.SetSizer(headerSizer)
hbmpSizer = wx.BoxSizer( wx.HORIZONTAL )
hlblSizer = wx.BoxSizer( wx.HORIZONTAL )
self.hcntSizer = wx.BoxSizer( wx.HORIZONTAL)
hbmpSizer = wx.BoxSizer(wx.HORIZONTAL)
hlblSizer = wx.BoxSizer(wx.HORIZONTAL)
self.hcntSizer = wx.BoxSizer(wx.HORIZONTAL)
hbmpSizer.Add( self.headerBmp, 0,0, 5 )
hbmpSizer.Add(self.headerBmp, 0, 0, 5)
self.headerLabel = wx.StaticText( self.headerPanel, wx.ID_ANY, u"PYFA", wx.DefaultPosition, wx.DefaultSize, 0 )
hlblSizer.Add( self.headerLabel, 0, wx.EXPAND , 5 )
self.headerLabel = wx.StaticText(self.headerPanel, wx.ID_ANY, u"PYFA", wx.DefaultPosition, wx.DefaultSize, 0)
hlblSizer.Add(self.headerLabel, 0, wx.EXPAND, 5)
headerSizer.Add( hbmpSizer, 0, wx.RIGHT, 5 )
headerSizer.Add( hlblSizer, 0, wx.RIGHT, 5 )
headerSizer.Add( self.hcntSizer, 0, wx.RIGHT, 5)
headerSizer.Add(hbmpSizer, 0, wx.RIGHT, 5)
headerSizer.Add(hlblSizer, 0, wx.RIGHT, 5)
headerSizer.Add(self.hcntSizer, 0, wx.RIGHT, 5)
# Set the static text font weight to BOLD
# Set the static text font weight to BOLD
headerFont=parent.GetFont()
headerFont = parent.GetFont()
headerFont.SetWeight(wx.BOLD)
self.headerLabel.SetFont(headerFont)
# Create the content panel and its main sizer
# Create the content panel and its main sizer
self.contentSizer = wx.BoxSizer( wx.VERTICAL )
self.contentSizer = wx.BoxSizer(wx.VERTICAL)
self.contentPanel = wx.Panel(self)
self.contentPanel.SetSizer(self.contentSizer)
self.mainSizer.Add( self.contentPanel, 0, wx.EXPAND | wx.RIGHT | wx.LEFT , 5)
self.mainSizer.Add(self.contentPanel, 0, wx.EXPAND | wx.RIGHT | wx.LEFT, 5)
self.Layout()
# Connect Events
# Connect Events
self.headerLabel.Bind(wx.EVT_LEFT_UP, self.toggleContent)
self.headerBmp.Bind(wx.EVT_LEFT_UP, self.toggleContent)
self.headerPanel.Bind(wx.EVT_LEFT_UP, self.toggleContent)
self.headerLabel.Bind( wx.EVT_LEFT_UP, self.toggleContent )
self.headerBmp.Bind( wx.EVT_LEFT_UP, self.toggleContent )
self.headerPanel.Bind( wx.EVT_LEFT_UP, self.toggleContent )
def __del__( self ):
def __del__(self):
pass
def AddToggleItem(self, hitem):
hitem.Bind( wx.EVT_LEFT_UP, self.toggleContent )
hitem.Bind(wx.EVT_LEFT_UP, self.toggleContent)
def GetHeaderContentSizer(self):
return self.hcntSizer
@@ -126,7 +114,7 @@ class TogglePanel ( wx.Panel ):
return self.headerPanel
def InsertItemInHeader(self, item):
self.hcntSizer.Add(item,0,0,0)
self.hcntSizer.Add(item, 0, 0, 0)
self.Layout()
def AddSizer(self, sizer):

View File

@@ -13,14 +13,14 @@ It uses the easeOutQuad equation from caurina.transitions.Tweener to do the anim
import wx
import copy
import math
from gui.utils import colorUtils
import gui.utils.drawUtils as drawUtils
import gui.utils.animEffects as animEffects
import gui.utils.fonts as fonts
from service import fit
from service.fit import Fit
class PyGauge(wx.PyWindow):
"""
@@ -29,7 +29,7 @@ class PyGauge(wx.PyWindow):
"""
def __init__(self, parent, id=wx.ID_ANY, range=100, pos=wx.DefaultPosition,
size=(-1,30), style=0):
size=(-1, 30), style=0):
"""
Default class constructor.
@@ -46,8 +46,8 @@ class PyGauge(wx.PyWindow):
self._size = size
self._border_colour = wx.BLACK
self._barColour = self._barColourSorted = [wx.Colour(212,228,255)]
self._barGradient = self._barGradientSorted = None
self._barColour = self._barColourSorted = [wx.Colour(212, 228, 255)]
self._barGradient = self._barGradientSorted = None
self._border_padding = 0
self._range = range
@@ -67,10 +67,10 @@ class PyGauge(wx.PyWindow):
self._animDirection = 0
self.animEffect = animEffects.OUT_QUAD
self.transitionsColors = [( wx.Colour(191, 191, 191, 255) , wx.Colour(96, 191, 0, 255) ),
( wx.Colour(191, 167, 96, 255) , wx.Colour(255, 191, 0, 255) ),
( wx.Colour(255, 191, 0, 255) , wx.Colour(255, 128, 0, 255) ),
( wx.Colour(255, 128, 0, 255) , wx.Colour(255, 0, 0, 255) )]
self.transitionsColors = [(wx.Colour(191, 191, 191, 255), wx.Colour(96, 191, 0, 255)),
(wx.Colour(191, 167, 96, 255), wx.Colour(255, 191, 0, 255)),
(wx.Colour(255, 191, 0, 255), wx.Colour(255, 128, 0, 255)),
(wx.Colour(255, 128, 0, 255), wx.Colour(255, 0, 0, 255))]
self.gradientEffect = -35
self._percentage = 0
@@ -79,8 +79,8 @@ class PyGauge(wx.PyWindow):
self.font = wx.Font(fonts.NORMAL, wx.SWISS, wx.NORMAL, wx.NORMAL, False)
self.SetBarGradient((wx.Colour(119,119,119),wx.Colour(153,153,153)))
self.SetBackgroundColour(wx.Colour(51,51,51))
self.SetBarGradient((wx.Colour(119, 119, 119), wx.Colour(153, 153, 153)))
self.SetBackgroundColour(wx.Colour(51, 51, 51))
self._tooltip = wx.ToolTip("")
self.SetToolTip(self._tooltip)
self._tooltip.SetTip("0.00/100.00")
@@ -107,7 +107,6 @@ class PyGauge(wx.PyWindow):
return wx.Size(self._size[0], self._size[1])
def GetBorderColour(self):
return self._border_colour
@@ -121,7 +120,7 @@ class PyGauge(wx.PyWindow):
return self._barColour[0]
def SetBarColour(self, colour):
if type(colour) != type([]):
if not isinstance(colour, list):
self._barColour = [colour]
else:
self._barColour = list(colour)
@@ -130,31 +129,30 @@ class PyGauge(wx.PyWindow):
GetBarColor = GetBarColour
def SetFractionDigits(self, digits):
self._fractionDigits=digits
self._fractionDigits = digits
def GetBarGradient(self):
""" Returns a tuple containing the gradient start and end colours. """
if self._barGradient == None:
if self._barGradient is None:
return None
return self._barGradient[0]
def SetBarGradient(self, gradient = None):
def SetBarGradient(self, gradient=None):
"""
Sets the bar gradient. This overrides the BarColour.
:param `gradient`: a tuple containing the gradient start and end colours.
"""
if gradient == None:
if gradient is None:
self._barGradient = None
else:
if type(gradient) != type([]):
if not isinstance(gradient, list):
self._barGradient = [gradient]
else:
self._barGradient = list(gradient)
def GetBorderPadding(self):
""" Gets the border padding. """
@@ -169,14 +167,13 @@ class PyGauge(wx.PyWindow):
self._border_padding = padding
def GetRange(self):
""" Returns the maximum value of the gauge. """
return self._range
def Animate(self):
sFit = fit.Fit.getInstance()
sFit = Fit.getInstance()
if sFit.serviceFittingOptions["enableGaugeAnimation"]:
if not self._timer:
self._timer = wx.Timer(self, self._timerId)
@@ -186,7 +183,7 @@ class PyGauge(wx.PyWindow):
self._animValue = self._percentage
self.Refresh()
def SetRange(self, range, reinit = False):
def SetRange(self, range, reinit=False):
"""
Sets the range of the gauge. The gauge length is its
value as a proportion of the range.
@@ -197,16 +194,16 @@ class PyGauge(wx.PyWindow):
if self._range == range:
return
range = float(range)
range_ = float(range)
if range <= 0:
if range_ <= 0:
self._range = 0.01
else:
self._range = range
self._range = range_
if reinit is False:
self._oldPercentage = self._percentage
self._percentage = (self._value/self._range) * 100
self._percentage = (self._value / self._range) * 100
else:
self._oldPercentage = self._percentage
self._percentage = 0
@@ -214,9 +211,7 @@ class PyGauge(wx.PyWindow):
self.Animate()
self._tooltip.SetTip("%.2f/%.2f" % (self._value, self._range if self._range >0.01 else 0))
self._tooltip.SetTip("%.2f/%.2f" % (self._value, self._range if self._range > 0.01 else 0))
def GetValue(self):
""" Returns the current position of the gauge. """
@@ -233,22 +228,22 @@ class PyGauge(wx.PyWindow):
self._value = value
if value < 0:
self._value = 0
self._percentage = (self._value/self._range) * 100
self._percentage = (self._value / self._range) * 100
self.Animate()
self._tooltip.SetTip("%.2f/%.2f" % (self._value, self._range))
def SetValueRange(self, value, range, reinit = False):
def SetValueRange(self, value, range, reinit=False):
if self._value == value and self._range == range:
return
range = float(range)
range_ = float(range)
if range <= 0:
if range_ <= 0:
self._range = 0.01
else:
self._range = range
self._range = range_
value = float(value)
@@ -258,15 +253,14 @@ class PyGauge(wx.PyWindow):
if reinit is False:
self._oldPercentage = self._percentage
self._percentage = (self._value/self._range) * 100
self._percentage = (self._value / self._range) * 100
else:
self._oldPercentage = self._percentage
self._percentage = 0
self.Animate()
self._tooltip.SetTip("%.2f/%.2f" % (self._value, self._range if self._range >0.01 else 0))
self._tooltip.SetTip("%.2f/%.2f" % (self._value, self._range if self._range > 0.01 else 0))
def OnEraseBackground(self, event):
"""
@@ -308,7 +302,7 @@ class PyGauge(wx.PyWindow):
dc.SetPen(wx.Pen(self.GetBorderColour()))
dc.DrawRectangleRect(rect)
pad = 1 + self.GetBorderPadding()
rect.Deflate(pad,pad)
rect.Deflate(pad, pad)
if self.GetBarGradient():
@@ -326,48 +320,48 @@ class PyGauge(wx.PyWindow):
# time on them if not needed. See GH issue #282
pv = value
xv=1
xv = 1
transition = 0
if pv <= 100:
xv = pv/100
xv = pv / 100
transition = 0
elif pv <=101:
xv = pv -100
elif pv <= 101:
xv = pv - 100
transition = 1
elif pv <= 103:
xv = (pv -101)/2
xv = (pv - 101) / 2
transition = 2
elif pv <= 105:
xv = (pv -103)/2
xv = (pv - 103) / 2
transition = 3
else:
pv = 106
xv = pv -100
xv = pv - 100
transition = -1
if transition != -1:
colorS,colorE = self.transitionsColors[transition]
colorS, colorE = self.transitionsColors[transition]
color = colorUtils.CalculateTransitionColor(colorS, colorE, xv)
else:
color = wx.Colour(191,48,48)
color = wx.Colour(191, 48, 48)
if self.gradientEffect > 0:
gcolor = colorUtils.BrightenColor(color, float(self.gradientEffect) / 100)
gMid = colorUtils.BrightenColor(color, float(self.gradientEffect/2) / 100)
gcolor = colorUtils.BrightenColor(color, float(self.gradientEffect) / 100)
gMid = colorUtils.BrightenColor(color, float(self.gradientEffect / 2) / 100)
else:
gcolor = colorUtils.DarkenColor(color, float(-self.gradientEffect) / 100)
gMid = colorUtils.DarkenColor(color, float(-self.gradientEffect/2) / 100)
gcolor = colorUtils.DarkenColor(color, float(-self.gradientEffect) / 100)
gMid = colorUtils.DarkenColor(color, float(-self.gradientEffect / 2) / 100)
gBmp = drawUtils.DrawGradientBar(r.width, r.height, gMid, color, gcolor)
dc.DrawBitmap(gBmp, r.left, r.top)
else:
colour=self.GetBarColour()
colour = self.GetBarColour()
dc.SetBrush(wx.Brush(colour))
dc.SetPen(wx.Pen(colour))
if value > 100:
@@ -381,14 +375,14 @@ class PyGauge(wx.PyWindow):
dc.SetFont(self.font)
r = copy.copy(rect)
r.left +=1
r.top +=1
r.left += 1
r.top += 1
if self._range == 0.01 and self._value > 0:
formatStr = u'\u221e'
dc.SetTextForeground(wx.Colour(80,80,80))
formatStr = u'\u221e'
dc.SetTextForeground(wx.Colour(80, 80, 80))
dc.DrawLabel(formatStr, r, wx.ALIGN_CENTER)
dc.SetTextForeground(wx.Colour(255,255,255))
dc.SetTextForeground(wx.Colour(255, 255, 255))
dc.DrawLabel(formatStr, rect, wx.ALIGN_CENTER)
else:
if self.GetBarGradient() and self._showRemaining:
@@ -404,20 +398,20 @@ class PyGauge(wx.PyWindow):
else:
formatStr = "{0:." + str(self._fractionDigits) + "f}%"
dc.SetTextForeground(wx.Colour(80,80,80))
dc.SetTextForeground(wx.Colour(80, 80, 80))
dc.DrawLabel(formatStr.format(value), r, wx.ALIGN_CENTER)
dc.SetTextForeground(wx.Colour(255,255,255))
dc.SetTextForeground(wx.Colour(255, 255, 255))
dc.DrawLabel(formatStr.format(value), rect, wx.ALIGN_CENTER)
def OnTimer(self,event):
def OnTimer(self, event):
"""
Handles the ``wx.EVT_TIMER`` event for L{PyfaGauge}.
:param `event`: a timer event
"""
oldValue=self._oldPercentage
value=self._percentage
oldValue = self._oldPercentage
value = self._percentage
start = 0
direction = 1 if oldValue < value else -1
@@ -436,13 +430,13 @@ class PyGauge(wx.PyWindow):
stop_timer = True
if direction == 1:
if (oldValue+step) < value:
self._animValue = oldValue+step
if (oldValue + step) < value:
self._animValue = oldValue + step
else:
stop_timer = True
else:
if (oldValue-step) > value:
self._animValue = oldValue-step
if (oldValue - step) > value:
self._animValue = oldValue - step
else:
stop_timer = True
@@ -451,4 +445,3 @@ class PyGauge(wx.PyWindow):
self._timer.Stop()
self.Refresh()

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2014 Ryan Holmes
#
# This file is part of pyfa.
@@ -15,13 +15,12 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from service.targetResists import TargetResists
from gui.bitmapLoader import BitmapLoader
import service
from gui.utils.clipboard import toClipboard, fromClipboard
from service.targetResists import ImportError
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator
@@ -44,7 +43,7 @@ class TargetResistsTextValidor(BaseValidator):
raise ValueError("Target Resist Profile name already in use, please choose another.")
return True
except ValueError, e:
except ValueError as e:
wx.MessageBox(u"{}".format(e), "Error")
textCtrl.SetFocus()
return False
@@ -56,34 +55,34 @@ class TargetResistsEntityEditor(EntityEditor):
self.SetEditorValidator(TargetResistsTextValidor)
def getEntitiesFromContext(self):
sTR = service.TargetResists.getInstance()
sTR = TargetResists.getInstance()
choices = sorted(sTR.getTargetResistsList(), key=lambda p: p.name)
return choices
def DoNew(self, name):
sTR = service.TargetResists.getInstance()
sTR = TargetResists.getInstance()
return sTR.newPattern(name)
def DoRename(self, entity, name):
sTR = service.TargetResists.getInstance()
sTR = TargetResists.getInstance()
sTR.renamePattern(entity, name)
def DoCopy(self, entity, name):
sTR = service.TargetResists.getInstance()
sTR = TargetResists.getInstance()
copy = sTR.copyPattern(entity)
sTR.renamePattern(copy, name)
return copy
def DoDelete(self, entity):
sTR = service.TargetResists.getInstance()
sTR = TargetResists.getInstance()
sTR.deletePattern(entity)
class ResistsEditorDlg(wx.Dialog):
class ResistsEditorDlg(wx.Dialog):
DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive")
def __init__(self, parent):
wx.Dialog.__init__(self, parent, id = wx.ID_ANY, title = u"Target Resists Editor", size = wx.Size( 350,240 ))
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title=u"Target Resists Editor", size=wx.Size(350, 240))
self.block = False
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
@@ -104,24 +103,24 @@ class ResistsEditorDlg(wx.Dialog):
resistEditSizer.SetFlexibleDirection(wx.BOTH)
resistEditSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
width = -1
defSize = wx.Size(50,-1)
defSize = wx.Size(50, -1)
for i, type in enumerate(self.DAMAGE_TYPES):
if i%2:
for i, type_ in enumerate(self.DAMAGE_TYPES):
if i % 2:
style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT
border = 25
else:
style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT
border = 5
bmp = wx.StaticBitmap(self, wx.ID_ANY, BitmapLoader.getBitmap("%s_big"%type, "gui"))
bmp = wx.StaticBitmap(self, wx.ID_ANY, BitmapLoader.getBitmap("%s_big" % type_, "gui"))
resistEditSizer.Add(bmp, 0, style, border)
# set text edit
setattr(self, "%sEdit"%type, wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPosition, defSize))
editObj = getattr(self, "%sEdit"%type)
setattr(self, "%sEdit" % type_, wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPosition, defSize))
editObj = getattr(self, "%sEdit" % type_)
resistEditSizer.Add(editObj, 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5)
resistEditSizer.Add(wx.StaticText( self, wx.ID_ANY, u"%", wx.DefaultPosition, wx.DefaultSize, 0 ), 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5)
resistEditSizer.Add(wx.StaticText(self, wx.ID_ANY, u"%", wx.DefaultPosition, wx.DefaultSize, 0), 0,
wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5)
editObj.Bind(wx.EVT_TEXT, self.ValuesUpdated)
# Color we use to reset invalid value color
@@ -138,7 +137,7 @@ class ResistsEditorDlg(wx.Dialog):
self.stNotice.Wrap(-1)
perSizer.Add(self.stNotice, 0, wx.BOTTOM | wx.TOP | wx.LEFT, 5)
footerSizer.Add(perSizer, 1, wx.ALIGN_CENTER_VERTICAL, 5)
footerSizer.Add(perSizer, 1, wx.ALIGN_CENTER_VERTICAL, 5)
self.totSizer = wx.BoxSizer(wx.VERTICAL)
@@ -147,8 +146,8 @@ class ResistsEditorDlg(wx.Dialog):
mainSizer.Add(contentSizer, 1, wx.EXPAND, 0)
if "wxGTK" in wx.PlatformInfo:
self.closeBtn = wx.Button( self, wx.ID_ANY, u"Close", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.closeBtn, 0, wx.ALL|wx.ALIGN_RIGHT, 5 )
self.closeBtn = wx.Button(self, wx.ID_ANY, u"Close", wx.DefaultPosition, wx.DefaultSize, 0)
mainSizer.Add(self.closeBtn, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
self.closeBtn.Bind(wx.EVT_BUTTON, self.closeEvent)
self.SetSizer(mainSizer)
@@ -160,13 +159,13 @@ class ResistsEditorDlg(wx.Dialog):
bitmap = wx.ArtProvider.GetBitmap(art, wx.ART_BUTTON)
btn = wx.BitmapButton(self, wx.ID_ANY, bitmap)
btn.SetMinSize( btn.GetSize() )
btn.SetMaxSize( btn.GetSize() )
btn.SetMinSize(btn.GetSize())
btn.SetMaxSize(btn.GetSize())
btn.Layout()
setattr(self, name, btn)
btn.Enable(True)
btn.SetToolTipString("%s patterns %s clipboard" % (name, direction) )
btn.SetToolTipString("%s patterns %s clipboard" % (name, direction))
footerSizer.Add(btn, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_RIGHT)
btn.Bind(wx.EVT_BUTTON, getattr(self, "{}Patterns".format(name.lower())))
@@ -201,8 +200,8 @@ class ResistsEditorDlg(wx.Dialog):
try:
p = self.entityEditor.getActiveEntity()
for type in self.DAMAGE_TYPES:
editObj = getattr(self, "%sEdit"%type)
for type_ in self.DAMAGE_TYPES:
editObj = getattr(self, "%sEdit" % type_)
if editObj.GetValue() == "":
# if we are blank, overwrite with 0
@@ -215,7 +214,7 @@ class ResistsEditorDlg(wx.Dialog):
assert 0 <= value <= 100
# if everything checks out, set resist attribute
setattr(p, "%sAmount"%type, value/100)
setattr(p, "%sAmount" % type_, value / 100)
editObj.SetForegroundColour(self.colorReset)
self.stNotice.SetLabel("")
@@ -224,7 +223,7 @@ class ResistsEditorDlg(wx.Dialog):
if event is not None:
event.Skip()
service.TargetResists.getInstance().saveChanges(p)
TargetResists.getInstance().saveChanges(p)
except ValueError:
editObj.SetForegroundColour(wx.RED)
@@ -250,13 +249,13 @@ class ResistsEditorDlg(wx.Dialog):
# Set new values
for field in self.DAMAGE_TYPES:
edit = getattr(self, "%sEdit" % field)
amount = getattr(p, "%sAmount" % field)*100
amount = getattr(p, "%sAmount" % field) * 100
edit.ChangeValue(str(amount))
self.block = False
self.ValuesUpdated()
def __del__( self ):
def __del__(self):
pass
def importPatterns(self, event):
@@ -264,13 +263,13 @@ class ResistsEditorDlg(wx.Dialog):
text = fromClipboard()
if text:
sTR = service.TargetResists.getInstance()
sTR = TargetResists.getInstance()
try:
sTR.importPatterns(text)
self.stNotice.SetLabel("Patterns successfully imported from clipboard")
except service.targetResists.ImportError, e:
except ImportError as e:
self.stNotice.SetLabel(str(e))
except Exception, e:
except Exception:
self.stNotice.SetLabel("Could not import from clipboard: unknown errors")
finally:
self.entityEditor.refreshEntityList()
@@ -279,6 +278,6 @@ class ResistsEditorDlg(wx.Dialog):
def exportPatterns(self, event):
"Event fired when export to clipboard button is clicked"
sTR = service.TargetResists.getInstance()
toClipboard( sTR.exportPatterns() )
sTR = TargetResists.getInstance()
toClipboard(sTR.exportPatterns())
self.stNotice.SetLabel("Patterns exported to clipboard")

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2016 Ryan Holmes
#
# This file is part of pyfa.
@@ -15,19 +15,19 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from gui.bitmapLoader import BitmapLoader
from gui.builtinViews.implantEditor import BaseImplantEditorView
import service
from gui.utils.clipboard import toClipboard, fromClipboard
from service.implantSet import ImportError
import logging
import wx
from service.implantSet import ImplantSets
from gui.builtinViews.implantEditor import BaseImplantEditorView
from gui.utils.clipboard import toClipboard, fromClipboard
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator
logger = logging.getLogger(__name__)
class ImplantTextValidor(BaseValidator):
def __init__(self):
BaseValidator.__init__(self)
@@ -47,7 +47,7 @@ class ImplantTextValidor(BaseValidator):
raise ValueError("Imlplant Set name already in use, please choose another.")
return True
except ValueError, e:
except ValueError as e:
wx.MessageBox(u"{}".format(e), "Error")
textCtrl.SetFocus()
return False
@@ -59,25 +59,25 @@ class ImplantSetEntityEditor(EntityEditor):
self.SetEditorValidator(ImplantTextValidor)
def getEntitiesFromContext(self):
sIS = service.ImplantSets.getInstance()
sIS = ImplantSets.getInstance()
return sorted(sIS.getImplantSetList(), key=lambda c: c.name)
def DoNew(self, name):
sIS = service.ImplantSets.getInstance()
sIS = ImplantSets.getInstance()
return sIS.newSet(name)
def DoRename(self, entity, name):
sIS = service.ImplantSets.getInstance()
sIS = ImplantSets.getInstance()
sIS.renameSet(entity, name)
def DoCopy(self, entity, name):
sIS = service.ImplantSets.getInstance()
sIS = ImplantSets.getInstance()
copy = sIS.copySet(entity)
sIS.renameSet(copy, name)
return copy
def DoDelete(self, entity):
sIS = service.ImplantSets.getInstance()
sIS = ImplantSets.getInstance()
sIS.deleteSet(entity)
@@ -91,28 +91,28 @@ class ImplantSetEditor(BaseImplantEditorView):
self.Parent.entityEditor.Bind(wx.EVT_CHOICE, self.contextChanged)
def getImplantsFromContext(self):
sIS = service.ImplantSets.getInstance()
set = self.Parent.entityEditor.getActiveEntity()
if set:
return sIS.getImplants(set.ID)
sIS = ImplantSets.getInstance()
set_ = self.Parent.entityEditor.getActiveEntity()
if set_:
return sIS.getImplants(set_.ID)
return []
def addImplantToContext(self, item):
sIS = service.ImplantSets.getInstance()
set = self.Parent.entityEditor.getActiveEntity()
sIS = ImplantSets.getInstance()
set_ = self.Parent.entityEditor.getActiveEntity()
sIS.addImplant(set.ID, item.ID)
sIS.addImplant(set_.ID, item.ID)
def removeImplantFromContext(self, implant):
sIS = service.ImplantSets.getInstance()
set = self.Parent.entityEditor.getActiveEntity()
sIS = ImplantSets.getInstance()
set_ = self.Parent.entityEditor.getActiveEntity()
sIS.removeImplant(set_.ID, implant)
sIS.removeImplant(set.ID, implant)
class ImplantSetEditorDlg(wx.Dialog):
def __init__(self, parent):
wx.Dialog.__init__(self, parent, id = wx.ID_ANY, title = u"Implant Set Editor", size = wx.Size(640, 600))
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title=u"Implant Set Editor", size=wx.Size(640, 600))
self.block = False
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
@@ -138,25 +138,25 @@ class ImplantSetEditorDlg(wx.Dialog):
footerSizer.Add(self.stNotice, 1, wx.BOTTOM | wx.TOP | wx.LEFT, 5)
if "wxGTK" in wx.PlatformInfo:
self.closeBtn = wx.Button( self, wx.ID_ANY, u"Close", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.closeBtn, 0, wx.ALL|wx.ALIGN_RIGHT, 5 )
self.closeBtn = wx.Button(self, wx.ID_ANY, u"Close", wx.DefaultPosition, wx.DefaultSize, 0)
mainSizer.Add(self.closeBtn, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
self.closeBtn.Bind(wx.EVT_BUTTON, self.closeEvent)
importExport = (("Import", wx.ART_FILE_OPEN, "from"),
("Export", wx.ART_FILE_SAVE_AS, "to"))
for name, art, direction in importExport:
bitmap = wx.ArtProvider.GetBitmap(art, wx.ART_BUTTON)
btn = wx.BitmapButton(self, wx.ID_ANY, bitmap)
bitmap = wx.ArtProvider.GetBitmap(art, wx.ART_BUTTON)
btn = wx.BitmapButton(self, wx.ID_ANY, bitmap)
btn.SetMinSize( btn.GetSize() )
btn.SetMaxSize( btn.GetSize() )
btn.SetMinSize(btn.GetSize())
btn.SetMaxSize(btn.GetSize())
btn.Layout()
setattr(self, name, btn)
btn.Enable(True)
btn.SetToolTipString("%s implant sets %s clipboard" % (name, direction) )
footerSizer.Add(btn, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_RIGHT)
btn.Layout()
setattr(self, name, btn)
btn.Enable(True)
btn.SetToolTipString("%s implant sets %s clipboard" % (name, direction))
footerSizer.Add(btn, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_RIGHT)
mainSizer.Add(footerSizer, 0, wx.ALL | wx.EXPAND, 5)
@@ -183,7 +183,7 @@ class ImplantSetEditorDlg(wx.Dialog):
def closeEvent(self, event):
self.Destroy()
def __del__( self ):
def __del__(self):
pass
def importPatterns(self, event):
@@ -191,14 +191,14 @@ class ImplantSetEditorDlg(wx.Dialog):
text = fromClipboard()
if text:
sIS = service.ImplantSets.getInstance()
sIS = ImplantSets.getInstance()
try:
sIS.importSets(text)
self.stNotice.SetLabel("Patterns successfully imported from clipboard")
self.showInput(False)
except ImportError, e:
except ImportError as e:
self.stNotice.SetLabel(str(e))
except Exception, e:
except Exception as e:
logging.exception("Unhandled Exception")
self.stNotice.SetLabel("Could not import from clipboard: unknown errors")
finally:
@@ -209,6 +209,6 @@ class ImplantSetEditorDlg(wx.Dialog):
def exportPatterns(self, event):
"Event fired when export to clipboard button is clicked"
sIS = service.ImplantSets.getInstance()
sIS = ImplantSets.getInstance()
toClipboard(sIS.exportSets())
self.stNotice.SetLabel("Sets exported to clipboard")

View File

@@ -1,5 +1,4 @@
import wx
import gui.utils.colorUtils as colorUtils
import gui.utils.drawUtils as drawUtils
SB_ITEM_NORMAL = 0
@@ -7,14 +6,15 @@ SB_ITEM_SELECTED = 1
SB_ITEM_HIGHLIGHTED = 2
SB_ITEM_DISABLED = 4
BTN_NORMAL = 1
BTN_PRESSED = 2
BTN_HOVER = 4
BTN_NORMAL = 1
BTN_PRESSED = 2
BTN_HOVER = 4
BTN_DISABLED = 8
class PFBaseButton(object):
def __init__(self, normalBitmap = wx.NullBitmap,label = "", callback = None, hoverBitmap = None, disabledBitmap = None, show = True):
def __init__(self, normalBitmap=wx.NullBitmap, label="", callback=None, hoverBitmap=None, disabledBitmap=None,
show=True):
self.normalBmp = normalBitmap
self.dropShadowOpacity = 0.2
@@ -48,7 +48,7 @@ class PFBaseButton(object):
if self.callback:
self.callback()
def SetState(self, state = BTN_NORMAL):
def SetState(self, state=BTN_NORMAL):
self.state = state
def GetState(self):
@@ -57,7 +57,7 @@ class PFBaseButton(object):
def GetSize(self):
w = self.normalBmp.GetWidth()
h = self.normalBmp.GetHeight()
return (w,h)
return (w, h)
def GetBitmap(self):
return self.normalBmp
@@ -70,22 +70,23 @@ class PFBaseButton(object):
return self.label
def GetHoverBitmap(self):
if self.hoverBmp == None:
if self.hoverBmp is None:
return self.normalBmp
return self.hoverBmp
def GetDisabledBitmap(self):
if self.disabledBmp == None:
if self.disabledBmp is None:
return self.normalBmp
return self.disabledBmp
def GetDropShadowBitmap(self):
return self.dropShadowBmp
class PFToolbar(object):
def __init__(self, parent):
self.Parent = parent
self.buttons =[]
self.buttons = []
self.toolbarX = 0
self.toolbarY = 0
self.padding = 2
@@ -94,7 +95,7 @@ class PFToolbar(object):
def SetPosition(self, pos):
self.toolbarX, self.toolbarY = pos
def AddButton(self, btnBitmap, label = "", clickCallback = None, hoverBitmap = None, disabledBitmap = None, show = True):
def AddButton(self, btnBitmap, label="", clickCallback=None, hoverBitmap=None, disabledBitmap=None, show=True):
btn = PFBaseButton(btnBitmap, label, clickCallback, hoverBitmap, disabledBitmap, show)
self.buttons.append(btn)
return btn
@@ -115,7 +116,7 @@ class PFToolbar(object):
continue
state = button.GetState()
if self.HitTest( (bx, self.toolbarY), event.GetPosition(), button.GetSize()):
if self.HitTest((bx, self.toolbarY), event.GetPosition(), button.GetSize()):
changeCursor = True
if not state & BTN_HOVER:
button.SetState(state | BTN_HOVER)
@@ -135,7 +136,7 @@ class PFToolbar(object):
return doRefresh
def MouseClick(self, event):
mx,my = event.GetPosition()
mx, my = event.GetPosition()
bx = self.toolbarX
for button in self.buttons:
if not button.IsVisible():
@@ -143,8 +144,8 @@ class PFToolbar(object):
state = button.GetState()
if state & BTN_PRESSED:
button.SetState(state ^ BTN_PRESSED )
if self.HitTest( (bx, self.toolbarY), event.GetPosition(), button.GetSize()):
button.SetState(state ^ BTN_PRESSED)
if self.HitTest((bx, self.toolbarY), event.GetPosition(), button.GetSize()):
return button
else:
return False
@@ -158,7 +159,7 @@ class PFToolbar(object):
state = button.GetState()
if self.HitTest( (bx, self.toolbarY), event.GetPosition(), button.GetSize()):
if self.HitTest((bx, self.toolbarY), event.GetPosition(), button.GetSize()):
if event.LeftDown() or event.LeftDClick():
button.SetState(state | BTN_PRESSED)
@@ -230,14 +231,14 @@ class PFToolbar(object):
bmpWidth = bmp.GetWidth()
pdc.DrawBitmap(dropShadowBmp,bx + self.padding / 2, self.toolbarY + self.padding / 2)
pdc.DrawBitmap(dropShadowBmp, bx + self.padding / 2, self.toolbarY + self.padding / 2)
pdc.DrawBitmap(bmp, tbx, by)
bx += bmpWidth + self.padding
class SFBrowserItem(wx.Window):
def __init__(self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = (0,16), style = 0):
def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=(0, 16), style=0):
wx.Window.__init__(self, parent, id, pos, size, style)
self.highlighted = False
@@ -248,7 +249,6 @@ class SFBrowserItem(wx.Window):
self.toolbar = PFToolbar(self)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
@@ -256,8 +256,7 @@ class SFBrowserItem(wx.Window):
if "wxMSW" in wx.PlatformInfo:
self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDown)
self.Bind(wx.EVT_LEFT_DOWN,self.OnLeftDown)
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow)
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
self.Bind(wx.EVT_MOTION, self.OnMotion)
@@ -271,7 +270,7 @@ class SFBrowserItem(wx.Window):
self.RenderBackground()
mdc.DrawBitmap(self.bkBitmap, 0,0)
mdc.DrawBitmap(self.bkBitmap, 0, 0)
self.DrawItem(mdc)
self.toolbar.Render(mdc)
@@ -291,7 +290,7 @@ class SFBrowserItem(wx.Window):
def MouseMove(self, event):
pass
def SetDraggable(self, mode = True):
def SetDraggable(self, mode=True):
self.canBeDragged = mode
def OnLeftUp(self, event):
@@ -302,14 +301,13 @@ class SFBrowserItem(wx.Window):
mposx, mposy = wx.GetMousePosition()
rect = self.GetRect()
rect.top = rect.left = 0
cx,cy = self.ScreenToClient((mposx,mposy))
if not rect.Contains((cx,cy)):
cx, cy = self.ScreenToClient((mposx, mposy))
if not rect.Contains((cx, cy)):
self.SetHighlighted(False)
self.toolbar.ClearState()
self.Refresh()
return
btn = self.toolbar.MouseClick(event)
if btn is not None:
@@ -323,7 +321,6 @@ class SFBrowserItem(wx.Window):
self.MouseLeftUp(event)
def OnLeftDown(self, event):
if not self.HasCapture():
self.CaptureMouse()
@@ -360,10 +357,10 @@ class SFBrowserItem(wx.Window):
def GetType(self):
return -1
def SetSelected(self, select = True):
def SetSelected(self, select=True):
self.selected = select
def SetHighlighted(self, highlight = True):
def SetHighlighted(self, highlight=True):
self.highlighted = highlight
def GetState(self):
@@ -373,7 +370,7 @@ class SFBrowserItem(wx.Window):
elif self.selected:
if self.highlighted:
state = SB_ITEM_SELECTED | SB_ITEM_HIGHLIGHTED
state = SB_ITEM_SELECTED | SB_ITEM_HIGHLIGHTED
else:
state = SB_ITEM_SELECTED
else:
@@ -396,7 +393,7 @@ class SFBrowserItem(wx.Window):
mFactor = 0.45
eFactor = 0.30
elif state == SB_ITEM_SELECTED | SB_ITEM_HIGHLIGHTED:
elif state == SB_ITEM_SELECTED | SB_ITEM_HIGHLIGHTED:
eFactor = 0.3
elif state == SB_ITEM_SELECTED:
eFactor = 0.15
@@ -405,7 +402,7 @@ class SFBrowserItem(wx.Window):
if self.bkBitmap:
if self.bkBitmap.eFactor == eFactor and self.bkBitmap.sFactor == sFactor and self.bkBitmap.mFactor == mFactor \
and rect.width == self.bkBitmap.GetWidth() and rect.height == self.bkBitmap.GetHeight() :
and rect.width == self.bkBitmap.GetWidth() and rect.height == self.bkBitmap.GetHeight():
return
else:
del self.bkBitmap

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,25 +15,27 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from gui.statsView import StatsView
import service
from gui.pyfatogglepanel import TogglePanel
import gui.builtinStatsViews
from gui.contextMenu import ContextMenu
#import gui.builtinViews.fittingView as fv
from service.fit import Fit
import gui.mainFrame
import gui.builtinStatsViews
import gui.globalEvents as GE
# import gui.builtinViews.fittingView as fv
from gui.statsView import StatsView
from gui.contextMenu import ContextMenu
from gui.pyfatogglepanel import TogglePanel
class StatsPane(wx.Panel):
DEFAULT_VIEWS = ["resourcesViewFull", "resistancesViewFull" ,"rechargeViewFull", "firepowerViewFull",
DEFAULT_VIEWS = ["resourcesViewFull", "resistancesViewFull", "rechargeViewFull", "firepowerViewFull",
"capacitorViewFull", "targetingmiscViewFull",
"priceViewFull",]
"priceViewFull"]
def fitChanged(self, event):
sFit = service.Fit.getInstance()
sFit = Fit.getInstance()
fit = sFit.getFit(event.fitID)
for view in self.views:
view.refreshPanel(fit)
@@ -44,7 +46,7 @@ class StatsPane(wx.Panel):
# Use 25% smaller fonts if MAC or force font size to 8 for msw/linux
if "__WXMAC__" in wx.PlatformInfo :
if "__WXMAC__" in wx.PlatformInfo:
self.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
else:
standardFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
@@ -57,7 +59,7 @@ class StatsPane(wx.Panel):
self.views = []
self.nameViewMap = {}
maxviews = len(self.DEFAULT_VIEWS)
i=0
i = 0
for viewName in self.DEFAULT_VIEWS:
tp = TogglePanel(self)
contentPanel = tp.GetContentPane()
@@ -79,19 +81,20 @@ 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.TOP | wx.LEFT | wx.RIGHT, 2)
i+=1
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())
width,height = self.GetSize()
self.SetMinSize((width+9,-1))
width, height = self.GetSize()
self.SetMinSize((width + 9, -1))
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
def contextHandler(self, contentPanel):
viewName = contentPanel.viewName
def handler(event):
menu = ContextMenu.getMenu(None, (viewName,))
if menu is not None:

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,10 +15,12 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
class StatsView(object):
views = {}
def __init__(self):
pass
@@ -39,4 +41,5 @@ class StatsView(object):
def refreshPanel(self, fit):
raise NotImplementedError()
from gui.builtinStatsViews import *
from gui.builtinStatsViews import * # noqa

View File

@@ -1,4 +1,4 @@
#===============================================================================
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
@@ -15,87 +15,95 @@
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# =============================================================================
import wx
from gui.bitmapLoader import BitmapLoader
import config
import service
import dateutil.parser
from service.settings import UpdateSettings as svc_UpdateSettings
class UpdateDialog(wx.Dialog):
def __init__(self, parent, release):
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = "Pyfa Update", pos = wx.DefaultPosition, size = wx.Size( 400,300 ), style = wx.DEFAULT_DIALOG_STYLE )
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title="Pyfa Update", pos=wx.DefaultPosition,
size=wx.Size(400, 300), style=wx.DEFAULT_DIALOG_STYLE)
self.UpdateSettings = service.settings.UpdateSettings.getInstance()
self.UpdateSettings = svc_UpdateSettings.getInstance()
self.releaseInfo = release
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
mainSizer = wx.BoxSizer( wx.VERTICAL )
mainSizer = wx.BoxSizer(wx.VERTICAL)
headSizer = wx.BoxSizer( wx.HORIZONTAL )
headSizer = wx.BoxSizer(wx.HORIZONTAL)
self.headingText = wx.StaticText( self, wx.ID_ANY, "Pyfa Update Available!", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_CENTRE )
self.headingText.Wrap( -1 )
self.headingText.SetFont( wx.Font( 14, 74, 90, 92, False) )
self.headingText = wx.StaticText(self, wx.ID_ANY, "Pyfa Update Available!", wx.DefaultPosition, wx.DefaultSize,
wx.ALIGN_CENTRE)
self.headingText.Wrap(-1)
self.headingText.SetFont(wx.Font(14, 74, 90, 92, False))
headSizer.Add( self.headingText, 1, wx.ALL, 5 )
mainSizer.Add( headSizer, 0, wx.EXPAND, 5 )
headSizer.Add(self.headingText, 1, wx.ALL, 5)
mainSizer.Add(headSizer, 0, wx.EXPAND, 5)
mainSizer.Add( wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ), 0, wx.EXPAND |wx.ALL, 5 )
mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0,
wx.EXPAND | wx.ALL, 5)
versionSizer = wx.BoxSizer( wx.HORIZONTAL )
versionSizer = wx.BoxSizer(wx.HORIZONTAL)
if(self.releaseInfo['prerelease']):
self.releaseText = wx.StaticText( self, wx.ID_ANY, "Pre-release", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT )
self.releaseText.SetFont( wx.Font( 12, 74, 90, 92, False) )
self.releaseText.SetForegroundColour( wx.Colour( 230, 0, 0 ) )
if (self.releaseInfo['prerelease']):
self.releaseText = wx.StaticText(self, wx.ID_ANY, "Pre-release", wx.DefaultPosition, wx.DefaultSize,
wx.ALIGN_RIGHT)
self.releaseText.SetFont(wx.Font(12, 74, 90, 92, False))
self.releaseText.SetForegroundColour(wx.Colour(230, 0, 0))
else:
self.releaseText = wx.StaticText( self, wx.ID_ANY, "Stable", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT )
self.releaseText.SetFont( wx.Font( 12, 74, 90, 90, False) )
self.releaseText = wx.StaticText(self, wx.ID_ANY, "Stable", wx.DefaultPosition, wx.DefaultSize,
wx.ALIGN_RIGHT)
self.releaseText.SetFont(wx.Font(12, 74, 90, 90, False))
self.releaseText.Wrap( -1 )
self.releaseText.Wrap(-1)
versionSizer.Add( self.releaseText, 1, wx.ALL, 5 )
versionSizer.Add(self.releaseText, 1, wx.ALL, 5)
self.versionText = wx.StaticText( self, wx.ID_ANY, self.releaseInfo['tag_name'], wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_LEFT )
self.versionText.Wrap( -1 )
self.versionText.SetFont( wx.Font( 12, 74, 90, 90, False) )
self.versionText = wx.StaticText(self, wx.ID_ANY, self.releaseInfo['tag_name'], wx.DefaultPosition,
wx.DefaultSize, wx.ALIGN_LEFT)
self.versionText.Wrap(-1)
self.versionText.SetFont(wx.Font(12, 74, 90, 90, False))
versionSizer.Add( self.versionText, 1, wx.ALL, 5 )
versionSizer.AddSpacer( ( 15, 5), 0, wx.EXPAND, 5 )
versionSizer.Add(self.versionText, 1, wx.ALL, 5)
versionSizer.AddSpacer((15, 5), 0, wx.EXPAND, 5)
mainSizer.Add( versionSizer, 0, wx.EXPAND, 5 )
mainSizer.AddSpacer( ( 0, 5), 0, wx.EXPAND, 5 )
mainSizer.Add(versionSizer, 0, wx.EXPAND, 5)
mainSizer.AddSpacer((0, 5), 0, wx.EXPAND, 5)
releaseDate = dateutil.parser.parse(self.releaseInfo['published_at'])
notesSizer = wx.BoxSizer( wx.HORIZONTAL )
self.notesTextCtrl = wx.TextCtrl( self, wx.ID_ANY, str(releaseDate.date())+":\n\n"+self.releaseInfo['body'], wx.DefaultPosition, wx.DefaultSize, wx.TE_AUTO_URL|wx.TE_MULTILINE|wx.TE_READONLY|wx.DOUBLE_BORDER|wx.TRANSPARENT_WINDOW )
notesSizer = wx.BoxSizer(wx.HORIZONTAL)
self.notesTextCtrl = wx.TextCtrl(self, wx.ID_ANY, str(releaseDate.date()) + ":\n\n" + self.releaseInfo['body'],
wx.DefaultPosition, wx.DefaultSize,
wx.TE_AUTO_URL | wx.TE_MULTILINE | wx.TE_READONLY | wx.DOUBLE_BORDER | wx.TRANSPARENT_WINDOW)
notesSizer.Add( self.notesTextCtrl, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 5 )
mainSizer.Add( notesSizer, 1, wx.EXPAND, 5 )
notesSizer.Add(self.notesTextCtrl, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, 5)
mainSizer.Add(notesSizer, 1, wx.EXPAND, 5)
self.supressCheckbox = wx.CheckBox( self, wx.ID_ANY, "Don't remind me again for this release", wx.DefaultPosition, wx.DefaultSize, 0 )
self.supressCheckbox = wx.CheckBox(self, wx.ID_ANY, "Don't remind me again for this release",
wx.DefaultPosition, wx.DefaultSize, 0)
self.supressCheckbox.Bind(wx.EVT_CHECKBOX, self.SuppressChange)
mainSizer.Add( self.supressCheckbox, 0, wx.ALL, 5 )
mainSizer.Add( wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ), 0, wx.EXPAND |wx.ALL, 5 )
mainSizer.Add(self.supressCheckbox, 0, wx.ALL, 5)
mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0,
wx.EXPAND | wx.ALL, 5)
actionSizer = wx.BoxSizer( wx.HORIZONTAL )
actionSizer = wx.BoxSizer(wx.HORIZONTAL)
goSizer = wx.BoxSizer( wx.VERTICAL )
self.downloadButton = wx.Button( self, wx.ID_ANY, "Download", wx.DefaultPosition, wx.DefaultSize, 0 )
goSizer = wx.BoxSizer(wx.VERTICAL)
self.downloadButton = wx.Button(self, wx.ID_ANY, "Download", wx.DefaultPosition, wx.DefaultSize, 0)
self.downloadButton.Bind(wx.EVT_BUTTON, self.OnDownload)
goSizer.Add( self.downloadButton, 0, wx.ALL, 5 )
actionSizer.Add( goSizer, 1, wx.EXPAND, 5 )
goSizer.Add(self.downloadButton, 0, wx.ALL, 5)
actionSizer.Add(goSizer, 1, wx.EXPAND, 5)
self.closeButton = wx.Button(self, wx.ID_CLOSE)
self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
actionSizer.Add( self.closeButton, 0, wx.ALL, 5 )
mainSizer.Add( actionSizer, 0, wx.EXPAND, 5 )
actionSizer.Add(self.closeButton, 0, wx.ALL, 5)
mainSizer.Add(actionSizer, 0, wx.EXPAND, 5)
self.SetSizer( mainSizer )
self.SetSizer(mainSizer)
self.Layout()
# Handle use-case of suppressing a release, then a new version becoming available.
@@ -104,7 +112,7 @@ class UpdateDialog(wx.Dialog):
# safely reset this setting
self.UpdateSettings.set('version', None)
self.Centre( wx.BOTH )
self.Centre(wx.BOTH)
def OnClose(self, e):
self.Close()
@@ -116,5 +124,5 @@ class UpdateDialog(wx.Dialog):
self.UpdateSettings.set('version', None)
def OnDownload(self, e):
wx.LaunchDefaultBrowser('https://github.com/pyfa-org/Pyfa/releases/tag/'+self.releaseInfo['tag_name'])
wx.LaunchDefaultBrowser('https://github.com/pyfa-org/Pyfa/releases/tag/' + self.releaseInfo['tag_name'])
self.OnClose(e)

View File

@@ -1,83 +1,97 @@
import math
def OUT_CIRC (t, b, c, d):
t=float(t)
b=float(b)
c=float(c)
d=float(d)
t = t/d -1
return c * math.sqrt(1 - t*t) + b;
def OUT_CIRC(t, b, c, d):
t = float(t)
b = float(b)
c = float(c)
d = float(d)
t = t / d - 1
return c * math.sqrt(1 - t * t) + b
def OUT_QUART(t, b, c, d):
t=float(t)
b=float(b)
c=float(c)
d=float(d)
t = t/d -1
return -c * ((t)*t*t*t - 1) + b;
t = float(t)
b = float(b)
c = float(c)
d = float(d)
t = t / d - 1
return -c * (t * t * t * t - 1) + b
def INOUT_CIRC(t, b, c, d):
t=float(t)
b=float(b)
c=float(c)
d=float(d)
t = float(t)
b = float(b)
c = float(c)
d = float(d)
t1 = t / (d / 2)
if ((t / (d/2)) < 1):
return -c/2 * (math.sqrt(1 - (t/(d/2))**2) - 1) + b
return c/2 * (math.sqrt(1 - (t1-2)**2) + 1) + b;
def IN_CUBIC (t, b, c, d):
t=float(t)
b=float(b)
c=float(c)
d=float(d)
t = t/d
return c*t*t*t + b
def OUT_QUAD (t, b, c, d):
t=float(t)
b=float(b)
c=float(c)
d=float(d)
t/=d
return -c *(t)*(t-2) + b
def OUT_BOUNCE (t, b, c, d):
t=float(t)
b=float(b)
c=float(c)
d=float(d)
t/=d
if ((t) < (1/2.75)):
return c*(7.5625*t*t) + b
if (t / (d / 2)) < 1:
return -c / 2 * (math.sqrt(1 - (t / (d / 2)) ** 2) - 1) + b
else:
if (t < (2/2.75)):
t-=(1.5/2.75)
return c*(7.5625*t*t + .75) + b
else:
if (t < (2.5/2.75)):
t-=(2.25/2.75)
return c*(7.5625*(t)*t + .9375) + b
else:
t-=(2.625/2.75)
return c*(7.5625*(t)*t + .984375) + b
return c / 2 * (math.sqrt(1 - (t1 - 2) ** 2) + 1) + b
def IN_CUBIC(t, b, c, d):
t = float(t)
b = float(b)
c = float(c)
d = float(d)
t = t / d
return c * t * t * t + b
def OUT_QUAD(t, b, c, d):
t = float(t)
b = float(b)
c = float(c)
d = float(d)
t /= d
return -c * t * (t - 2) + b
def OUT_BOUNCE(t, b, c, d):
t = float(t)
b = float(b)
c = float(c)
d = float(d)
t /= d
if t < (1 / 2.75):
return c * (7.5625 * t * t) + b
elif t < (2 / 2.75):
t -= (1.5 / 2.75)
return c * (7.5625 * t * t + .75) + b
elif t < (2.5 / 2.75):
t -= (2.25 / 2.75)
return c * (7.5625 * t * t + .9375) + b
else:
t -= (2.625 / 2.75)
return c * (7.5625 * t * t + .984375) + b
def INOUT_EXP(t, b, c, d):
t=float(t)
b=float(b)
c=float(c)
d=float(d)
t1 = t / (d/2)
if t==0:
return b
if t==d:
return b+c
if (t1) < 1:
return c/2 * math.pow(2, 10 * (t1 - 1)) + b - c * 0.0005
return c/2 * 1.0005 * (-math.pow(2, -10 * (t1-1)) + 2) + b
t = float(t)
b = float(b)
c = float(c)
d = float(d)
t1 = t / (d / 2)
if t == 0:
return b
elif t == d:
return b + c
elif t1 < 1:
return c / 2 * math.pow(2, 10 * (t1 - 1)) + b - c * 0.0005
else:
return c / 2 * 1.0005 * (-math.pow(2, -10 * (t1 - 1)) + 2) + b

Some files were not shown because too many files have changed in this diff Show More