Merge branch 'development' into More_Variations
Conflicts: gui/builtinContextMenus/metaSwap.py
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,13 +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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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 +32,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,23 +69,22 @@ 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
|
||||
|
||||
# is it before the left edge?
|
||||
if cr.x < 0 and sppu_x > 0:
|
||||
if cr.x < 0 < sppu_x:
|
||||
new_vs_x = vs_x + (cr.x / sppu_x)
|
||||
|
||||
# is it above the top?
|
||||
if cr.y < 0 and sppu_y > 0:
|
||||
if cr.y < 0 < sppu_y:
|
||||
new_vs_y = vs_y + (cr.y / sppu_y)
|
||||
|
||||
# For the right and bottom edges, scroll enough to show the
|
||||
@@ -110,8 +111,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 +123,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 +140,14 @@ 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) ):
|
||||
for i in xrange(len(self._wList)):
|
||||
iwidth, iheight = self._wList[i].GetSize()
|
||||
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 +155,6 @@ class PFListPane(wx.ScrolledWindow):
|
||||
child.Destroy()
|
||||
self._wList.remove(child)
|
||||
|
||||
|
||||
def RemoveAllChildren(self):
|
||||
for widget in self._wList:
|
||||
widget.Destroy()
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
# noinspection PyPackageRequirements
|
||||
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 +35,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 +51,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 +69,11 @@ 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("")
|
||||
@staticmethod
|
||||
def OnEditSetFocus(event):
|
||||
# value = self.EditBox.GetValue()
|
||||
# if value == self.descriptiveText:
|
||||
# self.EditBox.ChangeValue("")
|
||||
event.Skip()
|
||||
|
||||
def OnEditKillFocus(self, event):
|
||||
@@ -80,10 +81,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()
|
||||
@@ -104,14 +104,15 @@ class PFSearchBox(wx.Window):
|
||||
x, y = target
|
||||
px, py = position
|
||||
aX, aY = area
|
||||
if (px > x and px < x + aX) and (py > y and py < y + aY):
|
||||
if (x < px < x + aX) and (y < py < y + aY):
|
||||
return True
|
||||
return False
|
||||
|
||||
def GetButtonsPos(self):
|
||||
btnpos = []
|
||||
btnpos.append( (self.searchButtonX, self.searchButtonY) )
|
||||
btnpos.append( (self.cancelButtonX, self.cancelButtonY) )
|
||||
btnpos = [
|
||||
(self.searchButtonX, self.searchButtonY),
|
||||
(self.cancelButtonX, self.cancelButtonY)
|
||||
]
|
||||
return btnpos
|
||||
|
||||
def GetButtonsSize(self):
|
||||
@@ -131,8 +132,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 +141,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 +159,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 +219,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 +247,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 +256,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 +273,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 +284,3 @@ class PFSearchBox(wx.Window):
|
||||
|
||||
def GetDescriptiveText(self):
|
||||
return self.descriptiveText
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,10 +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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import gui.mainFrame
|
||||
from gui.boosterView import BoosterView
|
||||
from gui.droneView import DroneView
|
||||
from gui.fighterView import FighterView
|
||||
@@ -31,13 +31,13 @@ from gui.notesView import NotesView
|
||||
from gui.pyfatogglepanel import TogglePanel
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
import gui.chromeTabs
|
||||
from gui.chromeTabs import PFNotebook
|
||||
|
||||
|
||||
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()
|
||||
@@ -45,9 +45,7 @@ class AdditionsPane(TogglePanel):
|
||||
baseSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
pane.SetSizer(baseSizer)
|
||||
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
self.notebook = gui.chromeTabs.PFNotebook(pane, False)
|
||||
self.notebook = PFNotebook(pane, False)
|
||||
self.notebook.SetMinSize((-1, 1000))
|
||||
|
||||
baseSizer.Add(self.notebook, 1, wx.EXPAND)
|
||||
@@ -62,28 +60,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)
|
||||
|
||||
@@ -92,20 +90,17 @@ class AdditionsPane(TogglePanel):
|
||||
def select(self, name):
|
||||
self.notebook.SetSelection(self.PANES.index(name))
|
||||
|
||||
def toggleBoosters(self, event):
|
||||
self.notebook.ToggleShown(self.booster)
|
||||
|
||||
def getName(self, idx):
|
||||
return self.PANES[idx]
|
||||
|
||||
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 +109,3 @@ class AdditionsPane(TogglePanel):
|
||||
self.parent.SetSashInvisible(False)
|
||||
self.parent.SetMinimumPaneSize(200)
|
||||
self.parent.SetSashPosition(self.old_pos, True)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,24 +15,32 @@
|
||||
#
|
||||
# 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.path
|
||||
import config
|
||||
import wx
|
||||
import zipfile
|
||||
import cStringIO
|
||||
import os.path
|
||||
import zipfile
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
import config
|
||||
|
||||
from logbook import Logger
|
||||
logging = Logger(__name__)
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
from utils.compat import OrderedDict
|
||||
|
||||
class BitmapLoader():
|
||||
|
||||
class BitmapLoader(object):
|
||||
try:
|
||||
archive = zipfile.ZipFile(os.path.join(config.pyfaPath, 'imgs.zip'), 'r')
|
||||
logging.info("Using zipped image files.")
|
||||
except IOError:
|
||||
logging.info("Using local image files.")
|
||||
archive = None
|
||||
|
||||
cachedBitmaps = OrderedDict()
|
||||
@@ -42,7 +50,7 @@ class BitmapLoader():
|
||||
@classmethod
|
||||
def getStaticBitmap(cls, name, parent, location):
|
||||
static = wx.StaticBitmap(parent)
|
||||
static.SetBitmap(cls.getBitmap(name,location))
|
||||
static.SetBitmap(cls.getBitmap(name, location))
|
||||
return static
|
||||
|
||||
@classmethod
|
||||
@@ -83,11 +91,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 = os.path.join(config.pyfaPath, 'imgs', location, filename)
|
||||
path = os.path.join(config.pyfaPath, 'imgs' + os.sep + location + os.sep + 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))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,29 +15,32 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import service
|
||||
import gui.display as d
|
||||
import gui.globalEvents as GE
|
||||
import gui.marketBrowser as mb
|
||||
import gui.marketBrowser as marketBrowser
|
||||
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, *args, **kwargs):
|
||||
super(BoosterViewDrop, self).__init__(*args, **kwargs)
|
||||
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",
|
||||
@@ -50,7 +53,7 @@ class BoosterView(d.Display):
|
||||
self.lastFitId = None
|
||||
|
||||
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
|
||||
self.mainFrame.Bind(mb.ITEM_SELECTED, self.addItem)
|
||||
self.mainFrame.Bind(marketBrowser.ITEM_SELECTED, self.addItem)
|
||||
|
||||
self.Bind(wx.EVT_LEFT_DCLICK, self.removeItem)
|
||||
self.Bind(wx.EVT_LEFT_DOWN, self.click)
|
||||
@@ -58,24 +61,24 @@ 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)
|
||||
|
||||
def handleListDrag(self, x, y, data):
|
||||
'''
|
||||
"""
|
||||
Handles dragging of items from various pyfa displays which support it
|
||||
|
||||
data is list with two indices:
|
||||
data[0] is hard-coded str of originating source
|
||||
data[1] is typeID or index of data we want to manipulate
|
||||
'''
|
||||
"""
|
||||
|
||||
if data[0] == "market":
|
||||
wx.PostEvent(self.mainFrame, mb.ItemSelected(itemID=int(data[1])))
|
||||
wx.PostEvent(self.mainFrame, marketBrowser.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 +88,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 +118,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 +142,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 +153,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 +165,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]
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
__all__ = [
|
||||
"openFit",
|
||||
#"moduleGlobalAmmoPicker",
|
||||
# "moduleGlobalAmmoPicker",
|
||||
"moduleAmmoPicker",
|
||||
"itemStats",
|
||||
"damagePattern",
|
||||
|
||||
@@ -1,35 +1,38 @@
|
||||
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
|
||||
# noinspection PyPackageRequirements
|
||||
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()
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
from gui.contextMenu import ContextMenu
|
||||
from gui.itemStats import ItemStatsDialog
|
||||
import eos.types
|
||||
from eos.saveddata.fit import Fit as es_Fit
|
||||
import gui.mainFrame
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
# noinspection PyPackageRequirements
|
||||
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 +24,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,31 +50,36 @@ class AmountChanger(wx.Dialog):
|
||||
self.button.Bind(wx.EVT_BUTTON, self.change)
|
||||
|
||||
def change(self, event):
|
||||
sFit = service.Fit.getInstance()
|
||||
if self.input.GetLineText(0).strip() == '':
|
||||
event.Skip()
|
||||
self.Close()
|
||||
return
|
||||
|
||||
sFit = Fit.getInstance()
|
||||
mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
fitID = mainFrame.getActiveFit()
|
||||
|
||||
if isinstance(self.thing, eos.types.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):
|
||||
sFit.changeActiveFighters(fitID, self.thing, int(self.input.GetLineText(0)))
|
||||
if isinstance(self.thing, es_Cargo):
|
||||
sFit.addCargo(fitID, self.thing.item.ID, int(float(self.input.GetLineText(0))), replace=True)
|
||||
elif isinstance(self.thing, es_Fit):
|
||||
sFit.changeAmount(fitID, self.thing, int(float(self.input.GetLineText(0))))
|
||||
elif isinstance(self.thing, es_Fighter):
|
||||
sFit.changeActiveFighters(fitID, self.thing, int(float(self.input.GetLineText(0))))
|
||||
|
||||
wx.PostEvent(mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
event.Skip()
|
||||
self.Close()
|
||||
|
||||
## checks to make sure it's valid number
|
||||
def onChar(self, event):
|
||||
# checks to make sure it's valid number
|
||||
@staticmethod
|
||||
def onChar(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
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
from gui.contextMenu import ContextMenu
|
||||
from gui.itemStats import ItemStatsDialog
|
||||
import eos.types
|
||||
import gui.mainFrame
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
# noinspection PyPackageRequirements
|
||||
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 +24,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 +32,5 @@ class Cargo(ContextMenu):
|
||||
self.mainFrame.additionsPane.select("Cargo")
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
|
||||
Cargo.register()
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import service
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from eos.types import Skill
|
||||
from eos.saveddata.character 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 +18,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 +102,5 @@ class ChangeAffectingSkills(ContextMenu):
|
||||
wx.PostEvent(self.mainFrame, GE.CharListUpdated())
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
|
||||
ChangeAffectingSkills.register()
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
# noinspection PyPackageRequirements
|
||||
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
|
||||
from utils.compat import OrderedDict
|
||||
|
||||
|
||||
class DamagePattern(ContextMenu):
|
||||
def __init__(self):
|
||||
@@ -18,8 +21,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 +37,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 +62,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 +101,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()
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import service
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import gui.globalEvents as GE
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
class ItemRemove(ContextMenu):
|
||||
def __init__(self):
|
||||
@@ -15,7 +17,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 +26,5 @@ class ItemRemove(ContextMenu):
|
||||
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
|
||||
ItemRemove.register()
|
||||
|
||||
@@ -1,59 +1,60 @@
|
||||
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
|
||||
# noinspection PyPackageRequirements
|
||||
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()
|
||||
|
||||
@@ -1,35 +1,37 @@
|
||||
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
|
||||
# noinspection PyPackageRequirements
|
||||
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()
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# noinspection PyPackageRequirements
|
||||
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 +50,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()
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
# noinspection PyPackageRequirements
|
||||
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 +36,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 +63,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 +71,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])
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import service
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import gui.globalEvents as GE
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
class ItemRemove(ContextMenu):
|
||||
def __init__(self):
|
||||
@@ -21,15 +23,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 +49,4 @@ class ItemRemove(ContextMenu):
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
|
||||
|
||||
|
||||
ItemRemove.register()
|
||||
|
||||
@@ -1,65 +1,68 @@
|
||||
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
|
||||
# noinspection PyPackageRequirements
|
||||
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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from gui.contextMenu import ContextMenu
|
||||
from gui.itemStats import ItemStatsDialog
|
||||
import gui.mainFrame
|
||||
import service
|
||||
# coding: utf-8
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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):
|
||||
@@ -23,7 +27,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])
|
||||
@@ -47,7 +51,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):
|
||||
@@ -94,10 +99,10 @@ class MetaSwap(ContextMenu):
|
||||
event.Skip()
|
||||
return
|
||||
|
||||
sFit = service.Fit.getInstance()
|
||||
sFit = Fit.getInstance()
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
fit = sFit.getFit(fitID)
|
||||
|
||||
|
||||
for selected_item in self.selection:
|
||||
if type(selected_item).__name__== 'Module':
|
||||
pos = fit.modules.index(selected_item)
|
||||
@@ -153,4 +158,5 @@ class MetaSwap(ContextMenu):
|
||||
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
|
||||
MetaSwap.register()
|
||||
|
||||
@@ -1,223 +1,233 @@
|
||||
# -*- 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
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
from service.fit import Fit
|
||||
from service.market import Market
|
||||
from eos.saveddata.module 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
|
||||
|
||||
@staticmethod
|
||||
def numericConverter(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
|
||||
|
||||
@staticmethod
|
||||
def addSeperator(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 and item and base:
|
||||
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()
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import service
|
||||
# noinspection PyPackageRequirements
|
||||
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 eos.db.saveddata.queries import getFit as db_getFit
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
class ModuleGlobalAmmoPicker(ModuleAmmoPicker):
|
||||
def __init__(self):
|
||||
super(ModuleGlobalAmmoPicker, self).__init__()
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def getText(self, itmContext, selection):
|
||||
@@ -26,9 +26,9 @@ class ModuleGlobalAmmoPicker(ModuleAmmoPicker):
|
||||
event.Skip()
|
||||
return
|
||||
|
||||
sFit = service.Fit.getInstance()
|
||||
sFit = Fit.getInstance()
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
fit = eos.db.getFit(fitID)
|
||||
fit = db_getFit(fitID)
|
||||
|
||||
selectedModule = self.modules[0]
|
||||
allModules = []
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from gui.shipBrowser import FitSelected
|
||||
|
||||
|
||||
class OpenFit(ContextMenu):
|
||||
def __init__(self):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
@@ -17,4 +19,5 @@ class OpenFit(ContextMenu):
|
||||
fit = selection[0]
|
||||
wx.PostEvent(self.mainFrame, FitSelected(fitID=fit.ID, startup=2))
|
||||
|
||||
|
||||
OpenFit.register()
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import gui.globalEvents as GE
|
||||
import service
|
||||
from service.market import Market
|
||||
|
||||
|
||||
class PriceClear(ContextMenu):
|
||||
def __init__(self):
|
||||
@@ -15,8 +17,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()
|
||||
|
||||
@@ -1,37 +1,39 @@
|
||||
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
|
||||
# noinspection PyPackageRequirements
|
||||
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()
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# noinspection PyPackageRequirements
|
||||
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 +18,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()
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
# noinspection PyPackageRequirements
|
||||
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 +15,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 +55,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()
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
# noinspection PyPackageRequirements
|
||||
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
|
||||
from utils.compat import OrderedDict
|
||||
|
||||
|
||||
class TargetResists(ContextMenu):
|
||||
def __init__(self):
|
||||
@@ -18,7 +21,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 +36,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 +53,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 +67,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 +96,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 +104,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()
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import gui.globalEvents as GE
|
||||
import service
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from service.market import Market
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
class WhProjector(ContextMenu):
|
||||
def __init__(self):
|
||||
@@ -16,7 +19,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 +44,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()
|
||||
|
||||
@@ -1 +1 @@
|
||||
__all__ = ["fitDps"]
|
||||
__all__ = ["fitDps"]
|
||||
|
||||
@@ -1,94 +1,95 @@
|
||||
#===============================================================================
|
||||
# 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.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
|
||||
|
||||
class FitDpsGraph(Graph):
|
||||
propertyAttributeMap = {"angle": "maxVelocity",
|
||||
"distance": "maxRange",
|
||||
"signatureRadius": "signatureRadius",
|
||||
"velocity": "maxVelocity"}
|
||||
|
||||
propertyLabelMap = {"angle": "Target Angle (degrees)",
|
||||
"distance": "Distance to Target (km)",
|
||||
"signatureRadius": "Target Signature Radius (m)",
|
||||
"velocity": "Target Velocity (m/s)"}
|
||||
|
||||
defaults = FitDps.defaults.copy()
|
||||
|
||||
def __init__(self):
|
||||
Graph.__init__(self)
|
||||
self.defaults["distance"] = "0-20"
|
||||
self.name = "DPS"
|
||||
self.fitDps = None
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def getFields(self):
|
||||
return self.defaults
|
||||
|
||||
def getLabels(self):
|
||||
return self.propertyLabelMap
|
||||
|
||||
def getIcons(self):
|
||||
icons = {}
|
||||
sAttr = service.Attribute.getInstance()
|
||||
for key, attrName in self.propertyAttributeMap.iteritems():
|
||||
iconFile = sAttr.getAttributeInfo(attrName).icon.iconFile
|
||||
bitmap = BitmapLoader.getBitmap(iconFile, "icons")
|
||||
if bitmap:
|
||||
icons[key] = bitmap
|
||||
|
||||
return icons
|
||||
|
||||
def getPoints(self, fit, fields):
|
||||
fitDps = getattr(self, "fitDps", None)
|
||||
if fitDps is None or fitDps.fit != fit:
|
||||
fitDps = self.fitDps = FitDps(fit)
|
||||
|
||||
fitDps.clearData()
|
||||
variable = None
|
||||
for fieldName, value in fields.iteritems():
|
||||
d = Data(fieldName, value)
|
||||
if not d.isConstant():
|
||||
if variable is None:
|
||||
variable = fieldName
|
||||
else:
|
||||
#We can't handle more then one variable atm, OOPS FUCK OUT
|
||||
return False, "Can only handle 1 variable"
|
||||
|
||||
fitDps.setData(d)
|
||||
|
||||
if variable is None:
|
||||
return False, "No variable"
|
||||
|
||||
x = []
|
||||
y = []
|
||||
for point, val in fitDps.getIterator():
|
||||
x.append(point[variable])
|
||||
y.append(val)
|
||||
|
||||
return x, y
|
||||
|
||||
FitDpsGraph.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.graph import Graph
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from eos.graph.fitDps import FitDpsGraph as FitDps
|
||||
from eos.graph import Data
|
||||
import gui.mainFrame
|
||||
from service.attribute import Attribute
|
||||
|
||||
|
||||
class FitDpsGraph(Graph):
|
||||
propertyAttributeMap = {"angle": "maxVelocity",
|
||||
"distance": "maxRange",
|
||||
"signatureRadius": "signatureRadius",
|
||||
"velocity": "maxVelocity"}
|
||||
|
||||
propertyLabelMap = {"angle": "Target Angle (degrees)",
|
||||
"distance": "Distance to Target (km)",
|
||||
"signatureRadius": "Target Signature Radius (m)",
|
||||
"velocity": "Target Velocity (m/s)"}
|
||||
|
||||
defaults = FitDps.defaults.copy()
|
||||
|
||||
def __init__(self):
|
||||
Graph.__init__(self)
|
||||
self.defaults["distance"] = "0-20"
|
||||
self.name = "DPS"
|
||||
self.fitDps = None
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def getFields(self):
|
||||
return self.defaults
|
||||
|
||||
def getLabels(self):
|
||||
return self.propertyLabelMap
|
||||
|
||||
def getIcons(self):
|
||||
icons = {}
|
||||
sAttr = Attribute.getInstance()
|
||||
for key, attrName in self.propertyAttributeMap.iteritems():
|
||||
iconFile = sAttr.getAttributeInfo(attrName).icon.iconFile
|
||||
bitmap = BitmapLoader.getBitmap(iconFile, "icons")
|
||||
if bitmap:
|
||||
icons[key] = bitmap
|
||||
|
||||
return icons
|
||||
|
||||
def getPoints(self, fit, fields):
|
||||
fitDps = getattr(self, "fitDps", None)
|
||||
if fitDps is None or fitDps.fit != fit:
|
||||
fitDps = self.fitDps = FitDps(fit)
|
||||
|
||||
fitDps.clearData()
|
||||
variable = None
|
||||
for fieldName, value in fields.iteritems():
|
||||
d = Data(fieldName, value)
|
||||
if not d.isConstant():
|
||||
if variable is None:
|
||||
variable = fieldName
|
||||
else:
|
||||
# We can't handle more then one variable atm, OOPS FUCK OUT
|
||||
return False, "Can only handle 1 variable"
|
||||
|
||||
fitDps.setData(d)
|
||||
|
||||
if variable is None:
|
||||
return False, "No variable"
|
||||
|
||||
x = []
|
||||
y = []
|
||||
for point, val in fitDps.getIterator():
|
||||
x.append(point[variable])
|
||||
y.append(val)
|
||||
|
||||
return x, y
|
||||
|
||||
|
||||
FitDpsGraph.register()
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
__all__ = ["pyfaGeneralPreferences","pyfaHTMLExportPreferences","pyfaUpdatePreferences","pyfaNetworkPreferences"]
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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")
|
||||
|
||||
@@ -1,94 +1,95 @@
|
||||
#===============================================================================
|
||||
# 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/>.
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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()
|
||||
|
||||
@@ -1,104 +1,117 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
from gui.preferenceView import PreferenceView
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
import gui.mainFrame
|
||||
import service
|
||||
from service.crest import CrestModes
|
||||
|
||||
from service.settings import CRESTSettings
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
from wx.lib.intctrl import IntCtrl
|
||||
|
||||
class PFCrestPref ( PreferenceView):
|
||||
if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0)):
|
||||
from service.crest import Crest
|
||||
|
||||
|
||||
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 +120,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 +147,5 @@ class PFCrestPref ( PreferenceView):
|
||||
def getImage(self):
|
||||
return BitmapLoader.getBitmap("eve", "gui")
|
||||
|
||||
|
||||
PFCrestPref.register()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import copy
|
||||
|
||||
@@ -10,13 +11,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 +31,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 +59,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 +82,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 +100,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 +122,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 +359,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 +377,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 +391,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 +418,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):
|
||||
@@ -414,16 +426,17 @@ class PFGaugePref ( PreferenceView):
|
||||
self.SetColours()
|
||||
event.Skip()
|
||||
|
||||
def OnOk(self, event):
|
||||
#Apply New Settings
|
||||
@staticmethod
|
||||
def OnOk(event):
|
||||
# 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 +491,8 @@ class PFGaugePref ( PreferenceView):
|
||||
self.SetColours()
|
||||
event.Skip()
|
||||
|
||||
def __del__( self ):
|
||||
def __del__(self):
|
||||
pass
|
||||
|
||||
|
||||
PFGaugePref.register()
|
||||
|
||||
@@ -1,76 +1,99 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
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
|
||||
from service.price import Price
|
||||
from service.market import Market
|
||||
|
||||
|
||||
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()
|
||||
priceSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
self.stDefaultSystem = wx.StaticText(panel, wx.ID_ANY, u"Default Market Prices:", wx.DefaultPosition, wx.DefaultSize, 0)
|
||||
self.stDefaultSystem.Wrap(-1)
|
||||
priceSizer.Add(self.stDefaultSystem, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
|
||||
|
||||
self.chPriceSystem = wx.Choice(panel, choices=Price.systemsList.keys())
|
||||
priceSizer.Add(self.chPriceSystem, 1, wx.ALL | wx.EXPAND, 5)
|
||||
|
||||
mainSizer.Add(priceSizer, 0, wx.ALL | wx.EXPAND, 0)
|
||||
|
||||
self.sFit = Fit.getInstance()
|
||||
|
||||
self.cbGlobalChar.SetValue(self.sFit.serviceFittingOptions["useGlobalCharacter"])
|
||||
self.cbGlobalDmgPattern.SetValue(self.sFit.serviceFittingOptions["useGlobalDamagePattern"])
|
||||
@@ -85,6 +108,7 @@ class PFGeneralPref ( PreferenceView):
|
||||
self.cbGaugeAnimation.SetValue(self.sFit.serviceFittingOptions["enableGaugeAnimation"])
|
||||
self.cbExportCharges.SetValue(self.sFit.serviceFittingOptions["exportCharges"])
|
||||
self.cbOpenFitInNew.SetValue(self.sFit.serviceFittingOptions["openFitInNew"])
|
||||
self.chPriceSystem.SetStringSelection(self.sFit.serviceFittingOptions["priceSystem"])
|
||||
|
||||
self.cbGlobalChar.Bind(wx.EVT_CHECKBOX, self.OnCBGlobalCharStateChange)
|
||||
self.cbGlobalDmgPattern.Bind(wx.EVT_CHECKBOX, self.OnCBGlobalDmgPatternStateChange)
|
||||
@@ -99,10 +123,11 @@ class PFGeneralPref ( PreferenceView):
|
||||
self.cbGaugeAnimation.Bind(wx.EVT_CHECKBOX, self.onCBGaugeAnimation)
|
||||
self.cbExportCharges.Bind(wx.EVT_CHECKBOX, self.onCBExportCharges)
|
||||
self.cbOpenFitInNew.Bind(wx.EVT_CHECKBOX, self.onCBOpenFitInNew)
|
||||
self.chPriceSystem.Bind(wx.EVT_CHOICE, self.onPriceSelection)
|
||||
|
||||
self.cbRackLabels.Enable(self.sFit.serviceFittingOptions["rackSlots"] or False)
|
||||
|
||||
panel.SetSizer( mainSizer )
|
||||
panel.SetSizer(mainSizer)
|
||||
panel.Layout()
|
||||
|
||||
def onCBGlobalColorBySlot(self, event):
|
||||
@@ -163,11 +188,25 @@ 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()
|
||||
def onPriceSelection(self, event):
|
||||
system = self.chPriceSystem.GetString(self.chPriceSystem.GetSelection())
|
||||
self.sFit.serviceFittingOptions["priceSystem"] = system
|
||||
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
|
||||
sMkt = Market.getInstance()
|
||||
sMkt.clearPriceCache()
|
||||
|
||||
self.sFit.refreshFit(fitID)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
event.Skip()
|
||||
|
||||
|
||||
PFGeneralPref.register()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import os
|
||||
|
||||
@@ -5,78 +6,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 +99,5 @@ class PFHTMLExportPref ( PreferenceView):
|
||||
def getImage(self):
|
||||
return BitmapLoader.getBitmap("prefs_html", "gui")
|
||||
|
||||
|
||||
PFHTMLExportPref.register()
|
||||
|
||||
@@ -1,53 +1,58 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
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 +66,9 @@ class PFNetworkPref ( PreferenceView):
|
||||
|
||||
self.toggleNetworks(self.cbEnableNetwork.GetValue())
|
||||
|
||||
#---------------
|
||||
# ---------------
|
||||
# Proxy
|
||||
#---------------
|
||||
# ---------------
|
||||
|
||||
self.nMode = self.settings.getMode()
|
||||
self.nAddr = self.settings.getAddress()
|
||||
@@ -73,51 +78,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 +133,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 +164,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 +240,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 +268,5 @@ class PFNetworkPref ( PreferenceView):
|
||||
def getImage(self):
|
||||
return BitmapLoader.getBitmap("prefs_proxy", "gui")
|
||||
|
||||
|
||||
PFNetworkPref.register()
|
||||
|
||||
@@ -1,84 +1,83 @@
|
||||
# noinspection PyPackageRequirements
|
||||
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 )
|
||||
if self.UpdateSettings.get('version'):
|
||||
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 +95,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()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,24 +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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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 +107,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:
|
||||
@@ -127,8 +131,8 @@ class CapacitorViewFull(StatsView):
|
||||
capStable = fit.capStable if fit is not None else False
|
||||
lblNameTime = "label%sCapacitorTime"
|
||||
lblNameState = "label%sCapacitorState"
|
||||
if isinstance(capState, tuple):
|
||||
t = "%.1f%%-%.1f%%" % capState
|
||||
if isinstance(capState, tuple) and len(capState) >= 2:
|
||||
t = ("{0}%-{1}%", capState[0], capState[1])
|
||||
s = ""
|
||||
else:
|
||||
if capStable:
|
||||
@@ -147,4 +151,5 @@ class CapacitorViewFull(StatsView):
|
||||
self.panel.Layout()
|
||||
self.headerPanel.Layout()
|
||||
|
||||
|
||||
CapacitorViewFull.register()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# 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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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 +38,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 +87,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 +117,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 +142,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 +169,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()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2014 Alexandros Kosiaris
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,26 +15,30 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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 +51,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 +70,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 +107,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,11 +126,11 @@ 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 * 3600, 3, 0, 0, u"%s m\u00B3/h",None),
|
||||
("labelFullminingyieldDrone", lambda: fit.droneYield * 3600, 3, 0, 0, u"%s m\u00B3/h", None),
|
||||
("labelFullminingyieldTotal", lambda: fit.totalYield * 3600, 3, 0, 0, u"%s m\u00B3/h", None))
|
||||
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),
|
||||
("labelFullminingyieldTotal", lambda: fit.totalYield, 3, 0, 0, u"%s m\u00B3/s", None))
|
||||
|
||||
counter = 0
|
||||
for labelName, value, prec, lowest, highest, valueFormat, altFormat in stats:
|
||||
@@ -136,11 +140,12 @@ class MiningYieldViewFull(StatsView):
|
||||
if self._cachedValues[counter] != value:
|
||||
valueStr = formatAmount(value, prec, lowest, highest)
|
||||
label.SetLabel(valueFormat % valueStr)
|
||||
tipStr = valueFormat % valueStr if altFormat is None else altFormat % value
|
||||
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()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# 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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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
|
||||
from service.price import Price
|
||||
|
||||
|
||||
class PriceViewFull(StatsView):
|
||||
name = "priceViewFull"
|
||||
|
||||
def __init__(self, parent):
|
||||
StatsView.__init__(self)
|
||||
self.parent = parent
|
||||
@@ -72,27 +75,10 @@ class PriceViewFull(StatsView):
|
||||
def refreshPanel(self, fit):
|
||||
if fit is not None:
|
||||
self.fit = fit
|
||||
# Compose a list of all the data we need & request it
|
||||
typeIDs = []
|
||||
typeIDs.append(fit.ship.item.ID)
|
||||
|
||||
for mod in fit.modules:
|
||||
if not mod.isEmpty:
|
||||
typeIDs.append(mod.itemID)
|
||||
typeIDs = Price.fitItemsList(fit)
|
||||
|
||||
for drone in fit.drones:
|
||||
for _ in xrange(drone.amount):
|
||||
typeIDs.append(drone.itemID)
|
||||
|
||||
for fighter in fit.fighters:
|
||||
for _ in xrange(fighter.amountActive):
|
||||
typeIDs.append(fighter.itemID)
|
||||
|
||||
for cargo in fit.cargo:
|
||||
for _ in xrange(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 +103,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()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,35 +15,38 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from gui.statsView import StatsView
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
import gui.mainFrame
|
||||
import gui.builtinStatsViews.resistancesViewFull as rvf
|
||||
import service
|
||||
from gui.builtinStatsViews.resistancesViewFull import EFFECTIVE_HP_TOGGLED
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
class RechargeViewFull(StatsView):
|
||||
name = "rechargeViewFull"
|
||||
|
||||
def __init__(self, parent):
|
||||
StatsView.__init__(self)
|
||||
self.parent = parent
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
self.mainFrame.Bind(rvf.EFFECTIVE_HP_TOGGLED, self.toggleEffective)
|
||||
self.mainFrame.Bind(EFFECTIVE_HP_TOGGLED, self.toggleEffective)
|
||||
self.effective = True
|
||||
|
||||
def getHeaderText(self, fit):
|
||||
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 +56,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 +83,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 +95,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 +126,5 @@ class RechargeViewFull(StatsView):
|
||||
self.panel.Layout()
|
||||
self.headerPanel.Layout()
|
||||
|
||||
|
||||
RechargeViewFull.register()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,23 +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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from gui.statsView import StatsView
|
||||
from gui import builtinStatsViews
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui import pygauge as PG
|
||||
from gui.pygauge import PyGauge
|
||||
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 +45,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 +56,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 +67,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 = 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 +151,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 +165,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 +196,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 +209,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 +224,5 @@ class ResistancesViewFull(StatsView):
|
||||
self.panel.Layout()
|
||||
self.headerPanel.Layout()
|
||||
|
||||
ResistancesViewFull.register()
|
||||
|
||||
ResistancesViewFull.register()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,20 +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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from gui.statsView import StatsView
|
||||
from gui import builtinStatsViews
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui import pygauge as PG
|
||||
from gui.pygauge import PyGauge
|
||||
import gui.mainFrame
|
||||
import gui.chromeTabs
|
||||
from gui.chromeTabs import EVT_NOTEBOOK_PAGE_CHANGED
|
||||
|
||||
from eos.types import Hardpoint
|
||||
from eos.saveddata.module import Hardpoint
|
||||
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
|
||||
|
||||
class ResourcesViewFull(StatsView):
|
||||
name = "resourcesViewFull"
|
||||
contexts = ["drone", "fighter", "cargo"]
|
||||
@@ -37,7 +38,7 @@ class ResourcesViewFull(StatsView):
|
||||
StatsView.__init__(self)
|
||||
self.parent = parent
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
self.mainFrame.additionsPane.notebook.Bind(gui.chromeTabs.EVT_NOTEBOOK_PAGE_CHANGED, self.pageChanged)
|
||||
self.mainFrame.additionsPane.notebook.Bind(EVT_NOTEBOOK_PAGE_CHANGED, self.pageChanged)
|
||||
|
||||
def pageChanged(self, event):
|
||||
page = self.mainFrame.additionsPane.getName(event.GetSelection())
|
||||
@@ -79,7 +80,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 +100,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,18 +169,19 @@ 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
|
||||
|
||||
gauge = PG.PyGauge(parent, wx.ID_ANY, 1)
|
||||
gauge = PyGauge(parent, wx.ID_ANY, 1)
|
||||
gauge.SetValueRange(0, 0)
|
||||
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,77 +190,88 @@ 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
|
||||
labelUTH = ""
|
||||
totalTurretHardpoints = 0
|
||||
labelTTH = ""
|
||||
usedLauncherHardpoints = 0
|
||||
labelULH = ""
|
||||
totalLauncherHardPoints = 0
|
||||
labelTLH = ""
|
||||
usedDronesActive = 0
|
||||
labelUDA = ""
|
||||
totalDronesActive = 0
|
||||
labelTDA = ""
|
||||
usedFighterTubes = 0
|
||||
labelUFT = ""
|
||||
totalFighterTubes = 0
|
||||
labelTFT = ""
|
||||
usedCalibrationPoints = 0
|
||||
labelUCP = ""
|
||||
totalCalibrationPoints = 0
|
||||
labelTCP = ""
|
||||
|
||||
for labelName, value, prec, lowest, highest in stats:
|
||||
label = getattr(self, labelName % panel)
|
||||
value = value() if fit is not None else 0
|
||||
value = value if value is not None else 0
|
||||
|
||||
if labelName % panel == "label%sUsedTurretHardpoints" % panel:
|
||||
usedTurretHardpoints = value
|
||||
labelUTH = label
|
||||
|
||||
if labelName % panel == "label%sTotalTurretHardpoints" % panel:
|
||||
elif labelName % panel == "label%sTotalTurretHardpoints" % panel:
|
||||
totalTurretHardpoints = value
|
||||
labelTTH = label
|
||||
|
||||
if labelName % panel == "label%sUsedLauncherHardpoints" % panel:
|
||||
elif labelName % panel == "label%sUsedLauncherHardpoints" % panel:
|
||||
usedLauncherHardpoints = value
|
||||
labelULH = label
|
||||
|
||||
if labelName % panel == "label%sTotalLauncherHardpoints" % panel:
|
||||
elif labelName % panel == "label%sTotalLauncherHardpoints" % panel:
|
||||
totalLauncherHardPoints = value
|
||||
labelTLH = label
|
||||
|
||||
if labelName % panel == "label%sUsedDronesActive" % panel:
|
||||
elif labelName % panel == "label%sUsedDronesActive" % panel:
|
||||
usedDronesActive = value
|
||||
labelUDA = label
|
||||
|
||||
if labelName % panel == "label%sTotalDronesActive" % panel:
|
||||
elif labelName % panel == "label%sTotalDronesActive" % panel:
|
||||
totalDronesActive = value
|
||||
labelTDA = label
|
||||
|
||||
if labelName % panel == "label%sUsedFighterTubes" % panel:
|
||||
elif labelName % panel == "label%sUsedFighterTubes" % panel:
|
||||
usedFighterTubes = value
|
||||
labelUFT = label
|
||||
|
||||
if labelName % panel == "label%sTotalFighterTubes" % panel:
|
||||
elif labelName % panel == "label%sTotalFighterTubes" % panel:
|
||||
totalFighterTubes = value
|
||||
labelTFT = label
|
||||
|
||||
if labelName % panel == "label%sUsedCalibrationPoints" % panel:
|
||||
elif labelName % panel == "label%sUsedCalibrationPoints" % panel:
|
||||
usedCalibrationPoints = value
|
||||
labelUCP = label
|
||||
|
||||
if labelName % panel == "label%sTotalCalibrationPoints" % panel:
|
||||
elif labelName % panel == "label%sTotalCalibrationPoints" % panel:
|
||||
totalCalibrationPoints = value
|
||||
labelTCP = label
|
||||
|
||||
@@ -303,12 +318,16 @@ 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"),
|
||||
)
|
||||
else:
|
||||
resMax = None
|
||||
|
||||
i = 0
|
||||
for resourceType in ("cpu", "pg", "droneBay", "fighterBay", "droneBandwidth", "cargoBay"):
|
||||
@@ -316,11 +335,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 +347,10 @@ class ResourcesViewFull(StatsView):
|
||||
|
||||
gauge.SetValueRange(0, 0)
|
||||
|
||||
i+=1
|
||||
i += 1
|
||||
|
||||
self.panel.Layout()
|
||||
self.headerPanel.Layout()
|
||||
|
||||
|
||||
ResourcesViewFull.register()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,29 +15,32 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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 +49,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 +71,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 +101,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 +134,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 +160,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 +178,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 +192,25 @@ 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 = [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]))
|
||||
@@ -225,7 +230,7 @@ class TargetingMiscViewFull(StatsView):
|
||||
if fit.jamChance > 0:
|
||||
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))
|
||||
else:
|
||||
label.SetToolTip(wx.ToolTip(""))
|
||||
elif labelName == "labelFullCargo":
|
||||
@@ -233,8 +238,7 @@ class TargetingMiscViewFull(StatsView):
|
||||
cachedCargo = self._cachedValues[counter]
|
||||
# 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 = [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 +251,5 @@ class TargetingMiscViewFull(StatsView):
|
||||
self.panel.Layout()
|
||||
self.headerPanel.Layout()
|
||||
|
||||
|
||||
TargetingMiscViewFull.register()
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
__all__ = ["ammo", "ammoIcon", "attributeDisplay", "baseIcon", "baseName",
|
||||
"capacitorUse", "maxRange", "price", "propertyDisplay", "state", "misc", "abilities"]
|
||||
__all__ = ["ammo", "ammoIcon", "attributeDisplay", "baseIcon", "baseName",
|
||||
"capacitorUse", "maxRange", "price", "propertyDisplay", "state", "misc", "abilities"]
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -16,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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from eos.saveddata.fighter import Fighter
|
||||
from gui.viewColumn import ViewColumn
|
||||
import gui.mainFrame
|
||||
|
||||
import wx
|
||||
from eos.types import Fighter
|
||||
|
||||
|
||||
class Abilities(ViewColumn):
|
||||
name = "Fighter Abilities"
|
||||
|
||||
def __init__(self, fittingView, params):
|
||||
ViewColumn.__init__(self, fittingView)
|
||||
|
||||
@@ -41,4 +42,5 @@ class Abilities(ViewColumn):
|
||||
return "None"
|
||||
return ", ".join(active)
|
||||
|
||||
|
||||
Abilities.register()
|
||||
|
||||
@@ -1,58 +1,59 @@
|
||||
#===============================================================================
|
||||
# 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 import builtinViewColumns
|
||||
from gui.viewColumn import ViewColumn
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
import wx
|
||||
from eos.types import Fighter
|
||||
|
||||
|
||||
class Ammo(ViewColumn):
|
||||
name = "Ammo"
|
||||
def __init__(self, fittingView, params):
|
||||
ViewColumn.__init__(self, fittingView)
|
||||
self.mask = wx.LIST_MASK_IMAGE
|
||||
self.imageId = fittingView.imageList.GetImageIndex("damagePattern_small", "gui")
|
||||
self.bitmap = BitmapLoader.getBitmap("damagePattern_small", "gui")
|
||||
|
||||
def getText(self, stuff):
|
||||
if isinstance(stuff, Fighter):
|
||||
# this is an experiment, not sure I like it. But it saves us from duplicating code.
|
||||
col = self.columns['Fighter Abilities'](self.fittingView, {})
|
||||
text = col.getText(stuff)
|
||||
del col
|
||||
return text
|
||||
if getattr(stuff, "charge", None) is not None:
|
||||
charges = stuff.numCharges
|
||||
if charges > 0:
|
||||
cycles = stuff.numShots
|
||||
if cycles !=0 and charges != cycles:
|
||||
return "%s (%d, %d cycles)" % (stuff.charge.name, charges, cycles)
|
||||
else:
|
||||
return "%s (%d)" % (stuff.charge.name, charges)
|
||||
else:
|
||||
return stuff.charge.name
|
||||
return ""
|
||||
|
||||
def getImageId(self, mod):
|
||||
return -1
|
||||
|
||||
Ammo.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/>.
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from eos.saveddata.fighter 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
|
||||
self.imageId = fittingView.imageList.GetImageIndex("damagePattern_small", "gui")
|
||||
self.bitmap = BitmapLoader.getBitmap("damagePattern_small", "gui")
|
||||
|
||||
def getText(self, stuff):
|
||||
if isinstance(stuff, Fighter):
|
||||
# this is an experiment, not sure I like it. But it saves us from duplicating code.
|
||||
col = self.columns['Fighter Abilities'](self.fittingView, {})
|
||||
text = col.getText(stuff)
|
||||
del col
|
||||
return text
|
||||
if getattr(stuff, "charge", None) is not None:
|
||||
charges = stuff.numCharges
|
||||
if charges > 0:
|
||||
cycles = stuff.numShots
|
||||
if cycles != 0 and charges != cycles:
|
||||
return "%s (%d, %d cycles)" % (stuff.charge.name, charges, cycles)
|
||||
else:
|
||||
return "%s (%d)" % (stuff.charge.name, charges)
|
||||
else:
|
||||
return stuff.charge.name
|
||||
return ""
|
||||
|
||||
def getImageId(self, mod):
|
||||
return -1
|
||||
|
||||
|
||||
Ammo.register()
|
||||
|
||||
@@ -1,55 +1,57 @@
|
||||
#===============================================================================
|
||||
# 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 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
|
||||
self.maxsize = self.size
|
||||
self.mask = wx.LIST_MASK_IMAGE
|
||||
self.columnText = ""
|
||||
|
||||
def getText(self, mod):
|
||||
return ""
|
||||
|
||||
def getImageId(self, stuff):
|
||||
if not isinstance(stuff, Module):
|
||||
return -1
|
||||
|
||||
if stuff.charge is None:
|
||||
return -1
|
||||
else:
|
||||
iconFile = stuff.charge.icon.iconFile if stuff.charge.icon else ""
|
||||
if iconFile:
|
||||
return self.fittingView.imageList.GetImageIndex(iconFile, "icons")
|
||||
else:
|
||||
return -1
|
||||
|
||||
def getToolTip(self, mod):
|
||||
if isinstance(mod, Module) and mod.charge is not None:
|
||||
return mod.charge.name
|
||||
|
||||
AmmoIcon.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
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from eos.saveddata.module import Module
|
||||
|
||||
|
||||
class AmmoIcon(ViewColumn):
|
||||
name = "Ammo 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 = ""
|
||||
|
||||
def getText(self, mod):
|
||||
return ""
|
||||
|
||||
def getImageId(self, stuff):
|
||||
if not isinstance(stuff, Module):
|
||||
return -1
|
||||
|
||||
if stuff.charge is None:
|
||||
return -1
|
||||
else:
|
||||
iconFile = stuff.charge.icon.iconFile if stuff.charge.icon else ""
|
||||
if iconFile:
|
||||
return self.fittingView.imageList.GetImageIndex(iconFile, "icons")
|
||||
else:
|
||||
return -1
|
||||
|
||||
def getToolTip(self, mod):
|
||||
if isinstance(mod, Module) and mod.charge is not None:
|
||||
return mod.charge.name
|
||||
|
||||
|
||||
AmmoIcon.register()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,21 +15,25 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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 +61,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 +81,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_ += 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 +107,5 @@ class AttributeDisplay(ViewColumn):
|
||||
("showIcon", bool, True),
|
||||
("direct", bool, False))
|
||||
|
||||
|
||||
AttributeDisplay.register()
|
||||
|
||||
@@ -1,44 +1,50 @@
|
||||
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()
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from eos.saveddata.implant import Implant
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.module import Module, Slot, Rack
|
||||
from eos.saveddata.fit import Fit
|
||||
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()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#===============================================================================
|
||||
# coding: utf-8
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -16,17 +16,24 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from eos.saveddata.cargo import Cargo
|
||||
from eos.saveddata.implant import Implant
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.fighter import Fighter
|
||||
from eos.saveddata.module import Module, Slot, Rack
|
||||
from eos.saveddata.fit import Fit
|
||||
from service.fit import Fit as FitSvc
|
||||
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 +46,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 +59,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 FitSvc.getInstance().serviceFittingOptions["rackLabels"]:
|
||||
if stuff.slot == Slot.MODE:
|
||||
return u'─ Tactical Mode ─'
|
||||
else:
|
||||
@@ -68,15 +76,16 @@ class BaseName(ViewColumn):
|
||||
else:
|
||||
item = getattr(stuff, "item", stuff)
|
||||
|
||||
if service.Fit.getInstance().serviceFittingOptions["showMarketShortcuts"]:
|
||||
if FitSvc.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()
|
||||
|
||||
@@ -1,56 +1,59 @@
|
||||
#===============================================================================
|
||||
# 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
|
||||
|
||||
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")
|
||||
self.imageId = fittingView.imageList.GetImageIndex("capacitorRecharge_small", "gui")
|
||||
self.bitmap = BitmapLoader.getBitmap("capacitorRecharge_small", "gui")
|
||||
|
||||
def getText(self, mod):
|
||||
if isinstance(mod, Mode):
|
||||
return ""
|
||||
|
||||
capUse = mod.capUse
|
||||
if capUse:
|
||||
return "%s%s" % ("+" if capUse < 0 else "", (formatAmount(-capUse, 3, 0, 3)))
|
||||
else:
|
||||
return ""
|
||||
|
||||
def getImageId(self, mod):
|
||||
return -1
|
||||
|
||||
def getToolTip(self, mod):
|
||||
return self.name
|
||||
|
||||
CapacitorUse.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/>.
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
from eos.saveddata.mode import Mode
|
||||
from service.attribute import Attribute
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
from gui.viewColumn import ViewColumn
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
|
||||
class CapacitorUse(ViewColumn):
|
||||
name = "Capacitor Usage"
|
||||
|
||||
def __init__(self, fittingView, params):
|
||||
ViewColumn.__init__(self, fittingView)
|
||||
|
||||
self.mask = wx.LIST_MASK_IMAGE
|
||||
|
||||
Attribute.getInstance().getAttributeInfo("capacitorNeed")
|
||||
self.imageId = fittingView.imageList.GetImageIndex("capacitorRecharge_small", "gui")
|
||||
self.bitmap = BitmapLoader.getBitmap("capacitorRecharge_small", "gui")
|
||||
|
||||
def getText(self, mod):
|
||||
if isinstance(mod, Mode):
|
||||
return ""
|
||||
|
||||
capUse = mod.capUse
|
||||
if capUse:
|
||||
return "%s%s" % ("+" if capUse < 0 else "", (formatAmount(-capUse, 3, 0, 3)))
|
||||
else:
|
||||
return ""
|
||||
|
||||
def getImageId(self, mod):
|
||||
return -1
|
||||
|
||||
def getToolTip(self, mod):
|
||||
return self.name
|
||||
|
||||
|
||||
CapacitorUse.register()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,25 +15,28 @@
|
||||
#
|
||||
# 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
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
from eos.saveddata.mode 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 +74,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
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos, Lucas Thode
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,17 +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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
from eos.saveddata.cargo import Cargo
|
||||
from eos.saveddata.drone import Drone
|
||||
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 +41,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 +50,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 +74,5 @@ class Price(ViewColumn):
|
||||
def getToolTip(self, mod):
|
||||
return self.name
|
||||
|
||||
|
||||
Price.register()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,18 +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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
from eos.saveddata.fit import Fit
|
||||
from eos.saveddata.implant import Implant
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.module import Module, State as State_, Rack
|
||||
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_
|
||||
|
||||
class State(ViewColumn):
|
||||
name = "State"
|
||||
|
||||
def __init__(self, fittingView, params):
|
||||
ViewColumn.__init__(self, fittingView)
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
@@ -44,7 +50,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 +64,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 +86,5 @@ class State(ViewColumn):
|
||||
return generic_active
|
||||
return generic_inactive
|
||||
|
||||
|
||||
State.register()
|
||||
|
||||
@@ -1 +1 @@
|
||||
__all__ = ["fittingView", "implantEditor"]
|
||||
__all__ = ["fittingView", "implantEditor"]
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import gui.globalEvents as GE
|
||||
import gui.chromeTabs
|
||||
from gui.chromeTabs import EVT_NOTEBOOK_PAGE_CHANGED
|
||||
import gui.mainFrame
|
||||
import service
|
||||
|
||||
|
||||
class BlankPage(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
@@ -11,20 +12,20 @@ class BlankPage(wx.Panel):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
self.parent = parent
|
||||
|
||||
self.parent.Bind(gui.chromeTabs.EVT_NOTEBOOK_PAGE_CHANGED, self.pageChanged)
|
||||
self.parent.Bind(EVT_NOTEBOOK_PAGE_CHANGED, self.pageChanged)
|
||||
self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
|
||||
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=None))
|
||||
|
||||
def Destroy(self):
|
||||
self.parent.Unbind(gui.chromeTabs.EVT_NOTEBOOK_PAGE_CHANGED, handler=self.pageChanged)
|
||||
self.parent.Unbind(EVT_NOTEBOOK_PAGE_CHANGED, handler=self.pageChanged)
|
||||
wx.Panel.Destroy(self)
|
||||
|
||||
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()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
import service
|
||||
|
||||
|
||||
class BaseValidator(wx.PyValidator):
|
||||
def __init__(self):
|
||||
@@ -15,6 +16,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 +26,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 +55,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 +138,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 +175,4 @@ class EntityEditor (wx.Panel):
|
||||
return False
|
||||
self.Parent.Show()
|
||||
|
||||
return True
|
||||
return True
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,29 +15,36 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
# noinspection PyPackageRequirements
|
||||
import wx.lib.newevent
|
||||
import service
|
||||
import gui.mainFrame
|
||||
import gui.marketBrowser
|
||||
import gui.display as d
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.shipBrowser
|
||||
import gui.multiSwitch
|
||||
from eos.types import Slot, Rack, Module, Mode
|
||||
from eos.saveddata.mode import Mode
|
||||
from eos.saveddata.module import Module, Slot, Rack
|
||||
from gui.builtinViewColumns.state import State
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
import gui.builtinViews.emptyView
|
||||
from gui.utils.exportHtml import exportHtml
|
||||
from logging import getLogger, Formatter
|
||||
from logbook import Logger
|
||||
from gui.chromeTabs import EVT_NOTEBOOK_PAGE_CHANGED
|
||||
|
||||
from service.fit import Fit
|
||||
from service.market import Market
|
||||
|
||||
import gui.globalEvents as GE
|
||||
|
||||
logger = getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
#Tab spawning handler
|
||||
|
||||
# Tab spawning handler
|
||||
class FitSpawner(gui.multiSwitch.TabSpawner):
|
||||
def __init__(self, multiSwitch):
|
||||
self.multiSwitch = multiSwitch
|
||||
@@ -54,11 +61,12 @@ class FitSpawner(gui.multiSwitch.TabSpawner):
|
||||
self.multiSwitch.SetSelection(index)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=event.fitID))
|
||||
break
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Caught exception in fitSelected")
|
||||
pyfalog.critical(e)
|
||||
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 +95,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, *args, **kwargs):
|
||||
super(FittingViewDrop, self).__init__(*args, **kwargs)
|
||||
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 +130,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 +140,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)
|
||||
@@ -150,7 +161,7 @@ class FittingView(d.Display):
|
||||
self.Bind(wx.EVT_SHOW, self.OnShow)
|
||||
self.Bind(wx.EVT_MOTION, self.OnMouseMove)
|
||||
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
|
||||
self.parent.Bind(gui.chromeTabs.EVT_NOTEBOOK_PAGE_CHANGED, self.pageChanged)
|
||||
self.parent.Bind(EVT_NOTEBOOK_PAGE_CHANGED, self.pageChanged)
|
||||
|
||||
def OnLeaveWindow(self, event):
|
||||
self.SetToolTip(None)
|
||||
@@ -178,13 +189,13 @@ class FittingView(d.Display):
|
||||
event.Skip()
|
||||
|
||||
def handleListDrag(self, x, y, data):
|
||||
'''
|
||||
"""
|
||||
Handles dragging of items from various pyfa displays which support it
|
||||
|
||||
data is list with two items:
|
||||
data[0] is hard-coded str of originating source
|
||||
data[1] is typeID or index of data we want to manipulate
|
||||
'''
|
||||
"""
|
||||
|
||||
if data[0] == "fitting":
|
||||
self.swapItems(x, y, int(data[1]))
|
||||
@@ -194,12 +205,12 @@ 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))
|
||||
|
||||
def Destroy(self):
|
||||
self.parent.Unbind(gui.chromeTabs.EVT_NOTEBOOK_PAGE_CHANGED, handler=self.pageChanged)
|
||||
self.parent.Unbind(EVT_NOTEBOOK_PAGE_CHANGED, handler=self.pageChanged)
|
||||
self.mainFrame.Unbind(GE.FIT_CHANGED, handler=self.fitChanged)
|
||||
self.mainFrame.Unbind(gui.shipBrowser.EVT_FIT_RENAMED, handler=self.fitRenamed)
|
||||
self.mainFrame.Unbind(gui.shipBrowser.EVT_FIT_REMOVED, handler=self.fitRemoved)
|
||||
@@ -210,7 +221,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))
|
||||
|
||||
@@ -224,11 +235,11 @@ class FittingView(d.Display):
|
||||
|
||||
if row != -1 and row not in self.blanks:
|
||||
data = wx.PyTextDataObject()
|
||||
data.SetText("fitting:"+str(self.mods[row].position))
|
||||
data.SetText("fitting:" + str(self.mods[row].modPosition))
|
||||
|
||||
dropSource = wx.DropSource(self)
|
||||
dropSource.SetData(data)
|
||||
res = dropSource.DoDragDrop()
|
||||
dropSource.DoDragDrop()
|
||||
|
||||
def getSelectedMods(self):
|
||||
sel = []
|
||||
@@ -239,25 +250,24 @@ 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()
|
||||
|
||||
def fitRemoved(self, event):
|
||||
'''
|
||||
"""
|
||||
If fit is removed and active, the page is deleted.
|
||||
We also refresh the fit of the new current page in case
|
||||
delete fit caused change in stats (projected)
|
||||
'''
|
||||
"""
|
||||
fitID = event.fitID
|
||||
|
||||
if fitID == self.getActiveFit():
|
||||
@@ -265,10 +275,11 @@ 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:
|
||||
pyfalog.warning("Caught dead object")
|
||||
pass
|
||||
|
||||
event.Skip()
|
||||
@@ -285,7 +296,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 +307,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 +321,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 +351,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))
|
||||
|
||||
@@ -349,36 +360,36 @@ class FittingView(d.Display):
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.activeFitID))
|
||||
|
||||
def addModule(self, x, y, srcIdx):
|
||||
'''Add a module from the market browser'''
|
||||
mstate = wx.GetMouseState()
|
||||
"""Add a module from the market browser"""
|
||||
|
||||
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].position, srcIdx)
|
||||
moduleChanged = sFit.changeModule(fitID, self.mods[dstRow].modPosition, srcIdx)
|
||||
if moduleChanged is None:
|
||||
# the new module doesn't fit in specified slot, try to simply append it
|
||||
wx.PostEvent(self.mainFrame, gui.marketBrowser.ItemSelected(itemID=srcIdx))
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
|
||||
|
||||
def swapCargo(self, x, y, srcIdx):
|
||||
'''Swap a module from cargo to fitting window'''
|
||||
"""Swap a module from cargo to fitting window"""
|
||||
mstate = wx.GetMouseState()
|
||||
|
||||
dstRow, _ = self.HitTest((x, y))
|
||||
if dstRow != -1 and dstRow not in self.blanks:
|
||||
module = self.mods[dstRow]
|
||||
|
||||
sFit = service.Fit.getInstance()
|
||||
sFit.moveCargoToModule(self.mainFrame.getActiveFit(), module.position, 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'''
|
||||
"""Swap two modules in fitting window"""
|
||||
mstate = wx.GetMouseState()
|
||||
sFit = service.Fit.getInstance()
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(self.activeFitID)
|
||||
|
||||
if mstate.CmdDown():
|
||||
@@ -389,6 +400,7 @@ class FittingView(d.Display):
|
||||
dstRow, _ = self.HitTest((x, y))
|
||||
|
||||
if dstRow != -1 and dstRow not in self.blanks:
|
||||
|
||||
mod1 = fit.modules[srcIdx]
|
||||
mod2 = self.mods[dstRow]
|
||||
|
||||
@@ -396,35 +408,38 @@ class FittingView(d.Display):
|
||||
if mod1.slot != mod2.slot:
|
||||
return
|
||||
|
||||
if clone and mod2.isEmpty:
|
||||
sFit.cloneModule(self.mainFrame.getActiveFit(), mod1.position, mod2.position)
|
||||
else:
|
||||
sFit.swapModules(self.mainFrame.getActiveFit(), mod1.position, mod2.position)
|
||||
if getattr(mod2, "modPosition"):
|
||||
if clone and mod2.isEmpty:
|
||||
sFit.cloneModule(self.mainFrame.getActiveFit(), srcIdx, mod2.modPosition)
|
||||
else:
|
||||
sFit.swapModules(self.mainFrame.getActiveFit(), srcIdx, mod2.modPosition)
|
||||
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
|
||||
else:
|
||||
pyfalog.error("Missing module position for: {0}", str(getattr(mod2, "ID", "Unknown")))
|
||||
|
||||
def generateMods(self):
|
||||
'''
|
||||
"""
|
||||
Generate module list.
|
||||
|
||||
This also injects dummy modules to visually separate racks. These modules are only
|
||||
known to the display, and not the backend, so it's safe.
|
||||
'''
|
||||
"""
|
||||
|
||||
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]
|
||||
|
||||
if fit is not None:
|
||||
self.mods = fit.modules[:]
|
||||
self.mods.sort(key=lambda mod: (slotOrder.index(mod.slot), mod.position))
|
||||
self.mods.sort(key=lambda _mod: (slotOrder.index(_mod.slot), _mod.position))
|
||||
|
||||
# Blanks is a list of indexes that mark non-module positions (such
|
||||
# as Racks and tactical Modes. This allows us to skip over common
|
||||
# module operations such as swapping, removing, copying, etc. that
|
||||
# would otherwise cause complications
|
||||
self.blanks = [] # preliminary markers where blanks will be inserted
|
||||
self.blanks = [] # preliminary markers where blanks will be inserted
|
||||
|
||||
if sFit.serviceFittingOptions["rackSlots"]:
|
||||
# flag to know when to add blanks, based on previous slot
|
||||
@@ -434,12 +449,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
|
||||
@@ -470,7 +485,7 @@ class FittingView(d.Display):
|
||||
|
||||
self.Show(self.activeFitID is not None and self.activeFitID == event.fitID)
|
||||
except wx._core.PyDeadObjectError:
|
||||
pass
|
||||
pyfalog.warning("Caught dead object")
|
||||
finally:
|
||||
event.Skip()
|
||||
|
||||
@@ -483,7 +498,7 @@ class FittingView(d.Display):
|
||||
if self.activeFitID is None:
|
||||
return
|
||||
|
||||
sMkt = service.Market.getInstance()
|
||||
sMkt = Market.getInstance()
|
||||
selection = []
|
||||
sel = self.GetFirstSelected()
|
||||
contexts = []
|
||||
@@ -497,7 +512,7 @@ class FittingView(d.Display):
|
||||
|
||||
itemContext = "Tactical Mode"
|
||||
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)
|
||||
@@ -506,22 +521,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"))
|
||||
@@ -530,13 +544,13 @@ class FittingView(d.Display):
|
||||
self.PopupMenu(menu)
|
||||
|
||||
def click(self, event):
|
||||
'''
|
||||
"""
|
||||
Handle click event on modules.
|
||||
|
||||
This is only useful for the State column. If multiple items are selected,
|
||||
and we have clicked the State column, iterate through the selections and
|
||||
change State
|
||||
'''
|
||||
"""
|
||||
row, _, col = self.HitTestSubItem(event.Position)
|
||||
|
||||
# only do State column and ignore invalid rows
|
||||
@@ -544,7 +558,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)
|
||||
|
||||
@@ -553,7 +567,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"
|
||||
@@ -578,16 +592,16 @@ class FittingView(d.Display):
|
||||
return self.slotColourMap.get(slot) or self.GetBackgroundColour()
|
||||
|
||||
def refresh(self, stuff):
|
||||
'''
|
||||
"""
|
||||
Displays fitting
|
||||
|
||||
Sends data to d.Display.refresh where the rows and columns are set up, then does a
|
||||
bit of post-processing (colors)
|
||||
'''
|
||||
"""
|
||||
self.Freeze()
|
||||
d.Display.refresh(self, stuff)
|
||||
|
||||
sFit = service.Fit.getInstance()
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(self.activeFitID)
|
||||
slotMap = {}
|
||||
|
||||
@@ -624,40 +638,44 @@ class FittingView(d.Display):
|
||||
if 'wxMac' in wx.PlatformInfo:
|
||||
try:
|
||||
self.MakeSnapshot()
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Failed to make snapshot")
|
||||
pyfalog.critical(e)
|
||||
|
||||
def OnShow(self, event):
|
||||
if event.GetShow():
|
||||
try:
|
||||
self.MakeSnapshot()
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Failed to make snapshot")
|
||||
pyfalog.critical(e)
|
||||
event.Skip()
|
||||
|
||||
def Snapshot(self):
|
||||
return self.FVsnapshot
|
||||
|
||||
def MakeSnapshot(self, maxColumns = 1337):
|
||||
# noinspection PyPropertyAccess
|
||||
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:
|
||||
return
|
||||
except Exception as e:
|
||||
pyfalog.critical("Failed to get fit")
|
||||
pyfalog.critical(e)
|
||||
|
||||
if fit is None:
|
||||
return
|
||||
@@ -671,28 +689,27 @@ class FittingView(d.Display):
|
||||
isize = 16
|
||||
headerSize = max(isize, tdc.GetTextExtent("W")[0]) + padding * 2
|
||||
|
||||
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)
|
||||
@@ -701,7 +718,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:
|
||||
@@ -719,26 +736,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)
|
||||
|
||||
@@ -768,8 +782,7 @@ 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)
|
||||
render.DrawHeaderButton(self, mdc, (cx, padding, columnsWidths[i], headerSize), wx.CONTROL_CURRENT, sortArrow=wx.HDR_SORT_ICON_NONE, params=opts)
|
||||
|
||||
cx += columnsWidths[i]
|
||||
|
||||
@@ -779,15 +792,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)
|
||||
@@ -798,14 +811,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)
|
||||
@@ -817,4 +830,4 @@ class FittingView(d.Display):
|
||||
|
||||
mdc.SelectObject(wx.NullBitmap)
|
||||
|
||||
self.FVsnapshot = mbmp
|
||||
self.FVsnapshot = mbmp
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import service
|
||||
import gui.display as d
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
import gui.PFSearchBox as SBox
|
||||
from gui.marketBrowser import SearchBox
|
||||
# noinspection PyPackageRequirements
|
||||
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 +21,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 +51,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 +85,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 +131,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 +141,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 +199,7 @@ class BaseImplantEditorView (wx.Panel):
|
||||
self.removeImplantFromContext(self.implants[pos])
|
||||
self.update()
|
||||
|
||||
|
||||
class AvailableImplantsView(d.Display):
|
||||
DEFAULT_COLS = ["attr:implantness",
|
||||
"Base Icon",
|
||||
@@ -203,6 +209,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 +242,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 +262,4 @@ class ItemView(d.Display):
|
||||
|
||||
self.items = sorted(list(items), key=lambda i: i.name)
|
||||
|
||||
self.update(self.items)
|
||||
self.update(self.items)
|
||||
|
||||
@@ -1,35 +1,38 @@
|
||||
#===============================================================================
|
||||
# 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.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:
|
||||
bitmap = BitmapLoader.getBitmap(*loaderArgs)
|
||||
if bitmap is None:
|
||||
return -1
|
||||
id = self.map[loaderArgs] = wx.ImageList.Add(self,bitmap)
|
||||
return id
|
||||
# =============================================================================
|
||||
# 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/>.
|
||||
# =============================================================================
|
||||
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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:
|
||||
bitmap = BitmapLoader.getBitmap(*loaderArgs)
|
||||
if bitmap is None:
|
||||
return -1
|
||||
id_ = self.map[loaderArgs] = wx.ImageList.Add(self, bitmap)
|
||||
return id_
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,31 +15,34 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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, *args, **kwargs):
|
||||
super(CargoViewDrop, self).__init__(*args, **kwargs)
|
||||
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,24 +61,24 @@ 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)
|
||||
|
||||
def handleListDrag(self, x, y, data):
|
||||
'''
|
||||
"""
|
||||
Handles dragging of items from various pyfa displays which support it
|
||||
|
||||
data is list with two indices:
|
||||
data[0] is hard-coded str of originating source
|
||||
data[1] is typeID or index of data we want to manipulate
|
||||
'''
|
||||
"""
|
||||
|
||||
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 +87,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))
|
||||
@@ -102,8 +105,8 @@ class CargoView(d.Display):
|
||||
event.Skip()
|
||||
|
||||
def swapModule(self, x, y, modIdx):
|
||||
'''Swap a module from fitting window with cargo'''
|
||||
sFit = service.Fit.getInstance()
|
||||
"""Swap a module from fitting window with cargo"""
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(self.mainFrame.getActiveFit())
|
||||
dstRow, _ = self.HitTest((x, y))
|
||||
mstate = wx.GetMouseState()
|
||||
@@ -111,26 +114,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 +142,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 +165,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 +178,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
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,18 +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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx.lib.newevent
|
||||
# noinspection PyPackageRequirements
|
||||
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
|
||||
from logbook import Logger
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class CharacterTextValidor(BaseValidator):
|
||||
@@ -49,6 +57,7 @@ class CharacterTextValidor(BaseValidator):
|
||||
|
||||
return True
|
||||
except ValueError, e:
|
||||
pyfalog.error(e)
|
||||
wx.MessageBox(u"{}".format(e), "Error")
|
||||
textCtrl.SetFocus()
|
||||
return False
|
||||
@@ -60,7 +69,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 +85,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))
|
||||
|
||||
@@ -158,6 +167,8 @@ class CharacterEditor(wx.Frame):
|
||||
self.Bind(GE.CHAR_LIST_UPDATED, self.refreshCharacterList)
|
||||
self.entityEditor.Bind(wx.EVT_CHOICE, self.charChanged)
|
||||
|
||||
self.charChanged(None)
|
||||
|
||||
def btnRestrict(self):
|
||||
char = self.entityEditor.getActiveEntity()
|
||||
|
||||
@@ -176,12 +187,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 +203,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 +234,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 +242,35 @@ 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)
|
||||
|
||||
self.clonesChoice = wx.Choice(self, wx.ID_ANY, style=0)
|
||||
i = self.clonesChoice.Append("Omega Clone", None)
|
||||
self.clonesChoice.SetSelection(i)
|
||||
pmainSizer.Add(self.clonesChoice, 0, wx.ALL | wx.EXPAND, 5)
|
||||
|
||||
sChar = Character.getInstance()
|
||||
self.alphaClones = sChar.getAlphaCloneList()
|
||||
char = self.charEditor.entityEditor.getActiveEntity()
|
||||
|
||||
for clone in self.alphaClones:
|
||||
i = self.clonesChoice.Append(clone.alphaCloneName, clone.ID)
|
||||
if clone.ID == char.alphaCloneID:
|
||||
self.clonesChoice.SetSelection(i)
|
||||
|
||||
self.clonesChoice.Bind(wx.EVT_CHOICE, self.cloneChanged)
|
||||
|
||||
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"))
|
||||
@@ -262,7 +290,7 @@ class SkillTreeView (wx.Panel):
|
||||
tree.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.scheduleMenu)
|
||||
|
||||
# bind the Character selection event
|
||||
self.charEditor.entityEditor.Bind(wx.EVT_CHOICE, self.populateSkillTree)
|
||||
self.charEditor.entityEditor.Bind(wx.EVT_CHOICE, self.charChanged)
|
||||
self.charEditor.Bind(GE.CHAR_LIST_UPDATED, self.populateSkillTree)
|
||||
|
||||
srcContext = "skillItem"
|
||||
@@ -286,7 +314,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")
|
||||
|
||||
@@ -295,11 +322,30 @@ class SkillTreeView (wx.Panel):
|
||||
|
||||
self.Layout()
|
||||
|
||||
def cloneChanged(self, event):
|
||||
sChar = Character.getInstance()
|
||||
sChar.setAlphaClone(self.charEditor.entityEditor.getActiveEntity(), event.ClientData)
|
||||
self.populateSkillTree()
|
||||
|
||||
def charChanged(self, event=None):
|
||||
char = self.charEditor.entityEditor.getActiveEntity()
|
||||
for i in range(self.clonesChoice.GetCount()):
|
||||
cloneID = self.clonesChoice.GetClientData(i)
|
||||
if char.alphaCloneID == cloneID:
|
||||
self.clonesChoice.SetSelection(i)
|
||||
|
||||
self.populateSkillTree(event)
|
||||
|
||||
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])
|
||||
|
||||
if char.name in ("All 0", "All 5"):
|
||||
self.clonesChoice.Disable()
|
||||
else:
|
||||
self.clonesChoice.Enable()
|
||||
|
||||
groups = sChar.getSkillGroups()
|
||||
imageId = self.skillBookImageId
|
||||
root = self.root
|
||||
@@ -325,8 +371,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 +394,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 +405,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 +434,7 @@ class SkillTreeView (wx.Panel):
|
||||
|
||||
class ImplantEditorView(BaseImplantEditorView):
|
||||
def __init__(self, parent):
|
||||
BaseImplantEditorView.__init__ (self, parent)
|
||||
BaseImplantEditorView.__init__(self, parent)
|
||||
|
||||
self.determineEnabled()
|
||||
|
||||
@@ -405,19 +451,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 +488,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 +500,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 +542,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 +588,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 +599,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 +627,25 @@ 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:
|
||||
self.stStatus.SetLabel("Authentication failure. Please check keyID and vCode combination.")
|
||||
except service.network.TimeoutError, e:
|
||||
self.stStatus.SetLabel("Request timed out. Please check network connectivity and/or proxy settings.")
|
||||
except AuthenticationError, e:
|
||||
msg = "Authentication failure. Please check keyID and vCode combination."
|
||||
pyfalog.info(msg)
|
||||
self.stStatus.SetLabel(msg)
|
||||
except TimeoutError, e:
|
||||
msg = "Request timed out. Please check network connectivity and/or proxy settings."
|
||||
pyfalog.info(msg)
|
||||
self.stStatus.SetLabel(msg)
|
||||
except Exception, e:
|
||||
self.stStatus.SetLabel("Error:\n%s"%e.message)
|
||||
pyfalog.error(e)
|
||||
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 +658,21 @@ 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:
|
||||
pyfalog.error("Unable to retrieve {0}\'s skills. Error message:\n{1}", charName, 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 +689,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()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,13 +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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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
|
||||
from logbook import Logger
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class CharacterSelection(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
@@ -42,9 +47,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 +71,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 +81,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 +99,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,20 +109,21 @@ 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:
|
||||
sChar.apiFetch(self.getActiveCharacter(), charName)
|
||||
except:
|
||||
except Exception as e:
|
||||
# can we do a popup, notifying user of API error?
|
||||
pass
|
||||
pyfalog.error("API fetch error")
|
||||
pyfalog.error(e)
|
||||
self.refreshCharacterList()
|
||||
|
||||
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 +135,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 +143,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 +162,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 +202,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 +214,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 +228,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 +240,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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Darriele
|
||||
#
|
||||
# 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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
# noinspection PyPackageRequirements
|
||||
import wx.lib.newevent
|
||||
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
|
||||
from logbook import Logger
|
||||
from service.fit import Fit
|
||||
|
||||
import service
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
_PageChanging, EVT_NOTEBOOK_PAGE_CHANGING = wx.lib.newevent.NewEvent()
|
||||
_PageChanged, EVT_NOTEBOOK_PAGE_CHANGED = wx.lib.newevent.NewEvent()
|
||||
@@ -34,7 +37,8 @@ _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():
|
||||
|
||||
class VetoAble(object):
|
||||
def __init__(self):
|
||||
self.__vetoed = False
|
||||
|
||||
@@ -45,7 +49,7 @@ class VetoAble():
|
||||
return self.__vetoed
|
||||
|
||||
|
||||
class NotebookTabChangeEvent():
|
||||
class NotebookTabChangeEvent(object):
|
||||
def __init__(self, old, new):
|
||||
self.__old = old
|
||||
self.__new = new
|
||||
@@ -91,7 +95,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 +103,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 = []
|
||||
@@ -147,7 +150,8 @@ class PFNotebook(wx.Panel):
|
||||
if self.activePage == page:
|
||||
self.ShowActive()
|
||||
|
||||
def GetBorders(self):
|
||||
@staticmethod
|
||||
def GetBorders():
|
||||
"""Gets border widths to better determine page size in ShowActive()"""
|
||||
|
||||
bx = wx.SystemSettings_GetMetric(wx.SYS_BORDER_X)
|
||||
@@ -234,7 +238,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)
|
||||
@@ -336,8 +340,8 @@ class PFNotebook(wx.Panel):
|
||||
event.Skip()
|
||||
|
||||
|
||||
class PFTabRenderer:
|
||||
def __init__(self, size=(36, 24), text=wx.EmptyString, img=None, inclination=6 , closeButton=True):
|
||||
class PFTabRenderer(object):
|
||||
def __init__(self, size=(36, 24), text=wx.EmptyString, img=None, inclination=6, closeButton=True):
|
||||
"""
|
||||
Renders a new tab
|
||||
|
||||
@@ -432,14 +436,15 @@ 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
|
||||
|
||||
def SetTabImage(self, img):
|
||||
self.tabImg = img
|
||||
|
||||
def CopyRegion(self, region):
|
||||
@staticmethod
|
||||
def CopyRegion(region):
|
||||
rect = region.GetBox()
|
||||
|
||||
newRegion = wx.Region(rect.X, rect.Y, rect.Width, rect.Height)
|
||||
@@ -497,7 +502,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 +511,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 +532,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 +553,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 +597,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)
|
||||
|
||||
@@ -606,10 +615,11 @@ class PFTabRenderer:
|
||||
|
||||
def __repr__(self):
|
||||
return "PFTabRenderer(text={}, disabled={}) at {}".format(
|
||||
self.text, self.disabled, hex(id(self))
|
||||
self.text, self.disabled, hex(id(self))
|
||||
)
|
||||
|
||||
class PFAddRenderer:
|
||||
|
||||
class PFAddRenderer(object):
|
||||
def __init__(self):
|
||||
"""Renders the add tab button"""
|
||||
self.addImg = BitmapLoader.getImage("ctabadd", "gui")
|
||||
@@ -628,7 +638,7 @@ class PFAddRenderer:
|
||||
def GetPosition(self):
|
||||
return self.position
|
||||
|
||||
def SetPosition(self,pos):
|
||||
def SetPosition(self, pos):
|
||||
self.position = pos
|
||||
|
||||
def GetSize(self):
|
||||
@@ -648,7 +658,8 @@ class PFAddRenderer:
|
||||
region = wx.RegionFromBitmap(self.tbmp)
|
||||
return region
|
||||
|
||||
def CopyRegion(self, region):
|
||||
@staticmethod
|
||||
def CopyRegion(region):
|
||||
rect = region.GetBox()
|
||||
|
||||
newRegion = wx.Region(rect.X, rect.Y, rect.Width, rect.Height)
|
||||
@@ -689,7 +700,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 +710,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 +876,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 +954,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():
|
||||
@@ -968,7 +980,8 @@ class PFTabsContainer(wx.Panel):
|
||||
return tab
|
||||
return None
|
||||
|
||||
def TabHitTest(self, tab, x, y):
|
||||
@staticmethod
|
||||
def TabHitTest(tab, x, y):
|
||||
tabRegion = tab.GetTabRegion()
|
||||
tabPos = tab.GetPosition()
|
||||
tabPosX, tabPosY = tabPos
|
||||
@@ -985,7 +998,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)
|
||||
@@ -1083,8 +1095,9 @@ class PFTabsContainer(wx.Panel):
|
||||
self.previewTab = tab
|
||||
self.previewTimer.Start(500, True)
|
||||
break
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Exception caught in CheckTabPreview.")
|
||||
pyfalog.critical(e)
|
||||
|
||||
def CheckAddHighlighted(self, x, y):
|
||||
"""
|
||||
@@ -1110,25 +1123,23 @@ 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)
|
||||
|
||||
# noinspection PyPackageRequirements,PyUnresolvedReferences,PyUnresolvedReferences,PyUnresolvedReferences
|
||||
from Carbon.Appearance import kThemeBrushDialogBackgroundActive
|
||||
# noinspection PyUnresolvedReferences
|
||||
brush.MacSetTheme(kThemeBrushDialogBackgroundActive)
|
||||
else:
|
||||
color = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE)
|
||||
brush = wx.Brush(color)
|
||||
|
||||
if "wxGTK" not in wx.PlatformInfo:
|
||||
mdc.SetBackground (brush)
|
||||
mdc.SetBackground(brush)
|
||||
mdc.Clear()
|
||||
|
||||
selected = None
|
||||
@@ -1136,21 +1147,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)
|
||||
@@ -1254,7 +1262,7 @@ class PFTabsContainer(wx.Panel):
|
||||
if self.tabMinWidth < 1:
|
||||
self.tabMinWidth = 1
|
||||
for tab in self.tabs:
|
||||
w, h = tab.GetSize()
|
||||
tab.GetSize()
|
||||
tab.SetSize((self.tabMinWidth, self.height))
|
||||
|
||||
if self.GetTabsCount() > 0:
|
||||
@@ -1265,13 +1273,14 @@ 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):
|
||||
selpos = None
|
||||
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 +1289,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 +1319,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 +1367,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 +1382,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 +1406,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 +1418,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)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,46 +15,51 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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:
|
||||
class DummyItem(object):
|
||||
def __init__(self, txt):
|
||||
self.name = txt
|
||||
self.icon = None
|
||||
|
||||
class DummyEntry:
|
||||
|
||||
class DummyEntry(object):
|
||||
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, *args, **kwargs):
|
||||
super(CommandViewDrop, self).__init__(*args, **kwargs)
|
||||
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 +71,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)
|
||||
@@ -74,56 +79,58 @@ class CommandView(d.Display):
|
||||
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.startDrag)
|
||||
self.SetDropTarget(CommandViewDrop(self.handleListDrag))
|
||||
|
||||
def handleListDrag(self, x, y, data):
|
||||
'''
|
||||
@staticmethod
|
||||
def handleListDrag(x, y, data):
|
||||
"""
|
||||
Handles dragging of items from various pyfa displays which support it
|
||||
|
||||
data is list with two indices:
|
||||
data[0] is hard-coded str of originating source
|
||||
data[1] is typeID or index of data we want to manipulate
|
||||
'''
|
||||
"""
|
||||
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)
|
||||
dropSource.DoDragDrop()
|
||||
|
||||
def fitSort(self, fit):
|
||||
@staticmethod
|
||||
def fitSort(fit):
|
||||
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
|
||||
@@ -147,7 +154,7 @@ class CommandView(d.Display):
|
||||
self.deselectItems()
|
||||
|
||||
# todo: verify
|
||||
if stuff == []:
|
||||
if not stuff:
|
||||
stuff = [DummyEntry("Drag a fit to this area")]
|
||||
|
||||
self.update(stuff)
|
||||
@@ -155,7 +162,7 @@ class CommandView(d.Display):
|
||||
def get(self, row):
|
||||
numFits = len(self.fits)
|
||||
|
||||
if (numFits) == 0:
|
||||
if numFits == 0:
|
||||
return None
|
||||
|
||||
return self.fits[row]
|
||||
@@ -168,7 +175,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,12 +189,12 @@ 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 = context + (("command",),)
|
||||
context = ((fitSrcContext, fitItemContext),)
|
||||
context += ("command",),
|
||||
menu = ContextMenu.getMenu((item,), *context)
|
||||
elif sel == -1:
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
@@ -204,6 +211,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))
|
||||
|
||||
@@ -1,179 +1,206 @@
|
||||
#===============================================================================
|
||||
# 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/>.
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__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):
|
||||
display_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):
|
||||
display_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 display_amount > 0 and i != len(fullContexts) - 1:
|
||||
rootMenu.AppendSeparator()
|
||||
|
||||
debug_end = len(cls._ids)
|
||||
if debug_end - debug_start:
|
||||
pyfalog.debug("{0} 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
|
||||
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
from gui.builtinContextMenus import ( # noqa: E402,F401
|
||||
openFit,
|
||||
# moduleGlobalAmmoPicker,
|
||||
moduleAmmoPicker,
|
||||
itemStats,
|
||||
damagePattern,
|
||||
marketJump,
|
||||
droneSplit,
|
||||
itemRemove,
|
||||
droneRemoveStack,
|
||||
ammoPattern,
|
||||
project,
|
||||
factorReload,
|
||||
whProjector,
|
||||
cargo,
|
||||
shipJump,
|
||||
changeAffectingSkills,
|
||||
tacticalMode,
|
||||
targetResists,
|
||||
priceClear,
|
||||
amount,
|
||||
metaSwap,
|
||||
implantSets,
|
||||
fighterAbilities,
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Lucas Thode
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,11 +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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
|
||||
class CopySelectDialog(wx.Dialog):
|
||||
copyFormatEft = 0
|
||||
copyFormatEftImps = 1
|
||||
@@ -29,7 +31,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 +42,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 +51,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)
|
||||
if buttonSizer:
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -1,66 +1,74 @@
|
||||
import time
|
||||
import webbrowser
|
||||
import json
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import requests
|
||||
|
||||
import service
|
||||
from service.crest import CrestModes
|
||||
from service.port import Port
|
||||
from service.fit import Fit
|
||||
|
||||
from eos.types import Cargo
|
||||
from eos.saveddata.cargo import Cargo
|
||||
from eos.db import getItem
|
||||
|
||||
import gui.display as d
|
||||
from gui.display import Display
|
||||
import gui.globalEvents as GE
|
||||
|
||||
from logbook import Logger
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0)):
|
||||
from service.crest import Crest, CrestModes
|
||||
|
||||
|
||||
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 +98,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 +111,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 +131,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 +140,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())
|
||||
@@ -140,65 +148,69 @@ class CrestFittings(wx.Frame):
|
||||
self.updateCacheStatus(None)
|
||||
self.cacheTimer.Start(1000)
|
||||
self.fitTree.populateSkillTree(fittings)
|
||||
except requests.exceptions.ConnectionError:
|
||||
self.statusbar.SetStatusText("Connection error, please check your internet connection")
|
||||
finally:
|
||||
del waitDialog
|
||||
except requests.exceptions.ConnectionError:
|
||||
msg = "Connection error, please check your internet connection"
|
||||
pyfalog.error(msg)
|
||||
self.statusbar.SetStatusText(msg)
|
||||
|
||||
def importFitting(self, event):
|
||||
selection = self.fitView.fitSelection
|
||||
if not selection:
|
||||
return
|
||||
data = self.fitTree.fittingsTreeCtrl.GetPyData(selection)
|
||||
sFit = service.Fit.getInstance()
|
||||
fits = sFit.importFitFromBuffer(data)
|
||||
sPort = Port.getInstance()
|
||||
fits = sPort.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:
|
||||
sCrest.delFitting(self.getActiveCharacter(), data['fittingID'])
|
||||
except requests.exceptions.ConnectionError:
|
||||
self.statusbar.SetStatusText("Connection error, please check your internet connection")
|
||||
msg = "Connection error, please check your internet connection"
|
||||
pyfalog.error(msg)
|
||||
self.statusbar.SetStatusText(msg)
|
||||
|
||||
|
||||
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 +229,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 +257,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 +266,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()
|
||||
sPort = Port.getInstance()
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
|
||||
self.statusbar.SetStatusText("", 0)
|
||||
@@ -264,64 +276,68 @@ 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)
|
||||
sFit = Fit.getInstance()
|
||||
data = sPort.exportCrest(sFit.getFit(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)
|
||||
except ValueError:
|
||||
pyfalog.warning("Value error on loading JSON.")
|
||||
self.statusbar.SetStatusText("", 1)
|
||||
except requests.exceptions.ConnectionError:
|
||||
self.statusbar.SetStatusText("Connection error, please check your internet connection", 1)
|
||||
msg = "Connection error, please check your internet connection"
|
||||
pyfalog.error(msg)
|
||||
self.statusbar.SetStatusText(msg)
|
||||
|
||||
|
||||
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()
|
||||
@@ -334,8 +350,9 @@ class CrestMgmt(wx.Dialog):
|
||||
self.lcCharacters.SetColumnWidth(0, wx.LIST_AUTOSIZE)
|
||||
self.lcCharacters.SetColumnWidth(1, wx.LIST_AUTOSIZE)
|
||||
|
||||
def addChar(self, event):
|
||||
sCrest = service.Crest.getInstance()
|
||||
@staticmethod
|
||||
def addChar(event):
|
||||
sCrest = Crest.getInstance()
|
||||
uri = sCrest.startServer()
|
||||
webbrowser.open(uri)
|
||||
|
||||
@@ -343,7 +360,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()
|
||||
|
||||
@@ -398,17 +415,18 @@ class FittingsTreeView(wx.Panel):
|
||||
cargo = Cargo(getItem(item['type']['id']))
|
||||
cargo.amount = item['quantity']
|
||||
list.append(cargo)
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Exception caught in displayFit")
|
||||
pyfalog.critical(e)
|
||||
|
||||
self.parent.fitView.fitSelection = selection
|
||||
self.parent.fitView.update(list)
|
||||
|
||||
|
||||
class FitView(d.Display):
|
||||
class FitView(Display):
|
||||
DEFAULT_COLS = ["Base Icon",
|
||||
"Base Name"]
|
||||
|
||||
def __init__(self, parent):
|
||||
d.Display.__init__(self, parent, style=wx.LC_SINGLE_SEL)
|
||||
Display.__init__(self, parent, style=wx.LC_SINGLE_SEL)
|
||||
self.fitSelection = None
|
||||
|
||||
101
gui/display.py
101
gui/display.py
@@ -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 sys
|
||||
# noinspection PyPackageRequirements
|
||||
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):
|
||||
DEFAULT_COLS = None
|
||||
|
||||
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 = []
|
||||
@@ -64,15 +67,15 @@ class Display(wx.ListCtrl):
|
||||
i += 1
|
||||
|
||||
info = wx.ListItem()
|
||||
# noinspection PyPropertyAccess
|
||||
info.m_mask = wx.LIST_MASK_WIDTH
|
||||
self.InsertColumnInfo(i, info)
|
||||
self.SetColumnWidth(i, 0)
|
||||
|
||||
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):
|
||||
"""
|
||||
@@ -89,11 +92,11 @@ class Display(wx.ListCtrl):
|
||||
|
||||
# Did the point hit any item?
|
||||
if (flags & wx.LIST_HITTEST_ONITEM) == 0:
|
||||
return (-1, 0, -1)
|
||||
return -1, 0, -1
|
||||
|
||||
# If it did hit an item and we are not in report mode, it must be the primary cell
|
||||
if not self.InReportView():
|
||||
return (rowIndex, wx.LIST_HITTEST_ONITEM, 0)
|
||||
return rowIndex, wx.LIST_HITTEST_ONITEM, 0
|
||||
|
||||
# Find which subitem is hit
|
||||
right = 0
|
||||
@@ -106,19 +109,18 @@ class Display(wx.ListCtrl):
|
||||
flag = wx.LIST_HITTEST_ONITEMICON
|
||||
else:
|
||||
flag = wx.LIST_HITTEST_ONITEMLABEL
|
||||
return (rowIndex, flag, i)
|
||||
return rowIndex, flag, i
|
||||
|
||||
return (rowIndex, 0, -1)
|
||||
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 +131,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()
|
||||
@@ -146,6 +147,7 @@ class Display(wx.ListCtrl):
|
||||
else:
|
||||
event.Skip()
|
||||
|
||||
# noinspection PyPropertyAccess
|
||||
def addColumn(self, i, col):
|
||||
self.activeColumns.append(col)
|
||||
info = wx.ListItem()
|
||||
@@ -171,41 +173,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 +218,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:
|
||||
if listItemCount - stuffItemCount > 20 > stuffItemCount:
|
||||
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 +267,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 +286,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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,43 +15,49 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
import gui.marketBrowser as mb
|
||||
import gui.display as d
|
||||
from gui.marketBrowser import ITEM_SELECTED, ItemSelected
|
||||
from gui.display import Display
|
||||
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, *args, **kwargs):
|
||||
super(DroneViewDrop, self).__init__(*args, **kwargs)
|
||||
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",]
|
||||
|
||||
class DroneView(Display):
|
||||
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)
|
||||
Display.__init__(self, parent, style=wx.LC_SINGLE_SEL | wx.BORDER_NONE)
|
||||
|
||||
self.lastFitId = None
|
||||
|
||||
@@ -59,19 +65,18 @@ class DroneView(d.Display):
|
||||
self.hoveredColumn = None
|
||||
|
||||
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
|
||||
self.mainFrame.Bind(mb.ITEM_SELECTED, self.addItem)
|
||||
self.mainFrame.Bind(ITEM_SELECTED, self.addItem)
|
||||
self.Bind(wx.EVT_LEFT_DCLICK, self.removeItem)
|
||||
self.Bind(wx.EVT_LEFT_DOWN, self.click)
|
||||
self.Bind(wx.EVT_KEY_UP, self.kbEvent)
|
||||
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 +112,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,31 +122,32 @@ 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):
|
||||
'''
|
||||
"""
|
||||
Handles dragging of items from various pyfa displays which support it
|
||||
|
||||
data is list with two indices:
|
||||
data[0] is hard-coded str of originating source
|
||||
data[1] is typeID or index of data we want to manipulate
|
||||
'''
|
||||
"""
|
||||
if data[0] == "drone": # we want to merge drones
|
||||
srcRow = int(data[1])
|
||||
dstRow, _ = self.HitTest((x, y))
|
||||
if srcRow != -1 and dstRow != -1:
|
||||
self._merge(srcRow, dstRow)
|
||||
elif data[0] == "market":
|
||||
wx.PostEvent(self.mainFrame, mb.ItemSelected(itemID=int(data[1])))
|
||||
wx.PostEvent(self.mainFrame, 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 +155,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 +165,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 +183,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 +196,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 +222,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 +233,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 +248,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))
|
||||
|
||||
94
gui/errorDialog.py
Normal file
94
gui/errorDialog.py
Normal file
@@ -0,0 +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
|
||||
import sys
|
||||
import gui.utils.fonts as fonts
|
||||
import config
|
||||
|
||||
|
||||
class ErrorFrame(wx.Frame):
|
||||
|
||||
def __init__(self, exception, tb):
|
||||
wx.Frame.__init__(self, None, id=wx.ID_ANY, title="pyfa error", pos=wx.DefaultPosition, size=wx.Size(500, 400),
|
||||
style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER | wx.STAY_ON_TOP)
|
||||
|
||||
desc = "pyfa has experienced an unexpected error. Below is the " \
|
||||
"Traceback that contains crucial information about how this " \
|
||||
"error was triggered. Please contact the developers with " \
|
||||
"the information provided through the EVE Online forums " \
|
||||
"or file a GitHub issue."
|
||||
|
||||
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
|
||||
|
||||
if 'wxMSW' in wx.PlatformInfo:
|
||||
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))
|
||||
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
headSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
self.headingText = wx.StaticText(self, wx.ID_ANY, "Error!", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_CENTRE)
|
||||
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)
|
||||
|
||||
mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0, wx.EXPAND | wx.ALL, 5)
|
||||
|
||||
descSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.descText = wx.TextCtrl(self, wx.ID_ANY, desc, wx.DefaultPosition, wx.DefaultSize,
|
||||
wx.TE_AUTO_URL | wx.TE_MULTILINE | wx.TE_READONLY | wx.BORDER_NONE | wx.TRANSPARENT_WINDOW)
|
||||
self.descText.SetFont(wx.Font(fonts.BIG, wx.SWISS, wx.NORMAL, wx.NORMAL))
|
||||
descSizer.Add(self.descText, 1, wx.ALL, 5)
|
||||
mainSizer.Add(descSizer, 1, wx.EXPAND, 5)
|
||||
|
||||
self.eveForums = wx.HyperlinkCtrl(self, wx.ID_ANY, "EVE Forums Thread", "https://forums.eveonline.com/default.aspx?g=posts&t=466425",
|
||||
wx.DefaultPosition, wx.DefaultSize, wx.HL_DEFAULT_STYLE)
|
||||
|
||||
mainSizer.Add(self.eveForums, 0, wx.ALL, 2)
|
||||
|
||||
self.eveForums = wx.HyperlinkCtrl(self, wx.ID_ANY, "Github Issues", "https://github.com/pyfa-org/Pyfa/issues",
|
||||
wx.DefaultPosition, wx.DefaultSize, wx.HL_DEFAULT_STYLE)
|
||||
|
||||
mainSizer.Add(self.eveForums, 0, wx.ALL, 2)
|
||||
|
||||
# mainSizer.AddSpacer((0, 5), 0, wx.EXPAND, 5)
|
||||
|
||||
self.errorTextCtrl = wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_RICH2 | wx.TE_DONTWRAP)
|
||||
self.errorTextCtrl.SetFont(wx.Font(8, wx.FONTFAMILY_TELETYPE, wx.NORMAL, wx.NORMAL))
|
||||
mainSizer.Add(self.errorTextCtrl, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 5)
|
||||
|
||||
self.errorTextCtrl.AppendText("pyfa root: ")
|
||||
self.errorTextCtrl.AppendText(config.pyfaPath or "Unknown")
|
||||
self.errorTextCtrl.AppendText('\n')
|
||||
self.errorTextCtrl.AppendText("save path: ")
|
||||
self.errorTextCtrl.AppendText(config.savePath or "Unknown")
|
||||
self.errorTextCtrl.AppendText('\n')
|
||||
self.errorTextCtrl.AppendText("fs encoding: ")
|
||||
self.errorTextCtrl.AppendText(sys.getfilesystemencoding())
|
||||
self.errorTextCtrl.AppendText('\n\n')
|
||||
self.errorTextCtrl.AppendText(tb)
|
||||
|
||||
self.SetSizer(mainSizer)
|
||||
mainSizer.Layout()
|
||||
self.Layout()
|
||||
|
||||
self.Centre(wx.BOTH)
|
||||
|
||||
self.Show()
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,37 +15,40 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
import gui.marketBrowser as mb
|
||||
import gui.marketBrowser as marketBrowser
|
||||
import gui.mainFrame
|
||||
import gui.display as d
|
||||
from gui.builtinViewColumns.state import State
|
||||
from eos.types import Slot
|
||||
from eos.saveddata.module 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, *args, **kwargs):
|
||||
super(FighterViewDrop, self).__init__(*args, **kwargs)
|
||||
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 +58,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 +77,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 +92,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 +108,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)
|
||||
@@ -124,19 +127,18 @@ class FighterDisplay(d.Display):
|
||||
self.hoveredColumn = None
|
||||
|
||||
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
|
||||
self.mainFrame.Bind(mb.ITEM_SELECTED, self.addItem)
|
||||
self.mainFrame.Bind(marketBrowser.ITEM_SELECTED, self.addItem)
|
||||
self.Bind(wx.EVT_LEFT_DCLICK, self.removeItem)
|
||||
self.Bind(wx.EVT_LEFT_DOWN, self.click)
|
||||
self.Bind(wx.EVT_KEY_UP, self.kbEvent)
|
||||
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 +174,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,29 +184,30 @@ 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):
|
||||
'''
|
||||
"""
|
||||
Handles dragging of items from various pyfa displays which support it
|
||||
|
||||
data is list with two indices:
|
||||
data[0] is hard-coded str of originating source
|
||||
data[1] is typeID or index of data we want to manipulate
|
||||
'''
|
||||
"""
|
||||
if data[0] == "fighter": # we want to merge fighters
|
||||
srcRow = int(data[1])
|
||||
dstRow, _ = self.HitTest((x, y))
|
||||
if srcRow != -1 and dstRow != -1:
|
||||
self._merge(srcRow, dstRow)
|
||||
elif data[0] == "market":
|
||||
wx.PostEvent(self.mainFrame, mb.ItemSelected(itemID=int(data[1])))
|
||||
wx.PostEvent(self.mainFrame, marketBrowser.ItemSelected(itemID=int(data[1])))
|
||||
|
||||
def _merge(self, src, dst):
|
||||
@staticmethod
|
||||
def _merge(src, dst):
|
||||
return
|
||||
|
||||
'''
|
||||
@@ -215,7 +217,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 +226,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 +259,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 +279,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 +290,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 +305,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))
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx.lib.newevent
|
||||
|
||||
FitChanged, FIT_CHANGED = wx.lib.newevent.NewEvent()
|
||||
|
||||
75
gui/graph.py
75
gui/graph.py
@@ -1,36 +1,39 @@
|
||||
#===============================================================================
|
||||
# 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/>.
|
||||
#===============================================================================
|
||||
|
||||
class Graph(object):
|
||||
views = []
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
Graph.views.append(cls)
|
||||
|
||||
def __init__(self):
|
||||
self.name = ""
|
||||
|
||||
def getFields(self, fit, fields):
|
||||
raise NotImplementedError()
|
||||
|
||||
def getIcons(self):
|
||||
return None
|
||||
|
||||
from gui.builtinGraphs 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/>.
|
||||
# =============================================================================
|
||||
|
||||
|
||||
class Graph(object):
|
||||
views = []
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
Graph.views.append(cls)
|
||||
|
||||
def __init__(self):
|
||||
self.name = ""
|
||||
|
||||
def getFields(self, fit, fields):
|
||||
raise NotImplementedError()
|
||||
|
||||
def getIcons(self):
|
||||
return None
|
||||
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
from gui.builtinGraphs import fitDps # noqa: E402, F401
|
||||
|
||||
@@ -1,278 +1,349 @@
|
||||
#===============================================================================
|
||||
# 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 os
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
import gui.display
|
||||
import gui.globalEvents as GE
|
||||
|
||||
from gui.graph import Graph
|
||||
import service
|
||||
import gui.mainFrame
|
||||
|
||||
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 = unicode(os.path.expanduser(os.path.join("~", ".matplotlib")))
|
||||
|
||||
cache_file = os.path.join(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 = 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
|
||||
from logbook import Logger
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
try:
|
||||
import matplotlib as mpl
|
||||
|
||||
mpl_version = int(mpl.__version__[0])
|
||||
if mpl_version >= 2:
|
||||
mpl.use('wxagg')
|
||||
mplImported = True
|
||||
else:
|
||||
mplImported = False
|
||||
from matplotlib.patches import Patch
|
||||
|
||||
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
|
||||
from matplotlib.figure import Figure
|
||||
|
||||
graphFrame_enabled = True
|
||||
mplImported = True
|
||||
except ImportError:
|
||||
Patch = mpl = Canvas = Figure = None
|
||||
graphFrame_enabled = False
|
||||
mplImported = False
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
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 graphFrame_enabled
|
||||
global mplImported
|
||||
|
||||
self.Patch = None
|
||||
self.mpl_version = -1
|
||||
|
||||
try:
|
||||
import matplotlib as mpl
|
||||
self.mpl_version = int(mpl.__version__[0])
|
||||
if self.mpl_version >= 2:
|
||||
mpl.use('wxagg')
|
||||
mplImported = True
|
||||
else:
|
||||
mplImported = False
|
||||
from matplotlib.patches import Patch
|
||||
self.Patch = Patch
|
||||
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
|
||||
from matplotlib.figure import Figure
|
||||
graphFrame_enabled = True
|
||||
except ImportError:
|
||||
Patch = mpl = Canvas = Figure = None
|
||||
graphFrame_enabled = False
|
||||
|
||||
self.legendFix = False
|
||||
if not graphFrame_enabled:
|
||||
pyfalog.info("Problems importing matplotlib; continuing without graphs")
|
||||
return
|
||||
|
||||
try:
|
||||
cache_dir = mpl._get_cachedir()
|
||||
except:
|
||||
cache_dir = os.path.expanduser(os.path.join("~", ".matplotlib"))
|
||||
|
||||
cache_file = os.path.join(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')
|
||||
|
||||
graphFrame_enabled = True
|
||||
if int(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
|
||||
|
||||
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:
|
||||
pyfalog.warning("Invalid values in '{0}'", fit.name)
|
||||
self.SetStatusText("Invalid values in '%s'" % fit.name)
|
||||
self.canvas.draw()
|
||||
return
|
||||
|
||||
if self.mpl_version < 2:
|
||||
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)
|
||||
elif self.mpl_version >= 2:
|
||||
legend2 = []
|
||||
legend_colors = {
|
||||
0: "blue",
|
||||
1: "orange",
|
||||
2: "green",
|
||||
3: "red",
|
||||
4: "purple",
|
||||
5: "brown",
|
||||
6: "pink",
|
||||
7: "grey",
|
||||
}
|
||||
|
||||
for i, i_name in enumerate(legend):
|
||||
try:
|
||||
selected_color = legend_colors[i]
|
||||
except:
|
||||
selected_color = None
|
||||
legend2.append(Patch(color=selected_color, label=i_name), )
|
||||
|
||||
if len(legend2) > 0:
|
||||
leg = self.subplot.legend(handles=legend2)
|
||||
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)
|
||||
|
||||
@@ -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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import service
|
||||
import gui.display as d
|
||||
import gui.marketBrowser as mb
|
||||
import gui.marketBrowser as marketBrowser
|
||||
import gui.mainFrame
|
||||
from gui.builtinViewColumns.state import State
|
||||
from gui.contextMenu import ContextMenu
|
||||
import globalEvents as GE
|
||||
from eos.types import ImplantLocation
|
||||
from eos.saveddata.fit 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 +50,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 +58,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 +72,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))
|
||||
@@ -88,17 +90,17 @@ class ImplantDisplay(d.Display):
|
||||
self.lastFitId = None
|
||||
|
||||
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
|
||||
self.mainFrame.Bind(mb.ITEM_SELECTED, self.addItem)
|
||||
self.mainFrame.Bind(marketBrowser.ITEM_SELECTED, self.addItem)
|
||||
self.Bind(wx.EVT_LEFT_DCLICK, self.removeItem)
|
||||
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 +109,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 +123,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 +140,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 +164,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 +175,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 +188,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 +197,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
|
||||
|
||||
|
||||
665
gui/itemStats.py
665
gui/itemStats.py
File diff suppressed because it is too large
Load Diff
446
gui/mainFrame.py
446
gui/mainFrame.py
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,28 +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 sys
|
||||
import os.path
|
||||
from logbook import Logger
|
||||
|
||||
import sqlalchemy
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
# noinspection PyPackageRequirements
|
||||
from wx._core import PyDeadObjectError
|
||||
# noinspection PyPackageRequirements
|
||||
from wx.lib.wordwrap import wordwrap
|
||||
# noinspection PyPackageRequirements
|
||||
from wx.lib.inspection import InspectionTool
|
||||
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
|
||||
from gui.chromeTabs import PFNotebook
|
||||
import gui.globalEvents as GE
|
||||
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
@@ -56,40 +59,62 @@ 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 *
|
||||
# noinspection PyUnresolvedReferences
|
||||
from gui.builtinViews import emptyView, entityEditor, fittingView, implantEditor # noqa: F401
|
||||
from gui import graphFrame
|
||||
|
||||
from service.settings import SettingsProvider
|
||||
from service.fit import Fit
|
||||
from service.character import Character
|
||||
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.db.saveddata.queries import getFit as db_getFit
|
||||
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 Crest
|
||||
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
|
||||
disableOverrideEditor = True
|
||||
disableOverrideEditor = False
|
||||
|
||||
#dummy panel(no paint no erasebk)
|
||||
try:
|
||||
from gui.propertyEditor import AttributeEditor
|
||||
except ImportError as e:
|
||||
AttributeEditor = None
|
||||
print("Error loading Attribute Editor: %s.\nAccess to Attribute Editor is disabled." % e.message)
|
||||
disableOverrideEditor = True
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
# 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)
|
||||
self.name = "LoadingOpenFits"
|
||||
self.mainFrame = MainFrame.getInstance()
|
||||
self.callback = callback
|
||||
self.fits = fits
|
||||
@@ -111,51 +136,56 @@ 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
|
||||
def __init__(self, title="pyfa"):
|
||||
pyfalog.debug("Initialize MainFrame")
|
||||
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
|
||||
if 'wxMSW' in wx.PlatformInfo:
|
||||
self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
|
||||
self.disableOverrideEditor = disableOverrideEditor
|
||||
|
||||
#Load and set the icon for pyfa main window
|
||||
# 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))
|
||||
|
||||
# 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)
|
||||
|
||||
self.fitMultiSwitch = MultiSwitch(self.fitting_additions_split)
|
||||
self.additionsPane = AdditionsPane(self.fitting_additions_split)
|
||||
|
||||
self.notebookBrowsers = gui.chromeTabs.PFNotebook(self.browser_fitting_split, False)
|
||||
self.notebookBrowsers = PFNotebook(self.browser_fitting_split, False)
|
||||
|
||||
marketImg = BitmapLoader.getImage("market_small", "gui")
|
||||
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,31 +210,31 @@ class MainFrame(wx.Frame):
|
||||
|
||||
self.SetSizer(mainSizer)
|
||||
|
||||
#Add menu
|
||||
# Add menu
|
||||
self.addPageId = wx.NewId()
|
||||
self.closePageId = wx.NewId()
|
||||
|
||||
self.widgetInspectMenuID = wx.NewId()
|
||||
self.SetMenuBar(MainMenuBar())
|
||||
self.SetMenuBar(MainMenuBar(self))
|
||||
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 +246,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 +268,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 +291,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 +325,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 +338,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,86 +353,107 @@ 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
|
||||
|
||||
try:
|
||||
import matplotlib
|
||||
matplotlib_version = matplotlib.__version__
|
||||
except:
|
||||
matplotlib_version = None
|
||||
|
||||
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__ +
|
||||
"\nmatplotlib: \t {}".format(matplotlib_version if matplotlib_version else "Not Installed"),
|
||||
500, wx.ClientDC(self))
|
||||
if "__WXGTK__" in wx.PlatformInfo:
|
||||
forumUrl = "http://forums.eveonline.com/default.aspx?g=posts&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()
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
pyfalog.error("Tried to destroy an object that doesn't exist in <showDamagePatternEditor>.")
|
||||
|
||||
def showImplantSetEditor(self, event):
|
||||
ImplantSetEditorDlg(self)
|
||||
|
||||
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:
|
||||
output = sFit.exportXml(None, self.getActiveFit())
|
||||
if format_ == 0:
|
||||
sPort = Port.getInstance()
|
||||
output = sPort.exportXml(None, fit)
|
||||
if '.' not in os.path.basename(path):
|
||||
path += ".xml"
|
||||
else:
|
||||
print "oops, invalid fit format %d" % format
|
||||
dlg.Destroy()
|
||||
print("oops, invalid fit format %d" % format_)
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
pyfalog.error("Tried to destroy an object that doesn't exist in <showExportDialog>.")
|
||||
return
|
||||
file = open(path, "w", encoding="utf-8")
|
||||
file.write(output)
|
||||
file.close()
|
||||
dlg.Destroy()
|
||||
|
||||
with open(path, "w", encoding="utf-8") as openfile:
|
||||
openfile.write(output)
|
||||
openfile.close()
|
||||
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
pyfalog.error("Tried to destroy an object that doesn't exist in <showExportDialog>.")
|
||||
|
||||
def showPreferenceDialog(self, event):
|
||||
dlg = PreferenceDialog(self)
|
||||
dlg.ShowModal()
|
||||
|
||||
def goWiki(self, event):
|
||||
@staticmethod
|
||||
def goWiki(event):
|
||||
webbrowser.open('https://github.com/pyfa-org/Pyfa/wiki')
|
||||
|
||||
def goForums(self, event):
|
||||
@staticmethod
|
||||
def goForums(event):
|
||||
webbrowser.open('https://forums.eveonline.com/default.aspx?g=posts&t=466425')
|
||||
|
||||
def loadDatabaseDefaults(self, event):
|
||||
@staticmethod
|
||||
def loadDatabaseDefaults(event):
|
||||
# Import values that must exist otherwise Pyfa breaks
|
||||
DefaultDatabaseValues.importRequiredDefaults()
|
||||
# Import default values for damage profiles
|
||||
@@ -415,7 +469,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 +497,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 +532,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 +569,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 +622,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 +635,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 +643,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 +669,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 +692,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 +707,35 @@ 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()))
|
||||
fit = db_getFit(self.getActiveFit())
|
||||
toClipboard(Port.exportXml(None, fit))
|
||||
|
||||
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
|
||||
pyfalog.error("Attempt to import failed:\n{0}", clipboard)
|
||||
else:
|
||||
self._openAfterImport(fits)
|
||||
|
||||
@@ -697,17 +752,22 @@ class MainFrame(wx.Frame):
|
||||
|
||||
CopySelectDict[selected]()
|
||||
|
||||
|
||||
dlg.Destroy()
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
pyfalog.error("Tried to destroy an object that doesn't exist in <exportToClipboard>.")
|
||||
|
||||
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,66 +790,85 @@ 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)
|
||||
if (dlg.ShowModal() == wx.ID_OK):
|
||||
sPort = Port.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)
|
||||
sPort.importFitsThreaded(dlg.GetPaths(), self.fileImportCallback)
|
||||
self.progressDialog.ShowModal()
|
||||
dlg.Destroy()
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
pyfalog.error("Tried to destroy an object that doesn't exist in <fileImportDialog>.")
|
||||
|
||||
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 +905,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 +930,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,13 +952,13 @@ class MainFrame(wx.Frame):
|
||||
def openGraphFrame(self, event):
|
||||
if not self.graphFrame:
|
||||
self.graphFrame = GraphFrame(self)
|
||||
if gui.graphFrame.enabled:
|
||||
|
||||
if graphFrame.graphFrame_enabled:
|
||||
self.graphFrame.Show()
|
||||
else:
|
||||
elif graphFrame.graphFrame_enabled:
|
||||
self.graphFrame.SetFocus()
|
||||
|
||||
def openWXInspectTool(self, event):
|
||||
from wx.lib.inspection import InspectionTool
|
||||
if not InspectionTool().initialized:
|
||||
InspectionTool().Init()
|
||||
|
||||
@@ -887,4 +968,3 @@ class MainFrame(wx.Frame):
|
||||
if not wnd:
|
||||
wnd = self
|
||||
InspectionTool().Show(wnd, True)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,21 +15,28 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
import config
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
import gui.mainFrame
|
||||
from service.character import Character
|
||||
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)):
|
||||
from logbook import Logger
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0)):
|
||||
from service.crest import Crest
|
||||
from service.crest import CrestModes
|
||||
|
||||
|
||||
class MainMenuBar(wx.MenuBar):
|
||||
def __init__(self):
|
||||
def __init__(self, mainFrame):
|
||||
pyfalog.debug("Initialize MainMenuBar")
|
||||
self.characterEditorId = wx.NewId()
|
||||
self.damagePatternEditorId = wx.NewId()
|
||||
self.targetResistsEditorId = wx.NewId()
|
||||
@@ -51,11 +58,11 @@ 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()
|
||||
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
self.mainFrame = mainFrame
|
||||
wx.MenuBar.__init__(self)
|
||||
|
||||
# File menu
|
||||
@@ -80,8 +87,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")
|
||||
@@ -114,13 +121,16 @@ class MainMenuBar(wx.MenuBar):
|
||||
graphFrameItem.SetBitmap(BitmapLoader.getBitmap("graphs_small", "gui"))
|
||||
windowMenu.AppendItem(graphFrameItem)
|
||||
|
||||
if not gui.graphFrame.graphFrame_enabled:
|
||||
self.Enable(self.graphFrameId, False)
|
||||
|
||||
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()
|
||||
@@ -136,7 +146,7 @@ class MainMenuBar(wx.MenuBar):
|
||||
self.Enable(self.eveFittingsId, False)
|
||||
self.Enable(self.exportToEveId, False)
|
||||
|
||||
if not gui.mainFrame.disableOverrideEditor:
|
||||
if not self.mainFrame.disableOverrideEditor:
|
||||
windowMenu.AppendSeparator()
|
||||
attrItem = wx.MenuItem(windowMenu, self.attrEditorId, "Attribute Overrides\tCTRL+B")
|
||||
attrItem.SetBitmap(BitmapLoader.getBitmap("fit_rename_small", "gui"))
|
||||
@@ -154,17 +164,19 @@ 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)
|
||||
|
||||
def fitChanged(self, event):
|
||||
pyfalog.debug("fitChanged triggered")
|
||||
enable = event.fitID is not None
|
||||
self.Enable(wx.ID_SAVEAS, enable)
|
||||
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 +186,3 @@ class MainMenuBar(wx.MenuBar):
|
||||
self.Enable(self.revertCharId, char.isDirty)
|
||||
|
||||
event.Skip()
|
||||
|
||||
|
||||
|
||||
@@ -1,456 +1,471 @@
|
||||
#===============================================================================
|
||||
# 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/>.
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from service.market import Market
|
||||
from service.attribute import Attribute
|
||||
from gui.display import Display
|
||||
import gui.PFSearchBox as SBox
|
||||
from gui.cachingImageList import CachingImageList
|
||||
from gui.contextMenu import ContextMenu
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
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)
|
||||
pyfalog.debug("Initialize marketBrowser")
|
||||
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 = []
|
||||
btn = None
|
||||
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)
|
||||
pyfalog.debug("Initialize marketTree")
|
||||
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 Exception as e:
|
||||
pyfalog.debug("Error appending item.")
|
||||
pyfalog.debug(e)
|
||||
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(Display):
|
||||
DEFAULT_COLS = ["Base Icon",
|
||||
"Base Name",
|
||||
"attr:power,,,True",
|
||||
"attr:cpu,,,True"]
|
||||
|
||||
def __init__(self, parent, marketBrowser):
|
||||
Display.__init__(self, parent)
|
||||
pyfalog.debug("Initialize ItemView")
|
||||
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
|
||||
pyfalog.debug("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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
@@ -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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
import gui.chromeTabs
|
||||
from gui.chromeTabs import PFNotebook
|
||||
import gui.builtinViews.emptyView
|
||||
|
||||
|
||||
class MultiSwitch(gui.chromeTabs.PFNotebook):
|
||||
class MultiSwitch(PFNotebook):
|
||||
def __init__(self, parent):
|
||||
gui.chromeTabs.PFNotebook.__init__(self, parent)
|
||||
#self.AddPage() # now handled by mainFrame
|
||||
PFNotebook.__init__(self, parent)
|
||||
# self.AddPage() # now handled by mainFrame
|
||||
self.handlers = handlers = []
|
||||
for type in TabSpawner.tabTypes:
|
||||
handlers.append(type(self))
|
||||
@@ -40,10 +40,10 @@ class MultiSwitch(gui.chromeTabs.PFNotebook):
|
||||
tabWnd = gui.builtinViews.emptyView.BlankPage(self)
|
||||
tabWnd.handleDrag = lambda type, info: self.handleDrag(type, info)
|
||||
|
||||
gui.chromeTabs.PFNotebook.AddPage(self, tabWnd, tabTitle, tabImage, True)
|
||||
PFNotebook.AddPage(self, tabWnd, tabTitle, tabImage, True)
|
||||
|
||||
def DeletePage(self, n, *args, **kwargs):
|
||||
gui.chromeTabs.PFNotebook.DeletePage(self, n, *args, **kwargs)
|
||||
PFNotebook.DeletePage(self, n, *args, **kwargs)
|
||||
if self.GetPageCount() == 0:
|
||||
self.AddPage()
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# noinspection PyPackageRequirements
|
||||
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 +21,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 +36,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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,18 +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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
import service
|
||||
# noinspection PyPackageRequirements
|
||||
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
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class DmgPatternTextValidor(BaseValidator):
|
||||
def __init__(self):
|
||||
@@ -47,7 +49,8 @@ class DmgPatternTextValidor(BaseValidator):
|
||||
raise ValueError("Damage Profile name already in use, please choose another.")
|
||||
|
||||
return True
|
||||
except ValueError, e:
|
||||
except ValueError as e:
|
||||
pyfalog.error(e)
|
||||
wx.MessageBox(u"{}".format(e), "Error")
|
||||
textCtrl.SetFocus()
|
||||
return False
|
||||
@@ -59,33 +62,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 +115,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 +127,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 +151,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 +160,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 +170,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 +200,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,20 +255,24 @@ 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:
|
||||
pyfalog.error(e)
|
||||
self.stNotice.SetLabel(str(e))
|
||||
except Exception, e:
|
||||
self.stNotice.SetLabel("Could not import from clipboard: unknown errors")
|
||||
except Exception as e:
|
||||
msg = "Could not import from clipboard: unknown errors"
|
||||
pyfalog.warning(msg)
|
||||
pyfalog.error(e)
|
||||
self.stNotice.SetLabel(msg)
|
||||
finally:
|
||||
self.entityEditor.refreshEntityList()
|
||||
else:
|
||||
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")
|
||||
|
||||
@@ -1,80 +1,81 @@
|
||||
#===============================================================================
|
||||
# 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 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")
|
||||
i = wx.IconFromBitmap(BitmapLoader.getBitmap("preferences_small", "gui"))
|
||||
self.SetIcon(i)
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
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.imageList = wx.ImageList(32,32)
|
||||
self.listbook.SetImageList(self.imageList)
|
||||
|
||||
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 )
|
||||
|
||||
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)
|
||||
|
||||
for prefView in PreferenceView.views:
|
||||
page = wx.Panel(self.listbook)
|
||||
bmp = prefView.getImage()
|
||||
if bmp:
|
||||
imgID = self.imageList.Add(bmp)
|
||||
else:
|
||||
imgID = -1
|
||||
prefView.populatePanel(page)
|
||||
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()
|
||||
if minHeight > bestFit[1]:
|
||||
self.SetSizeWH(450, minHeight)
|
||||
else:
|
||||
self.SetSizeWH(450, bestFit[1])
|
||||
|
||||
self.Layout()
|
||||
|
||||
self.btnOK.Bind(wx.EVT_BUTTON, self.OnBtnOK)
|
||||
|
||||
def OnBtnOK(self, event):
|
||||
self.Close()
|
||||
# =============================================================================
|
||||
# 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/>.
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from gui.preferenceView import PreferenceView
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
|
||||
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")
|
||||
i = wx.IconFromBitmap(BitmapLoader.getBitmap("preferences_small", "gui"))
|
||||
self.SetIcon(i)
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
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.imageList = wx.ImageList(32, 32)
|
||||
self.listbook.SetImageList(self.imageList)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
for prefView in PreferenceView.views:
|
||||
page = wx.Panel(self.listbook)
|
||||
bmp = prefView.getImage()
|
||||
if bmp:
|
||||
imgID = self.imageList.Add(bmp)
|
||||
else:
|
||||
imgID = -1
|
||||
prefView.populatePanel(page)
|
||||
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()
|
||||
if minHeight > bestFit[1]:
|
||||
self.SetSizeWH(450, minHeight)
|
||||
else:
|
||||
self.SetSizeWH(450, bestFit[1])
|
||||
|
||||
self.Layout()
|
||||
|
||||
self.btnOK.Bind(wx.EVT_BUTTON, self.OnBtnOK)
|
||||
|
||||
def OnBtnOK(self, event):
|
||||
self.Close()
|
||||
|
||||
@@ -1,41 +1,48 @@
|
||||
#===============================================================================
|
||||
# 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
|
||||
|
||||
class PreferenceView(object):
|
||||
views = []
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
PreferenceView.views.append(cls())
|
||||
|
||||
def populatePanel(self, panel):
|
||||
raise NotImplementedError()
|
||||
|
||||
def refreshPanel(self, fit):
|
||||
raise NotImplementedError()
|
||||
|
||||
def getImage(self):
|
||||
return wx.NullBitmap
|
||||
|
||||
from gui.builtinPreferenceViews 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/>.
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
|
||||
class PreferenceView(object):
|
||||
views = []
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
PreferenceView.views.append(cls())
|
||||
|
||||
def populatePanel(self, panel):
|
||||
raise NotImplementedError()
|
||||
|
||||
def refreshPanel(self, fit):
|
||||
raise NotImplementedError()
|
||||
|
||||
def getImage(self):
|
||||
return wx.NullBitmap
|
||||
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
from gui.builtinPreferenceViews import ( # noqa: E402, F401
|
||||
pyfaGeneralPreferences,
|
||||
pyfaNetworkPreferences,
|
||||
pyfaHTMLExportPreferences,
|
||||
pyfaCrestPreferences,
|
||||
pyfaUpdatePreferences
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,40 +15,47 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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:
|
||||
class DummyItem(object):
|
||||
def __init__(self, txt):
|
||||
self.name = txt
|
||||
self.icon = None
|
||||
|
||||
class DummyEntry:
|
||||
|
||||
class DummyEntry(object):
|
||||
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, *args, **kwargs):
|
||||
super(ProjectedViewDrop, self).__init__(*args, **kwargs)
|
||||
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 +65,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 +77,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)
|
||||
@@ -79,72 +86,73 @@ class ProjectedView(d.Display):
|
||||
self.SetDropTarget(ProjectedViewDrop(self.handleListDrag))
|
||||
|
||||
def handleListDrag(self, x, y, data):
|
||||
'''
|
||||
"""
|
||||
Handles dragging of items from various pyfa displays which support it
|
||||
|
||||
data is list with two indices:
|
||||
data[0] is hard-coded str of originating source
|
||||
data[1] is typeID or index of data we want to manipulate
|
||||
'''
|
||||
"""
|
||||
|
||||
if data[0] == "projected":
|
||||
# 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):
|
||||
@staticmethod
|
||||
def moduleSort(module):
|
||||
return module.item.name
|
||||
|
||||
def fighterSort(self, fighter):
|
||||
@staticmethod
|
||||
def fighterSort(fighter):
|
||||
return fighter.item.name
|
||||
|
||||
def droneSort(self, drone):
|
||||
@@ -155,16 +163,17 @@ class ProjectedView(d.Display):
|
||||
return (self.droneView.DRONE_ORDER.index(item.marketGroup.name),
|
||||
drone.item.name)
|
||||
|
||||
def fitSort(self, fit):
|
||||
@staticmethod
|
||||
def fitSort(fit):
|
||||
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
|
||||
@@ -198,7 +207,7 @@ class ProjectedView(d.Display):
|
||||
|
||||
self.deselectItems()
|
||||
|
||||
if stuff == []:
|
||||
if not stuff:
|
||||
stuff = [DummyEntry("Drag an item or fit, or use right-click menu for system effects")]
|
||||
|
||||
self.update(stuff)
|
||||
@@ -231,7 +240,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 +254,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,8 +279,8 @@ class ProjectedView(d.Display):
|
||||
else:
|
||||
fitSrcContext = "projectedFit"
|
||||
fitItemContext = item.name
|
||||
context = ((fitSrcContext,fitItemContext),)
|
||||
context = context + (("projected",),)
|
||||
context = ((fitSrcContext, fitItemContext),)
|
||||
context += ("projected",),
|
||||
menu = ContextMenu.getMenu((item,), *context)
|
||||
elif sel == -1:
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
@@ -287,6 +297,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))
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import csv
|
||||
from logbook import Logger
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
try:
|
||||
# noinspection PyPackageRequirements
|
||||
import wx.propgrid as wxpg
|
||||
except:
|
||||
if wx.VERSION < (2, 9):
|
||||
@@ -8,24 +13,22 @@ except:
|
||||
else:
|
||||
raise
|
||||
|
||||
import gui.PFSearchBox as SBox
|
||||
from gui.marketBrowser import SearchBox
|
||||
from eos.db.gamedata.queries import getItem, getAttributeInfo
|
||||
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
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
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 +48,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 +57,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 +70,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,27 +98,27 @@ 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)
|
||||
if (dlg.ShowModal() == wx.ID_OK):
|
||||
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:
|
||||
spamreader = csv.reader(csvfile)
|
||||
for row in spamreader:
|
||||
itemID, attrID, value = row
|
||||
item = eos.db.getItem(int(itemID))
|
||||
attr = eos.db.getAttributeInfo(int(attrID))
|
||||
item = getItem(int(itemID))
|
||||
attr = getAttributeInfo(int(attrID))
|
||||
item.setOverride(attr, float(value))
|
||||
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 +130,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 +150,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 +160,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 +181,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 +206,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 +217,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 +240,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()
|
||||
@@ -262,7 +270,7 @@ class AttributeGrid(wxpg.PropertyGrid):
|
||||
|
||||
self.itemView.updateItems()
|
||||
|
||||
logger.debug('%s changed to "%s"' % (p.GetName(), p.GetValueAsString()))
|
||||
pyfalog.debug('{0} changed to "{1}"', p.GetName(), p.GetValueAsString())
|
||||
|
||||
def OnPropGridSelect(self, event):
|
||||
pass
|
||||
|
||||
@@ -1,65 +1,56 @@
|
||||
# -*- 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
|
||||
###########################################################################
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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 +60,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 +115,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):
|
||||
@@ -157,7 +146,7 @@ class TogglePanel ( wx.Panel ):
|
||||
"""
|
||||
Handles the status changes (collapsing/expanding).
|
||||
|
||||
:param `sz`: an instance of `wx.Size`.
|
||||
:param sz: an instance of `wx.Size`.
|
||||
"""
|
||||
|
||||
# minimal size has priority over the best size so set here our min size
|
||||
|
||||
144
gui/pygauge.py
144
gui/pygauge.py
@@ -11,16 +11,17 @@ PyfaGauge is a generic Gauge implementation tailored for PYFA (Python Fitting As
|
||||
It uses the easeOutQuad equation from caurina.transitions.Tweener to do the animation stuff
|
||||
"""
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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 +30,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 +47,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 +68,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 +80,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 +108,6 @@ class PyGauge(wx.PyWindow):
|
||||
|
||||
return wx.Size(self._size[0], self._size[1])
|
||||
|
||||
|
||||
def GetBorderColour(self):
|
||||
return self._border_colour
|
||||
|
||||
@@ -121,7 +121,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 +130,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.
|
||||
: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. """
|
||||
|
||||
@@ -164,19 +163,18 @@ class PyGauge(wx.PyWindow):
|
||||
"""
|
||||
Sets the border padding.
|
||||
|
||||
:param `padding`: pixels between the border and the progress bar.
|
||||
:param padding: pixels between the border and the progress bar.
|
||||
"""
|
||||
|
||||
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,27 +184,28 @@ 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.
|
||||
|
||||
:param `range`: The maximum value of the gauge.
|
||||
:param reinit:
|
||||
:param range: The maximum value of the gauge.
|
||||
"""
|
||||
|
||||
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 +213,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 +230,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,21 +255,21 @@ 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):
|
||||
@staticmethod
|
||||
def OnEraseBackground(event):
|
||||
"""
|
||||
Handles the ``wx.EVT_ERASE_BACKGROUND`` event for L{PyGauge}.
|
||||
|
||||
:param `event`: a `wx.EraseEvent` event to be processed.
|
||||
:param event: a `wx.EraseEvent` event to be processed.
|
||||
|
||||
:note: This method is intentionally empty to reduce flicker.
|
||||
"""
|
||||
@@ -283,7 +280,7 @@ class PyGauge(wx.PyWindow):
|
||||
"""
|
||||
Handles the ``wx.EVT_PAINT`` event for L{PyGauge}.
|
||||
|
||||
:param `event`: a `wx.PaintEvent` event to be processed.
|
||||
:param event: a `wx.PaintEvent` event to be processed.
|
||||
"""
|
||||
|
||||
dc = wx.BufferedPaintDC(self)
|
||||
@@ -308,7 +305,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 +323,46 @@ class PyGauge(wx.PyWindow):
|
||||
# time on them if not needed. See GH issue #282
|
||||
|
||||
pv = value
|
||||
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 +376,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 +399,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
|
||||
: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 +431,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 +446,3 @@ class PyGauge(wx.PyWindow):
|
||||
self._timer.Stop()
|
||||
|
||||
self.Refresh()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2014 Ryan Holmes
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,14 +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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
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
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class TargetResistsTextValidor(BaseValidator):
|
||||
@@ -44,7 +47,8 @@ class TargetResistsTextValidor(BaseValidator):
|
||||
raise ValueError("Target Resist Profile name already in use, please choose another.")
|
||||
|
||||
return True
|
||||
except ValueError, e:
|
||||
except ValueError as e:
|
||||
pyfalog.error(e)
|
||||
wx.MessageBox(u"{}".format(e), "Error")
|
||||
textCtrl.SetFocus()
|
||||
return False
|
||||
@@ -56,34 +60,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 +108,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 +142,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 +151,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 +164,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())))
|
||||
|
||||
@@ -189,20 +193,22 @@ class ResistsEditorDlg(wx.Dialog):
|
||||
self.Destroy()
|
||||
|
||||
def ValuesUpdated(self, event=None):
|
||||
'''
|
||||
"""
|
||||
Event that is fired when resists values change. Iterates through all
|
||||
resist edit fields. If blank, sets it to 0.0. If it is not a proper
|
||||
decimal value, sets text color to red and refuses to save changes until
|
||||
issue is resolved
|
||||
'''
|
||||
"""
|
||||
if self.block:
|
||||
return
|
||||
|
||||
editObj = None
|
||||
|
||||
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 +221,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,19 +230,23 @@ 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)
|
||||
self.stNotice.SetLabel("Incorrect Formatting (decimals only)")
|
||||
msg = "Incorrect Formatting (decimals only)"
|
||||
pyfalog.warning(msg)
|
||||
self.stNotice.SetLabel(msg)
|
||||
except AssertionError:
|
||||
editObj.SetForegroundColour(wx.RED)
|
||||
self.stNotice.SetLabel("Incorrect Range (must be 0-100)")
|
||||
msg = "Incorrect Range (must be 0-100)"
|
||||
pyfalog.warning(msg)
|
||||
self.stNotice.SetLabel(msg)
|
||||
finally: # Refresh for color changes to take effect immediately
|
||||
self.Refresh()
|
||||
|
||||
def patternChanged(self, event=None):
|
||||
"Event fired when user selects pattern. Can also be called from script"
|
||||
"""Event fired when user selects pattern. Can also be called from script"""
|
||||
|
||||
if not self.entityEditor.checkEntitiesExist():
|
||||
self.Destroy()
|
||||
@@ -250,35 +260,39 @@ 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):
|
||||
"Event fired when import from clipboard button is clicked"
|
||||
"""Event fired when import from clipboard button is clicked"""
|
||||
|
||||
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:
|
||||
pyfalog.error(e)
|
||||
self.stNotice.SetLabel(str(e))
|
||||
except Exception, e:
|
||||
self.stNotice.SetLabel("Could not import from clipboard: unknown errors")
|
||||
except Exception as e:
|
||||
msg = "Could not import from clipboard:"
|
||||
pyfalog.warning(msg)
|
||||
pyfalog.error(e)
|
||||
self.stNotice.SetLabel(msg)
|
||||
finally:
|
||||
self.entityEditor.refreshEntityList()
|
||||
else:
|
||||
self.stNotice.SetLabel("Could not import from clipboard")
|
||||
|
||||
def exportPatterns(self, event):
|
||||
"Event fired when export to clipboard button is clicked"
|
||||
sTR = service.TargetResists.getInstance()
|
||||
toClipboard( sTR.exportPatterns() )
|
||||
"""Event fired when export to clipboard button is clicked"""
|
||||
sTR = TargetResists.getInstance()
|
||||
toClipboard(sTR.exportPatterns())
|
||||
self.stNotice.SetLabel("Patterns exported to clipboard")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
# Copyright (C) 2016 Ryan Holmes
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,18 +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/>.
|
||||
#===============================================================================
|
||||
# =============================================================================
|
||||
|
||||
from logbook import Logger
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
from service.implantSet import ImplantSets
|
||||
from gui.builtinViews.implantEditor import BaseImplantEditorView
|
||||
import service
|
||||
from gui.utils.clipboard import toClipboard, fromClipboard
|
||||
from service.implantSet import ImportError
|
||||
import logging
|
||||
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class ImplantTextValidor(BaseValidator):
|
||||
def __init__(self):
|
||||
@@ -47,7 +48,8 @@ class ImplantTextValidor(BaseValidator):
|
||||
raise ValueError("Imlplant Set name already in use, please choose another.")
|
||||
|
||||
return True
|
||||
except ValueError, e:
|
||||
except ValueError as e:
|
||||
pyfalog.error(e)
|
||||
wx.MessageBox(u"{}".format(e), "Error")
|
||||
textCtrl.SetFocus()
|
||||
return False
|
||||
@@ -59,25 +61,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 +93,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 +140,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,23 +185,24 @@ class ImplantSetEditorDlg(wx.Dialog):
|
||||
def closeEvent(self, event):
|
||||
self.Destroy()
|
||||
|
||||
def __del__( self ):
|
||||
def __del__(self):
|
||||
pass
|
||||
|
||||
def importPatterns(self, event):
|
||||
"Event fired when import from clipboard button is clicked"
|
||||
"""Event fired when import from clipboard button is clicked"""
|
||||
|
||||
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:
|
||||
pyfalog.error(e)
|
||||
self.stNotice.SetLabel(str(e))
|
||||
except Exception, e:
|
||||
logging.exception("Unhandled Exception")
|
||||
except Exception as e:
|
||||
pyfalog.error(e)
|
||||
self.stNotice.SetLabel("Could not import from clipboard: unknown errors")
|
||||
finally:
|
||||
self.updateChoices()
|
||||
@@ -207,8 +210,8 @@ class ImplantSetEditorDlg(wx.Dialog):
|
||||
self.stNotice.SetLabel("Could not import from clipboard")
|
||||
|
||||
def exportPatterns(self, event):
|
||||
"Event fired when export to clipboard button is clicked"
|
||||
"""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")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import gui.utils.colorUtils as colorUtils
|
||||
import gui.utils.drawUtils as drawUtils
|
||||
|
||||
SB_ITEM_NORMAL = 0
|
||||
@@ -7,14 +7,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 +49,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 +58,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 +71,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 +96,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 +117,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 +137,6 @@ class PFToolbar(object):
|
||||
return doRefresh
|
||||
|
||||
def MouseClick(self, event):
|
||||
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)
|
||||
@@ -195,11 +196,12 @@ class PFToolbar(object):
|
||||
|
||||
return height
|
||||
|
||||
def HitTest(self, target, position, area):
|
||||
@staticmethod
|
||||
def HitTest(target, position, area):
|
||||
x, y = target
|
||||
px, py = position
|
||||
aX, aY = area
|
||||
if (px > x and px < x + aX) and (py > y and py < y + aY):
|
||||
if (x < px < x + aX) and (y < py < y + aY):
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -230,14 +232,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 +250,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 +257,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 +271,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 +291,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 +302,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 +322,6 @@ class SFBrowserItem(wx.Window):
|
||||
|
||||
self.MouseLeftUp(event)
|
||||
|
||||
|
||||
def OnLeftDown(self, event):
|
||||
if not self.HasCapture():
|
||||
self.CaptureMouse()
|
||||
@@ -357,13 +355,14 @@ class SFBrowserItem(wx.Window):
|
||||
|
||||
event.Skip()
|
||||
|
||||
def GetType(self):
|
||||
@staticmethod
|
||||
def GetType():
|
||||
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 +372,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 +395,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 +404,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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user