From 6c317d56eee016aa9aba60d0dce50378d803ff76 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Mon, 12 Jun 2017 20:45:58 -0400 Subject: [PATCH] touch up the gauge code --- gui/builtinStatsViews/resistancesViewFull.py | 2 +- gui/builtinStatsViews/resourcesViewFull.py | 2 +- gui/pyfa_gauge.py | 419 +++++++++++++++++ gui/pygauge.py | 448 ------------------- 4 files changed, 421 insertions(+), 450 deletions(-) create mode 100644 gui/pyfa_gauge.py delete mode 100644 gui/pygauge.py diff --git a/gui/builtinStatsViews/resistancesViewFull.py b/gui/builtinStatsViews/resistancesViewFull.py index a06e4e444..7a6cc6ba9 100644 --- a/gui/builtinStatsViews/resistancesViewFull.py +++ b/gui/builtinStatsViews/resistancesViewFull.py @@ -21,7 +21,7 @@ import wx from gui.statsView import StatsView from gui.bitmap_loader import BitmapLoader -from gui.pygauge import PyGauge +from gui.pyfa_gauge import PyGauge from gui.utils.numberFormatter import formatAmount import gui.mainFrame import gui.globalEvents as GE diff --git a/gui/builtinStatsViews/resourcesViewFull.py b/gui/builtinStatsViews/resourcesViewFull.py index 2a8cb0196..bfc256fa3 100644 --- a/gui/builtinStatsViews/resourcesViewFull.py +++ b/gui/builtinStatsViews/resourcesViewFull.py @@ -21,7 +21,7 @@ import wx from gui.statsView import StatsView from gui.bitmap_loader import BitmapLoader -from gui.pygauge import PyGauge +from gui.pyfa_gauge import PyGauge import gui.mainFrame from gui.chrome_tabs import EVT_NOTEBOOK_PAGE_CHANGED diff --git a/gui/pyfa_gauge.py b/gui/pyfa_gauge.py new file mode 100644 index 000000000..ef436d74f --- /dev/null +++ b/gui/pyfa_gauge.py @@ -0,0 +1,419 @@ +#=============================================================================== +# PyfaGauge is a generic Gauge implementation tailored for pyfa (the Python +# Fitting Assistant). It uses the easeOutQuad equation from +# caurina.transitions.Tweener to do animations +# +# ToDo: make SetGradient(from and not dependant on value) +# ToDo: fix 0 range (currently resets range to 0.01, but this causes problems if +# we really set range at 0.01). Perhaps make it -1 and test percentage as +# a negativeor something. +# ToDo: possibly devise a way to determine transition percents on init +# (currently hardcoded) +# +#=============================================================================== + +import copy +import wx + +from gui.utils import color as color_utils +from gui.utils import draw, anim_effects + + +class PyGauge(wx.Window): + def __init__(self, parent, font, max_range=100, size=(-1, 30), *args, + **kargs): + + super().__init__(parent, size=size, *args, **kargs) + + self._size = size + + self._border_colour = wx.BLACK + self._bar_colour = None + self._bar_gradient = None + + 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._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.gradient_effect = -35 + + self._percentage = 0 + self._old_percentage = 0 + self._show_remaining = False + + self.font = font + + 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_ERASE_BACKGROUND, self.OnEraseBackground) + self.Bind(wx.EVT_TIMER, self.OnTimer) + self.Bind(wx.EVT_ENTER_WINDOW, self.OnWindowEnter) + self.Bind(wx.EVT_LEAVE_WINDOW, self.OnWindowLeave) + + 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: wx.Colour): + self._border_colour = colour + + def GetBarColour(self): + return self._bar_colour + + def SetBarColour(self, colour: wx.Colour=None): + self._bar_colour = colour + + def SetFractionDigits(self, digits): + self._fraction_digits = digits + + def GetBarGradient(self): + raise NotImplemented() + + def SetBarGradient(self, gradient=None): + raise NotImplemented() + + def GetBorderPadding(self) -> int: + 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 not self._timer: + self._timer = wx.Timer(self, self._timer_id) + + self._anim_step = 0 + self._timer.Start(self._period) + + 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. """ + if self._value == value: + return + + self._old_percentage = self._percentage + self._value = value + + if value < 0: + self._value = 0 + + 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. """ + + self.SetRange(range, reinit, animate=False) + self.SetValue(value, animate=False) + + self.Animate() + self._tooltip.SetTip("%.2f/%.2f" % + (self._value, + self._max_range if self._max_range > 0.01 else 0)) + + def OnEraseBackground(self, event): + pass + + def OnPaint(self, event): + dc = wx.BufferedPaintDC(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 self.GetBarColour(): + # if we have a bar color set, then we will use this + + colour = self.GetBarColour() + dc.SetBrush(wx.Brush(colour)) + dc.SetPen(wx.Pen(colour)) + + # calculate width of bar and draw it + if value > 100: + w = rect.width + else: + w = rect.width * (float(value) / 100) + + r = copy.copy(rect) + r.width = w + dc.DrawRectangle(r) + else: + # if bar color is not set, then we use pre-defined transitions + # for the colors based on the percentage value + + # calculate width of bar + if value > 100: + w = rect.width + else: + w = rect.width * (float(value) / 100) + r = copy.copy(rect) + r.width = w + + # determine transition range number and calculate xv (which is the + # progress between the two transition ranges) + pv = value + if pv <= 100: + xv = pv/100 + transition = 0 + elif pv <= 101: + xv = pv - 100 + transition = 1 + elif pv <= 103: + xv = (pv - 101)/2 + transition = 2 + elif pv <= 105: + xv = (pv - 103)/2 + transition = 3 + else: + pv = 106 + xv = pv - 100 + transition = -1 + + if transition != -1: + start_color, end_color = self.transition_colors[transition] + color = color_utils.CalculateTransition(start_color, end_color, + xv) + else: + color = wx.Colour(191, 48, 48) # dark red + + color_factor = self.gradient_effect / 100 + mid_factor = (self.gradient_effect / 2) / 100 + + if self.gradient_effect > 0: + gradient_color = color_utils.Brighten(color, color_factor) + gradient_mid = color_utils.Brighten(color, mid_factor) + else: + gradient_color = color_utils.Darken(color, color_factor * -1) + gradient_mid = color_utils.Darken(color, mid_factor * -1) + + # draw bar + gradient_bitmap = draw.DrawGradientBar( + r.width, + r.height, + gradient_mid, + color, + gradient_color + ) + dc.DrawBitmap(gradient_bitmap, r.left, r.top) + + # font stuff begins here + dc.SetFont(self.font) + + # determine shadow position + r = copy.copy(rect) + r.left += 1 + r.top += 1 + + if self._max_range == 0.01 and self._value > 0: + format = u'\u221e' # infinity symbol + # drop shadow + dc.SetTextForeground(wx.Colour(80, 80, 80)) # dark grey + dc.DrawLabel(format, r, wx.ALIGN_CENTER) + # text + dc.SetTextForeground(wx.WHITE) + dc.DrawLabel(format, rect, wx.ALIGN_CENTER) + else: + if not self.GetBarColour() and self._show_remaining: + # we only do these for gradients with mouse over + range = self._max_range if self._max_range > 0.01 else 0 + value = range - self._value + if value < 0: + label = "over" + value = -value + else: + label = "left" + format = "{0:." + str(self._fraction_digits) + "f} " + label + else: + format = "{0:." + str(self._fraction_digits) + "f}%" + + # drop shadow + dc.SetTextForeground(wx.Colour(80, 80, 80)) + dc.DrawLabel(format.format(value), r, wx.ALIGN_CENTER) + # text + dc.SetTextForeground(wx.WHITE) + dc.DrawLabel(format.format(value), rect, wx.ALIGN_CENTER) + + 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__": + def frange(x, y, jump): + while x < y: + yield x + x += jump + + class TestPanel(wx.Panel): + def __init__(self, parent, size=(500, 500)): + wx.Panel.__init__(self, parent, size=size) + box = wx.BoxSizer(wx.VERTICAL) + + # tests the colors of transition based on percentage used + # list of test values (from 99 -> 106 in increments of 0.5) + tests = [x for x in frange(99, 106.5, .5)] + + font = wx.Font(9, wx.SWISS, wx.NORMAL, wx.NORMAL, False) + + for i, value in enumerate(tests): + self.gauge = PyGauge(self, font, size=(100, 25)) + self.gauge.SetValueRange(value, 100) + self.gauge.SetFractionDigits(2) + box.Add(self.gauge, 0, wx.ALL, 2) + + gauge = PyGauge(self, font, size=(100, 25)) + gauge.SetBackgroundColour(wx.Colour(52, 86, 98)) + gauge.SetBarColour(wx.Colour(38, 133, 198)) + gauge.SetValue(59) + gauge.SetFractionDigits(1) + box.Add(gauge, 0, wx.ALL, 2) + + self.SetSizer(box) + self.Layout() + + # see animation going backwards with last gauge + wx.CallLater(2000, self.ChangeValues) + + def ChangeValues(self): + self.gauge.SetValueRange(4, 100) + + 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 = TestPanel(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 Chrome Tabs") + top.Show() + app.MainLoop() + diff --git a/gui/pygauge.py b/gui/pygauge.py deleted file mode 100644 index 6c08ea209..000000000 --- a/gui/pygauge.py +++ /dev/null @@ -1,448 +0,0 @@ -# --------------------------------------------------------------------------------- # -# PYFAGAUGE wxPython IMPLEMENTATION -# -# Darriele, @ 08/30/2010 -# Updated: 09/07/2010 -# Based on AWG : pygauge code -# --------------------------------------------------------------------------------- # - -""" -PyfaGauge is a generic Gauge implementation tailored for PYFA (Python Fitting Assistant) -It uses the easeOutQuad equation from caurina.transitions.Tweener to do the animation stuff -""" - -# noinspection PyPackageRequirements -import wx -import copy - -from gui.utils import color -import gui.utils.draw as drawUtils -import gui.utils.anim_effects as animEffects -import gui.utils.fonts as fonts - -from service.fit import Fit - - -class PyGauge(wx.PyWindow): - """ - This class provides a visual alternative for `wx.Gauge`. It currently - only support determinant mode (see SetValue and SetRange) - """ - - def __init__(self, parent, id=wx.ID_ANY, range=100, pos=wx.DefaultPosition, - size=(-1, 30), style=0): - """ - Default class constructor. - - :param `parent`: parent window. Must not be ``None``; - :param `id`: window identifier. A value of -1 indicates a default value; - :param `pos`: the control position. A value of (-1, -1) indicates a default position, - chosen by either the windowing system or wxPython, depending on platform; - :param `size`: the control size. A value of (-1, -1) indicates a default size, - chosen by either the windowing system or wxPython, depending on platform. - """ - - wx.PyWindow.__init__(self, parent, id, pos, size, style) - - self._size = size - - self._border_colour = wx.BLACK - self._barColour = self._barColourSorted = [wx.Colour(212, 228, 255)] - self._barGradient = self._barGradientSorted = None - - self._border_padding = 0 - self._range = range - self._value = 0 - - self._fractionDigits = 0 - - self._timerId = wx.NewId() - self._timer = None - - self._oldValue = 0 - - self._animDuration = 500 - self._animStep = 0 - self._period = 20 - self._animValue = 0 - self._animDirection = 0 - self.animEffect = animEffects.OUT_QUAD - - self.transitionsColors = [(wx.Colour(191, 191, 191, 255), wx.Colour(96, 191, 0, 255)), - (wx.Colour(191, 167, 96, 255), wx.Colour(255, 191, 0, 255)), - (wx.Colour(255, 191, 0, 255), wx.Colour(255, 128, 0, 255)), - (wx.Colour(255, 128, 0, 255), wx.Colour(255, 0, 0, 255))] - self.gradientEffect = -35 - - self._percentage = 0 - self._oldPercentage = 0 - self._showRemaining = False - - self.font = wx.Font(fonts.NORMAL, wx.SWISS, wx.NORMAL, wx.NORMAL, False) - - self.SetBarGradient((wx.Colour(119, 119, 119), wx.Colour(153, 153, 153))) - self.SetBackgroundColour(wx.Colour(51, 51, 51)) - self._tooltip = wx.ToolTip("") - self.SetToolTip(self._tooltip) - self._tooltip.SetTip("0.00/100.00") - - self.Bind(wx.EVT_PAINT, self.OnPaint) - self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground) - self.Bind(wx.EVT_TIMER, self.OnTimer) - self.Bind(wx.EVT_ENTER_WINDOW, self.OnWindowEnter) - self.Bind(wx.EVT_LEAVE_WINDOW, self.OnWindowLeave) - - def OnWindowEnter(self, event): - self._showRemaining = True - self.Refresh() - - def OnWindowLeave(self, event): - self._showRemaining = False - self.Refresh() - - def DoGetBestSize(self): - """ - Overridden base class virtual. Determines the best size of the - button based on the label and bezel size. - """ - - return wx.Size(self._size[0], self._size[1]) - - def GetBorderColour(self): - return self._border_colour - - def SetBorderColour(self, colour): - self._border_colour = colour - - SetBorderColor = SetBorderColour - GetBorderColor = GetBorderColour - - def GetBarColour(self): - return self._barColour[0] - - def SetBarColour(self, colour): - if not isinstance(colour, list): - self._barColour = [colour] - else: - self._barColour = list(colour) - - SetBarColor = SetBarColour - GetBarColor = GetBarColour - - def SetFractionDigits(self, digits): - self._fractionDigits = digits - - def GetBarGradient(self): - """ Returns a tuple containing the gradient start and end colours. """ - - if self._barGradient is None: - return None - - return self._barGradient[0] - - def SetBarGradient(self, gradient=None): - """ - Sets the bar gradient. This overrides the BarColour. - - :param gradient: a tuple containing the gradient start and end colours. - """ - if gradient is None: - self._barGradient = None - else: - if not isinstance(gradient, list): - self._barGradient = [gradient] - else: - self._barGradient = list(gradient) - - def GetBorderPadding(self): - """ Gets the border padding. """ - - return self._border_padding - - def SetBorderPadding(self, padding): - """ - Sets the border padding. - - :param padding: pixels between the border and the progress bar. - """ - - self._border_padding = padding - - def GetRange(self): - """ Returns the maximum value of the gauge. """ - - return self._range - - def Animate(self): - sFit = Fit.getInstance() - if sFit.serviceFittingOptions["enableGaugeAnimation"]: - if not self._timer: - self._timer = wx.Timer(self, self._timerId) - self._animStep = 0 - self._timer.Start(self._period) - else: - self._animValue = self._percentage - self.Refresh() - - def SetRange(self, range, reinit=False): - """ - Sets the range of the gauge. The gauge length is its - value as a proportion of the range. - - :param reinit: - :param range: The maximum value of the gauge. - """ - - if self._range == range: - return - - range_ = float(range) - - if range_ <= 0: - self._range = 0.01 - else: - self._range = range_ - - if reinit is False: - self._oldPercentage = self._percentage - self._percentage = (self._value / self._range) * 100 - else: - self._oldPercentage = self._percentage - self._percentage = 0 - self._value = 0 - - self.Animate() - - self._tooltip.SetTip("%.2f/%.2f" % (self._value, self._range if self._range > 0.01 else 0)) - - def GetValue(self): - """ Returns the current position of the gauge. """ - - return self._value - - def SetValue(self, value): - """ Sets the current position of the gauge. """ - if self._value == value: - return - - value = float(value) - self._oldPercentage = self._percentage - self._value = value - if value < 0: - self._value = 0 - self._percentage = (self._value / self._range) * 100 - - self.Animate() - - self._tooltip.SetTip("%.2f/%.2f" % (self._value, self._range)) - - def SetValueRange(self, value, range, reinit=False): - if self._value == value and self._range == range: - return - - range_ = float(range) - - if range_ <= 0: - self._range = 0.01 - else: - self._range = range_ - - value = float(value) - - self._value = value - if value < 0: - self._value = float(0) - - if reinit is False: - self._oldPercentage = self._percentage - self._percentage = (self._value / self._range) * 100 - - else: - self._oldPercentage = self._percentage - self._percentage = 0 - - self.Animate() - self._tooltip.SetTip("%.2f/%.2f" % (self._value, self._range if self._range > 0.01 else 0)) - - @staticmethod - def OnEraseBackground(event): - """ - Handles the ``wx.EVT_ERASE_BACKGROUND`` event for L{PyGauge}. - - :param event: a `wx.EraseEvent` event to be processed. - - :note: This method is intentionally empty to reduce flicker. - """ - - pass - - def OnPaint(self, event): - """ - Handles the ``wx.EVT_PAINT`` event for L{PyGauge}. - - :param event: a `wx.PaintEvent` event to be processed. - """ - - dc = wx.BufferedPaintDC(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.DrawRectangleRect(rect) - - value = self._percentage - if self._timer: - if self._timer.IsRunning(): - value = self._animValue - - if self._border_colour: - dc.SetPen(wx.Pen(self.GetBorderColour())) - dc.DrawRectangleRect(rect) - pad = 1 + self.GetBorderPadding() - rect.Deflate(pad, pad) - - if self.GetBarGradient(): - - if value > 100: - w = rect.width - else: - w = rect.width * (float(value) / 100) - r = copy.copy(rect) - r.width = w - - if r.width > 0: - # If we draw it with zero width, GTK throws errors. This way, - # only draw it if the gauge will actually show something. - # We stick other calculations in this block to avoid wasting - # time on them if not needed. See GH issue #282 - - pv = value - - if pv <= 100: - xv = pv / 100 - transition = 0 - - elif pv <= 101: - xv = pv - 100 - transition = 1 - - elif pv <= 103: - xv = (pv - 101) / 2 - transition = 2 - - elif pv <= 105: - xv = (pv - 103) / 2 - transition = 3 - - else: - pv = 106 - xv = pv - 100 - transition = -1 - - if transition != -1: - colorS, colorE = self.transitionsColors[transition] - color = color.CalculateTransitionColor(colorS, colorE, xv) - else: - color = wx.Colour(191, 48, 48) - - if self.gradientEffect > 0: - gcolor = color.BrightenColor(color, float(self.gradientEffect) / 100) - gMid = color.BrightenColor(color, float(self.gradientEffect / 2) / 100) - else: - gcolor = color.DarkenColor(color, float(-self.gradientEffect) / 100) - gMid = color.DarkenColor(color, float(-self.gradientEffect / 2) / 100) - - gBmp = drawUtils.DrawGradientBar(r.width, r.height, gMid, color, gcolor) - dc.DrawBitmap(gBmp, r.left, r.top) - - else: - colour = self.GetBarColour() - dc.SetBrush(wx.Brush(colour)) - dc.SetPen(wx.Pen(colour)) - if value > 100: - w = rect.width - else: - w = rect.width * (float(value) / 100) - r = copy.copy(rect) - r.width = w - dc.DrawRectangleRect(r) - - dc.SetFont(self.font) - - r = copy.copy(rect) - r.left += 1 - r.top += 1 - if self._range == 0.01 and self._value > 0: - formatStr = '\u221e' - dc.SetTextForeground(wx.Colour(80, 80, 80)) - dc.DrawLabel(formatStr, r, wx.ALIGN_CENTER) - - dc.SetTextForeground(wx.Colour(255, 255, 255)) - dc.DrawLabel(formatStr, rect, wx.ALIGN_CENTER) - else: - if self.GetBarGradient() and self._showRemaining: - range = self._range if self._range > 0.01 else 0 - value = range - self._value - if value < 0: - label = "over" - value = -value - else: - label = "left" - formatStr = "{0:." + str(self._fractionDigits) + "f} " + label - - else: - formatStr = "{0:." + str(self._fractionDigits) + "f}%" - - dc.SetTextForeground(wx.Colour(80, 80, 80)) - dc.DrawLabel(formatStr.format(value), r, wx.ALIGN_CENTER) - - dc.SetTextForeground(wx.Colour(255, 255, 255)) - dc.DrawLabel(formatStr.format(value), rect, wx.ALIGN_CENTER) - - def OnTimer(self, event): - """ - Handles the ``wx.EVT_TIMER`` event for L{PyfaGauge}. - - :param event: a timer event - """ - oldValue = self._oldPercentage - value = self._percentage - start = 0 - - direction = 1 if oldValue < value else -1 - - end = direction * (value - oldValue) - - self._animDirection = direction - step = self.animEffect(self._animStep, start, end, self._animDuration) - - self._animStep += self._period - - if self._timerId == event.GetId(): - stop_timer = False - - if self._animStep > self._animDuration: - stop_timer = True - - if direction == 1: - if (oldValue + step) < value: - self._animValue = oldValue + step - else: - stop_timer = True - else: - if (oldValue - step) > value: - self._animValue = oldValue - step - - else: - stop_timer = True - - if stop_timer: - self._timer.Stop() - - self.Refresh()