Merge branch 'master' of evefit.org:pyfa

This commit is contained in:
Lucas Thode
2010-11-29 04:58:58 -06:00
30 changed files with 427 additions and 201 deletions

2
eos

Submodule eos updated: 61bb6cf132...996dbac731

View File

@@ -20,7 +20,7 @@
import wx
import service
import gui.display as d
import gui.builtinViews.fittingView as fv
import gui.globalEvents as GE
import gui.marketBrowser as mb
from gui.builtinViewColumns.state import State
from gui.contextMenu import ContextMenu
@@ -32,7 +32,7 @@ class BoosterView(d.Display):
def __init__(self, parent):
d.Display.__init__(self, parent, style=wx.LC_SINGLE_SEL)
self.mainFrame.Bind(fv.FIT_CHANGED, self.fitChanged)
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
self.mainFrame.Bind(mb.ITEM_SELECTED, self.addItem)
self.Bind(wx.EVT_LEFT_DCLICK, self.removeItem)
self.Bind(wx.EVT_LEFT_DOWN, self.click)
@@ -55,7 +55,7 @@ class BoosterView(d.Display):
fitID = self.mainFrame.getActiveFit()
trigger = cFit.addBooster(fitID, event.itemID)
if trigger:
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.additionsPane.select("Boosters")
event.Skip()
@@ -66,7 +66,7 @@ class BoosterView(d.Display):
fitID = self.mainFrame.getActiveFit()
cFit = service.Fit.getInstance()
cFit.removeBooster(fitID, self.GetItemData(row))
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def click(self, event):
event.Skip()
@@ -77,7 +77,7 @@ class BoosterView(d.Display):
fitID = self.mainFrame.getActiveFit()
cFit = service.Fit.getInstance()
cFit.toggleBooster(fitID, row)
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def scheduleMenu(self, event):

View File

@@ -2,6 +2,7 @@ from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import wx
import gui.globalEvents as GE
from gui import bitmapLoader
class AmmoPattern(ContextMenu):
@@ -28,7 +29,7 @@ class AmmoPattern(ContextMenu):
fit = self.mainFrame.getActiveFit()
sFit = service.Fit.getInstance()
sFit.setAsPattern(fit, item)
wx.PostEvent(self.mainFrame, gui.builtinViews.fittingView.FitChanged(fitID=fit))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fit))
def getBitmap(self, context, selection):
return None

View File

