--- a/graphics/GraphicCommons.py Thu May 28 08:10:18 2009 +0200
+++ b/graphics/GraphicCommons.py Sat May 30 17:15:22 2009 +0200
@@ -23,6 +23,7 @@
#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import wx
+import time
from math import *
from types import *
@@ -188,6 +189,98 @@
#-------------------------------------------------------------------------------
+# Debug Data Consumer Class
+#-------------------------------------------------------------------------------
+
+class DebugDataConsumer:
+
+ def __init__(self):
+ self.LastValue = None
+ self.Value = None
+ self.Inhibited = False
+
+ def Inhibit(self, inhibit):
+ self.Inhibited = inhibit
+ if inhibit and self.LastValue is not None:
+ self.SetValue(self.LastValue)
+ self.LastValue = None
+
+ def NewValue(self, tick, value):
+ if self.Inhibited:
+ self.LastValue = value
+ else:
+ self.SetValue(value)
+
+ def SetValue(self, value):
+ self.Value = value
+
+#-------------------------------------------------------------------------------
+# Debug Viewer Class
+#-------------------------------------------------------------------------------
+
+REFRESH_PERIOD = 0.1
+
+class DebugViewer:
+
+ def __init__(self, producer, debug, register_tick=True):
+ self.DataProducer = producer
+ self.Debug = debug
+
+ self.DataConsumers = {}
+
+ self.LastRefreshTime = time.time()
+
+ if register_tick:
+ self.DataProducer.SubscribeDebugIECVariable("__tick__", self)
+
+ self.RefreshTimer = wx.Timer(self, -1)
+ self.Bind(wx.EVT_TIMER, self.OnRefreshTimer, self.RefreshTimer)
+
+ def __del__(self):
+ self.DataProducer.UnsubscribeDebugIECVariable("__tick__", self)
+ self.DeleteDataConsumers()
+ self.RefreshTimer.Stop()
+
+ def Inhibit(self, inhibit):
+ for consumer, iec_path in self.DataConsumers.iteritems():
+ consumer.Inhibit(inhibit)
+
+ def AddDataConsumer(self, iec_path, consumer):
+ result = self.DataProducer.SubscribeDebugIECVariable(iec_path, consumer) is not None
+ if result is not None and consumer != self:
+ self.DataConsumers[consumer] = iec_path
+ return result
+
+ def RemoveDataConsumer(self, consumer):
+ iec_path = self.DataConsumers.pop(consumer, None)
+ if iec_path is not None:
+ self.DataProducer.UnsubscribeDebugIECVariable(iec_path, consumer)
+
+ def DeleteDataConsumers(self):
+ for consumer, iec_path in self.DataConsumers.iteritems():
+ self.DataProducer.UnsubscribeDebugIECVariable(iec_path, consumer)
+ self.DataConsumers = {}
+
+ def OnRefreshTimer(self, event):
+ self.RefreshNewData()
+ event.Skip()
+
+ def NewDataAvailable(self):
+ self.Inhibit(True)
+ current_time = time.time()
+ if current_time - self.LastRefreshTime > REFRESH_PERIOD:
+ self.LastRefreshTime = current_time
+ wx.CallAfter(self.RefreshViewOnNewData)
+
+ def RefreshViewOnNewData(self):
+ if self:
+ self.RefreshNewData()
+ self.RefreshTimer.Start(int(REFRESH_PERIOD * 1000), oneShot=True)
+
+ def RefreshNewData(self):
+ self.Inhibit(False)
+
+#-------------------------------------------------------------------------------
# Viewer Rubberband
#-------------------------------------------------------------------------------
@@ -293,7 +386,7 @@
self.currentBox.height)
#-------------------------------------------------------------------------------
-# Viewer Rubberband
+# Viewer ToolTip
#-------------------------------------------------------------------------------
"""
@@ -312,10 +405,14 @@
def SetTip(self, tip):
self.Tip = tip
- dc = wx.ClientDC(self)
- w, h = dc.GetTextExtent(tip)
- self.SetSize(wx.Size(w + 4, h + 4))
- self.Refresh()
+ wx.CallAfter(self.RefreshTip)
+
+ def RefreshTip(self):
+ if self:
+ dc = wx.ClientDC(self)
+ w, h = dc.GetTextExtent(self.Tip)
+ self.SetSize(wx.Size(w + 4, h + 4))
+ self.Refresh()
def OnPaint(self, event):
dc = wx.AutoBufferedPaintDC(self)
@@ -1433,11 +1530,12 @@
Class that implements a wire for connecting two blocks
"""
-class Wire(Graphic_Element):
+class Wire(Graphic_Element, DebugDataConsumer):
# Create a new wire
def __init__(self, parent, start = None, end = None):
Graphic_Element.__init__(self, parent)
+ DebugDataConsumer.__init__(self)
self.StartPoint = start
self.EndPoint = end
self.StartConnected = None
@@ -1451,14 +1549,12 @@
self.Segments = []
self.SelectedSegment = None
self.Valid = True
- self.Value = None
self.ValueSize = None
self.ComputedValue = None
self.OverStart = False
self.OverEnd = False
self.ComputingType = False
self.ToolTip = None
- self.Font = parent.GetMiniFont()
def Flush(self):
self.StartConnected = None
@@ -1492,7 +1588,6 @@
rect = rect.Union(self.EndConnected.GetRedrawRect(movex, movey))
if self.ValueSize is not None:
width, height = self.ValueSize
- width, height = self.ValueSize
if self.BoundingBox[2] > width * 4 or self.BoundingBox[3] > height * 4:
x = self.Points[0].x + width * self.StartPoint[1][0] / 2
y = self.Points[0].y + (height * self.StartPoint[1][1] - 1) / 2
@@ -1624,7 +1719,7 @@
return False
def SetValue(self, value):
- if self.Value != value and self.Parent:
+ if self.Value != value:
self.Value = value
if value is not None and not isinstance(value, BooleanType):
if isinstance(value, StringType):
@@ -1636,16 +1731,14 @@
if len(self.ComputedValue) > 4:
self.ComputedValue = self.ComputedValue[:4] + "..."
if isinstance(self.ComputedValue, StringType):
- dc = wx.ClientDC(self.Parent)
- dc.SetFont(self.Font)
- self.ValueSize = dc.GetTextExtent(self.ComputedValue)
+ self.ValueSize = self.Parent.GetMiniTextExtent(self.ComputedValue)
else:
self.ValueSize = None
if self.StartConnected:
self.StartConnected.RefreshValue()
if self.EndConnected:
self.EndConnected.RefreshValue()
- self.Refresh()
+ self.Parent.UpdateRefreshRect(self.GetRedrawRect())
if isinstance(value, BooleanType) and self.StartConnected is not None:
block = self.StartConnected.GetParentBlock()
block.SpreadCurrent()
@@ -2514,7 +2607,7 @@
if self.SelectedSegment == len(self.Segments) - 1:
dc.DrawPoint(self.Points[-1].x, self.Points[-1].y)
if self.Value is not None and not isinstance(self.Value, BooleanType) and self.Value != "undefined":
- dc.SetFont(self.Font)
+ dc.SetFont(self.Parent.GetMiniFont())
dc.SetTextForeground(wx.NamedColour("purple"))
width, height = self.ValueSize
if self.BoundingBox[2] > width * 4 or self.BoundingBox[3] > height * 4: