Merge branch 'issue/1645'

This commit is contained in:
blitzmann
2018-06-21 00:21:08 -04:00
1895 changed files with 1598 additions and 242 deletions

504
gui/attribute_gauge.py Normal file
View File

@@ -0,0 +1,504 @@
import copy
import wx
import math
from gui.utils import color as color_utils
from gui.utils import draw, anim_effects
from service.fit import Fit
# todo: clean class up. Took from pyfa gauge, has a bunch of extra shit we don't need
class AttributeGauge(wx.Window):
def __init__(self, parent, max_range=100, animate=True, leading_edge=True, edge_on_neutral=True, guide_lines=False, size=(-1, 30), *args,
**kargs):
super().__init__(parent, size=size, *args, **kargs)
self._size = size
self.guide_lines = guide_lines
self._border_colour = wx.BLACK
self._bar_colour = None
self._bar_gradient = None
self.leading_edge = leading_edge
self.edge_on_neutral = edge_on_neutral
self._border_padding = 0
self._max_range = max_range
self._value = 0
self._fraction_digits = 0
self._timer_id = wx.NewId()
self._timer = None
self._oldValue = 0
self._animate = animate
self._anim_duration = 500
self._anim_step = 0
self._period = 20
self._anim_value = 0
self._anim_direction = 0
self.anim_effect = anim_effects.OUT_QUAD
# transition colors used based on how full (or overfilled) the gauge is.
self.transition_colors = [
(wx.Colour(191, 191, 191), wx.Colour(96, 191, 0)), # < 0-100%
(wx.Colour(191, 167, 96), wx.Colour(255, 191, 0)), # < 100-101%
(wx.Colour(255, 191, 0), wx.Colour(255, 128, 0)), # < 101-103%
(wx.Colour(255, 128, 0), wx.Colour(255, 0, 0)) # < 103-105%
]
self.goodColor = wx.Colour(96, 191, 0)
self.badColor = wx.Colour(255, 64, 0)
self.gradient_effect = -35
self._percentage = 0
self._old_percentage = 0
self._show_remaining = False
self.SetBackgroundColour(wx.Colour(51, 51, 51))
self._tooltip = wx.ToolTip("0.00/100.00")
self.SetToolTip(self._tooltip)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_TIMER, self.OnTimer)
self.Bind(wx.EVT_ENTER_WINDOW, self.OnWindowEnter)
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnWindowLeave)
self.SetBackgroundStyle(wx.BG_STYLE_PAINT)
def OnEraseBackground(self, event):
pass
def OnWindowEnter(self, event):
self._show_remaining = True
self.Refresh()
def OnWindowLeave(self, event):
self._show_remaining = False
self.Refresh()
def GetBorderColour(self):
return self._border_colour
def SetBorderColour(self, colour):
self._border_colour = colour
def GetBarColour(self):
return self._bar_colour
def SetBarColour(self, colour):
self._bar_colour = colour
def SetFractionDigits(self, digits):
self._fraction_digits = digits
def GetBarGradient(self):
if self._bar_gradient is None:
return None
return self._bar_gradient[0]
def SetBarGradient(self, gradient=None):
if gradient is None:
self._bar_gradient = None
else:
if not isinstance(gradient, list):
self._bar_gradient = [gradient]
else:
self._bar_gradient = list(gradient)
def GetBorderPadding(self):
return self._border_padding
def SetBorderPadding(self, padding):
self._border_padding = padding
def GetRange(self):
""" Returns the maximum value of the gauge. """
return self._max_range
def Animate(self):
if self._animate:
if not self._timer:
self._timer = wx.Timer(self, self._timer_id)
self._anim_step = 0
self._timer.Start(self._period)
else:
self._anim_value = self._percentage
self.Refresh()
def SetRange(self, range, reinit=False, animate=True):
"""
Sets the range of the gauge. The gauge length is its
value as a proportion of the range.
"""
if self._max_range == range:
return
# we cannot have a range of zero (laws of physics, etc), so we set it
if range <= 0:
self._max_range = 0.01
else:
self._max_range = range
if reinit is False:
self._old_percentage = self._percentage
self._percentage = (self._value / self._max_range) * 100
else:
self._old_percentage = self._percentage
self._percentage = 0
self._value = 0
if animate:
self.Animate()
self._tooltip.SetTip("%.2f/%.2f" % (self._value, self._max_range if self._max_range > 0.01 else 0))
def GetValue(self):
return self._value
def SetValue(self, value, animate=True):
""" Sets the current position of the gauge. """
print ("="*20, self._percentage)
if self._value == value:
return
self._old_percentage = self._percentage
self._value = value
self._percentage = (self._value / self._max_range) * 100
if animate:
self.Animate()
self._tooltip.SetTip("%.2f/%.2f" % (self._value, self._max_range))
def SetValueRange(self, value, range, reinit=False):
""" Set both value and range of the gauge. """
range_ = float(range)
if range_ <= 0:
self._max_range = 0.01
else:
self._max_range = range_
value = float(value)
self._value = value
if reinit is False:
self._old_percentage = self._percentage
self._percentage = (self._value / self._max_range) * 100
else:
self._old_percentage = self._percentage
self._percentage = 0
self.Animate()
self._tooltip.SetTip("%.2f/%.2f" %
(self._value, self._max_range if float(self._max_range) > 0.01 else 0))
def OnPaint(self, event):
dc = wx.AutoBufferedPaintDC(self)
rect = self.GetClientRect()
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
dc.Clear()
colour = self.GetBackgroundColour()
dc.SetBrush(wx.Brush(colour))
dc.SetPen(wx.Pen(colour))
dc.DrawRectangle(rect)
value = self._percentage
if self._timer:
if self._timer.IsRunning():
value = self._anim_value
if self._border_colour:
dc.SetPen(wx.Pen(self.GetBorderColour()))
dc.DrawRectangle(rect)
pad = 1 + self.GetBorderPadding()
rect.Deflate(pad, pad)
if True:
# if we have a bar color set, then we will use this
colour = self.goodColor if value >= 0 else self.badColor
is_even = rect.width % 2 == 0
# the size of half our available drawing area (since we're only working in halves)
half = (rect.width / 2)
# calculate width of bar as a percentage of half the space
w = abs(half * (value / 100))
w = min(w, half) # Ensure that we don't overshoot our drawing area
w = math.ceil(w) # round up to nearest pixel, this ensures that we don't lose representation for sub pixels
# print("Percentage: {}\t\t\t\t\tValue: {}\t\t\t\t\tWidth: {}\t\t\t\t\tHalf: {}\t\t\t\t\tRect Width: {}".format(round(self._percentage, 3), round(value,3), w, half, rect.width))
# set guide_lines every 10 pixels of the main gauge (not including borders)
if self.guide_lines:
for x in range(1, 20):
dc.SetBrush(wx.Brush(wx.LIGHT_GREY))
dc.SetPen(wx.Pen(wx.LIGHT_GREY))
dc.DrawRectangle(x*10, 1, 1, rect.height)
dc.SetBrush(wx.Brush(colour))
dc.SetPen(wx.Pen(colour))
# If we have an even width, we can simply dedicate the middle-most pixels to both sides
# However, if there is an odd width, the middle pixel is shared between the left and right gauge
if value >= 0:
padding = (half if is_even else math.ceil(half-1)) + 1
dc.DrawRectangle(padding, 1, w, rect.height)
else:
padding = half - w + 1 if is_even else math.ceil(half)-(w-1)
dc.DrawRectangle(padding, 1, w, rect.height)
if self.leading_edge and (self.edge_on_neutral or value != 0):
dc.SetPen(wx.Pen(wx.WHITE))
dc.SetBrush(wx.Brush(wx.WHITE))
if value > 0:
dc.DrawRectangle(min(padding + w, rect.width), 1, 1, rect.height)
else:
dc.DrawRectangle(max(padding-1, 1), 1, 1, rect.height)
def OnTimer(self, event):
old_value = self._old_percentage
value = self._percentage
start = 0
# -1 = left direction, 1 = right direction
direction = 1 if old_value < value else -1
end = direction * (value - old_value)
self._anim_direction = direction
step = self.anim_effect(self._anim_step, start, end, self._anim_duration)
self._anim_step += self._period
if self._timer_id == event.GetId():
stop_timer = False
if self._anim_step > self._anim_duration:
stop_timer = True
# add new value to the animation if we haven't reached our goal
# otherwise, stop animation
if direction == 1:
if old_value + step < value:
self._anim_value = old_value + step
else:
stop_timer = True
else:
if old_value - step > value:
self._anim_value = old_value - step
else:
stop_timer = True
if stop_timer:
self._timer.Stop()
self.Refresh()
if __name__ == "__main__":
import random
def frange(x, y, jump):
while x < y:
yield x
x += jump
class MyPanel(wx.Panel):
def __init__(self, parent, size=(500, 500)):
wx.Panel.__init__(self, parent, size=size)
box = wx.BoxSizer(wx.VERTICAL)
font = wx.Font(9, wx.SWISS, wx.NORMAL, wx.NORMAL, False)
self.gauge = gauge = AttributeGauge(self, size=(204, 4))
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
gauge.SetBarColour(wx.Colour(255, 128, 0))
gauge.SetValue(100)
gauge.SetFractionDigits(1)
box.Add(gauge, 0, wx.ALL|wx.CENTER, 10)
self.gauge11 = gauge = AttributeGauge(self, size=(204, 6))
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
gauge.SetBarColour(wx.Colour(255, 128, 0))
gauge.SetValue(100)
gauge.SetFractionDigits(1)
box.Add(gauge, 0, wx.ALL | wx.CENTER, 10)
self.gauge12 = gauge = AttributeGauge(self, size=(204, 8))
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
gauge.SetBarColour(wx.Colour(255, 128, 0))
gauge.SetValue(100)
gauge.SetFractionDigits(1)
box.Add(gauge, 0, wx.ALL | wx.CENTER, 10)
self.gauge13 = gauge = AttributeGauge(self, size=(204, 10))
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
gauge.SetBarColour(wx.Colour(255, 128, 0))
gauge.SetValue(100)
gauge.SetFractionDigits(1)
box.Add(gauge, 0, wx.ALL | wx.CENTER, 10)
self.value = wx.StaticText(self, label="Text")
box.Add(self.value, 0, wx.ALL | wx.CENTER, 5)
self.btn = wx.Button(self, label="Toggle Timer")
box.Add(self.btn, 0, wx.ALL | wx.CENTER, 5)
self.btn.Bind(wx.EVT_BUTTON, self.ToggleTimer)
self.spinCtrl = wx.SpinCtrl(self, min=-10000, max=10000)
box.Add(self.spinCtrl, 0, wx.ALL | wx.CENTER, 5)
self.spinCtrl.Bind(wx.EVT_SPINCTRL, self.UpdateValue)
self.m_staticline2 = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
box.Add(self.m_staticline2, 0, wx.EXPAND, 5)
self.spinCtrl2 = wx.SpinCtrl(self, min=0, max=10000)
box.Add(self.spinCtrl2, 0, wx.ALL | wx.CENTER, 5)
self.spinCtrl2.Bind(wx.EVT_SPINCTRL, self.UpdateValue2)
box.Add(wx.StaticText(self, label="Large Even Pixel Test"), 0, wx.ALL | wx.CENTER, 5)
guide_lines = False
self.gauge2 = gauge = AttributeGauge(self, guide_lines=guide_lines, size=(204, 8))
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
gauge.SetBarColour(wx.Colour(255, 128, 0))
gauge.SetValue(2)
gauge.SetFractionDigits(1)
box.Add(gauge, 0, wx.ALL | wx.CENTER, 10)
self.gauge3 = gauge = AttributeGauge(self, guide_lines=guide_lines, size=(204, 8))
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
gauge.SetBarColour(wx.Colour(255, 128, 0))
gauge.SetValue(-2)
gauge.SetFractionDigits(1)
box.Add(gauge, 0, wx.ALL | wx.CENTER, 10)
box.Add(wx.StaticText(self, label="Large Odd Pixel Test"), 0, wx.ALL | wx.CENTER, 5)
self.gauge4 = gauge = AttributeGauge(self, guide_lines=guide_lines, size=(205, 8))
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
gauge.SetBarColour(wx.Colour(255, 128, 0))
gauge.SetValue(2)
gauge.SetFractionDigits(1)
box.Add(gauge, 0, wx.ALL | wx.CENTER, 10)
self.gauge5 = gauge = AttributeGauge(self, guide_lines=guide_lines, size=(205, 8))
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
gauge.SetBarColour(wx.Colour(255, 128, 0))
gauge.SetValue(-2)
gauge.SetFractionDigits(1)
box.Add(gauge, 0, wx.ALL | wx.CENTER, 10)
box.Add(wx.StaticText(self, label="Small Even Pixel Test"), 0, wx.ALL | wx.CENTER, 5)
self.gauge6 = gauge = AttributeGauge(self, guide_lines=guide_lines, size=(100, 8))
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
gauge.SetBarColour(wx.Colour(255, 128, 0))
gauge.SetValue(75)
gauge.SetFractionDigits(1)
box.Add(gauge, 0, wx.ALL | wx.CENTER, 10)
self.gauge7 = gauge = AttributeGauge(self, guide_lines=guide_lines, size=(100, 8))
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
gauge.SetBarColour(wx.Colour(255, 128, 0))
gauge.SetValue(-75)
gauge.SetFractionDigits(1)
box.Add(gauge, 0, wx.ALL | wx.CENTER, 10)
box.Add(wx.StaticText(self, label="Small Odd Pixel Test"), 0, wx.ALL | wx.CENTER, 5)
self.gauge8 = gauge = AttributeGauge(self, guide_lines=guide_lines, max_range=100, size=(101, 8))
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
gauge.SetBarColour(wx.Colour(255, 128, 0))
gauge.SetValue(1)
gauge.SetFractionDigits(1)
box.Add(gauge, 0, wx.ALL | wx.CENTER, 10)
self.gauge9 = gauge = AttributeGauge(self, guide_lines=guide_lines, max_range=100, size=(101, 8))
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
gauge.SetBarColour(wx.Colour(255, 128, 0))
gauge.SetValue(-1)
gauge.SetFractionDigits(1)
box.Add(gauge, 0, wx.ALL | wx.CENTER, 10)
self.SetSizer(box)
self.Layout()
self.animTimer = wx.Timer(self, wx.NewId())
self.Bind(wx.EVT_TIMER, self.OnTimer)
self.animTimer.Start(1000)
def ToggleTimer(self, evt):
if self.animTimer.IsRunning:
self.animTimer.Stop()
else:
self.animTimer.Start(1000)
def UpdateValue(self, event):
if self.animTimer.IsRunning:
self.animTimer.Stop()
num = self.spinCtrl.GetValue()
self.gauge.SetValue(num)
self.gauge11.SetValue(num)
self.gauge12.SetValue(num)
self.gauge13.SetValue(num)
self.value.SetLabel(str(num))
def UpdateValue2(self, event):
num = self.spinCtrl2.GetValue()
self.gauge2.SetValue(num)
self.gauge3.SetValue(num*-1)
self.gauge4.SetValue(num)
self.gauge5.SetValue(num*-1)
self.gauge6.SetValue(num)
self.gauge7.SetValue(num*-1)
self.gauge8.SetValue(num)
self.gauge9.SetValue(num*-1)
def OnTimer(self, evt):
num = random.randint(-100,100)
self.gauge.SetValue(num)
self.gauge11.SetValue(num)
self.gauge12.SetValue(num)
self.gauge13.SetValue(num)
self.value.SetLabel(str(num))
class Frame(wx.Frame):
def __init__(self, title, size=(500, 800)):
wx.Frame.__init__(self, None, title=title, size=size)
self.statusbar = self.CreateStatusBar()
main_sizer = wx.BoxSizer(wx.VERTICAL)
panel = MyPanel(self, size=size)
main_sizer.Add(panel)
self.SetSizer(main_sizer)
app = wx.App(redirect=False) # Error messages go to popup window
top = Frame("Test Attribute Bar")
top.Show()
app.MainLoop()

View File

@@ -35,7 +35,7 @@ from service.fit import Fit
class DummyItem(object):
def __init__(self, txt):
self.name = txt
self.icon = None
self.iconID = None
class DummyEntry(object):

View File

@@ -39,7 +39,7 @@ pyfalog = Logger(__name__)
class DummyItem(object):
def __init__(self, txt):
self.name = txt
self.icon = None
self.iconID = None
class DummyEntry(object):

View File

@@ -34,6 +34,7 @@ class BoosterSideEffect(ContextMenu):
label = ability.name
id = ContextMenu.nextID()
self.effectIds[id] = ability
menuItem = wx.MenuItem(menu, id, label, kind=wx.ITEM_CHECK)
menu.Bind(wx.EVT_MENU, self.handleMode, menuItem)
return menuItem

View File

@@ -117,8 +117,8 @@ class ModuleAmmoPicker(ContextMenu):
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 charge is not None and charge.iconID is not None:
bitmap = BitmapLoader.getBitmap(charge.iconID, "icons")
if bitmap is not None:
item.SetBitmap(bitmap)

View File

@@ -0,0 +1,78 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
# noinspection PyPackageRequirements
import wx
import gui.globalEvents as GE
from service.fit import Fit
from service.settings import ContextMenuSettings
class MutaplasmidCM(ContextMenu):
def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.settings = ContextMenuSettings.getInstance()
self.eventIDs = {}
def display(self, srcContext, selection):
# if not self.settings.get('ammoPattern'):
# return False
if srcContext not in ("fittingModule") or self.mainFrame.getActiveFit() is None:
return False
mod = selection[0]
if len(mod.item.mutaplasmids) == 0 and not mod.isMutated:
return False
return True
def getText(self, itmContext, selection):
mod = selection[0]
return "Apply Mutaplasmid" if not mod.isMutated else "Revert to {}".format(mod.baseItem.name)
def getSubMenu(self, context, selection, rootMenu, i, pitem):
if selection[0].isMutated:
return None
msw = True if "wxMSW" in wx.PlatformInfo else False
self.skillIds = {}
sub = wx.Menu()
mod = selection[0]
menu = rootMenu if msw else sub
for item in mod.item.mutaplasmids:
label = item.item.name
id = ContextMenu.nextID()
self.eventIDs[id] = (item, mod)
skillItem = wx.MenuItem(menu, id, label)
menu.Bind(wx.EVT_MENU, self.handleMenu, skillItem)
sub.Append(skillItem)
return sub
def handleMenu(self, event):
mutaplasmid, mod = self.eventIDs[event.Id]
fit = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
# todo: dev out function to switch module to an abyssal module. Also, maybe open item stats here automatically
# with the attribute tab set?
sFit.convertMutaplasmid(fit, mod.modPosition, mutaplasmid)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fit))
def activate(self, fullContext, selection, i):
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
mod = selection[0]
sFit.changeModule(fitID, mod.modPosition, mod.baseItemID)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def getBitmap(self, context, selection):
return None
MutaplasmidCM.register()

View File

@@ -55,7 +55,7 @@ class FitDpsGraph(Graph):
icons = {}
sAttr = Attribute.getInstance()
for key, attrName in self.propertyAttributeMap.items():
iconFile = sAttr.getAttributeInfo(attrName).icon.iconFile
iconFile = sAttr.getAttributeInfo(attrName).iconID
bitmap = BitmapLoader.getBitmap(iconFile, "icons")
if bitmap:
icons[key] = bitmap

View File

@@ -0,0 +1,248 @@
import wx
import wx.lib.newevent
from gui.attribute_gauge import AttributeGauge
import eos
import eos.db
_ValueChanged, EVT_VALUE_CHANGED = wx.lib.newevent.NewEvent()
class AttributeSliderChangeEvent:
def __init__(self, obj, old_value, new_value, old_percentage, new_percentage):
self.__obj = obj
self.__old = old_value
self.__new = new_value
self.__old_percent = old_percentage
self.__new_percent = new_percentage
def GetObj(self):
return self.__obj
def GetOldValue(self):
return self.__old
def GetValue(self):
return self.__new
def GetOldPercentage(self):
return self.__old_percent
def GetPercentage(self):
return self.__new_percent
Object = property(GetObj)
OldValue = property(GetOldValue)
Value = property(GetValue)
OldPercentage = property(GetOldPercentage)
Percentage = property(GetPercentage)
class ValueChanged(_ValueChanged, AttributeSliderChangeEvent):
def __init__(self, obj, old_value, new_value, old_percentage, new_percentage):
_ValueChanged.__init__(self)
AttributeSliderChangeEvent.__init__(self, obj, old_value, new_value, old_percentage, new_percentage)
class AttributeSlider(wx.Panel):
# Slider which abstracts users values from internal values (because the built in slider does not deal with floats
# and the like), based on http://wxpython-users.wxwidgets.narkive.com/ekgBzA7u/anyone-ever-thought-of-a-floating-point-slider
def __init__(self, parent, baseValue, minMod, maxMod, inverse=False, id=-1):
wx.Panel.__init__(self, parent, id=id)
self.parent = parent
self.inverse = inverse
self.base_value = baseValue
self.UserMinValue = minMod
self.UserMaxValue = maxMod
# The internal slider basically represents the percentage towards the end of the range. It has to be normalized
# in this way, otherwise when we start off with a base, if the range is skewed to one side, the base value won't
# be centered. We use a range of -100,100 so that we can depend on the SliderValue to contain the percentage
# toward one end
# Additionally, since we want the slider to be accurate to 3 decimal places, we need to blow out the two ends here
# (if we have a slider that needs to land on 66.66% towards the right, it will actually be converted to 66%. Se we need it to support 6,666)
self.SliderMinValue = -100
self.SliderMaxValue = 100
self.SliderValue = 0
range = [(self.UserMinValue * self.base_value), (self.UserMaxValue * self.base_value)]
self.ctrl = wx.SpinCtrlDouble(self, min=min(range), max=max(range))
self.ctrl.SetDigits(3)
self.ctrl.Bind(wx.EVT_SPINCTRLDOUBLE, self.UpdateValue)
self.slider = AttributeGauge(self, size=(-1, 8))
b = 4
vsizer1 = wx.BoxSizer(wx.VERTICAL)
vsizer1.Add(self.ctrl, 0, wx.LEFT | wx.RIGHT | wx.CENTER, b)
vsizer1.Add(self.slider, 0, wx.EXPAND | wx.ALL , b)
self.SetSizerAndFit(vsizer1)
self.parent.SetClientSize((500, vsizer1.GetSize()[1]))
def UpdateValue(self, evt):
self.SetValue(self.ctrl.GetValue())
evt.Skip()
def SetValue(self, value, post_event=True):
# todo: check this against values that might be 2.5x and whatnot
mod = value / self.base_value
self.ctrl.SetValue(value)
slider_percentage = 0
if mod < 1:
modEnd = self.UserMinValue
slider_percentage = (1-mod)/(1 - modEnd) * -100
elif mod > 1:
modEnd = self.UserMaxValue
slider_percentage = ((mod-1)/(modEnd-1)) * 100
print(slider_percentage)
if self.inverse:
slider_percentage *= -1
self.slider.SetValue(slider_percentage)
if post_event:
wx.PostEvent(self, ValueChanged(self, None, value, None, slider_percentage))
class TestAttributeSlider(wx.Frame):
def __init__(self, parent, id):
title = 'Slider...'
pos = wx.DefaultPosition
size = wx.DefaultSize
sty = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, parent, id, title, pos, size, sty)
self.panel = AttributeSlider(self, -50, 0.8, 1.5, False)
self.panel.Bind(EVT_VALUE_CHANGED, self.thing)
self.panel.SetValue(-55)
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
def OnCloseWindow(self, event):
self.Destroy()
def thing(self, evt):
print("thing")
if __name__ == "__main__":
app = wx.App()
frame = TestAttributeSlider(None, wx.ID_ANY)
frame.Show()
app.MainLoop()
# class AttributeSliderDEV(wx.Panel):
# # Slider which abstracts users values from internal values (because the built in slider does not deal with floats
# # and the like), based on http://wxpython-users.wxwidgets.narkive.com/ekgBzA7u/anyone-ever-thought-of-a-floating-point-slider
#
# def __init__(self, parent, baseValue, minMod, maxMod):
# wx.Panel.__init__(self, parent)
#
# self.parent = parent
#
# self.base_value = baseValue
#
# self.UserMinValue = minMod
# self.UserMaxValue = maxMod
#
# # The internal slider basically represents the percentage towards the end of the range. It has to be normalized
# # in this way, otherwise when we start off with a base, if the range is skewed to one side, the base value won't
# # be centered. We use a range of -100,100 so that we can depend on the SliderValue to contain the percentage
# # toward one end
#
# # Additionally, since we want the slider to be accurate to 3 decimal places, we need to blow out the two ends here
# # (if we have a slider that needs to land on 66.66% towards the right, it will actually be converted to 66%. Se we need it to support 6,666)
#
# self.SliderMinValue = -100_000
# self.SliderMaxValue = 100_000
# self.SliderValue = 0
#
# self.statxt1 = wx.StaticText(self, wx.ID_ANY, 'left',
# style=wx.ST_NO_AUTORESIZE | wx.ALIGN_LEFT)
# self.statxt2 = wx.StaticText(self, wx.ID_ANY, 'middle',
# style=wx.ST_NO_AUTORESIZE | wx.ALIGN_CENTRE)
# self.statxt3 = wx.StaticText(self, wx.ID_ANY, 'right',
# style=wx.ST_NO_AUTORESIZE | wx.ALIGN_RIGHT)
#
# self.statxt1.SetLabel("{0:.3f}".format(self.UserMinValue * self.base_value))
# self.statxt1.SetToolTip("{0:+f}%".format((1-self.UserMinValue)*-100))
# self.statxt2.SetLabel("{0:.3f}".format(self.base_value))
# self.statxt3.SetLabel("{0:.3f}".format(self.UserMaxValue * self.base_value))
# self.statxt3.SetToolTip("{0:+f}%".format((1-self.UserMaxValue)*-100))
#
# self.slider = wx.Slider(
# self, wx.ID_ANY,
# self.SliderValue,
# self.SliderMinValue,
# self.SliderMaxValue,
# style=wx.SL_HORIZONTAL)
#
# self.slider.SetTickFreq((self.SliderMaxValue - self.SliderMinValue) / 15)
#
# self.slider.Bind(wx.EVT_SCROLL, self.OnScroll)
#
# b = 20
# hsizer1 = wx.BoxSizer(wx.HORIZONTAL)
# hsizer1.Add(self.statxt1, 1, wx.RIGHT, b)
# hsizer1.Add(self.statxt2, 1, wx.LEFT | wx.RIGHT, b)
# hsizer1.Add(self.statxt3, 1, wx.LEFT, b)
#
# b = 4
# vsizer1 = wx.BoxSizer(wx.VERTICAL)
# vsizer1.Add(hsizer1, 0, wx.EXPAND | wx.ALL, b)
# vsizer1.Add(self.slider, 0, wx.EXPAND | wx.LEFT | wx.TOP | wx.BOTTOM, b)
#
# self.SetSizerAndFit(vsizer1)
# self.parent.SetClientSize((500, vsizer1.GetSize()[1]))
#
# def OnScroll(self, event):
# self.CalculateUserValue()
#
# def SetValue(self, value):
# # todo: check this against values that might be 2.5x and whatnot
# mod = value / self.base_value
# slider_percentage = 0
# if mod < 1:
# modEnd = -1 * self.UserMinValue
# slider_percentage = (modEnd / mod) * 10_000
# elif mod > 1:
# modEnd = self.UserMaxValue
# slider_percentage = ((mod-1)/(modEnd-1)) * 100_000
#
# self.slider.SetValue(slider_percentage)
# self.CalculateUserValue()
#
# def CalculateUserValue(self):
# self.SliderValue = self.slider.GetValue()
#
# mod = 1
#
# # The slider value tells us when mod we're going to use, depending on its sign
# if self.SliderValue < 0:
# mod = self.UserMinValue
# elif self.SliderValue > 0:
# mod = self.UserMaxValue
#
# # Get the slider value percentage as an absolute value
# slider_mod = abs(self.SliderValue/1_000) / 100
#
# # Gets our new mod by use the slider's percentage to determine where in the spectrum it is
# new_mod = mod + ((1 - mod) - ((1 - mod) * slider_mod))
#
# # Modifies our base value, to get out modified value
# newValue = new_mod * self.base_value
#
# if mod == 1:
# self.statxt2.SetLabel("{0:.3f}".format(newValue))
# else:
# self.statxt2.SetLabel("{0:.3f} ({1:+.3f})".format(newValue, newValue - self.base_value, ))
# self.statxt2.SetToolTip("{0:+f}%".format(new_mod*100))

View File

@@ -237,16 +237,16 @@ class ItemAffectedBy(wx.Panel):
displayName = attrInfo.displayName if attrInfo and attrInfo.displayName != "" else attrName
if attrInfo:
if attrInfo.icon is not None:
iconFile = attrInfo.icon.iconFile
if attrInfo.iconID is not None:
iconFile = attrInfo.iconID
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"))
attrIcon = self.imageList.Add(BitmapLoader.getBitmap("0", "icons"))
else:
attrIcon = self.imageList.Add(BitmapLoader.getBitmap("7_15", "icons"))
attrIcon = self.imageList.Add(BitmapLoader.getBitmap("0", "icons"))
if self.showRealNames:
display = attrName
@@ -267,8 +267,8 @@ class ItemAffectedBy(wx.Panel):
if afflictorType == Ship:
itemIcon = self.imageList.Add(BitmapLoader.getBitmap("ship_small", "gui"))
elif item.icon:
bitmap = BitmapLoader.getBitmap(item.icon.iconFile, "icons")
elif item.iconID:
bitmap = BitmapLoader.getBitmap(item.iconID, "icons")
itemIcon = self.imageList.Add(bitmap) if bitmap else -1
else:
itemIcon = -1
@@ -373,8 +373,8 @@ class ItemAffectedBy(wx.Panel):
counter = len(afflictors)
if afflictorType == Ship:
itemIcon = self.imageList.Add(BitmapLoader.getBitmap("ship_small", "gui"))
elif item.icon:
bitmap = BitmapLoader.getBitmap(item.icon.iconFile, "icons")
elif item.iconID:
bitmap = BitmapLoader.getBitmap(item.iconID, "icons")
itemIcon = self.imageList.Add(bitmap) if bitmap else -1
else:
itemIcon = -1
@@ -398,17 +398,17 @@ class ItemAffectedBy(wx.Panel):
displayName = attrInfo.displayName if attrInfo else ""
if attrInfo:
if attrInfo.icon is not None:
iconFile = attrInfo.icon.iconFile
if attrInfo.iconID is not None:
iconFile = attrInfo.iconID
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"))
attrIcon = self.imageList.Add(BitmapLoader.getBitmap("0", "icons"))
else:
attrIcon = self.imageList.Add(BitmapLoader.getBitmap("7_15", "icons"))
attrIcon = self.imageList.Add(BitmapLoader.getBitmap("0", "icons"))
penalized = ""
if '*' in attrModifier:

View File

@@ -174,7 +174,12 @@ class ItemParams(wx.Panel):
info = self.attrInfo.get(name)
att = self.attrValues[name]
valDefault = getattr(info, "value", None)
# If we're working with a stuff object, we should get the original value from our getBaseAttrValue function,
# which will return the value with respect to the effective base (with mutators / overrides in place)
valDefault = getattr(info, "value", None) # Get default value from attribute
if self.stuff is not None:
# if it's a stuff, overwrite default (with fallback to current value)
valDefault = self.stuff.getBaseAttrValue(name, valDefault)
valueDefault = valDefault if valDefault is not None else att
val = getattr(att, "value", None)
@@ -189,8 +194,8 @@ class ItemParams(wx.Panel):
attrName += " ({})".format(info.ID)
if info:
if info.icon is not None:
iconFile = info.icon.iconFile
if info.iconID is not None:
iconFile = info.iconID
icon = BitmapLoader.getBitmap(iconFile, "icons")
if icon is None:
@@ -198,9 +203,9 @@ class ItemParams(wx.Panel):
attrIcon = self.imageList.Add(icon)
else:
attrIcon = self.imageList.Add(BitmapLoader.getBitmap("7_15", "icons"))
attrIcon = self.imageList.Add(BitmapLoader.getBitmap("0", "icons"))
else:
attrIcon = self.imageList.Add(BitmapLoader.getBitmap("7_15", "icons"))
attrIcon = self.imageList.Add(BitmapLoader.getBitmap("0", "icons"))
index = self.paramList.InsertItem(self.paramList.GetItemCount(), attrName, attrIcon)
idNameMap[idCount] = attrName

