258 lines
9.2 KiB
Python
258 lines
9.2 KiB
Python
# noinspection PyPackageRequirements
|
|
import wx
|
|
# noinspection PyPackageRequirements
|
|
from wx.lib.buttons import GenBitmapButton
|
|
|
|
import gui.builtinMarketBrowser.pfSearchBox as SBox
|
|
import gui.display as d
|
|
from gui.bitmap_loader import BitmapLoader
|
|
from gui.marketBrowser import SearchBox
|
|
from service.market import Market
|
|
|
|
|
|
class BaseImplantEditorView(wx.Panel):
|
|
|
|
def addMarketViewImage(self, iconFile):
|
|
if iconFile is None:
|
|
return -1
|
|
bitmap = BitmapLoader.getBitmap(iconFile, "icons")
|
|
if bitmap is None:
|
|
return -1
|
|
else:
|
|
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)
|
|
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
|
|
|
|
pmainSizer = wx.BoxSizer(wx.HORIZONTAL)
|
|
|
|
availableSizer = wx.BoxSizer(wx.VERTICAL)
|
|
|
|
self.searchBox = SearchBox(self)
|
|
self.itemView = ItemView(self)
|
|
|
|
self.itemView.Hide()
|
|
|
|
availableSizer.Add(self.searchBox, 0, wx.EXPAND)
|
|
availableSizer.Add(self.itemView, 1, wx.EXPAND)
|
|
|
|
self.availableImplantsTree = wx.TreeCtrl(self, wx.ID_ANY, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT)
|
|
root = self.availableRoot = self.availableImplantsTree.AddRoot("Available")
|
|
self.availableImplantsImageList = wx.ImageList(16, 16)
|
|
self.availableImplantsTree.SetImageList(self.availableImplantsImageList)
|
|
|
|
availableSizer.Add(self.availableImplantsTree, 1, wx.EXPAND)
|
|
|
|
pmainSizer.Add(availableSizer, 1, wx.ALL | wx.EXPAND, 5)
|
|
|
|
buttonSizer = wx.BoxSizer(wx.VERTICAL)
|
|
buttonSizer.AddStretchSpacer()
|
|
|
|
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)
|
|
buttonSizer.Add(self.btnRemove, 0)
|
|
|
|
buttonSizer.AddStretchSpacer()
|
|
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)
|
|
pmainSizer.Add(characterImplantSizer, 1, wx.EXPAND, 5)
|
|
|
|
self.SetSizer(pmainSizer)
|
|
|
|
# Populate the market tree
|
|
|
|
sMkt = Market.getInstance()
|
|
for mktGrp in sMkt.getImplantTree():
|
|
iconId = self.addMarketViewImage(sMkt.getIconByMarketGroup(mktGrp))
|
|
childId = self.availableImplantsTree.AppendItem(root, mktGrp.name, iconId, data=mktGrp.ID)
|
|
if sMkt.marketGroupHasTypesCheck(mktGrp) is False:
|
|
self.availableImplantsTree.AppendItem(childId, "dummy")
|
|
|
|
self.availableImplantsTree.SortChildren(self.availableRoot)
|
|
|
|
# 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
|
|
self.btnAdd.Bind(wx.EVT_BUTTON, self.itemSelected)
|
|
self.btnRemove.Bind(wx.EVT_BUTTON, self.removeItem)
|
|
|
|
# We update with an empty list first to set the initial size for Layout(), then update later with actual
|
|
# implants for character. This helps with sizing issues.
|
|
self.pluggedImplantsTree.update([])
|
|
self.bindContext()
|
|
self.Layout()
|
|
|
|
self.update()
|
|
|
|
def bindContext(self):
|
|
# Binds self.contextChanged to whatever changes the context
|
|
raise NotImplementedError()
|
|
|
|
def getImplantsFromContext(self):
|
|
""" Gets list of implants from current context """
|
|
raise NotImplementedError()
|
|
|
|
def addImplantToContext(self, item):
|
|
""" Adds implant to the current context"""
|
|
raise NotImplementedError()
|
|
|
|
def removeImplantFromContext(self, implant):
|
|
""" Removes implant from the current context"""
|
|
raise NotImplementedError()
|
|
|
|
def update(self):
|
|
"""Updates implant list based off the current context"""
|
|
self.implants = self.getImplantsFromContext()[:]
|
|
self.implants.sort(key=lambda i: int(i.getModifiedItemAttr("implantness")))
|
|
self.pluggedImplantsTree.update(self.implants)
|
|
|
|
def contextChanged(self, event):
|
|
self.update()
|
|
event.Skip()
|
|
|
|
def expandLookup(self, event):
|
|
tree = self.availableImplantsTree
|
|
sMkt = Market.getInstance()
|
|
parent = event.Item
|
|
child, _ = tree.GetFirstChild(parent)
|
|
text = tree.GetItemText(child)
|
|
|
|
if text == "dummy" or text == "itemdummy":
|
|
tree.Delete(child)
|
|
|
|
# if the dummy item is a market group, replace with actual market groups
|
|
if text == "dummy":
|
|
# Add 'real stoof!' instead
|
|
currentMktGrp = sMkt.getMarketGroup(tree.GetItemData(parent), eager="children")
|
|
for childMktGrp in sMkt.getMarketGroupChildren(currentMktGrp):
|
|
iconId = self.addMarketViewImage(sMkt.getIconByMarketGroup(childMktGrp))
|
|
childId = tree.AppendItem(parent, childMktGrp.name, iconId, data=childMktGrp.ID)
|
|
if sMkt.marketGroupHasTypesCheck(childMktGrp) is False:
|
|
tree.AppendItem(childId, "dummy")
|
|
else:
|
|
tree.AppendItem(childId, "itemdummy")
|
|
|
|
# replace dummy with actual items
|
|
if text == "itemdummy":
|
|
currentMktGrp = sMkt.getMarketGroup(tree.GetItemData(parent))
|
|
items = sMkt.getItemsByMarketGroup(currentMktGrp)
|
|
for item in items:
|
|
iconId = self.addMarketViewImage(item.iconID)
|
|
tree.AppendItem(parent, item.name, iconId, data=item)
|
|
|
|
tree.SortChildren(parent)
|
|
|
|
def itemSelected(self, event):
|
|
if event.EventObject is self.btnAdd:
|
|
# janky fix that sets EventObject so that we don't have similar code elsewhere.
|
|
if self.itemView.IsShown():
|
|
event.EventObject = self.itemView
|
|
else:
|
|
event.EventObject = self.availableImplantsTree
|
|
|
|
if event.EventObject is self.itemView:
|
|
curr = event.EventObject.GetFirstSelected()
|
|
|
|
while curr != -1:
|
|
item = self.itemView.items[curr]
|
|
self.addImplantToContext(item)
|
|
|
|
curr = event.EventObject.GetNextSelected(curr)
|
|
else:
|
|
root = self.availableImplantsTree.GetSelection()
|
|
|
|
if not root.IsOk():
|
|
return
|
|
|
|
nchilds = self.availableImplantsTree.GetChildrenCount(root)
|
|
if nchilds == 0:
|
|
item = self.availableImplantsTree.GetItemData(root)
|
|
self.addImplantToContext(item)
|
|
else:
|
|
event.Skip()
|
|
return
|
|
|
|
self.update()
|
|
|
|
def removeItem(self, event):
|
|
pos = self.pluggedImplantsTree.GetFirstSelected()
|
|
if pos != -1:
|
|
self.removeImplantFromContext(self.implants[pos])
|
|
self.update()
|
|
|
|
|
|
class AvailableImplantsView(d.Display):
|
|
DEFAULT_COLS = ["attr:implantness",
|
|
"Base Name"]
|
|
|
|
def __init__(self, parent):
|
|
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"]
|
|
|
|
def __init__(self, parent):
|
|
d.Display.__init__(self, parent)
|
|
self.parent = parent
|
|
self.searchBox = parent.searchBox
|
|
|
|
self.items = []
|
|
|
|
# Bind search actions
|
|
self.searchBox.Bind(SBox.EVT_TEXT_ENTER, self.scheduleSearch)
|
|
self.searchBox.Bind(SBox.EVT_SEARCH_BTN, self.scheduleSearch)
|
|
self.searchBox.Bind(SBox.EVT_CANCEL_BTN, self.clearSearch)
|
|
self.searchBox.Bind(SBox.EVT_TEXT, self.scheduleSearch)
|
|
|
|
def clearSearch(self, event=None):
|
|
if self.IsShown():
|
|
self.parent.availableImplantsTree.Show()
|
|
self.Hide()
|
|
self.parent.Layout()
|
|
|
|
if event:
|
|
self.searchBox.Clear()
|
|
|
|
self.items = []
|
|
self.update(self.items)
|
|
|
|
def scheduleSearch(self, event=None):
|
|
sMkt = Market.getInstance()
|
|
|
|
search = self.searchBox.GetLineText(0)
|
|
# Make sure we do not count wildcard as search symbol
|
|
realsearch = search.replace("*", "")
|
|
# Show nothing if query is too short
|
|
if len(realsearch) < 3:
|
|
self.clearSearch()
|
|
return
|
|
|
|
sMkt.searchItems(search, self.populateSearch, ["Implant"])
|
|
|
|
def populateSearch(self, items):
|
|
if not self.IsShown():
|
|
self.parent.availableImplantsTree.Hide()
|
|
self.Show()
|
|
self.parent.Layout()
|
|
|
|
items = [i for i in items if i.group.name != 'Booster']
|
|
self.items = sorted(list(items), key=lambda i: i.name)
|
|
|
|
self.update(self.items)
|