@@ -1,7 +1,7 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import gui.builtinViews.fittingView
import gui.globalEvents as GE
import wx
from gui import bitmapLoader
@@ -26,7 +26,7 @@ class DamagePattern(ContextMenu):
fitID = self.mainFrame.getActiveFit()
sFit.setDamagePattern(fitID, self.patterns[i])
setattr(self.mainFrame,"_activeDmgPattern",self.patterns[i])
wx.PostEvent(self.mainFrame, gui.builtinViews.fittingView.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def getBitmap(self, context, selection):
sFit = service.Fit.getInstance()

View File

@@ -1,7 +1,7 @@
from gui.contextMenu import ContextMenu
from gui.itemStats import ItemStatsDialog
import gui.mainFrame
import gui.builtinViews.fittingView
import gui.globalEvents as GE
import service
import wx
@@ -54,5 +54,5 @@ class DroneSpinner(wx.Dialog):
sFit.splitDroneStack(fitID, self.drone, self.spinner.GetValue())
else:
sFit.splitProjectedDroneStack(fitID, self.drone, self.spinner.GetValue())
wx.PostEvent(mainFrame, gui.builtinViews.fittingView.FitChanged(fitID=fitID))
wx.PostEvent(mainFrame, GE.FitChanged(fitID=fitID))
event.Skip()

View File

@@ -1,7 +1,7 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import gui.builtinViews.fittingView
import gui.globalEvents as GE
import wx
from gui import bitmapLoader
@@ -19,7 +19,7 @@ class FactorReload(ContextMenu):
sFit = service.Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.toggleFactorReload(fitID)
wx.PostEvent(self.mainFrame, gui.builtinViews.fittingView.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def getBitmap(self, context, selection):
sFit = service.Fit.getInstance()

View File

@@ -4,7 +4,7 @@ import service
import wx
from gui import bitmapLoader
from eos.types import Hardpoint
import gui.builtinViews.fittingView
import gui.globalEvents as GE
class ModuleAmmoPicker(ContextMenu):
def __init__(self):
@@ -179,6 +179,6 @@ class ModuleAmmoPicker(ContextMenu):
fitID = self.mainFrame.getActiveFit()
sFit.setAmmo(fitID, charge.ID if charge is not None else None, self.modules)
wx.PostEvent(self.mainFrame, gui.builtinViews.fittingView.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
ModuleAmmoPicker.register()

View File

@@ -1,7 +1,7 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import gui.builtinViews.fittingView
import gui.globalEvents as GE
import wx
class Project(ContextMenu):
@@ -22,6 +22,6 @@ class Project(ContextMenu):
sFit = service.Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.project(fitID, selection[0])
wx.PostEvent(self.mainFrame, gui.builtinViews.fittingView.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
Project.register()

View File

@@ -99,7 +99,7 @@ class TargetingMiscViewFull(StatsView):
stats = (("labelTargets", lambda: fit.maxTargets, 3, 0, 0, ""),
("labelRange", lambda: fit.maxTargetRange / 1000, 3, 0, 0, "km"),
("labelScanRes", lambda: fit.ship.getModifiedItemAttr('scanResolution'), 3, 0, 0, "mm"),
("labelScanRes", lambda: fit.ship.getModifiedItemAttr("scanResolution"), 3, 0, 0, "mm"),
("labelSensorStr", lambda: fit.scanStrength, 3, 0, 0, ""),
("labelCtrlRange", lambda: fit.extraAttributes["droneControlRange"] / 1000, 3, 0, 0, "km"),
("labelFullSpeed", lambda: fit.ship.getModifiedItemAttr("maxVelocity"), 3, 0, 0, "m/s"),
@@ -120,15 +120,20 @@ class TargetingMiscViewFull(StatsView):
("Destroyer", 83), ("Cruiser", 130),
("Battlecruiser", 265), ("Battleship",420)]
if labelName is "labelScanRes":
lockTime = "%s\n" % "Lock Times".center(28)
lockTime = "%s\n" % "Lock Times".center(30)
for size, radius in RADII:
left = "%s [%d] " % (size, radius)
right = "% .1fs" % fit.calculateLockTime(radius)
lockTime += "%s\t%s\n" % (right,left)
left = "%.1fs" % fit.calculateLockTime(radius)
right = "%s [%d]" % (size, radius)
lockTime += "%5s\t%s\n" % (left,right)
# print lockTime # THIS IS ALIGNED!
label.SetToolTip(wx.ToolTip(lockTime))
elif labelName is "labelSensorStr":
label.SetToolTip(wx.ToolTip("Type: %s - %.1f" % (fit.scanType, value)))
elif labelName is "labelFullSigRadius":
label.SetToolTip(wx.ToolTip("Probe Size: %.3f" % fit.probeSize))
elif labelName is "labelFullWarpSpeed":
label.SetToolTip(wx.ToolTip("Max Warp Distance: %.1f AU" %
fit.maxWarpDistance))
elif fit is not None:
label.SetToolTip(wx.ToolTip("%.1f" % value))
self._cachedValues[counter] = value

View File

@@ -0,0 +1,26 @@
import wx
import gui.globalEvents as GE
import gui.chromeTabs
import gui.mainFrame
import service
class BlankPage(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, size=(0, 0))
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.parent = parent
self.parent.Bind(gui.chromeTabs.EVT_NOTEBOOK_PAGE_CHANGED, self.pageChanged)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=None))
def Destroy(self):
self.parent.Unbind(gui.chromeTabs.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)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
event.Skip()

View File

@@ -30,7 +30,7 @@ from eos.types import Slot
from gui.builtinViewColumns.state import State
from gui import bitmapLoader
FitChanged, FIT_CHANGED = wx.lib.newevent.NewEvent()
import gui.globalEvents as GE
#Tab spawning handler
class FitSpawner(gui.multiSwitch.TabSpawner):
@@ -48,6 +48,7 @@ class FitSpawner(gui.multiSwitch.TabSpawner):
if page.activeFitID == event.fitID:
count +=1
self.multiSwitch.SetSelection(index)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=event.fitID))
break
except:
pass
@@ -108,7 +109,7 @@ class FittingView(d.Display):
d.Display.__init__(self, parent, size = (0,0))
self.Show(False)
self.parent = parent
self.mainFrame.Bind(FIT_CHANGED, self.fitChanged)
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
self.mainFrame.Bind(gui.shipBrowser.EVT_FIT_RENAMED, self.fitRenamed)
self.mainFrame.Bind(gui.shipBrowser.EVT_FIT_REMOVED, self.fitRemoved)
self.mainFrame.Bind(gui.marketBrowser.ITEM_SELECTED, self.appendItem)
@@ -138,7 +139,7 @@ class FittingView(d.Display):
def Destroy(self):
self.parent.Unbind(gui.chromeTabs.EVT_NOTEBOOK_PAGE_CHANGED, handler=self.pageChanged)
self.mainFrame.Unbind(FIT_CHANGED, handler=self.fitChanged)
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)
self.mainFrame.Unbind(gui.marketBrowser.ITEM_SELECTED, handler=self.appendItem)
@@ -150,7 +151,7 @@ class FittingView(d.Display):
fitID = self.getActiveFit()
sFit = service.Fit.getInstance()
sFit.switchFit(fitID)
wx.PostEvent(self.mainFrame, FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
event.Skip()
@@ -190,7 +191,7 @@ class FittingView(d.Display):
if populate is not None:
self.Select(firstSel)
if populate: self.slotsChanged()
wx.PostEvent(self.mainFrame, FitChanged(fitID=self.activeFitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.activeFitID))
event.Skip()
@@ -216,7 +217,7 @@ class FittingView(d.Display):
self.slotsChanged()
sFit = service.Fit.getInstance()
sFit.switchFit(fitID)
wx.PostEvent(self.mainFrame, FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.updateTab()
event.Skip()
@@ -242,13 +243,13 @@ class FittingView(d.Display):
sel = self.GetNextSelected(sel)
cFit.setAmmo(fitID, itemID, modules)
wx.PostEvent(self.mainFrame, FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
else:
populate = cFit.appendModule(fitID, itemID)
if populate:
self.slotsChanged()
if populate is not None:
wx.PostEvent(self.mainFrame, FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
event.Skip()
@@ -262,7 +263,7 @@ class FittingView(d.Display):
if populate is not None:
if populate: self.slotsChanged()
wx.PostEvent(self.mainFrame, FitChanged(fitID=self.activeFitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.activeFitID))
event.Skip()
@@ -368,7 +369,7 @@ class FittingView(d.Display):
sFit = service.Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.toggleModulesState(fitID, self.mods[self.GetItemData(row)], mods, "right" if event.Button == 3 else "left")
wx.PostEvent(self.mainFrame, FitChanged(fitID=self.mainFrame.getActiveFit()))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
else:
event.Skip()

View File

@@ -27,7 +27,7 @@ import service
import gui.display as d
from gui.contextMenu import ContextMenu
import sys
import gui.builtinViews.fittingView as fv
import gui.globalEvents as GE
CharListUpdated, CHAR_LIST_UPDATED = wx.lib.newevent.NewEvent()
CharChanged, CHAR_CHANGED = wx.lib.newevent.NewEvent()
@@ -40,7 +40,7 @@ class CharacterEditor(wx.Frame):
i = wx.IconFromBitmap(bitmapLoader.getBitmap("character_small", "icons"))
self.SetIcon(i)
self.disableWin=wx.WindowDisabler(self)
self.disableWin= wx.WindowDisabler(self)
self.SetSizeHintsSz(wx.Size(640, 600), wx.DefaultSize)
self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
@@ -126,16 +126,18 @@ class CharacterEditor(wx.Frame):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
def editingFinished(self, event):
del self.disableWin
wx.PostEvent(self.mainFrame, CharListUpdated())
self.Destroy()
event.Skip()
def registerEvents(self):
self.Bind(wx.EVT_CLOSE, self.closeEvent)
self.skillTreeChoice.Bind(wx.EVT_CHOICE, self.charChanged)
def closeEvent(self, event):
event.Skip()
del self.disableWin
wx.PostEvent(self.mainFrame, CharListUpdated())
self.Destroy()
def restrict(self):
self.btnRename.Enable(False)
@@ -247,7 +249,7 @@ class CharacterEditor(wx.Frame):
fitID = self.mainFrame.getActiveFit()
if fitID is not None:
cFit.clearFit(fitID)
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
wx.Frame.Destroy(self)

View File

@@ -21,7 +21,7 @@ import wx
import service
from gui import characterEditor as ce
from gui import bitmapLoader
from gui.builtinViews import fittingView as fv
import gui.globalEvents as GE
import gui.mainFrame
class CharacterSelection(wx.Panel):
@@ -49,7 +49,7 @@ class CharacterSelection(wx.Panel):
self.skillReqsStaticBitmap.SetBitmap(self.cleanSkills)
self.Bind(wx.EVT_CHOICE, self.charChanged)
self.mainFrame.Bind(ce.CHAR_LIST_UPDATED, self.refreshCharacterList)
self.mainFrame.Bind(fv.FIT_CHANGED, self.fitChanged)
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
panelSize = wx.Size(-1,30)
self.SetMinSize(panelSize)
@@ -93,7 +93,7 @@ class CharacterSelection(wx.Panel):
cFit = service.Fit.getInstance()
cFit.changeChar(fitID, charID)
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def selectChar(self, charID):
choice = self.charChoice

View File

@@ -150,10 +150,11 @@ class PFNotebook(wx.Panel):
def GetPageCount(self):
return len(self.pages)
def AddPage(self, tabWnd, tabTitle ="Empty Tab", tabImage = None, showClose = True):
def AddPage(self, tabWnd = None, tabTitle ="Empty Tab", tabImage = None, showClose = True):
if self.activePage:
self.activePage.Hide()
if not tabWnd:
tabWnd = wx.Panel(self)
tabWnd.Reparent(self.pageContainer)
self.pageContainer.Layout()
@@ -796,6 +797,9 @@ class PFTabsContainer(wx.Panel):
index = self.GetTabIndex(tab)
self.DeleteTab(index)
wx.PostEvent(self.Parent, PageClosed(index=index))
sel = self.GetSelected()
if sel is not None:
wx.PostEvent(self.Parent, PageChanged(-1, sel))
return True
return False
@@ -811,7 +815,7 @@ class PFTabsContainer(wx.Panel):
if ev.isVetoed():
return False
self.Parent.AddPage(wx.Panel(self.Parent, size = (0,0)))
self.Parent.AddPage()
wx.PostEvent(self.Parent, PageAdded())
return True

View File

@@ -20,7 +20,7 @@
import wx
import service
import gui.builtinViews.fittingView as fv
import gui.globalEvents as GE
import gui.marketBrowser as mb
import gui.display as d
from gui.builtinViewColumns.state import State
@@ -50,7 +50,7 @@ class DroneView(d.Display):
def __init__(self, parent):
d.Display.__init__(self, parent, style=wx.LC_SINGLE_SEL)
self.mainFrame.Bind(fv.FIT_CHANGED, self.fitChanged)
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
self.mainFrame.Bind(mb.ITEM_SELECTED, self.addItem)
self.Bind(wx.EVT_LEFT_DCLICK, self.removeItem)
self.Bind(wx.EVT_LEFT_DOWN, self.click)
@@ -83,7 +83,7 @@ class DroneView(d.Display):
sFit = service.Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
if sFit.mergeDrones(fitID, self.drones[src], self.drones[dst]):
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
DRONE_ORDER = ('Light Scout Drones', 'Medium Scout Drones',
'Heavy Attack Drones', 'Sentry Drones', 'Fighters',
@@ -115,7 +115,7 @@ class DroneView(d.Display):
fitID = self.mainFrame.getActiveFit()
trigger = cFit.addDrone(fitID, event.itemID)
if trigger:
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.additionsPane.select("Drones")
event.Skip()
@@ -129,7 +129,7 @@ class DroneView(d.Display):
cFit = service.Fit.getInstance()
drone = self.drones[self.GetItemData(row)]
cFit.removeDrone(fitID, self.original.index(drone))
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def click(self, event):
event.Skip()
@@ -141,7 +141,7 @@ class DroneView(d.Display):
cFit = service.Fit.getInstance()
drone = self.drones[row]
cFit.toggleDrone(fitID, self.original.index(drone))
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def scheduleMenu(self, event):
event.Skip()

View File

@@ -4,6 +4,7 @@ from gui import bitmapLoader
import gui.mainFrame
from gui.PFListPane import PFListPane
import service.fleet
from util import GetPartialText
from wx.lib.buttons import GenBitmapButton
@@ -429,12 +430,12 @@ class FleetItem(wx.Window):
bdc.SetFont(self.fontBig)
fnx,fny = bdc.GetTextExtent(self.fleetName)
pfn = self.GetPartialText(self.fleetName, bdc, self.copyPosX - 16 - self.padding - tx - textStart, 1)
pfn = GetPartialText(bdc, self.fleetName, self.copyPosX - 16 - self.padding - tx - textStart)
bdc.DrawText(pfn, textStart, (rect.height/2 - fny) / 2)
bdc.SetFont(self.fontSmall)
fcx,fcy = bdc.GetTextExtent(fleetCount)
pfc = self.GetPartialText(fleetCount, bdc, self.copyPosX - 16 - self.padding - tx - textStart, 1)
pfc = GetPartialText(bdc, fleetCount, self.copyPosX - 16 - self.padding - tx - textStart)
bdc.DrawText(pfc, textStart, rect.height/2 + (rect.height/2 -fcy) / 2 )
bdc.SetFont(self.fontSmall)
@@ -474,18 +475,6 @@ class FleetItem(wx.Window):
self.AdjustFleetNameEditSize(textStart, self.copyPosX - self.editWidth - self.padding)
def GetPartialText(self, text, dc , maxWidth, minChars):
textwidths = dc.GetPartialTextExtents(text + "...")
count = 0
for i in textwidths:
if i <= maxWidth:
count +=1
else:
break
return "%s%s" % (text[:count if count > minChars else minChars], "..." if len(text) > count else "" )
def AdjustFleetNameEditSize(self, start,end):
fnEditSize = self.tcFleetName.GetSize()
wSize = self.GetSize()

3
gui/globalEvents.py Normal file
View File

@@ -0,0 +1,3 @@
import wx.lib.newevent
FitChanged, FIT_CHANGED = wx.lib.newevent.NewEvent()

View File

@@ -20,6 +20,7 @@
import wx
import bitmapLoader
import gui.display
import gui.globalEvents as GE
try:
import matplotlib as mpl
@@ -37,32 +38,37 @@ import gui.mainFrame
class GraphFrame(wx.Frame):
def __init__(self, parent, style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE | wx.FRAME_FLOAT_ON_PARENT):
wx.Frame.__init__(self, parent, title=u"pyfa: Graph Generator", style=style, size=(640, 480))
wx.Frame.__init__(self, parent, title=u"pyfa: Graph Generator", style=style, size=(520, 390))
i = wx.IconFromBitmap(bitmapLoader.getBitmap("graphs_small", "icons"))
self.SetIcon(i)
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.CreateStatusBar()
horSizer = wx.BoxSizer(wx.HORIZONTAL)
self.SetSizer(horSizer)
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
horSizer.Add(self.mainSizer, 1, wx.EXPAND)
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((320, -1))
horSizer.Add(self.fitList, 0, wx.EXPAND)
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)
@@ -75,7 +81,7 @@ class GraphFrame(wx.Frame):
dummyBox = wx.BoxSizer(wx.VERTICAL)
self.gridPanel.SetSizer(dummyBox)
self.gridSizer = wx.FlexGridSizer(0, 2)
self.gridSizer = wx.FlexGridSizer(0, 4)
self.gridSizer.AddGrowableCol(1)
dummyBox.Add(self.gridSizer, 0, wx.EXPAND)
@@ -86,18 +92,24 @@ class GraphFrame(wx.Frame):
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(gui.builtinViews.fittingView.FIT_CHANGED, self.draw)
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(gui.builtinViews.fittingView.FIT_CHANGED, handler=self.draw)
self.mainFrame.Unbind(GE.FIT_CHANGED, handler=self.draw)
event.Skip()
def getView(self):
@@ -212,5 +224,5 @@ class FitDisplay(gui.display.Display):
"Base Name"]
def __init__(self, parent):
gui.display.Display.__init__(self, parent, style = wx.SIMPLE_BORDER)
gui.display.Display.__init__(self, parent)

View File

@@ -20,11 +20,10 @@
import wx
import service
import gui.display as d
import gui.builtinViews.fittingView as fv
import gui.marketBrowser as mb
from gui.builtinViewColumns.state import State
from gui.contextMenu import ContextMenu
import globalEvents as GE
class ImplantView(d.Display):
DEFAULT_COLS = ["State",
"attr:implantness",
@@ -32,7 +31,7 @@ class ImplantView(d.Display):
def __init__(self, parent):
d.Display.__init__(self, parent, style=wx.LC_SINGLE_SEL)
self.mainFrame.Bind(fv.FIT_CHANGED, self.fitChanged)
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
self.mainFrame.Bind(mb.ITEM_SELECTED, self.addItem)
self.Bind(wx.EVT_LEFT_DCLICK, self.removeItem)
self.Bind(wx.EVT_KEY_UP, self.kbEvent)
@@ -51,7 +50,7 @@ class ImplantView(d.Display):
if row != -1:
cFit.removeImplant(fitID, self.GetItemData(row))
row = self.GetNextSelected(row)
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def fitChanged(self, event):
cFit = service.Fit.getInstance()
@@ -69,7 +68,7 @@ class ImplantView(d.Display):
fitID = self.mainFrame.getActiveFit()
trigger = cFit.addImplant(fitID, event.itemID)
if trigger:
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.additionsPane.select("Implants")
event.Skip()
@@ -81,7 +80,7 @@ class ImplantView(d.Display):
cFit = service.Fit.getInstance()
implant = self.implants[self.GetItemData(row)]
cFit.removeImplant(fitID, self.original.index(implant))
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def click(self, event):
event.Skip()
@@ -92,7 +91,7 @@ class ImplantView(d.Display):
fitID = self.mainFrame.getActiveFit()
cFit = service.Fit.getInstance()
cFit.toggleImplant(fitID, row)
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def scheduleMenu(self, event):
event.Skip()

View File

@@ -569,7 +569,8 @@ class ItemAffectedBy (wx.Panel):
if afflictorType == Ship:
itemIcon = self.imageList.Add(bitmapLoader.getBitmap("ship_small", "icons"))
elif baseAfflictor.item.icon:
itemIcon = self.imageList.Add(bitmapLoader.getBitmap(baseAfflictor.item.icon.iconFile, "pack"))
bitmap = bitmapLoader.getBitmap(baseAfflictor.item.icon.iconFile, "pack")
itemIcon = self.imageList.Add(bitmap) if bitmap else -1
else:
itemIcon = -1

View File

@@ -21,6 +21,7 @@ import wx
import bitmapLoader
import gui.mainFrame
import gui.graphFrame
import gui.globalEvents as GE
class MainMenuBar(wx.MenuBar):
def __init__(self):
@@ -90,7 +91,7 @@ class MainMenuBar(wx.MenuBar):
self.mainFrame.Bind(gui.builtinViews.fittingView.FIT_CHANGED, self.fitChanged)
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
def fitChanged(self, event):
enable = event.fitID is not None

View File

@@ -19,6 +19,7 @@
import wx
import gui.chromeTabs
import gui.builtinViews.emptyView
class MultiSwitch(gui.chromeTabs.PFNotebook):
def __init__(self, parent):
@@ -36,7 +37,7 @@ class MultiSwitch(gui.chromeTabs.PFNotebook):
def AddPage(self, tabWnd=None, tabTitle="Empty Tab", tabImage=None):
if tabWnd is None:
tabWnd = BlankPage(self)
tabWnd = gui.builtinViews.emptyView.BlankPage(self)
tabWnd.handleDrag = lambda type, info: self.handleDrag(type, info)
gui.chromeTabs.PFNotebook.AddPage(self, tabWnd, tabTitle, tabImage, True)
@@ -47,10 +48,6 @@ class MultiSwitch(gui.chromeTabs.PFNotebook):
if self.GetPageCount() == 0:
self.AddPage()
class BlankPage(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, size=(0, 0))
class TabSpawner(object):
tabTypes = []
@classmethod

View File

@@ -19,9 +19,9 @@
import wx
import bitmapLoader
from wx.lib.intctrl import IntCtrl
import service
from util import toClipboard, fromClipboard
from util import toClipboard, fromClipboard, FloatCtrl
###########################################################################
## Class DmgPatternEditorDlg
###########################################################################
@@ -103,22 +103,26 @@ class DmgPatternEditorDlg (wx.Dialog):
self.bmpEM = wx.StaticBitmap(self, wx.ID_ANY, self.embitmap)
dmgeditSizer.Add(self.bmpEM, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 5)
self.editEm = IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize)
self.editEm = FloatCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize)
self.editEm.SetPrecision(2)
dmgeditSizer.Add(self.editEm, 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5)
self.bmpTHERM = wx.StaticBitmap(self, wx.ID_ANY, self.thermbitmap)
dmgeditSizer.Add(self.bmpTHERM, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT, 25)
self.editThermal = IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize, 0)
self.editThermal = FloatCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize, 0)
self.editThermal.SetPrecision(2)
dmgeditSizer.Add(self.editThermal, 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5)
self.bmpKIN = wx.StaticBitmap(self, wx.ID_ANY, self.kinbitmap)
dmgeditSizer.Add(self.bmpKIN, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 5)
self.editKinetic = IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize)
self.editKinetic = FloatCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize)
self.editKinetic.SetPrecision(2)
dmgeditSizer.Add(self.editKinetic, 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5)
self.bmpEXP = wx.StaticBitmap(self, wx.ID_ANY, self.expbitmap)
dmgeditSizer.Add(self.bmpEXP, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT, 25)
self.editExplosive = IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize, 0)
self.editExplosive = FloatCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize, 0)
self.editExplosive.SetPrecision(2)
dmgeditSizer.Add(self.editExplosive, 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5)
contentSizer.Add(dmgeditSizer, 1, wx.EXPAND | wx.ALL, 5)
@@ -136,12 +140,6 @@ class DmgPatternEditorDlg (wx.Dialog):
self.totSizer = wx.BoxSizer(wx.VERTICAL)
# self.stTotal = wx.StaticText(self, wx.ID_ANY, u"LOL")
# self.stTotal.Wrap(-1)
# self.totSizer.Add(self.stTotal, 0, wx.ALIGN_RIGHT | wx.BOTTOM | wx.RIGHT, 5)
# footerSizer.Add(self.totSizer, 1, 0, 5)
contentSizer.Add(footerSizer, 0, wx.EXPAND, 5)
mainSizer.Add(contentSizer, 1, wx.EXPAND, 0)
@@ -167,12 +165,6 @@ class DmgPatternEditorDlg (wx.Dialog):
bsize = self.GetBestSize()
self.SetSize((-1,bsize.height))
self.editEm.SetLimited(True)
self.editThermal.SetLimited(True)
self.editKinetic.SetLimited(True)
self.editExplosive.SetLimited(True)
self.editEm.SetMin(0)
self.editThermal.SetMin(0)
self.editKinetic.SetMin(0)
@@ -214,9 +206,7 @@ class DmgPatternEditorDlg (wx.Dialog):
else:
ltext = format %(0, 0, 0, 0)
#ttext = "Total: % 6d" % (total)
self.stPercentages.SetLabel(ltext)
#self.stTotal.SetLabel(ttext)
self.totSizer.Layout()
if event is not None:
@@ -297,7 +287,7 @@ class DmgPatternEditorDlg (wx.Dialog):
def processRename(self, event):
newName = self.namePicker.GetLineText(0)
self.stPercentages.SetLabel("")
# self.stTotal.SetLabel("")
p = self.getActivePattern()
for pattern in self.choices:
if pattern.name == newName and p != pattern:

