From 58b422a6d9ac6607a0c23f7a5e0ddb4e35c3346f Mon Sep 17 00:00:00 2001 From: blitzmann Date: Tue, 5 Jun 2018 09:02:15 -0400 Subject: [PATCH] Add a bunch of tests, and get it looking just right. Still need to do some general cleanup --- gui/attribute_gauge.py | 226 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 199 insertions(+), 27 deletions(-) diff --git a/gui/attribute_gauge.py b/gui/attribute_gauge.py index d667b44c1..6755e3e1f 100644 --- a/gui/attribute_gauge.py +++ b/gui/attribute_gauge.py @@ -15,6 +15,7 @@ import copy import wx +import math from gui.utils import color as color_utils from gui.utils import draw, anim_effects @@ -22,17 +23,21 @@ from service.fit import Fit class AttributeGauge(wx.Window): - def __init__(self, parent, max_range=100, size=(-1, 30), *args, + def __init__(self, parent, max_range=100, animate=True, leading_edge=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 = True + self._border_padding = 0 self._max_range = max_range self._value = 0 @@ -44,6 +49,7 @@ class AttributeGauge(wx.Window): self._oldValue = 0 + self._animate = animate self._anim_duration = 500 self._anim_step = 0 self._period = 20 @@ -59,6 +65,9 @@ class AttributeGauge(wx.Window): (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 @@ -128,8 +137,7 @@ class AttributeGauge(wx.Window): return self._max_range def Animate(self): - #sFit = Fit.getInstance() - if False: + if self._animate: if not self._timer: self._timer = wx.Timer(self, self._timer_id) @@ -172,6 +180,8 @@ class AttributeGauge(wx.Window): def SetValue(self, value, animate=True): """ Sets the current position of the gauge. """ + + print ("="*20, self._percentage) if self._value == value: return @@ -197,8 +207,6 @@ class AttributeGauge(wx.Window): value = float(value) self._value = value - if value < 0: - self._value = float(0) if reinit is False: self._old_percentage = self._percentage @@ -226,7 +234,7 @@ class AttributeGauge(wx.Window): dc.DrawRectangle(rect) - value = abs(self._percentage) + value = self._percentage if self._timer: if self._timer.IsRunning(): @@ -238,27 +246,50 @@ class AttributeGauge(wx.Window): pad = 1 + self.GetBorderPadding() rect.Deflate(pad, pad) - if self.GetBarColour(): + if self.GetBarColour(): # todo, get rid of this # 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) - colour = self.GetBarColour() dc.SetBrush(wx.Brush(colour)) dc.SetPen(wx.Pen(colour)) - half = (rect.width / 2) - # calculate width of bar and draw it - w = (rect.width * (value / 100)) / 2 - w = min(w, half) + # 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 - print(half, w) - - if self._percentage >= 0: - padding = half + if value >= 0: + padding = (half if is_even else math.ceil(half-1)) + 1 + dc.DrawRectangle(padding, 1, w, rect.height) else: - padding = min(half-w, half) + padding = half - w + 1 if is_even else math.ceil(half)-(w-1) + dc.DrawRectangle(padding, 1, w, rect.height) - #r = copy.copy(rect) - dc.DrawRectangle(padding+1, 1, w, rect.height) + if self.leading_edge and 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 @@ -301,6 +332,8 @@ class AttributeGauge(wx.Window): if __name__ == "__main__": + import random + def frange(x, y, jump): while x < y: yield x @@ -313,21 +346,160 @@ if __name__ == "__main__": font = wx.Font(9, wx.SWISS, wx.NORMAL, wx.NORMAL, False) - gauge = AttributeGauge(self, size=(100, 25)) + self.gauge = gauge = AttributeGauge(self, size=(204, 4)) gauge.SetBackgroundColour(wx.Colour(52, 86, 98)) gauge.SetBarColour(wx.Colour(255, 128, 0)) - gauge.SetValue(-25) + gauge.SetValue(100) gauge.SetFractionDigits(1) - box.Add(gauge, 0, wx.ALL, 2) + 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() - # see animation going backwards with last gauge - #wx.CallLater(2000, self.ChangeValues) + self.animTimer = wx.Timer(self, wx.NewId()) + self.Bind(wx.EVT_TIMER, self.OnTimer) - def ChangeValues(self): - self.gauge.SetValueRange(4, 100) + 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)): @@ -339,6 +511,6 @@ if __name__ == "__main__": self.SetSizer(main_sizer) app = wx.App(redirect=False) # Error messages go to popup window - top = Frame("Test Chrome Tabs") + top = Frame("Test Attribute Bar") top.Show() app.MainLoop()