170 lines
6.5 KiB
Python
170 lines
6.5 KiB
Python
# 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 .itemAttributes import ItemParams
|
|
from gui.bitmap_loader import BitmapLoader
|
|
import gui.globalEvents as GE
|
|
import random
|
|
|
|
from logbook import Logger
|
|
|
|
pyfalog = Logger(__name__)
|
|
|
|
|
|
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):
|
|
baseValueFormated = m.attribute.unit.TranslateValue(m.baseValue)[0]
|
|
valueFormated = m.attribute.unit.TranslateValue(m.value)[0]
|
|
slider = AttributeSlider(self, baseValueFormated, m.minMod, m.maxMod, not m.highIsGood)
|
|
slider.SetValue(valueFormated, 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, ItemParams.FormatValue(*m.attribute.unit.TranslateValue(worse_range[0])))
|
|
range_low.SetForegroundColour(self.goodColor if worse_range[2] else self.badColor)
|
|
|
|
range_high = wx.StaticText(self, wx.ID_ANY, ItemParams.FormatValue(*m.attribute.unit.TranslateValue(better_range[0])))
|
|
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.refreshBtn = wx.Button(self, wx.ID_ANY, "Reset defaults", wx.DefaultPosition, wx.DefaultSize, 0)
|
|
bSizer.Add(self.refreshBtn, 0, wx.ALIGN_CENTER_VERTICAL)
|
|
self.refreshBtn.Bind(wx.EVT_BUTTON, self.resetMutatedValues)
|
|
|
|
self.randomBtn = wx.Button(self, wx.ID_ANY, "Random stats", wx.DefaultPosition, wx.DefaultSize, 0)
|
|
bSizer.Add(self.randomBtn, 0, wx.ALIGN_CENTER_VERTICAL)
|
|
self.randomBtn.Bind(wx.EVT_BUTTON, self.randomMutatedValues)
|
|
|
|
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
|
|
value = m.attribute.unit.ComplicateValue(value)
|
|
sFit = Fit.getInstance()
|
|
|
|
sFit.changeMutatedValue(m, value)
|
|
if self.timer:
|
|
self.timer.Stop()
|
|
self.timer = None
|
|
|
|
for x in self.Parent.Children:
|
|
if isinstance(x, ItemParams):
|
|
x.RefreshValues(None)
|
|
break
|
|
self.timer = wx.CallLater(1000, self.callLater)
|
|
|
|
def resetMutatedValues(self, evt):
|
|
sFit = Fit.getInstance()
|
|
|
|
for slider, m in self.event_mapping.items():
|
|
value = sFit.changeMutatedValue(m, m.baseValue)
|
|
value = m.attribute.unit.TranslateValue(value)[0]
|
|
slider.SetValue(value)
|
|
|
|
evt.Skip()
|
|
|
|
def randomMutatedValues(self, evt):
|
|
sFit = Fit.getInstance()
|
|
|
|
for slider, m in self.event_mapping.items():
|
|
value = random.uniform(m.minValue, m.maxValue)
|
|
value = sFit.changeMutatedValue(m, value)
|
|
value = m.attribute.unit.TranslateValue(value)[0]
|
|
slider.SetValue(value)
|
|
|
|
evt.Skip()
|
|
|
|
def callLater(self):
|
|
self.timer = None
|
|
sFit = Fit.getInstance()
|
|
|
|
# recalc the fit that this module affects. This is not necessarily the currently active fit
|
|
sFit.refreshFit(self.activeFit)
|
|
|
|
mainFrame = gui.mainFrame.MainFrame.getInstance()
|
|
activeFit = mainFrame.getActiveFit()
|
|
|
|
if activeFit != self.activeFit:
|
|
# if we're no longer on the fit this module is affecting, simulate a "switch fit" so that the active fit
|
|
# can be recalculated (if needed)
|
|
sFit.switchFit(activeFit)
|
|
|
|
# Send signal to GUI to update stats with current active fit
|
|
wx.PostEvent(mainFrame, GE.FitChanged(fitID=activeFit))
|