View File

@@ -19,7 +19,7 @@
import wx
import gui.display as d
import gui.builtinViews.fittingView as fv
import gui.globalEvents as GE
import service
import gui.droneView
from gui.builtinViewColumns.state import State
@@ -49,7 +49,7 @@ class ProjectedView(d.Display):
def __init__(self, parent):
d.Display.__init__(self, parent, style = wx.LC_SINGLE_SEL)
self.mainFrame.Bind(fv.FIT_CHANGED, self.fitChanged)
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
self.Bind(wx.EVT_LEFT_DOWN, self.click)
self.Bind(wx.EVT_RIGHT_DOWN, self.click)
self.Bind(wx.EVT_LEFT_DCLICK, self.remove)
@@ -66,7 +66,7 @@ class ProjectedView(d.Display):
sFit = service.Fit.getInstance()
draggedFit = sFit.getFit(fitID)
sFit.project(activeFit,draggedFit)
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=activeFit))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFit))
def startDrag(self, event):
row = event.GetIndex()
@@ -90,7 +90,7 @@ class ProjectedView(d.Display):
sFit = service.Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
if sFit.mergeDrones(fitID, self.get(src), dstDrone, True):
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def moduleSort(self, module):
@@ -148,7 +148,7 @@ class ProjectedView(d.Display):
fitID = self.mainFrame.getActiveFit()
cFit = service.Fit.getInstance()
cFit.toggleProjected(fitID, item, "right" if event.Button == 3 else "left")
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
elif event.Button == 3:
if isinstance(item, eos.types.Drone):
context = ("projectedDrone",)
@@ -172,4 +172,4 @@ class ProjectedView(d.Display):
fitID = self.mainFrame.getActiveFit()
cFit = service.Fit.getInstance()
cFit.removeProjected(fitID, self.get(row))
wx.PostEvent(self.mainFrame, fv.FitChanged(fitID=fitID))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))