View File

@@ -44,8 +44,8 @@ class ItemDependents(wx.Panel):
child = self.reqTree.AppendItem(parent, "Level {}".format(self.romanNb[int(x)]), sbIconId)
for item in items:
if item.icon:
bitmap = BitmapLoader.getBitmap(item.icon.iconFile, "icons")
if item.iconID:
bitmap = BitmapLoader.getBitmap(item.iconID, "icons")
itemIcon = self.imageList.Add(bitmap) if bitmap else -1
else:
itemIcon = -1

View File

@@ -0,0 +1,120 @@
# noinspection PyPackageRequirements
import wx
from service.fit import Fit
from .attributeSlider import AttributeSlider, EVT_VALUE_CHANGED
import gui.mainFrame
from gui.contextMenu import ContextMenu
from gui.bitmap_loader import BitmapLoader
import gui.globalEvents as GE
import gui.mainFrame
class ItemMutator(wx.Panel):
def __init__(self, parent, stuff, item):
wx.Panel.__init__(self, parent)
self.stuff = stuff
self.item = item
self.timer = None
self.activeFit = gui.mainFrame.MainFrame.getInstance().getActiveFit()
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.goodColor = wx.Colour(96, 191, 0)
self.badColor = wx.Colour(255, 64, 0)
self.event_mapping = {}
for m in sorted(stuff.mutators.values(), key=lambda x: x.attribute.displayName):
slider = AttributeSlider(self, m.baseValue, m.minMod, m.maxMod, not m.highIsGood)
slider.SetValue(m.value, False)
slider.Bind(EVT_VALUE_CHANGED, self.changeMutatedValue)
self.event_mapping[slider] = m
headingSizer = wx.BoxSizer(wx.HORIZONTAL)
# create array for the two ranges
min_t = [round(m.minValue, 3), m.minMod, None]
max_t = [round(m.maxValue, 3), m.maxMod, None]
# Then we need to determine if it's better than original, which will be the color
min_t[2] = min_t[1] < 1 if not m.highIsGood else 1 < min_t[1]
max_t[2] = max_t[1] < 1 if not m.highIsGood else 1 < max_t[1]
# Lastly, we need to determine which range value is "worse" (left side) or "better" (right side)
if (m.highIsGood and min_t[1] > max_t[1]) or (not m.highIsGood and min_t[1] < max_t[1]):
better_range = min_t
else:
better_range = max_t
if (m.highIsGood and max_t[1] < min_t[1]) or (not m.highIsGood and max_t[1] > min_t[1]):
worse_range = max_t
else:
worse_range = min_t
print("{}: \nHigh is good: {}".format(m.attribute.displayName, m.attribute.highIsGood))
print("Value {}".format(m.baseValue))
print(min_t)
print(max_t)
print(better_range)
print(worse_range)
font = parent.GetFont()
font.SetWeight(wx.BOLD)
headingSizer.Add(BitmapLoader.getStaticBitmap(m.attribute.iconID, self, "icons"), 0, wx.RIGHT, 10)
displayName = wx.StaticText(self, wx.ID_ANY, m.attribute.displayName)
displayName.SetFont(font)
headingSizer.Add(displayName, 3, wx.ALL | wx.EXPAND, 0)
range_low = wx.StaticText(self, wx.ID_ANY, "{} {}".format(worse_range[0], m.attribute.unit.displayName))
range_low.SetForegroundColour(self.goodColor if worse_range[2] else self.badColor)
range_high = wx.StaticText(self, wx.ID_ANY, "{} {}".format(better_range[0], m.attribute.unit.displayName))
range_high.SetForegroundColour(self.goodColor if better_range[2] else self.badColor)
headingSizer.Add(range_low, 0, wx.ALL | wx.EXPAND, 0)
headingSizer.Add(wx.StaticText(self, wx.ID_ANY, " ── "), 0, wx.RIGHT | wx.LEFT | wx.EXPAND, 5)
headingSizer.Add(range_high, 0, wx.RIGHT | wx.EXPAND, 10)
mainSizer.Add(headingSizer, 0, wx.ALL | wx.EXPAND, 5)
mainSizer.Add(slider, 0, wx.RIGHT | wx.LEFT | wx.EXPAND, 10)
mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0, wx.ALL | wx.EXPAND, 5)
mainSizer.AddStretchSpacer()
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.saveBtn = wx.Button(self, wx.ID_ANY, "Save Attributes", wx.DefaultPosition, wx.DefaultSize, 0)
bSizer.Add(self.saveBtn, 0, wx.ALIGN_CENTER_VERTICAL)
mainSizer.Add(bSizer, 0, wx.RIGHT | wx.LEFT | wx.EXPAND, 0)
self.SetSizer(mainSizer)
self.Layout()
def changeMutatedValue(self, evt):
m = self.event_mapping[evt.Object]
value = evt.Value
sFit = Fit.getInstance()
sFit.changeMutatedValue(m, value)
if self.timer:
self.timer.Stop()
self.timer = None
self.timer = wx.CallLater(1000, self.callLater)
def callLater(self):
self.timer = None
print("recalc fit")
sFit = Fit.getInstance()
sFit.refreshFit(self.activeFit)
# todo BUG: if fit is not currently active, this causes the changed fit to show...?
wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitID=self.activeFit))

