277 lines
11 KiB
Python
277 lines
11 KiB
Python
import sys
|
|
import csv
|
|
import config
|
|
|
|
# noinspection PyPackageRequirements
|
|
import wx
|
|
|
|
from .helpers import AutoListCtrl
|
|
|
|
from gui.bitmap_loader import BitmapLoader
|
|
from service.market import Market
|
|
from service.attribute import Attribute
|
|
from gui.utils.numberFormatter import formatAmount
|
|
|
|
|
|
class ItemParams(wx.Panel):
|
|
def __init__(self, parent, stuff, item, context=None):
|
|
wx.Panel.__init__(self, parent)
|
|
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
|
|
|
self.paramList = AutoListCtrl(self, wx.ID_ANY,
|
|
style=wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES | wx.NO_BORDER)
|
|
mainSizer.Add(self.paramList, 1, wx.ALL | wx.EXPAND, 0)
|
|
self.SetSizer(mainSizer)
|
|
|
|
self.toggleView = 1
|
|
self.stuff = stuff
|
|
self.item = item
|
|
self.attrInfo = {}
|
|
self.attrValues = {}
|
|
self._fetchValues()
|
|
|
|
self.m_staticline = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
|
|
mainSizer.Add(self.m_staticline, 0, wx.EXPAND)
|
|
bSizer = wx.BoxSizer(wx.HORIZONTAL)
|
|
|
|
self.totalAttrsLabel = wx.StaticText(self, wx.ID_ANY, " ", wx.DefaultPosition, wx.DefaultSize, 0)
|
|
bSizer.Add(self.totalAttrsLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT)
|
|
|
|
self.toggleViewBtn = wx.ToggleButton(self, wx.ID_ANY, "Toggle view mode", wx.DefaultPosition, wx.DefaultSize,
|
|
0)
|
|
bSizer.Add(self.toggleViewBtn, 0, wx.ALIGN_CENTER_VERTICAL)
|
|
|
|
self.exportStatsBtn = wx.ToggleButton(self, wx.ID_ANY, "Export Item Stats", wx.DefaultPosition, wx.DefaultSize,
|
|
0)
|
|
bSizer.Add(self.exportStatsBtn, 0, wx.ALIGN_CENTER_VERTICAL)
|
|
|
|
if stuff is not None:
|
|
self.refreshBtn = wx.Button(self, wx.ID_ANY, "Refresh", wx.DefaultPosition, wx.DefaultSize, wx.BU_EXACTFIT)
|
|
bSizer.Add(self.refreshBtn, 0, wx.ALIGN_CENTER_VERTICAL)
|
|
self.refreshBtn.Bind(wx.EVT_BUTTON, self.RefreshValues)
|
|
|
|
mainSizer.Add(bSizer, 0, wx.ALIGN_RIGHT)
|
|
|
|
self.PopulateList()
|
|
|
|
self.toggleViewBtn.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleViewMode)
|
|
self.exportStatsBtn.Bind(wx.EVT_TOGGLEBUTTON, self.ExportItemStats)
|
|
|
|
def _fetchValues(self):
|
|
if self.stuff is None:
|
|
self.attrInfo.clear()
|
|
self.attrValues.clear()
|
|
self.attrInfo.update(self.item.attributes)
|
|
self.attrValues.update(self.item.attributes)
|
|
elif self.stuff.item == self.item:
|
|
self.attrInfo.clear()
|
|
self.attrValues.clear()
|
|
self.attrInfo.update(self.stuff.item.attributes)
|
|
self.attrValues.update(self.stuff.itemModifiedAttributes)
|
|
elif self.stuff.charge == self.item:
|
|
self.attrInfo.clear()
|
|
self.attrValues.clear()
|
|
self.attrInfo.update(self.stuff.charge.attributes)
|
|
self.attrValues.update(self.stuff.chargeModifiedAttributes)
|
|
# When item for stats window no longer exists, don't change anything
|
|
else:
|
|
return
|
|
|
|
def UpdateList(self):
|
|
self.Freeze()
|
|
self.paramList.ClearAll()
|
|
self.PopulateList()
|
|
self.Thaw()
|
|
self.paramList.resizeLastColumn(100)
|
|
|
|
def RefreshValues(self, event):
|
|
self._fetchValues()
|
|
self.UpdateList()
|
|
event.Skip()
|
|
|
|
def ToggleViewMode(self, event):
|
|
self.toggleView *= -1
|
|
self.UpdateList()
|
|
event.Skip()
|
|
|
|
def ExportItemStats(self, event):
|
|
exportFileName = self.item.name + " (" + str(self.item.ID) + ").csv"
|
|
|
|
saveFileDialog = wx.FileDialog(self, "Save CSV file", "", exportFileName,
|
|
"CSV files (*.csv)|*.csv", wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
|
|
|
|
if saveFileDialog.ShowModal() == wx.ID_CANCEL:
|
|
return # the user hit cancel...
|
|
|
|
with open(saveFileDialog.GetPath(), "wb") as exportFile:
|
|
writer = csv.writer(exportFile, delimiter=',')
|
|
|
|
writer.writerow(
|
|
[
|
|
"ID",
|
|
"Internal Name",
|
|
"Friendly Name",
|
|
"Modified Value",
|
|
"Base Value",
|
|
]
|
|
)
|
|
|
|
for attribute in self.attrValues:
|
|
|
|
try:
|
|
attribute_id = self.attrInfo[attribute].ID
|
|
except (KeyError, AttributeError):
|
|
attribute_id = ''
|
|
|
|
try:
|
|
attribute_name = self.attrInfo[attribute].name
|
|
except (KeyError, AttributeError):
|
|
attribute_name = attribute
|
|
|
|
try:
|
|
attribute_displayname = self.attrInfo[attribute].displayName
|
|
except (KeyError, AttributeError):
|
|
attribute_displayname = ''
|
|
|
|
try:
|
|
attribute_value = self.attrInfo[attribute].value
|
|
except (KeyError, AttributeError):
|
|
attribute_value = ''
|
|
|
|
try:
|
|
attribute_modified_value = self.attrValues[attribute].value
|
|
except (KeyError, AttributeError):
|
|
attribute_modified_value = self.attrValues[attribute]
|
|
|
|
writer.writerow(
|
|
[
|
|
attribute_id,
|
|
attribute_name,
|
|
attribute_displayname,
|
|
attribute_modified_value,
|
|
attribute_value,
|
|
]
|
|
)
|
|
|
|
def PopulateList(self):
|
|
self.paramList.InsertColumn(0, "Attribute")
|
|
self.paramList.InsertColumn(1, "Current Value")
|
|
if self.stuff is not None:
|
|
self.paramList.InsertColumn(2, "Base Value")
|
|
self.paramList.SetColumnWidth(0, 110)
|
|
self.paramList.SetColumnWidth(1, 90)
|
|
if self.stuff is not None:
|
|
self.paramList.SetColumnWidth(2, 90)
|
|
self.paramList.setResizeColumn(0)
|
|
self.imageList = wx.ImageList(16, 16)
|
|
self.paramList.SetImageList(self.imageList, wx.IMAGE_LIST_SMALL)
|
|
|
|
names = list(self.attrValues.keys())
|
|
names.sort()
|
|
|
|
idNameMap = {}
|
|
idCount = 0
|
|
for name in names:
|
|
info = self.attrInfo.get(name)
|
|
att = self.attrValues[name]
|
|
|
|
valDefault = getattr(info, "value", None)
|
|
valueDefault = valDefault if valDefault is not None else att
|
|
|
|
val = getattr(att, "value", None)
|
|
value = val if val is not None else att
|
|
|
|
if info and info.displayName and self.toggleView == 1:
|
|
attrName = info.displayName
|
|
else:
|
|
attrName = name
|
|
|
|
if info and config.debug:
|
|
attrName += " ({})".format(info.ID)
|
|
|
|
if info:
|
|
if info.icon is not None:
|
|
iconFile = info.icon.iconFile
|
|
icon = BitmapLoader.getBitmap(iconFile, "icons")
|
|
|
|
if icon is None:
|
|
icon = BitmapLoader.getBitmap("transparent16x16", "gui")
|
|
|
|
attrIcon = self.imageList.Add(icon)
|
|
else:
|
|
attrIcon = self.imageList.Add(BitmapLoader.getBitmap("7_15", "icons"))
|
|
else:
|
|
attrIcon = self.imageList.Add(BitmapLoader.getBitmap("7_15", "icons"))
|
|
|
|
index = self.paramList.InsertItem(sys.maxsize, attrName, attrIcon)
|
|
idNameMap[idCount] = attrName
|
|
self.paramList.SetItemData(index, idCount)
|
|
idCount += 1
|
|
|
|
if self.toggleView != 1:
|
|
valueUnit = str(value)
|
|
elif info and info.unit:
|
|
valueUnit = self.TranslateValueUnit(value, info.unit.displayName, info.unit.name)
|
|
else:
|
|
valueUnit = formatAmount(value, 3, 0, 0)
|
|
|
|
if self.toggleView != 1:
|
|
valueUnitDefault = str(valueDefault)
|
|
elif info and info.unit:
|
|
valueUnitDefault = self.TranslateValueUnit(valueDefault, info.unit.displayName, info.unit.name)
|
|
else:
|
|
valueUnitDefault = formatAmount(valueDefault, 3, 0, 0)
|
|
|
|
self.paramList.SetItem(index, 1, valueUnit)
|
|
if self.stuff is not None:
|
|
self.paramList.SetItem(index, 2, valueUnitDefault)
|
|
# @todo: pheonix, this lamda used cmp() which no longer exists in py3. Probably a better way to do this in the
|
|
# long run, take a look
|
|
self.paramList.SortItems(lambda id1, id2: (idNameMap[id1] > idNameMap[id2]) - (idNameMap[id1] < idNameMap[id2]))
|
|
self.paramList.RefreshRows()
|
|
self.totalAttrsLabel.SetLabel("%d attributes. " % idCount)
|
|
self.Layout()
|
|
|
|
@staticmethod
|
|
def TranslateValueUnit(value, unitName, unitDisplayName):
|
|
def itemIDCallback():
|
|
item = Market.getInstance().getItem(value)
|
|
return "%s (%d)" % (item.name, value) if item is not None else str(value)
|
|
|
|
def groupIDCallback():
|
|
group = Market.getInstance().getGroup(value)
|
|
return "%s (%d)" % (group.name, value) if group is not None else str(value)
|
|
|
|
def attributeIDCallback():
|
|
if not value: # some attributes come through with a value of 0? See #1387
|
|
return "%d" % (value)
|
|
attribute = Attribute.getInstance().getAttributeInfo(value)
|
|
return "%s (%d)" % (attribute.name.capitalize(), value)
|
|
|
|
trans = {
|
|
"Inverse Absolute Percent" : (lambda: (1 - value) * 100, unitName),
|
|
"Inversed Modifier Percent": (lambda: (1 - value) * 100, unitName),
|
|
"Modifier Percent" : (
|
|
lambda: ("%+.2f" if ((value - 1) * 100) % 1 else "%+d") % ((value - 1) * 100), unitName),
|
|
"Volume" : (lambda: value, "m\u00B3"),
|
|
"Sizeclass" : (lambda: value, ""),
|
|
"Absolute Percent" : (lambda: (value * 100), unitName),
|
|
"Milliseconds" : (lambda: value / 1000.0, unitName),
|
|
"typeID" : (itemIDCallback, ""),
|
|
"groupID" : (groupIDCallback, ""),
|
|
"attributeID" : (attributeIDCallback, "")
|
|
}
|
|
|
|
override = trans.get(unitDisplayName)
|
|
if override is not None:
|
|
v = override[0]()
|
|
if isinstance(v, str):
|
|
fvalue = v
|
|
elif isinstance(v, (int, float)):
|
|
fvalue = formatAmount(v, 3, 0, 0)
|
|
else:
|
|
fvalue = v
|
|
return "%s %s" % (fvalue, override[1])
|
|
else:
|
|
return "%s %s" % (formatAmount(value, 3, 0), unitName)
|