View File

@@ -4,7 +4,7 @@
## pyfatogllepanel.py
##
## Author: Darriele - HomeWorld
## Serial: 2010092801 (YYYYMMDDII)
##
## Project home: http://www.evefit.org - pyfa project
## http://www.evefit.org is the home for pyfa / eos / aurora
## Some portions of code are based on
@@ -41,34 +41,24 @@ class TogglePanel ( wx.Panel ):
self.forceLayout = forceLayout
self.bkColour = self.GetBackgroundColour()
# Odd stuff :S
# self.SetBackgroundColour( self.bkColour )
# Create the main sizer of this 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
# Create the header panel
self.headerPanel = wx.Panel(self)
# self.headerPanel.SetBackgroundColour( self.bkColour)
self.mainSizer.Add(self.headerPanel,0,wx.EXPAND | wx.TOP|wx.BOTTOM|wx.RIGHT, 1)
# Attempt to use native treeitembitmaps - fails on some linux distros / w.mangers
# self.bmpExpanded = self.GetNativeTreeItemBitmap("expanded")
# self.bmpCollapsed = self.GetNativeTreeItemBitmap("")
#
# Load expanded/collapsed bitmaps from the icons folder
# Load expanded/collapsed bitmaps from the icons folder
self.bmpExpanded = bitmapLoader.getBitmap("down-arrow2","icons")
self.bmpCollapsed = bitmapLoader.getBitmap("up-arrow2","icons")
# Make the bitmaps have the same color as window text
# Make the bitmaps have the same color as window text
sysTextColour = wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOWTEXT )
@@ -80,12 +70,10 @@ class TogglePanel ( wx.Panel ):
img.Replace(0, 0, 0, sysTextColour[0], sysTextColour[1], sysTextColour[2])
self.bmpCollapsed = wx.BitmapFromImage(img)
# Assign the bitmaps to the header static bitmap control
self.headerBmp = wx.StaticBitmap(self.headerPanel )
self.headerBmp.SetBitmap( self.bmpExpanded)
# Create the header sizer and append the static bitmap and static text controls
# Create the header sizer and add static bitmap and static text controls to it
headerSizer = wx.BoxSizer( wx.HORIZONTAL )
self.headerPanel.SetSizer( headerSizer)
@@ -103,14 +91,13 @@ class TogglePanel ( wx.Panel ):
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.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.contentPanel = wx.Panel(self)
@@ -121,25 +108,15 @@ class TogglePanel ( wx.Panel ):
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.Bind(wx.EVT_PAINT, self.OnPaint)
# self.headerPanel.Bind(wx.EVT_PAINT, self.OnPaint)
# self.contentPanel.Bind(wx.EVT_PAINT, self.OnPaint)
def __del__( self ):
pass
# def OnPaint(self, event):
# self.contentPanel.Layout()
# self.headerPanel.Layout()
# event.Skip()
def AddToggleItem(self, hitem):
hitem.Bind( wx.EVT_LEFT_UP, self.toggleContent )
@@ -148,9 +125,11 @@ class TogglePanel ( wx.Panel ):
def GetHeaderPanel(self):
return self.headerPanel
def InsertItemInHeader(self, item):
self.hcntSizer.Add(item,0,0,0)
self.Layout()
def AddSizer(self, sizer):
self.contentSizer.Add(sizer, 0, wx.EXPAND | wx.ALL, 0)
self.Layout()
@@ -161,22 +140,6 @@ class TogglePanel ( wx.Panel ):
def SetLabel(self, label):
self.headerLabel.SetLabel(label)
def GetNativeTreeItemBitmap(self, mode):
bitmap = wx.EmptyBitmap(24, 24)
dc = wx.MemoryDC()
dc.SelectObject(bitmap)
dc.SetBackground(wx.TheBrushList.FindOrCreateBrush(self.parent.GetBackgroundColour(), wx.SOLID))
dc.Clear()
wx.RendererNative.Get().DrawTreeItemButton(self, dc, wx.Rect(0, 0, 24, 24), wx.CONTROL_EXPANDED if mode == "expanded" else 0)
dc.Destroy()
return bitmap
# Virtual event handlers, overide them in your derived class
def IsCollapsed(self):
""" Returns ``True`` if the pane window is currently hidden. """
if self._toggle == 1:
@@ -229,22 +192,17 @@ class TogglePanel ( wx.Panel ):
self.parent.Fit()
# Toggle the content panel (hide/show)
def toggleContent( self, event ):
self.Freeze()
if self._toggle == 1:
# self.contentPanel.Hide()
self.contentMinSize = self.contentPanel.GetSize()
self.contentPanel.SetMinSize(wx.Size(self.contentMinSize[0],0))
self.headerBmp.SetBitmap( self.bmpCollapsed)
else:
# self.contentPanel.Show()
self.contentPanel.SetMinSize(self.contentMinSize)
self.headerBmp.SetBitmap( self.bmpExpanded)
@@ -257,23 +215,3 @@ class TogglePanel ( wx.Panel ):
self.OnStateChange(self.GetBestSize())
else:
self.parent.Layout()
# self.parent.Layout()
# Highlight stuff, not used for now
def enterWindow( self, event ):
self.headerPanel.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_HIGHLIGHT ) )
self.headerPanel.Refresh()
event.Skip()
def leaveWindow( self, event ):
self.headerPanel.SetBackgroundColour( self.bkColour )
self.headerPanel.Refresh()
event.Skip()