View File

@@ -23,7 +23,7 @@ pyfalog = Logger(__name__)
class FitItem(SFItem.SFBrowserItem):
def __init__(self, parent, fitID=None, shipFittingInfo=("Test", "TestTrait", "cnc's avatar", 0, 0, None), shipID=None,
itemData=None,
itemData=None, graphicID=None,
id=wx.ID_ANY, pos=wx.DefaultPosition,
size=(0, 40), style=0):
@@ -51,7 +51,7 @@ class FitItem(SFItem.SFBrowserItem):
self.deleted = False
if shipID:
self.shipBmp = BitmapLoader.getBitmap(str(shipID), "renders")
self.shipBmp = BitmapLoader.getBitmap(str(graphicID), "renders")
if not self.shipBmp:
self.shipBmp = BitmapLoader.getBitmap("ship_no_image_big", "gui")

View File

@@ -18,7 +18,7 @@ pyfalog = Logger(__name__)
class ShipItem(SFItem.SFBrowserItem):
def __init__(self, parent, shipID=None, shipFittingInfo=("Test", "TestTrait", 2), itemData=None,
def __init__(self, parent, shipID=None, shipFittingInfo=("Test", "TestTrait", 2), itemData=None, graphicID=None,
id=wx.ID_ANY, pos=wx.DefaultPosition,
size=(0, 40), style=0):
SFItem.SFBrowserItem.__init__(self, parent, size=size)
@@ -36,8 +36,8 @@ class ShipItem(SFItem.SFBrowserItem):
self.fontSmall = wx.Font(fonts.SMALL, wx.SWISS, wx.NORMAL, wx.NORMAL)
self.shipBmp = None
if shipID:
self.shipBmp = BitmapLoader.getBitmap(str(shipID), "renders")
if graphicID:
self.shipBmp = BitmapLoader.getBitmap(str(graphicID), "renders")
if not self.shipBmp:
self.shipBmp = BitmapLoader.getBitmap("ship_no_image_big", "gui")

View File

@@ -43,7 +43,7 @@ class AmmoIcon(ViewColumn):
if stuff.charge is None:
return -1
else:
iconFile = stuff.charge.icon.iconFile if stuff.charge.icon else ""
iconFile = stuff.charge.iconID if stuff.charge.iconID else ""
if iconFile:
return self.fittingView.imageList.GetImageIndex(iconFile, "icons")
else:

View File

@@ -41,7 +41,7 @@ class AttributeDisplay(ViewColumn):
iconFile = "pg_small"
iconType = "gui"
else:
iconFile = info.icon.iconFile if info.icon else None
iconFile = info.iconID
iconType = "icons"
if iconFile:
self.imageId = fittingView.imageList.GetImageIndex(iconFile, iconType)

View File

@@ -35,10 +35,10 @@ class BaseIcon(ViewColumn):
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 "")
return self.loadIconFile(stuff.item.iconID or "")
item = getattr(stuff, "item", stuff)
return self.loadIconFile(item.icon.iconFile if item.icon else "")
return self.loadIconFile(item.iconID)
def loadIconFile(self, iconFile):
if iconFile:

View File

@@ -40,7 +40,7 @@ class MaxRange(ViewColumn):
info = sAttr.getAttributeInfo("maxRange")
self.info = info
if params["showIcon"]:
iconFile = info.icon.iconFile if info.icon else None
iconFile = info.iconID
if iconFile:
self.imageId = fittingView.imageList.GetImageIndex(iconFile, "icons")
self.bitmap = BitmapLoader.getBitmap(iconFile, "icons")

View File

@@ -41,7 +41,7 @@ class PropertyDisplay(ViewColumn):
iconFile = "pg_small"
iconType = "gui"
else:
iconFile = info.icon.iconFile if info.icon else None
iconFile = info.iconID if info.icon else None
iconType = "icons"
if iconFile:
self.imageId = fittingView.imageList.GetImageIndex(iconFile, iconType)

View File

