Move the slider to another file (makes it easier to test), and adjust the logic so that the base value is always considered in the center, no matter the skew of the ranges

This commit is contained in:
blitzmann
2018-06-04 02:53:14 -04:00
parent b3acc8fd21
commit c9f555a860
2 changed files with 113 additions and 92 deletions

View File

@@ -0,0 +1,112 @@
import wx
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):
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
self.SliderMinValue = -100
self.SliderMaxValue = 100
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.SliderValue = self.slider.GetValue()
# The slkider 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
else:
mod = 1
# Get the slider value percentage as an absolute value
slider_mod = abs(self.SliderValue) / 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 vale, 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(newValue))
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, 200, .80, 1.5)
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
def OnCloseWindow(self, event):
self.Destroy()
if __name__ == "__main__":
app = wx.App()
frame = TestAttributeSlider(None, wx.ID_ANY)
frame.Show()
app.MainLoop()

View File

@@ -11,6 +11,7 @@ from eos.saveddata.module import Module
from eos.saveddata.ship import Ship
from eos.saveddata.citadel import Citadel
from eos.saveddata.fit import Fit
from .attributeSlider import AttributeSlider
import gui.mainFrame
from gui.contextMenu import ContextMenu
@@ -42,95 +43,3 @@ class ItemMutator(wx.Panel):
self.SetSizer(mainSizer)
self.Layout()
class AttributeSlider(wx.Panel):
# 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.mod = 100 # modifier for the underlying Slider (ensure we don't hit floats, which it doesn't support)
self.base_value = baseValue
self.UserMinValue = minMod
self.UserMaxValue = maxMod
self.UserValue = 1
self.SliderMinValue = self.UserMinValue * self.mod
self.SliderMaxValue = self.UserMaxValue * self.mod
self.SliderValue = self.UserValue * self.mod
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.UserValue * 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.SliderValue = self.slider.GetValue()
self.UserValue = self.SliderValue / self.mod
newValue = self.UserValue * self.base_value
if self.UserValue == 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((1 - self.UserValue) * -100))
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, 200, 0.20, 1.3)
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
def OnCloseWindow(self, event):
self.Destroy()
if __name__ == "__main__":
app = wx.App()
frame = TestAttributeSlider(None, wx.ID_ANY)
frame.Show()
app.MainLoop()