Experimental shipBrowser changes
This commit is contained in:
@@ -1,430 +1,417 @@
|
||||
import wx
|
||||
import copy
|
||||
from gui import bitmapLoader
|
||||
import service
|
||||
import bitmapLoader
|
||||
import gui.mainFrame
|
||||
import wx.lib.newevent
|
||||
|
||||
FitCreated, EVT_FIT_CREATED = wx.lib.newevent.NewEvent()
|
||||
FitRenamed, EVT_FIT_RENAMED = wx.lib.newevent.NewEvent()
|
||||
FitRemoved, EVT_FIT_REMOVED = wx.lib.newevent.NewEvent()
|
||||
FitSelected, EVT_FIT_SELECTED = wx.lib.newevent.NewEvent()
|
||||
FitRemoved, EVT_FIT_REMOVED = wx.lib.newevent.NewEvent()
|
||||
|
||||
class ShipBrowser(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
wx.Panel.__init__(self, parent)
|
||||
wx.Panel.__init__ (self, parent)
|
||||
|
||||
self.built = False
|
||||
self.viewSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.SetSizer(self.viewSizer)
|
||||
self._lastWidth = 0
|
||||
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
|
||||
|
||||
self.shipMenu = ShipMenu(self)
|
||||
self.viewSizer.Add(self.shipMenu, 0, wx.EXPAND)
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
hpane = HeaderPane(self)
|
||||
mainSizer.Add(hpane, 0, wx.EXPAND)
|
||||
|
||||
self.searchView = ShipView(self)
|
||||
#self.viewSizer.Add(self.searchView, 1, wx.EXPAND)
|
||||
self.searchView.Hide()
|
||||
self.lpane = ListPane(self)
|
||||
mainSizer.Add(self.lpane, 1, wx.EXPAND)
|
||||
self.SetSizer(mainSizer)
|
||||
self.Layout()
|
||||
self.Show()
|
||||
|
||||
self.shipView = ShipView(self)
|
||||
self.viewSizer.Add(self.shipView, 1, wx.EXPAND)
|
||||
|
||||
self.shipImageList = wx.ImageList(16, 16)
|
||||
self.shipView.SetImageList(self.shipImageList)
|
||||
self.searchView.SetImageList(self.shipImageList)
|
||||
|
||||
self.shipRoot = self.shipView.AddRoot("Ships")
|
||||
self.searchRoot = self.searchView.AddRoot("Ships")
|
||||
|
||||
self.raceImageIds = {}
|
||||
self.races = ["amarr", "caldari", "gallente", "minmatar", "ore", "serpentis", "angel", "blood", "sansha", "guristas"]
|
||||
for race in self.races:
|
||||
imageId = self.shipImageList.Add(bitmapLoader.getBitmap("race_%s_small" % race, "icons"))
|
||||
self.raceImageIds[race] = imageId
|
||||
self.fitIconId = self.shipImageList.Add(bitmapLoader.getBitmap("fit_small", "icons"))
|
||||
self.races.append("None")
|
||||
self.idRaceMap = {}
|
||||
|
||||
self.shipView.races = self.races
|
||||
self.shipView.idRaceMap = self.idRaceMap
|
||||
|
||||
self.searchView.races = self.races
|
||||
self.searchView.idRaceMap = self.idRaceMap
|
||||
|
||||
self.build()
|
||||
|
||||
#Bind our lookup methods for our trees
|
||||
for tree in (self.shipView, self.searchView):
|
||||
tree.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.expandLookup)
|
||||
tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.toggleButtons)
|
||||
tree.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.changeFitName)
|
||||
tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.triggerFitSelect)
|
||||
|
||||
#Bind buttons
|
||||
self.shipMenu.new.Bind(wx.EVT_BUTTON, self.newFit)
|
||||
self.shipMenu.rename.Bind(wx.EVT_BUTTON, self.renameFit)
|
||||
self.shipMenu.delete.Bind(wx.EVT_BUTTON, self.deleteFit)
|
||||
self.shipMenu.copy.Bind(wx.EVT_BUTTON, self.copyFit)
|
||||
|
||||
#Bind search
|
||||
self.shipMenu.search.Bind(wx.EVT_TEXT_ENTER, self.scheduleSearch)
|
||||
self.shipMenu.search.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN, self.scheduleSearch)
|
||||
self.shipMenu.search.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN, self.clearSearch)
|
||||
self.shipMenu.search.Bind(wx.EVT_TEXT, self.scheduleSearch)
|
||||
self.Bind(wx.EVT_TIMER, self.startSearch)
|
||||
|
||||
self.searchTimer = wx.Timer(self)
|
||||
|
||||
self.timer = None
|
||||
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def build(self):
|
||||
if not self.built:
|
||||
self.built = True
|
||||
cMarket = service.Market.getInstance()
|
||||
shipRoot = cMarket.getShipRoot()
|
||||
iconId = self.shipImageList.Add(bitmapLoader.getBitmap("ship_small", "icons"))
|
||||
for id, name in shipRoot:
|
||||
childId = self.shipView.AppendItem(self.shipRoot, name, iconId, data=wx.TreeItemData(("group", id)))
|
||||
self.shipView.AppendItem(childId, "dummy")
|
||||
|
||||
self.shipView.SortChildren(self.shipRoot)
|
||||
|
||||
def getActiveTree(self):
|
||||
if self.searchView:
|
||||
if self.searchView.IsShown():
|
||||
return self.searchView
|
||||
else:
|
||||
return self.shipView
|
||||
|
||||
def triggerFitSelect(self, event):
|
||||
selection = event.Item
|
||||
if selection.IsOk():
|
||||
tree = self.getActiveTree()
|
||||
data = tree.GetPyData(selection)
|
||||
if data is not None:
|
||||
type, fitID = data
|
||||
if type == "fit":
|
||||
if self.mainFrame.getActiveFit() != fitID:
|
||||
wx.PostEvent(self.mainFrame, FitSelected(fitID=fitID))
|
||||
self.lpane.Refresh()
|
||||
self.Centre(wx.BOTH)
|
||||
self.Bind(wx.EVT_SIZE, self.SizeRefreshList)
|
||||
self.stage1()
|
||||
|
||||
def SizeRefreshList(self, event):
|
||||
ewidth, eheight = event.GetSize()
|
||||
## if ewidth != self._lastWidth:
|
||||
## self._lastWidth = ewidth
|
||||
self.lpane.Refresh()
|
||||
event.Skip()
|
||||
|
||||
def toggleButtons(self, event):
|
||||
tree = self.getActiveTree()
|
||||
if tree is None:
|
||||
return
|
||||
root = tree.GetSelection()
|
||||
btns = (self.shipMenu.new, self.shipMenu.rename, self.shipMenu.delete, self.shipMenu.copy)
|
||||
if not root.IsOk():
|
||||
for btn in btns:
|
||||
btn.Enable(False)
|
||||
else:
|
||||
data = tree.GetPyData(root)
|
||||
if data is None:
|
||||
return
|
||||
|
||||
type, fitID = data
|
||||
if type == "fit":
|
||||
for btn in btns:
|
||||
btn.Enable()
|
||||
|
||||
elif type == "ship":
|
||||
for btn in btns:
|
||||
btn.Enable(btn == self.shipMenu.new)
|
||||
|
||||
else:
|
||||
for btn in btns:
|
||||
btn.Enable(False)
|
||||
|
||||
event.Skip()
|
||||
|
||||
def expandLookup(self, event):
|
||||
tree = self.getActiveTree()
|
||||
root = event.Item
|
||||
child, cookie = tree.GetFirstChild(root)
|
||||
self.idRaceMap.clear()
|
||||
if tree.GetItemText(child) == "dummy":
|
||||
tree.Delete(child)
|
||||
|
||||
cMarket = service.Market.getInstance()
|
||||
cFit = service.Fit.getInstance()
|
||||
|
||||
type, groupID = tree.GetPyData(root)
|
||||
if type == "group":
|
||||
for id, name, race in cMarket.getShipList(groupID):
|
||||
iconId = self.raceImageIds[race] if race in self.raceImageIds else -1
|
||||
self.idRaceMap[id] = race
|
||||
childId = tree.AppendItem(root, name, iconId, data=wx.TreeItemData(("ship", id)))
|
||||
for fitID, fitName in cFit.getFitsWithShip(id):
|
||||
tree.AppendItem(childId, fitName, self.fitIconId, data=wx.TreeItemData(("fit", fitID)))
|
||||
|
||||
tree.SortChildren(root)
|
||||
|
||||
event.Skip()
|
||||
|
||||
def newFit(self, event):
|
||||
tree = self.getActiveTree()
|
||||
root = tree.GetSelection()
|
||||
if not root.IsOk():
|
||||
return
|
||||
|
||||
type, shipID = tree.GetPyData(root)
|
||||
cFit = service.Fit.getInstance()
|
||||
noChildren = False
|
||||
if type == "fit":
|
||||
fit = cFit.getFit(shipID)
|
||||
type, shipID = "ship", fit.ship.item.ID
|
||||
name = "%s fit" % fit.ship.item.name
|
||||
if tree == self.searchView:
|
||||
root = self.searchRoot
|
||||
noChildren = True
|
||||
else:
|
||||
name = "%s fit" % tree.GetItemText(root)
|
||||
|
||||
fitID = cFit.newFit(shipID, name)
|
||||
childId = tree.AppendItem(root, name, self.fitIconId, data=wx.TreeItemData(("fit", fitID)))
|
||||
tree.SetItemText(childId, name)
|
||||
if not noChildren:
|
||||
tree.SortChildren(root)
|
||||
tree.Expand(root)
|
||||
|
||||
tree.SelectItem(childId)
|
||||
tree.EditLabel(childId)
|
||||
|
||||
wx.PostEvent(self.mainFrame, FitCreated(fitID=fitID))
|
||||
|
||||
def renameFit(self, event):
|
||||
tree = self.getActiveTree()
|
||||
root = tree.GetSelection()
|
||||
type, _ = tree.GetPyData(root)
|
||||
if type == "fit":
|
||||
tree.EditLabel(root)
|
||||
|
||||
event.Skip()
|
||||
|
||||
def changeFitName(self, event):
|
||||
self.triggerFitSelect(event)
|
||||
if event.IsEditCancelled():
|
||||
return
|
||||
|
||||
tree = self.getActiveTree()
|
||||
item = event.Item
|
||||
newName = event.Label
|
||||
type, fitID = tree.GetPyData(item)
|
||||
cFit = service.Fit.getInstance()
|
||||
cFit.renameFit(fitID, newName)
|
||||
|
||||
if tree == self.searchView:
|
||||
def checkRename(item):
|
||||
type, id = tree.GetPyData(item)
|
||||
if type == "fit" and id == fitID:
|
||||
if tree.GetItemParent(item) == self.searchRoot:
|
||||
tree.SetItemText(item, "%s (%s)" % (newName, cFit.getFit(fitID).ship.item.name))
|
||||
else:
|
||||
tree.SetItemText(item, newName)
|
||||
|
||||
self.checkSearchView(checkRename)
|
||||
|
||||
wx.CallAfter(tree.SortChildren, tree.GetItemParent(item))
|
||||
|
||||
wx.PostEvent(self.mainFrame, FitRenamed(fitID=fitID))
|
||||
|
||||
def deleteFit(self, event):
|
||||
tree = self.getActiveTree()
|
||||
root = tree.GetSelection()
|
||||
type, fitID = tree.GetPyData(root)
|
||||
if type == "fit":
|
||||
cFit = service.Fit.getInstance()
|
||||
cFit.deleteFit(fitID)
|
||||
tree.Delete(root)
|
||||
|
||||
if tree == self.searchView:
|
||||
def checkRemoval(item):
|
||||
type, id = tree.GetPyData(item)
|
||||
if type == "fit" and id == fitID:
|
||||
tree.Delete(item)
|
||||
|
||||
self.checkSearchView(checkRemoval)
|
||||
wx.PostEvent(self.mainFrame, FitRemoved(fitID=fitID))
|
||||
|
||||
def checkSearchView(self, callback):
|
||||
tree = self.searchView
|
||||
item, cookie = tree.GetFirstChild(self.searchRoot)
|
||||
while item.IsOk():
|
||||
type, id = tree.GetPyData(item)
|
||||
if type == "ship":
|
||||
child, childCookie = tree.GetFirstChild(item)
|
||||
while child.IsOk():
|
||||
callback(child)
|
||||
child, childCookie = tree.GetNextChild(child, childCookie)
|
||||
|
||||
callback(item)
|
||||
item, cookie = tree.GetNextChild(item, cookie)
|
||||
|
||||
def copyFit(self, event):
|
||||
tree = self.getActiveTree()
|
||||
root = tree.GetSelection()
|
||||
type, fitID = tree.GetPyData(root)
|
||||
if type == "fit":
|
||||
cFit = service.Fit.getInstance()
|
||||
newID = cFit.copyFit(fitID)
|
||||
parent = tree.GetItemParent(root)
|
||||
newFit= cFit.getFit(newID)
|
||||
name = newFit.name
|
||||
iconID = tree.GetItemImage(root)
|
||||
childId = tree.AppendItem(parent, name, iconID, data=wx.TreeItemData(("fit", newID)))
|
||||
tree.SetItemText(childId, name)
|
||||
tree.SelectItem(childId)
|
||||
tree.EditLabel(childId)
|
||||
|
||||
wx.PostEvent(self.mainFrame, FitCreated(fitID=newID))
|
||||
|
||||
def scheduleSearch(self, event):
|
||||
self.searchTimer.Stop()
|
||||
self.searchTimer.Start(50, wx.TIMER_ONE_SHOT)
|
||||
event.Skip()
|
||||
|
||||
def clearSearch(self, event, clearText=True):
|
||||
if self.getActiveTree() == self.searchView:
|
||||
if clearText:
|
||||
self.shipMenu.search.Clear()
|
||||
|
||||
self.viewSizer.Replace(self.searchView, self.shipView)
|
||||
|
||||
self.shipView.Show()
|
||||
self.searchView.Hide()
|
||||
|
||||
self.viewSizer.Layout()
|
||||
|
||||
event.Skip()
|
||||
|
||||
def startSearch(self, event):
|
||||
|
||||
search = self.shipMenu.search.GetLineText(0)
|
||||
if len(search) < 3:
|
||||
self.clearSearch(event, False)
|
||||
return
|
||||
|
||||
self.viewSizer.Replace(self.shipView, self.searchView)
|
||||
|
||||
self.shipView.Hide()
|
||||
self.searchView.Show()
|
||||
|
||||
self.viewSizer.Layout()
|
||||
|
||||
#GTFO OLD STOOF
|
||||
self.searchView.DeleteAllItems()
|
||||
self.searchRoot = self.searchView.AddRoot("Search")
|
||||
|
||||
#Get NEW STOOF
|
||||
cMarket = service.Market.getInstance()
|
||||
cFit = service.Fit.getInstance()
|
||||
|
||||
for id, name, race in cMarket.searchShips(search):
|
||||
iconId = self.raceImageIds[race] if race in self.raceImageIds else -1
|
||||
self.idRaceMap[id] = race
|
||||
childId = self.searchView.AppendItem(self.searchRoot, name, iconId, data=wx.TreeItemData(("ship", id)))
|
||||
for fitID, fitName in cFit.getFitsWithShip(id):
|
||||
self.searchView.AppendItem(childId, fitName, self.fitIconId, data=wx.TreeItemData(("fit", fitID)))
|
||||
|
||||
foundFits = cMarket.searchFits(search)
|
||||
if foundFits:
|
||||
for id, name, shipName in foundFits:
|
||||
rowText = "{0} ({1})".format(name, shipName)
|
||||
self.searchView.AppendItem(self.searchRoot, rowText, self.fitIconId, data=wx.TreeItemData(("fit", id)))
|
||||
|
||||
self.searchView.SortChildren(self.searchRoot)
|
||||
|
||||
#To make sure that the shipView stays in sync, we'll clear its fits data
|
||||
root = self.shipRoot
|
||||
child, cookie = self.shipView.GetFirstChild(root)
|
||||
while child.IsOk():
|
||||
self.shipView.DeleteChildren(child)
|
||||
self.shipView.AppendItem(child, "dummy")
|
||||
self.shipView.Collapse(child)
|
||||
child, cookie = self.shipView.GetNextChild(root, cookie)
|
||||
|
||||
if event is not None:
|
||||
event.Skip()
|
||||
|
||||
def getSelectedFitID(self):
|
||||
tree = self.getActiveTree()
|
||||
selection = tree.GetSelection()
|
||||
if selection.IsOk():
|
||||
data = tree.GetPyData(selection)
|
||||
if data is not None:
|
||||
type, fitID = data
|
||||
if type == "fit":
|
||||
return fitID
|
||||
|
||||
|
||||
class ShipView(wx.TreeCtrl):
|
||||
def __init__(self, parent):
|
||||
wx.TreeCtrl.__init__(self, parent, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT | wx.TR_EDIT_LABELS)
|
||||
self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.vetoEdit)
|
||||
self.rename = False
|
||||
|
||||
def OnCompareItems(self, treeId1, treeId2):
|
||||
child, cookie = self.GetFirstChild(treeId1)
|
||||
type1, id1 = self.GetPyData(treeId1)
|
||||
type2, id2 = self.GetPyData(treeId2)
|
||||
if type1 != type2:
|
||||
order = ["group", "ship", "fit"]
|
||||
return cmp(order.index(type1), order.index(type2))
|
||||
|
||||
if type1 in ("fit", "group"):
|
||||
return cmp(self.GetItemText(treeId1), self.GetItemText(treeId2))
|
||||
else:
|
||||
c = cmp(self.races.index(self.idRaceMap.get(id1) or "None"), self.races.index(self.idRaceMap.get(id2) or "None"))
|
||||
if c != 0:
|
||||
return c
|
||||
else:
|
||||
return cmp(self.GetItemText(treeId1), self.GetItemText(treeId2))
|
||||
|
||||
def OnEraseBackGround(self, event):
|
||||
#Prevent flicker by not letting the parent's method get called.
|
||||
def __del__(self):
|
||||
pass
|
||||
|
||||
def EditLabel(self, childId):
|
||||
self.rename = True
|
||||
wx.TreeCtrl.EditLabel(self, childId)
|
||||
def stage1(self):
|
||||
sMarket = service.Market.getInstance()
|
||||
self.lpane.RemoveAllChildren()
|
||||
for ID, name in sMarket.getShipRoot():
|
||||
self.lpane.AddWidget(CategoryItem(self.lpane, ID, (name, 0)))
|
||||
|
||||
def vetoEdit(self, event):
|
||||
if not self.rename:
|
||||
event.Veto()
|
||||
self.Layout()
|
||||
self.Show()
|
||||
|
||||
self.rename = False
|
||||
def stage2(self, categoryID):
|
||||
sMarket = service.Market.getInstance()
|
||||
self.lpane.RemoveAllChildren()
|
||||
for ID, name, race in sMarket.getShipList(categoryID):
|
||||
self.lpane.AddWidget(ShipItem(self.lpane, ID, (name, 0), race))
|
||||
|
||||
class ShipMenu(wx.Panel):
|
||||
self.Layout()
|
||||
self.Show()
|
||||
|
||||
class HeaderPane (wx.Panel):
|
||||
def __init__(self, parent):
|
||||
wx.Panel.__init__(self, parent)
|
||||
self.parent = parent
|
||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.SetSizer(sizer)
|
||||
wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(500, 32), style=wx.TAB_TRAVERSAL)
|
||||
|
||||
size = None
|
||||
for name, art in (("new", wx.ART_NEW), ("rename", bitmapLoader.getBitmap("rename", "icons")), ("copy", wx.ART_COPY), ("delete", wx.ART_DELETE)):
|
||||
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()
|
||||
bSizer3 = wx.BoxSizer(wx.VERTICAL)
|
||||
self.stHeader = wx.StaticText(self, wx.ID_ANY, u"Header --->", wx.DefaultPosition, wx.DefaultSize, 0)
|
||||
self.stHeader.Wrap(-1)
|
||||
bSizer3.Add(self.stHeader, 0, wx.ALL | wx.EXPAND, 5)
|
||||
|
||||
btn.SetMinSize(size)
|
||||
btn.SetMaxSize(size)
|
||||
class ListPane (wx.ScrolledWindow):
|
||||
def __init__(self, parent):
|
||||
wx.ScrolledWindow.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(500, 300), style=wx.TAB_TRAVERSAL)
|
||||
self._wList = []
|
||||
self._wCount = 0
|
||||
self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
|
||||
|
||||
btn.Layout()
|
||||
setattr(self, name, btn)
|
||||
btn.Enable(False)
|
||||
btn.SetToolTipString("%s fit" % name.capitalize())
|
||||
sizer.Add(btn, 0, wx.EXPAND)
|
||||
|
||||
p = wx.Panel(self)
|
||||
psizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
p.SetSizer(psizer)
|
||||
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.search = wx.SearchCtrl(p, wx.ID_ANY, style=wx.TE_PROCESS_ENTER)
|
||||
self.search.ShowCancelButton(True)
|
||||
psizer.Add(self.search, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
|
||||
# p.SetMinSize((wx.SIZE_AUTO_WIDTH, 27))
|
||||
sizer.Add(p, 1, wx.EXPAND)
|
||||
def MScrollUp(self, event):
|
||||
|
||||
posy = self.GetScrollPos(wx.VERTICAL)
|
||||
posy -= 2
|
||||
self.Scroll(0, posy)
|
||||
self.Refresh()
|
||||
event.Skip()
|
||||
|
||||
def MScrollDown(self, event):
|
||||
|
||||
posy = self.GetScrollPos(wx.VERTICAL)
|
||||
posy += 2
|
||||
self.Scroll(0, posy)
|
||||
self.Refresh()
|
||||
event.Skip()
|
||||
|
||||
|
||||
def AddWidget(self, widget):
|
||||
widget.Reparent(self)
|
||||
self._wList.append(widget)
|
||||
self._wCount += 1
|
||||
|
||||
def Refresh(self):
|
||||
ypos = 0
|
||||
cwidth, cheight = self.GetClientSize()
|
||||
for i in xrange(self._wCount):
|
||||
xa, ya = self.CalcScrolledPosition((0, ypos))
|
||||
iwidth, iheight = self._wList[i].GetSize()
|
||||
self._wList[i].SetPosition((xa, ya))
|
||||
self._wList[i].SetSize((cwidth, iheight))
|
||||
|
||||
ypos += iheight
|
||||
|
||||
self._wList[i].Show()
|
||||
self._wList[i].Refresh()
|
||||
self.SetVirtualSize((1, ypos))
|
||||
|
||||
def RemoveAllChildren(self):
|
||||
for widget in self._wList:
|
||||
self.RemoveChild(widget)
|
||||
widget.Hide()
|
||||
widget.Destroy()
|
||||
|
||||
class CategoryItem(wx.Window):
|
||||
def __init__(self, parent, categoryID, shipFittingInfo,
|
||||
id=wx.ID_ANY, range=100, pos=wx.DefaultPosition,
|
||||
size=(-1,16), style=0):
|
||||
wx.Window.__init__(self, parent, id, pos, size, style)
|
||||
|
||||
if categoryID:
|
||||
self.shipBmp = bitmapLoader.getBitmap("ship_small","icons")
|
||||
else:
|
||||
self.shipBmp = wx.EmptyBitmap(16,16)
|
||||
|
||||
self.categoryID = categoryID
|
||||
self.shipFittingInfo = shipFittingInfo
|
||||
self.shipName, dummy = shipFittingInfo
|
||||
self.width,self.height = size
|
||||
|
||||
self.highlighted = 0
|
||||
self.editWasShown = 0
|
||||
|
||||
|
||||
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
||||
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
|
||||
self.Bind(wx.EVT_LEFT_UP, self.checkPosition)
|
||||
self.Bind(wx.EVT_ENTER_WINDOW, self.enterW)
|
||||
self.Bind(wx.EVT_LEAVE_WINDOW, self.leaveW)
|
||||
|
||||
self.shipBrowser = self.Parent.Parent
|
||||
|
||||
def checkPosition(self, event):
|
||||
|
||||
pos = event.GetPosition()
|
||||
x,y = pos
|
||||
self.shipBrowser.stage2(self.categoryID)
|
||||
event.Skip()
|
||||
|
||||
def enterW(self,event):
|
||||
self.highlighted = 1
|
||||
self.Refresh()
|
||||
event.Skip()
|
||||
|
||||
def leaveW(self,event):
|
||||
self.highlighted = 0
|
||||
self.Refresh()
|
||||
event.Skip()
|
||||
|
||||
|
||||
def OnEraseBackground(self, event):
|
||||
pass
|
||||
|
||||
def OnPaint(self,event):
|
||||
rect = self.GetRect()
|
||||
|
||||
canvas = wx.EmptyBitmap(rect.width, rect.height)
|
||||
mdc = wx.BufferedPaintDC(self)
|
||||
mdc.SelectObject(canvas)
|
||||
r = copy.copy(rect)
|
||||
r.top = 0
|
||||
r.left = 0
|
||||
r.height = r.height / 2
|
||||
if self.highlighted:
|
||||
mdc.SetBackground(wx.Brush(wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT)))
|
||||
mdc.Clear()
|
||||
mdc.SetTextForeground(wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
|
||||
else:
|
||||
mdc.SetBackground(wx.Brush(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)))
|
||||
mdc.SetTextForeground(wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOWTEXT ))
|
||||
mdc.Clear()
|
||||
|
||||
mdc.DrawBitmap(self.shipBmp,5+(rect.height-self.shipBmp.GetHeight())/2,(rect.height-self.shipBmp.GetWidth())/2,0)
|
||||
mdc.SetFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD, False))
|
||||
|
||||
|
||||
|
||||
shipName, fittings = self.shipFittingInfo
|
||||
|
||||
|
||||
|
||||
xpos = self.shipBmp.GetWidth() + 10
|
||||
|
||||
xtext, ytext = mdc.GetTextExtent(shipName)
|
||||
ypos = (rect.height - ytext) / 2
|
||||
mdc.DrawText(shipName, xpos, ypos)
|
||||
xpos+=xtext+5
|
||||
|
||||
mdc.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, False))
|
||||
|
||||
if fittings <1:
|
||||
fformat = "No fittings"
|
||||
else:
|
||||
if fittings == 1:
|
||||
fformat = "%d fitting"
|
||||
else:
|
||||
fformat = "%d fittings"
|
||||
|
||||
if fittings>0:
|
||||
xtext, ytext = mdc.GetTextExtent(fformat % fittings)
|
||||
ypos = (rect.height - ytext)/2
|
||||
else:
|
||||
xtext, ytext = mdc.GetTextExtent(fformat)
|
||||
ypos = (rect.height - ytext)/2
|
||||
|
||||
#seems that a scrolled window without scrollbars shown always HasScrollbar ><
|
||||
|
||||
if self.Parent.HasScrollbar(wx.VERTICAL):
|
||||
addX = 20
|
||||
else:
|
||||
addX = 20
|
||||
|
||||
fPosX = rect.width - addX - xtext
|
||||
fPosY = (rect.height -ytext)/2
|
||||
if fittings > 0:
|
||||
mdc.DrawText(fformat % fittings, fPosX, fPosY)
|
||||
else:
|
||||
mdc.DrawText(fformat, fPosX, fPosY)
|
||||
|
||||
event.Skip()
|
||||
|
||||
def Destroy(self):
|
||||
self.Unbind(wx.EVT_PAINT)
|
||||
self.Unbind(wx.EVT_ERASE_BACKGROUND)
|
||||
self.Unbind(wx.EVT_LEFT_UP)
|
||||
self.Unbind(wx.EVT_ENTER_WINDOW)
|
||||
self.Unbind(wx.EVT_LEAVE_WINDOW)
|
||||
self.Close()
|
||||
|
||||
|
||||
class ShipItem(wx.Window):
|
||||
def __init__(self, parent, shipID=None, shipFittingInfo=("Test", 2), itemData=None,
|
||||
id=wx.ID_ANY, range=100, pos=wx.DefaultPosition,
|
||||
size=(-1, 38), style=0):
|
||||
wx.Window.__init__(self, parent, id, pos, size, style)
|
||||
|
||||
self._itemData = itemData
|
||||
|
||||
self.shipBmp = wx.EmptyBitmap(32, 32)
|
||||
self.shipFittingInfo = shipFittingInfo
|
||||
self.shipName, dummy = shipFittingInfo
|
||||
self.newBmp = bitmapLoader.getBitmap("add_small", "icons")
|
||||
|
||||
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
||||
self.editPosX = 0
|
||||
self.editPosY = 0
|
||||
self.highlighted = 0
|
||||
self.editWasShown = 0
|
||||
|
||||
self.tcFitName = wx.TextCtrl(self, wx.ID_ANY, "%s fit" % self.shipName, wx.DefaultPosition, wx.DefaultSize, wx.TE_PROCESS_ENTER)
|
||||
self.tcFitName.Show(False)
|
||||
|
||||
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
|
||||
|
||||
self.Bind(wx.EVT_LEFT_UP, self.checkPosition)
|
||||
self.Bind(wx.EVT_MOTION, self.cursorCheck)
|
||||
|
||||
self.Bind(wx.EVT_ENTER_WINDOW, self.enterW)
|
||||
self.Bind(wx.EVT_LEAVE_WINDOW, self.leaveW)
|
||||
|
||||
self.tcFitName.Bind(wx.EVT_TEXT_ENTER, self.createNewFit)
|
||||
self.tcFitName.Bind(wx.EVT_KILL_FOCUS, self.editLostFocus)
|
||||
self.tcFitName.Bind(wx.EVT_KEY_DOWN, self.editCheckEsc)
|
||||
|
||||
def SetData(self, data):
|
||||
self._itemData = data
|
||||
|
||||
def GetData(self):
|
||||
return self._itemData
|
||||
|
||||
def editLostFocus(self, event):
|
||||
self.tcFitName.Show(False)
|
||||
if self.highlighted == 1:
|
||||
self.editWasShown = 1
|
||||
|
||||
def editCheckEsc(self, event):
|
||||
if event.GetKeyCode() == wx.WXK_ESCAPE:
|
||||
self.tcFitName.Show(False)
|
||||
self.editWasShown = 0
|
||||
else:
|
||||
event.Skip()
|
||||
|
||||
def cursorCheck(self, event):
|
||||
pos = event.GetPosition()
|
||||
if self.NHitTest((self.editPosX, self.editPosY), pos, (16, 16)):
|
||||
self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
|
||||
else:
|
||||
self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
|
||||
def checkPosition(self, event):
|
||||
|
||||
pos = event.GetPosition()
|
||||
x, y = pos
|
||||
if self.NHitTest((self.editPosX, self.editPosY), pos, (16, 16)):
|
||||
if self.editWasShown == 1:
|
||||
self.createNewFit()
|
||||
return
|
||||
else:
|
||||
self.Refresh()
|
||||
fnEditSize = self.tcFitName.GetSize()
|
||||
wSize = self.GetSize()
|
||||
fnEditPosX = self.editPosX - fnEditSize.width - 5
|
||||
fnEditPosY = (wSize.height - fnEditSize.height) / 2
|
||||
self.tcFitName.SetPosition((fnEditPosX, fnEditPosY))
|
||||
self.tcFitName.Show(True)
|
||||
self.tcFitName.SetFocus()
|
||||
self.tcFitName.SelectAll()
|
||||
return
|
||||
|
||||
if (not self.NHitTest((self.editPosX, self.editPosY), pos, (16, 16))):
|
||||
self.editWasShown = 0
|
||||
self.Refresh()
|
||||
|
||||
|
||||
event.Skip()
|
||||
|
||||
def createNewFit(self, event=None):
|
||||
print "New :", self.tcFitName.GetValue(), "GTFO from stage2 to stage 3 (refresh stage 3)"
|
||||
self.tcFitName.Show(False)
|
||||
self.editWasShown = 0
|
||||
|
||||
def NHitTest(self, 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):
|
||||
return True
|
||||
return False
|
||||
def enterW(self, event):
|
||||
self.highlighted = 1
|
||||
self.Refresh()
|
||||
event.Skip()
|
||||
|
||||
def leaveW(self, event):
|
||||
self.highlighted = 0
|
||||
self.Refresh()
|
||||
event.Skip()
|
||||
|
||||
def OnEraseBackground(self, event):
|
||||
pass
|
||||
|
||||
def OnPaint(self, event):
|
||||
rect = self.GetRect()
|
||||
|
||||
canvas = wx.EmptyBitmap(rect.width, rect.height)
|
||||
mdc = wx.BufferedPaintDC(self)
|
||||
mdc.SelectObject(canvas)
|
||||
r = copy.copy(rect)
|
||||
r.top = 0
|
||||
r.left = 0
|
||||
r.height = r.height / 2
|
||||
if self.highlighted:
|
||||
mdc.SetBackground(wx.Brush(wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT)))
|
||||
mdc.Clear()
|
||||
mdc.SetTextForeground(wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
|
||||
##
|
||||
## sr = 221
|
||||
## sg = 221
|
||||
## sb = 221
|
||||
##
|
||||
## startColor = (sr,sg,sb)
|
||||
##
|
||||
## mdc.GradientFillLinear(r,startColor,wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW),wx.SOUTH)
|
||||
## r.top = r.height
|
||||
## mdc.GradientFillLinear(r,startColor,wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW),wx.NORTH)
|
||||
## mdc.SetTextForeground(wx.BLACK)
|
||||
mdc.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False))
|
||||
else:
|
||||
mdc.SetBackground(wx.Brush(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)))
|
||||
mdc.SetTextForeground(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT))
|
||||
mdc.Clear()
|
||||
mdc.SetFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD, False))
|
||||
# mdc.DrawBitmap(self.effBmp,5+(rect.height-40)/2,(rect.height-40)/2,0)
|
||||
mdc.DrawBitmap(self.shipBmp, 5 + (rect.height - 32) / 2, (rect.height - 32) / 2, 0)
|
||||
|
||||
|
||||
|
||||
|
||||
shipName, fittings = self.shipFittingInfo
|
||||
|
||||
|
||||
ypos = (rect.height - 32) / 2
|
||||
textStart = 48
|
||||
xtext, ytext = mdc.GetTextExtent(shipName)
|
||||
mdc.DrawText(shipName, textStart, ypos)
|
||||
ypos += ytext
|
||||
|
||||
mdc.SetFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.NORMAL, False))
|
||||
|
||||
xtext, ytext = mdc.GetTextExtent("%d fitting(s)")
|
||||
mdc.DrawText("%d fitting(s)" % fittings, textStart, ypos)
|
||||
mdc.SetFont(wx.Font(7, wx.SWISS, wx.NORMAL, wx.NORMAL, False))
|
||||
|
||||
self.editPosX = rect.width - 20
|
||||
self.editPosY = (rect.height - 16) / 2
|
||||
mdc.DrawBitmap(self.newBmp, self.editPosX, self.editPosY, 0)
|
||||
event.Skip()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user