@@ -156,7 +156,7 @@ class BaseImplantEditorView(wx.Panel):
currentMktGrp = sMkt.getMarketGroup(tree.GetItemData(parent))
items = sMkt.getItemsByMarketGroup(currentMktGrp)
for item in items:
iconId = self.addMarketViewImage(item.icon.iconFile)
iconId = self.addMarketViewImage(item.iconID)
tree.AppendItem(parent, item.name, iconId, data=item)
tree.SortChildren(parent)

View File

@@ -208,5 +208,6 @@ from gui.builtinContextMenus import ( # noqa: E402,F401
fighterAbilities,
boosterSideEffects,
commandFits,
tabbedFits
tabbedFits,
mutaplasmids,
)

View File

@@ -34,6 +34,9 @@ from gui.builtinItemStatsViews.itemDependants import ItemDependents
from gui.builtinItemStatsViews.itemEffects import ItemEffects
from gui.builtinItemStatsViews.itemAffectedBy import ItemAffectedBy
from gui.builtinItemStatsViews.itemProperties import ItemProperties
from gui.builtinItemStatsViews.itemMutator import ItemMutator
from eos.saveddata.module import Module
class ItemStatsDialog(wx.Dialog):
@@ -79,10 +82,8 @@ class ItemStatsDialog(wx.Dialog):
item = sMkt.getItem(victim.ID)
victim = None
self.context = itmContext
if item.icon is not None:
before, sep, after = item.icon.iconFile.rpartition("_")
iconFile = "%s%s%s" % (before, sep, "0%s" % after if len(after) < 2 else after)
itemImg = BitmapLoader.getBitmap(iconFile, "icons")
if item.iconID is not None:
itemImg = BitmapLoader.getBitmap(item.iconID, "icons")
if itemImg is not None:
self.SetIcon(wx.Icon(itemImg))
self.SetTitle("%s: %s%s" % ("%s Stats" % itmContext if itmContext is not None else "Stats", item.name,
@@ -163,6 +164,10 @@ class ItemStatsContainer(wx.Panel):
self.traits = ItemTraits(self.nbContainer, stuff, item)
self.nbContainer.AddPage(self.traits, "Traits")
if isinstance(stuff, Module) and stuff.isMutated:
self.mutator = ItemMutator(self.nbContainer, stuff, item)
self.nbContainer.AddPage(self.mutator, "Multiplasmid")
self.desc = ItemDescription(self.nbContainer, stuff, item)
self.nbContainer.AddPage(self.desc, "Description")

View File

@@ -130,8 +130,8 @@ class PyGauge(wx.Window):
return self._max_range
def Animate(self):
sFit = Fit.getInstance()
if sFit.serviceFittingOptions["enableGaugeAnimation"]:
#sFit = Fit.getInstance()
if True:
if not self._timer:
self._timer = wx.Timer(self, self._timer_id)
@@ -425,6 +425,13 @@ if __name__ == "__main__":
gauge.SetFractionDigits(1)
box.Add(gauge, 0, wx.ALL, 2)
gauge = PyGauge(self, font, size=(100, 5))
gauge.SetBackgroundColour(wx.Colour(52, 86, 98))
gauge.SetBarColour(wx.Colour(255, 128, 0))
gauge.SetValue(59)
gauge.SetFractionDigits(1)
box.Add(gauge, 0, wx.ALL, 2)
self.SetSizer(box)
self.Layout()

View File

@@ -236,10 +236,10 @@ class ShipBrowser(wx.Panel):
if self.filterShipsWithNoFits:
if fits > 0:
if filter_:
self.lpane.AddWidget(ShipItem(self.lpane, ship.ID, (ship.name, shipTrait, fits), ship.race))
self.lpane.AddWidget(ShipItem(self.lpane, ship.ID, (ship.name, shipTrait, fits), ship.race, ship.graphicID))
else:
if filter_:
self.lpane.AddWidget(ShipItem(self.lpane, ship.ID, (ship.name, shipTrait, fits), ship.race))
self.lpane.AddWidget(ShipItem(self.lpane, ship.ID, (ship.name, shipTrait, fits), ship.race, ship.graphicID))
self.raceselect.RebuildRaces(racesList)
@@ -335,8 +335,8 @@ class ShipBrowser(wx.Panel):
shipTrait = ship.traits.traitText if (ship.traits is not None) else "" # empty string if no traits
for ID, name, booster, timestamp, notes in fitList:
self.lpane.AddWidget(FitItem(self.lpane, ID, (shipName, shipTrait, name, booster, timestamp, notes), shipID))
for ID, name, booster, timestamp, notes, graphicID in fitList:
self.lpane.AddWidget(FitItem(self.lpane, ID, (shipName, shipTrait, name, booster, timestamp, notes), shipID, graphicID=graphicID))
self.lpane.RefreshList()
self.lpane.Thaw()
@@ -374,7 +374,7 @@ class ShipBrowser(wx.Panel):
self.lpane.AddWidget(
ShipItem(self.lpane, ship.ID, (ship.name, shipTrait, len(sFit.getFitsWithShip(ship.ID))),
ship.race))
ship.race, ship.graphicID))
for ID, name, shipID, shipName, booster, timestamp, notes in fitList:
ship = sMkt.getItem(shipID)
@@ -384,7 +384,7 @@ class ShipBrowser(wx.Panel):
shipTrait = ship.traits.traitText if (ship.traits is not None) else "" # empty string if no traits
self.lpane.AddWidget(FitItem(self.lpane, ID, (shipName, shipTrait, name, booster, timestamp, notes), shipID))
self.lpane.AddWidget(FitItem(self.lpane, ID, (shipName, shipTrait, name, booster, timestamp, notes), shipID, graphicID=ship.graphicID))
if len(ships) == 0 and len(fitList) == 0:
self.lpane.AddWidget(PFStaticText(self.lpane, label="No matching results."))
self.lpane.RefreshList(doFocus=False)
@@ -435,6 +435,7 @@ class ShipBrowser(wx.Panel):
fit[4]
),
shipItem.ID,
graphicID=shipItem.graphicID
))
self.lpane.RefreshList(doFocus=False)
self.lpane.Thaw()