Merge branch 'issue/1645'
This commit is contained in:
504
gui/attribute_gauge.py
Normal file
504
gui/attribute_gauge.py
Normal 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()
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
78
gui/builtinContextMenus/mutaplasmids.py
Normal file
78
gui/builtinContextMenus/mutaplasmids.py
Normal 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()
|
||||
@@ -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
|
||||
|
||||
248
gui/builtinItemStatsViews/attributeSlider.py
Normal file
248
gui/builtinItemStatsViews/attributeSlider.py
Normal 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))
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
120
gui/builtinItemStatsViews/itemMutator.py
Normal file
120
gui/builtinItemStatsViews/itemMutator.py
Normal 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))
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -208,5 +208,6 @@ from gui.builtinContextMenus import ( # noqa: E402,F401
|
||||
fighterAbilities,
|
||||
boosterSideEffects,
|
||||
commandFits,
|
||||
tabbedFits
|
||||
tabbedFits,
|
||||
mutaplasmids,
|
||||
)
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user