diff --git a/gui/attribute_gauge.py b/gui/attribute_gauge.py index e73e0461d..7eea0619e 100644 --- a/gui/attribute_gauge.py +++ b/gui/attribute_gauge.py @@ -9,18 +9,17 @@ from gui.utils import anim_effects 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) + def __init__( + self, parent, max_range=100, animate=True, leading_edge=True, + edge_on_neutral=True, guide_lines=False, size=(-1, 30), *args, **kwargs + ): + super().__init__(parent, size=size, *args, **kwargs) 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 @@ -29,8 +28,6 @@ class AttributeGauge(wx.Window): self._max_range = max_range self._value = 0 - self._fraction_digits = 0 - self._timer_id = wx.NewId() self._timer = None @@ -44,14 +41,6 @@ class AttributeGauge(wx.Window): 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) @@ -68,51 +57,17 @@ class AttributeGauge(wx.Window): 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 @@ -134,6 +89,11 @@ class AttributeGauge(wx.Window): self._anim_value = self._percentage self.Refresh() + def FreezeAnimation(self): + self._animate = False + if self._timer: + self._timer.Stop() + def SetRange(self, range, reinit=False, animate=True): """ Sets the range of the gauge. The gauge length is its @@ -231,51 +191,50 @@ class AttributeGauge(wx.Window): 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 + # 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 + 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) + # 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 + # 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)) + # 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) + # 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)) + 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 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) + 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: - 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) + dc.DrawRectangle(max(padding - 1, 1), 1, 1, rect.height) def OnTimer(self, event): old_value = self._old_percentage diff --git a/gui/builtinItemStatsViews/attributeSlider.py b/gui/builtinItemStatsViews/attributeSlider.py index 159981a82..300599f2a 100644 --- a/gui/builtinItemStatsViews/attributeSlider.py +++ b/gui/builtinItemStatsViews/attributeSlider.py @@ -163,111 +163,3 @@ if __name__ == "__main__": 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)) diff --git a/gui/builtinItemStatsViews/itemMutator.py b/gui/builtinItemStatsViews/itemMutator.py index 3472a323f..1f8d2f1b7 100644 --- a/gui/builtinItemStatsViews/itemMutator.py +++ b/gui/builtinItemStatsViews/itemMutator.py @@ -61,8 +61,8 @@ class ItemMutatorPanel(wx.Panel): self.SetSizer(mainSizer) self.Layout() - def submitMutationChanges(self): - self.mutaList.submitMutationChanges() + def OnWindowClose(self): + self.mutaList.OnWindowClose() class ItemMutatorList(wx.ScrolledWindow): @@ -211,7 +211,8 @@ class ItemMutatorList(wx.ScrolledWindow): slider.SetValue(value) evt.Skip() - def submitMutationChanges(self): + def OnWindowClose(self): + # Submit mutation changes fit = Fit.getInstance().getFit(self.carryingFitID) if self.mod in fit.modules: currentMutation = {} @@ -223,6 +224,9 @@ class ItemMutatorList(wx.ScrolledWindow): position=fit.modules.index(self.mod), mutation=currentMutation, oldMutation=self.initialMutations)) + # Stop animations to prevent crashes when window is closed while it's in progress + for slider in self.event_mapping: + slider.slider.FreezeAnimation() def callLater(self): self.timer = None diff --git a/gui/itemStats.py b/gui/itemStats.py index b17cea954..6d3ec2679 100644 --- a/gui/itemStats.py +++ b/gui/itemStats.py @@ -129,12 +129,12 @@ class ItemStatsDialog(wx.Dialog): self.SetSize(size) self.parentWnd.RegisterStatsWindow(self) - self.Show() - + self.Bind(wx.EVT_CLOSE, self.OnClose) self.Bind(wx.EVT_CHAR_HOOK, self.kbEvent) - self.Bind(wx.EVT_CLOSE, self.closeEvent) self.Bind(wx.EVT_ACTIVATE, self.OnActivate) + self.Show() + def OnActivate(self, event): self.parentWnd.SetActiveStatsWindow(self) @@ -142,21 +142,18 @@ class ItemStatsDialog(wx.Dialog): keycode = event.GetKeyCode() mstate = wx.GetMouseState() if keycode == wx.WXK_ESCAPE and mstate.GetModifiers() == wx.MOD_NONE: - self.closeWindow() + self.Close() return event.Skip() - def closeEvent(self, event): - self.container.onParentClose() - self.closeWindow() - event.Skip() - - def closeWindow(self): + def OnClose(self, event): + self.container.OnWindowClose() if self.dlgOrder == ItemStatsDialog.counter: ItemStatsDialog.counter -= 1 self.parentWnd.UnregisterStatsWindow(self) self.Destroy() + class ItemStatsContainer(wx.Panel): def __init__(self, parent, stuff, item, context=None): @@ -218,7 +215,7 @@ class ItemStatsContainer(wx.Panel): if tab != -1: self.nbContainer.SetSelection(tab) - def onParentClose(self): + def OnWindowClose(self): mutaPanel = getattr(self, 'mutator', None) if mutaPanel is not None: - mutaPanel.submitMutationChanges() + mutaPanel.OnWindowClose()