View File

@@ -2,7 +2,7 @@ import wx
import copy
from gui import bitmapLoader
import gui.mainFrame
import gui.builtinViews.fittingView
import gui.globalEvents as GE
import time
from gui.PFListPane import PFListPane
import service
@@ -76,7 +76,7 @@ class ShipBrowser(wx.Panel):
self.Bind(EVT_SB_STAGE3_SEL, self.stage3)
self.Bind(EVT_SB_SEARCH_SEL, self.searchStage)
self.mainFrame.Bind(gui.builtinViews.fittingView.FIT_CHANGED, self.RefreshList)
self.mainFrame.Bind(GE.FIT_CHANGED, self.RefreshList)
self.stage1(None)
@@ -1483,6 +1483,7 @@ class FitItem(wx.Window):
def selectFit(self, event=None):
wx.PostEvent(self.mainFrame, FitSelected(fitID=self.fitID))
self.Parent.RefreshList(True)
def NHitTest(self, target, position, area):
x, y = target

View File

@@ -23,8 +23,9 @@ import service
from gui.pyfatogglepanel import TogglePanel
import gui.builtinStatsViews
from gui.contextMenu import ContextMenu
import gui.builtinViews.fittingView as fv
#import gui.builtinViews.fittingView as fv
import gui.mainFrame
import gui.globalEvents as GE
class StatsPane(wx.Panel):
DEFAULT_VIEWS = ["resourcesViewFull", "resistancesViewFull" ,"rechargeViewFull", "firepowerViewFull",
@@ -84,7 +85,7 @@ class StatsPane(wx.Panel):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.mainFrame.Bind(fv.FIT_CHANGED, self.fitChanged)
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
def contextHandler(self, contentPanel):
viewName = contentPanel.viewName

View File

@@ -69,14 +69,17 @@ class DamagePattern():
current = self.getDamagePatternList()
for pattern in current:
lookup[pattern.name] = pattern
imports = eos.types.DamagePattern.importPatterns(text)
for pattern in imports:
if pattern.name in lookup:
match = lookup[pattern.name]
match.__dict__.update(pattern.__dict__)
else:
eos.db.save(pattern)
eos.db.commit()
try:
imports = eos.types.DamagePattern.importPatterns(text)
for pattern in imports:
if pattern.name in lookup:
match = lookup[pattern.name]
match.__dict__.update(pattern.__dict__)
else:
eos.db.save(pattern)
eos.db.commit()
except:
pass
def exportPatterns(self):
patterns = self.getDamagePatternList()

252
util.py
View File

@@ -1,5 +1,6 @@
import math
import wx
import fpformat
def formatAmount(val, prec=3, lowest=0, highest=0):
"""
@@ -91,3 +92,254 @@ def fromClipboard():
else:
clip.Close()
return None
def GetPartialText(dc, text , maxWidth):
ellipsis = "..."
base_w, h = dc.GetTextExtent(ellipsis)
lenText = len(text)
drawntext = text
w, dummy = dc.GetTextExtent(text)
while lenText > 1:
if w + base_w <= maxWidth:
break
w_c, h_c = dc.GetTextExtent(drawntext[-1])
drawntext = drawntext[0:-1]
lenText -= 1
w -= w_c
while len(ellipsis) > 0 and w + base_w > maxWidth:
ellipsis = ellipsis[0:-1]
base_w, h = dc.GetTextExtent(ellipsis)
if len(text) > lenText:
return drawntext + ellipsis
else:
return text
def set_float(val,default=None):
""" utility to set a floating value, useful for converting from strings """
if val in (None,''): return default
try:
return float(val)
except:
return default
class closure:
"""A very simple callback class to emulate a closure (reference to
a function with arguments) in python.
This class holds a user-defined function to be executed when the
class is invoked as a function. This is useful in many situations,
especially for 'callbacks' where lambda's are quite enough.
Many Tkinter 'actions' can use such callbacks.
>>>def my_action(x=None):
... print 'my action: x = ', x
>>>c = closure(my_action,x=1)
..... sometime later ...
>>>c()
my action: x = 1
>>>c(x=2)
my action: x = 2
based on Command class from J. Grayson's Tkinter book.
"""
def __init__(self,func=None,*args, **kw):
self.func = func
self.kw = kw
self.args = args
def __call__(self, *args, **kw):
self.kw.update(kw)
if (self.func == None): return None
self.args = args
return apply(self.func,self.args,self.kw)
class FloatCtrl(wx.TextCtrl):
""" Numerical Float Control::
a wx.TextCtrl that allows only numerical input, can take a precision argument
and optional upper / lower bounds
"""
def __init__(self, parent, value='', min='', max='',
action=None, precision=3, action_kw={}, **kwargs):
self.__digits = '0123456789.-'
self.__prec = precision
if precision is None: self.__prec = 0
self.format = '%%.%if' % self.__prec
self.__val = set_float(value)
self.__max = set_float(max)
self.__min = set_float(min)
self.fgcol_valid = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOWTEXT)
self.bgcol_valid = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)
self.fgcol_invalid ="Red"
self.bgcol_invalid =(254,254,80)
# set up action
self.__action = closure()
if callable(action): self.__action.func = action
if len(action_kw.keys())>0: self.__action.kw = action_kw
this_sty = wx.TE_PROCESS_ENTER
kw = kwargs
if kw.has_key('style'): this_sty = this_sty | kw['style']
kw['style'] = this_sty
wx.TextCtrl.__init__(self, parent, wx.ID_ANY, **kw)
self.__CheckValid(self.__val)
self.SetValue(self.__val)
self.Bind(wx.EVT_CHAR, self.onChar)
# self.Bind(wx.EVT_CHAR, self.CharEvent)
self.Bind(wx.EVT_TEXT, self.onText)
self.Bind(wx.EVT_SET_FOCUS, self.onSetFocus)
self.Bind(wx.EVT_KILL_FOCUS, self.onKillFocus)
self.Bind(wx.EVT_SIZE, self.onResize)
self.__GetMark()
def SetAction(self,action,action_kw={}):
self.__action = closure()
if callable(action): self.__action.func = action
if len(action_kw.keys())>0: self.__action.kw = action_kw
def SetPrecision(self,p):
if p is None: p = 0
self.__prec = p
self.format = '%%.%if' % p
def __GetMark(self):
" keep track of cursor position within text"
try:
self.__mark = min(wx.TextCtrl.GetSelection(self)[0],
len(wx.TextCtrl.GetValue(self).strip()))
except:
self.__mark = 0
def __SetMark(self,m=None):
" "
if m==None: m = self.__mark
self.SetSelection(m,m)
def SetValue(self,value=None,act=True):
" main method to set value "
# print 'Set Value '
if value == None: value = wx.TextCtrl.GetValue(self).strip()
self.__CheckValid(value)
self.__GetMark()
if self.__valid:
self.__Text_SetValue(self.__val)
self.SetForegroundColour(self.fgcol_valid)
self.SetBackgroundColour(self.bgcol_valid)
if callable(self.__action) and act: self.__action(value=self.__val)
else:
self.__val = self.__bound_val
self.__Text_SetValue(self.__val)
self.__CheckValid(self.__val)
self.SetForegroundColour(self.fgcol_invalid)
self.SetBackgroundColour(self.bgcol_invalid)
self.__SetMark()
def onKillFocus(self, event):
self.__GetMark()
event.Skip()
def onResize(self, event):
event.Skip()
def onSetFocus(self, event=None):
self.__SetMark()
if event: event.Skip()
def onChar(self, event):
""" on Character event"""
key = event.GetKeyCode()
entry = wx.TextCtrl.GetValue(self).strip()
pos = wx.TextCtrl.GetSelection(self)
# really, the order here is important:
# 1. return sends to ValidateEntry
if (key == wx.WXK_RETURN):
self.SetValue(entry)
return
# 2. other non-text characters are passed without change
if (key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255):
event.Skip()
return
# 3. check for multiple '.' and out of place '-' signs and ignore these
# note that chr(key) will now work due to return at #2
has_minus = '-' in entry
ckey = chr(key)
if ((ckey == '.' and (self.__prec == 0 or '.' in entry) ) or
(ckey == '-' and (has_minus or pos[0] != 0)) or
(ckey != '-' and has_minus and pos[0] == 0)):
return
# 4. allow digits, but not other characters
if (chr(key) in self.__digits):
event.Skip()
return
# return without event.Skip() : do not propagate event
return
def onText(self, event=None):
try:
if event.GetString() != '':
self.__CheckValid(event.GetString())
except:
pass
event.Skip()
def GetValue(self):
if self.__prec > 0:
return set_float(fpformat.fix(self.__val, self.__prec))
else:
return int(self.__val)
def GetMin(self): return self.__min
def GetMax(self): return self.__max
def SetMin(self,min): self.__min = set_float(min)
def SetMax(self,max): self.__max = set_float(max)
def __Text_SetValue(self,value):
wx.TextCtrl.SetValue(self, self.format % set_float(value))
self.Refresh()
def __CheckValid(self,value):
# print ' Check valid ', value
v = self.__val
try:
self.__valid = True
v = set_float(value)
if self.__min != None and (v < self.__min):
self.__valid = False
v = self.__min
if self.__max != None and (v > self.__max):
self.__valid = False
v = self.__max
except:
self.__valid = False
self.__bound_val = v
if self.__valid:
self.__bound_val = self.__val = v
self.SetForegroundColour(self.fgcol_valid)
self.SetBackgroundColour(self.bgcol_valid)
else:
self.SetForegroundColour(self.fgcol_invalid)
self.SetBackgroundColour(self.bgcol_invalid)
self.Refresh()