Fix pygauges to draw labels correctly
This commit is contained in:
162
gui/pygauge.py
162
gui/pygauge.py
@@ -9,11 +9,11 @@
|
|||||||
# 1. Indeterminate mode (see wx.Gauge)
|
# 1. Indeterminate mode (see wx.Gauge)
|
||||||
# 2. Vertical bar
|
# 2. Vertical bar
|
||||||
# 3. Bitmap support (bar, background)
|
# 3. Bitmap support (bar, background)
|
||||||
# 4. UpdateFunction - Pass a function to PyGauge which will be called every X
|
# 4. UpdateFunction - Pass a function to PyGauge which will be called every X
|
||||||
# milliseconds and the value will be updated to the returned value.
|
# milliseconds and the value will be updated to the returned value.
|
||||||
# 5. Currently the full gradient is drawn from 0 to value. Perhaps the gradient
|
# 5. Currently the full gradient is drawn from 0 to value. Perhaps the gradient
|
||||||
# should be drawn from 0 to range and clipped at 0 to value.
|
# should be drawn from 0 to range and clipped at 0 to value.
|
||||||
# 6. Add a label?
|
# 6. Add a label?
|
||||||
#
|
#
|
||||||
# For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please
|
# For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please
|
||||||
# Write To The:
|
# Write To The:
|
||||||
@@ -30,7 +30,7 @@ Description
|
|||||||
===========
|
===========
|
||||||
|
|
||||||
PyGauge supports the determinate mode functions as wxGauge and adds an Update function
|
PyGauge supports the determinate mode functions as wxGauge and adds an Update function
|
||||||
which takes a value and a time parameter. The value is added to the current value over
|
which takes a value and a time parameter. The value is added to the current value over
|
||||||
a period of time milliseconds.
|
a period of time milliseconds.
|
||||||
|
|
||||||
Supported Platforms
|
Supported Platforms
|
||||||
@@ -42,7 +42,7 @@ PyGauge has been tested on the following platforms:
|
|||||||
License And Version
|
License And Version
|
||||||
===================
|
===================
|
||||||
|
|
||||||
PyGauge is distributed under the wxPython license.
|
PyGauge is distributed under the wxPython license.
|
||||||
|
|
||||||
Latest Revision: Andrea Gavana @ 14 Apr 2010, 12.00 GMT
|
Latest Revision: Andrea Gavana @ 14 Apr 2010, 12.00 GMT
|
||||||
|
|
||||||
@@ -53,11 +53,11 @@ import wx
|
|||||||
import copy
|
import copy
|
||||||
|
|
||||||
class PyGauge(wx.PyWindow):
|
class PyGauge(wx.PyWindow):
|
||||||
"""
|
"""
|
||||||
This class provides a visual alternative for `wx.Gauge`. It currently
|
This class provides a visual alternative for `wx.Gauge`. It currently
|
||||||
only support determinant mode (see SetValue and SetRange)
|
only support determinant mode (see SetValue and SetRange)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, parent, id=wx.ID_ANY, range=100, pos=wx.DefaultPosition,
|
def __init__(self, parent, id=wx.ID_ANY, range=100, pos=wx.DefaultPosition,
|
||||||
size=(-1,30), style=0):
|
size=(-1,30), style=0):
|
||||||
"""
|
"""
|
||||||
@@ -72,9 +72,9 @@ class PyGauge(wx.PyWindow):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
wx.PyWindow.__init__(self, parent, id, pos, size, style)
|
wx.PyWindow.__init__(self, parent, id, pos, size, style)
|
||||||
|
|
||||||
self._size = size
|
self._size = size
|
||||||
|
|
||||||
self._border_colour = wx.BLACK
|
self._border_colour = wx.BLACK
|
||||||
self._barColour = self._barColourSorted = [wx.Colour(212,228,255)]
|
self._barColour = self._barColourSorted = [wx.Colour(212,228,255)]
|
||||||
self._barGradient = self._barGradientSorted = None
|
self._barGradient = self._barGradientSorted = None
|
||||||
@@ -91,59 +91,59 @@ class PyGauge(wx.PyWindow):
|
|||||||
self.SetBarGradient((wx.Colour(153,153,153),wx.Colour(204,204,204)))
|
self.SetBarGradient((wx.Colour(153,153,153),wx.Colour(204,204,204)))
|
||||||
self.SetBackgroundColour(wx.Colour(102,102,102))
|
self.SetBackgroundColour(wx.Colour(102,102,102))
|
||||||
|
|
||||||
|
|
||||||
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
||||||
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
|
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
|
||||||
self.Bind(wx.EVT_TIMER, self.OnTimer)
|
self.Bind(wx.EVT_TIMER, self.OnTimer)
|
||||||
|
|
||||||
|
|
||||||
def DoGetBestSize(self):
|
def DoGetBestSize(self):
|
||||||
"""
|
"""
|
||||||
Overridden base class virtual. Determines the best size of the
|
Overridden base class virtual. Determines the best size of the
|
||||||
button based on the label and bezel size.
|
button based on the label and bezel size.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return wx.Size(self._size[0], self._size[1])
|
return wx.Size(self._size[0], self._size[1])
|
||||||
|
|
||||||
|
|
||||||
def GetBorderColour(self):
|
def GetBorderColour(self):
|
||||||
return self._border_colour
|
return self._border_colour
|
||||||
|
|
||||||
def SetBorderColour(self, colour):
|
def SetBorderColour(self, colour):
|
||||||
self._border_colour = colour
|
self._border_colour = colour
|
||||||
|
|
||||||
SetBorderColor = SetBorderColour
|
SetBorderColor = SetBorderColour
|
||||||
GetBorderColor = GetBorderColour
|
GetBorderColor = GetBorderColour
|
||||||
|
|
||||||
def GetBarColour(self):
|
def GetBarColour(self):
|
||||||
return self._barColour[0]
|
return self._barColour[0]
|
||||||
|
|
||||||
def SetBarColour(self, colour):
|
def SetBarColour(self, colour):
|
||||||
if type(colour) != type([]):
|
if type(colour) != type([]):
|
||||||
self._barColour = [colour]
|
self._barColour = [colour]
|
||||||
else:
|
else:
|
||||||
self._barColour = list(colour)
|
self._barColour = list(colour)
|
||||||
|
|
||||||
self.SortForDisplay()
|
self.SortForDisplay()
|
||||||
|
|
||||||
SetBarColor = SetBarColour
|
SetBarColor = SetBarColour
|
||||||
GetBarColor = GetBarColour
|
GetBarColor = GetBarColour
|
||||||
|
|
||||||
def SetSkipDigitsFlag(self,flag):
|
def SetSkipDigitsFlag(self,flag):
|
||||||
self._skipDigits=flag
|
self._skipDigits=flag
|
||||||
|
|
||||||
def GetBarGradient(self):
|
def GetBarGradient(self):
|
||||||
""" Returns a tuple containing the gradient start and end colours. """
|
""" Returns a tuple containing the gradient start and end colours. """
|
||||||
|
|
||||||
if self._barGradient == None:
|
if self._barGradient == None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return self._barGradient[0]
|
return self._barGradient[0]
|
||||||
|
|
||||||
def SetBarGradient(self, gradient = None):
|
def SetBarGradient(self, gradient = None):
|
||||||
"""
|
"""
|
||||||
Sets the bar gradient. This overrides the BarColour.
|
Sets the bar gradient. This overrides the BarColour.
|
||||||
|
|
||||||
:param `gradient`: a tuple containing the gradient start and end colours.
|
:param `gradient`: a tuple containing the gradient start and end colours.
|
||||||
"""
|
"""
|
||||||
if gradient == None:
|
if gradient == None:
|
||||||
@@ -153,57 +153,57 @@ class PyGauge(wx.PyWindow):
|
|||||||
self._barGradient = [gradient]
|
self._barGradient = [gradient]
|
||||||
else:
|
else:
|
||||||
self._barGradient = list(gradient)
|
self._barGradient = list(gradient)
|
||||||
|
|
||||||
self.SortForDisplay()
|
self.SortForDisplay()
|
||||||
|
|
||||||
|
|
||||||
def GetBorderPadding(self):
|
def GetBorderPadding(self):
|
||||||
""" Gets the border padding. """
|
""" Gets the border padding. """
|
||||||
|
|
||||||
return self._border_padding
|
return self._border_padding
|
||||||
|
|
||||||
def SetBorderPadding(self, padding):
|
def SetBorderPadding(self, padding):
|
||||||
"""
|
"""
|
||||||
Sets the border padding.
|
Sets the border padding.
|
||||||
|
|
||||||
:param `padding`: pixels between the border and the progress bar.
|
:param `padding`: pixels between the border and the progress bar.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self._border_padding = padding
|
self._border_padding = padding
|
||||||
|
|
||||||
|
|
||||||
def GetRange(self):
|
def GetRange(self):
|
||||||
""" Returns the maximum value of the gauge. """
|
""" Returns the maximum value of the gauge. """
|
||||||
|
|
||||||
return self._range
|
return self._range
|
||||||
|
|
||||||
def SetRange(self, range):
|
def SetRange(self, range):
|
||||||
"""
|
"""
|
||||||
Sets the range of the gauge. The gauge length is its
|
Sets the range of the gauge. The gauge length is its
|
||||||
value as a proportion of the range.
|
value as a proportion of the range.
|
||||||
|
|
||||||
:param `range`: The maximum value of the gauge.
|
:param `range`: The maximum value of the gauge.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if range <= 0:
|
if range <= 0:
|
||||||
raise Exception("ERROR:\n Gauge range must be greater than 0.")
|
raise Exception("ERROR:\n Gauge range must be greater than 0.")
|
||||||
|
|
||||||
self._range = range
|
self._range = range
|
||||||
|
|
||||||
|
|
||||||
def GetValue(self):
|
def GetValue(self):
|
||||||
""" Returns the current position of the gauge. """
|
""" Returns the current position of the gauge. """
|
||||||
|
|
||||||
return self._value[0]
|
return self._value[0]
|
||||||
|
|
||||||
def SetValue(self, value):
|
def SetValue(self, value):
|
||||||
""" Sets the current position of the gauge. """
|
""" Sets the current position of the gauge. """
|
||||||
|
|
||||||
if type(value) != type([]):
|
if type(value) != type([]):
|
||||||
self._value = [value]
|
self._value = [value]
|
||||||
else:
|
else:
|
||||||
self._value = list(value)
|
self._value = list(value)
|
||||||
|
|
||||||
self.SortForDisplay()
|
self.SortForDisplay()
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
if value > self._range:
|
if value > self._range:
|
||||||
@@ -211,19 +211,19 @@ class PyGauge(wx.PyWindow):
|
|||||||
self._value[0] = self._range
|
self._value[0] = self._range
|
||||||
else:
|
else:
|
||||||
self._overdrive = value
|
self._overdrive = value
|
||||||
|
|
||||||
for v in self._value:
|
for v in self._value:
|
||||||
if v < 0 or v > self._range:
|
if v < 0 or v > self._range:
|
||||||
raise Exception("ERROR:\n Gauge value must be between 0 and it's range. ")
|
raise Exception("ERROR:\n Gauge value must be between 0 and it's range. ")
|
||||||
|
|
||||||
|
|
||||||
def OnEraseBackground(self, event):
|
def OnEraseBackground(self, event):
|
||||||
"""
|
"""
|
||||||
Handles the ``wx.EVT_ERASE_BACKGROUND`` event for L{PyGauge}.
|
Handles the ``wx.EVT_ERASE_BACKGROUND`` event for L{PyGauge}.
|
||||||
|
|
||||||
:param `event`: a `wx.EraseEvent` event to be processed.
|
:param `event`: a `wx.EraseEvent` event to be processed.
|
||||||
|
|
||||||
:note: This method is intentionally empty to reduce flicker.
|
:note: This method is intentionally empty to reduce flicker.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
@@ -238,15 +238,15 @@ class PyGauge(wx.PyWindow):
|
|||||||
|
|
||||||
dc = wx.BufferedPaintDC(self)
|
dc = wx.BufferedPaintDC(self)
|
||||||
rect = self.GetClientRect()
|
rect = self.GetClientRect()
|
||||||
|
|
||||||
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
|
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
|
||||||
dc.Clear()
|
dc.Clear()
|
||||||
colour = self.GetBackgroundColour()
|
colour = self.GetBackgroundColour()
|
||||||
dc.SetBrush(wx.Brush(colour))
|
dc.SetBrush(wx.Brush(colour))
|
||||||
dc.SetPen(wx.Pen(colour))
|
dc.SetPen(wx.Pen(colour))
|
||||||
dc.DrawRectangleRect(rect)
|
dc.DrawRectangleRect(rect)
|
||||||
|
|
||||||
|
|
||||||
if self._border_colour:
|
if self._border_colour:
|
||||||
dc.SetPen(wx.Pen(self.GetBorderColour()))
|
dc.SetPen(wx.Pen(self.GetBorderColour()))
|
||||||
dc.DrawRectangleRect(rect)
|
dc.DrawRectangleRect(rect)
|
||||||
@@ -263,15 +263,15 @@ class PyGauge(wx.PyWindow):
|
|||||||
c1,c2 = gradient
|
c1,c2 = gradient
|
||||||
w = rect.width * (float(self._valueSorted[i]) / self._range)
|
w = rect.width * (float(self._valueSorted[i]) / self._range)
|
||||||
r = copy.copy(rect)
|
r = copy.copy(rect)
|
||||||
r.width = w
|
r.width = w
|
||||||
dc.GradientFillLinear(r, c1, c2, wx.EAST)
|
dc.GradientFillLinear(r, c1, c2, wx.EAST)
|
||||||
else:
|
else:
|
||||||
for i, colour in enumerate(self._barColourSorted):
|
for i, colour in enumerate(self._barColourSorted):
|
||||||
dc.SetBrush(wx.Brush(colour))
|
dc.SetBrush(wx.Brush(colour))
|
||||||
dc.SetPen(wx.Pen(colour))
|
dc.SetPen(wx.Pen(colour))
|
||||||
w = rect.width * (float(self._valueSorted[i]) / self._range)
|
w = rect.width * (float(self._valueSorted[i]) / self._range)
|
||||||
r = copy.copy(rect)
|
r = copy.copy(rect)
|
||||||
r.width = w
|
r.width = w
|
||||||
dc.DrawRectangleRect(r)
|
dc.DrawRectangleRect(r)
|
||||||
|
|
||||||
dc.SetTextForeground(wx.Colour(255,255,255))
|
dc.SetTextForeground(wx.Colour(255,255,255))
|
||||||
@@ -283,22 +283,22 @@ class PyGauge(wx.PyWindow):
|
|||||||
value = self._value[0]
|
value = self._value[0]
|
||||||
|
|
||||||
if self._skipDigits == True:
|
if self._skipDigits == True:
|
||||||
dc.DrawLabel(str(int(value*100/self._range)) + "%", rect, wx.ALIGN_CENTER)
|
dc.DrawLabel("%d%%" % (value*100/self._range), rect, wx.ALIGN_CENTER)
|
||||||
else:
|
else:
|
||||||
dc.DrawLabel(str(round(float(value*100/self._range)))+ "%",rect,wx.ALIGN_CENTER)
|
dc.DrawLabel("%.1f%%" % (value * 100 / self._range) , rect, wx.ALIGN_CENTER)
|
||||||
|
|
||||||
def OnTimer(self,event):
|
def OnTimer(self,event):
|
||||||
"""
|
"""
|
||||||
Handles the ``wx.EVT_TIMER`` event for L{PyGauge}.
|
Handles the ``wx.EVT_TIMER`` event for L{PyGauge}.
|
||||||
|
|
||||||
:param `event`: a timer event
|
:param `event`: a timer event
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self._timerId == event.GetId():
|
if self._timerId == event.GetId():
|
||||||
stop_timer = True
|
stop_timer = True
|
||||||
for i, v in enumerate(self._value):
|
for i, v in enumerate(self._value):
|
||||||
self._value[i] += self._update_step[i]
|
self._value[i] += self._update_step[i]
|
||||||
|
|
||||||
if self._update_step[i] > 0:
|
if self._update_step[i] > 0:
|
||||||
if self._value[i] > self._update_value[i]:
|
if self._value[i] > self._update_value[i]:
|
||||||
self._value[i] = self._update_value[i]
|
self._value[i] = self._update_value[i]
|
||||||
@@ -307,15 +307,15 @@ class PyGauge(wx.PyWindow):
|
|||||||
if self._value[i] < self._update_value[i]:
|
if self._value[i] < self._update_value[i]:
|
||||||
self._value[i] = self._update_value[i]
|
self._value[i] = self._update_value[i]
|
||||||
else: stop_timer = False
|
else: stop_timer = False
|
||||||
|
|
||||||
if stop_timer:
|
if stop_timer:
|
||||||
self._timer.Stop()
|
self._timer.Stop()
|
||||||
|
|
||||||
self.SortForDisplay()
|
self.SortForDisplay()
|
||||||
|
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
|
|
||||||
|
|
||||||
def Update(self, value, time=0, index=0):
|
def Update(self, value, time=0, index=0):
|
||||||
"""
|
"""
|
||||||
Update the gauge by adding value to it over time milliseconds. Time
|
Update the gauge by adding value to it over time milliseconds. Time
|
||||||
@@ -329,7 +329,7 @@ class PyGauge(wx.PyWindow):
|
|||||||
if time == 0: time=500
|
if time == 0: time=500
|
||||||
if type(value) != type([]):
|
if type(value) != type([]):
|
||||||
value = [value]
|
value = [value]
|
||||||
|
|
||||||
if len(value) != len(self._value):
|
if len(value) != len(self._value):
|
||||||
raise Exception("ERROR:\n len(value) != len(self.GetValue()) ")
|
raise Exception("ERROR:\n len(value) != len(self.GetValue()) ")
|
||||||
|
|
||||||
@@ -338,20 +338,20 @@ class PyGauge(wx.PyWindow):
|
|||||||
for i, v in enumerate(self._value):
|
for i, v in enumerate(self._value):
|
||||||
if value[i]+v < 0 or value[i]+v > self._range:
|
if value[i]+v < 0 or value[i]+v > self._range:
|
||||||
raise Exception("ERROR2:\n Gauge value must be between 0 and it's range. ")
|
raise Exception("ERROR2:\n Gauge value must be between 0 and it's range. ")
|
||||||
|
|
||||||
self._update_value.append( value[i] +v )
|
self._update_value.append( value[i] +v )
|
||||||
self._update_step.append( float(value[i]) / ( time/50 ) )
|
self._update_step.append( float(value[i]) / ( time/50 ) )
|
||||||
|
|
||||||
#print self._update_
|
#print self._update_
|
||||||
|
|
||||||
if not self._timer:
|
if not self._timer:
|
||||||
self._timer = wx.Timer(self, self._timerId)
|
self._timer = wx.Timer(self, self._timerId)
|
||||||
|
|
||||||
self._timer.Start(100)
|
self._timer.Start(100)
|
||||||
|
|
||||||
def SortForDisplay(self):
|
def SortForDisplay(self):
|
||||||
""" Internal method which sorts things so we draw the longest bar first. """
|
""" Internal method which sorts things so we draw the longest bar first. """
|
||||||
|
|
||||||
if self.GetBarGradient():
|
if self.GetBarGradient():
|
||||||
tmp = sorted(zip(self._value,self._barGradient)); tmp.reverse()
|
tmp = sorted(zip(self._value,self._barGradient)); tmp.reverse()
|
||||||
a,b = zip(*tmp)
|
a,b = zip(*tmp)
|
||||||
|
|||||||
Reference in New Issue
Block a user