Fix bugs in GraphicViewer with selection and navigation
authorlaurent
Sat, 31 Mar 2012 15:03:50 +0200
changeset 665 6a376615142e
parent 664 02e8c6e882af
child 666 d4bb66691248
Fix bugs in GraphicViewer with selection and navigation
GraphicViewer.py
--- a/GraphicViewer.py	Sat Mar 31 13:18:13 2012 +0200
+++ b/GraphicViewer.py	Sat Mar 31 15:03:50 2012 +0200
@@ -80,7 +80,7 @@
         
     def _init_coll_RangeSizer_Growables(self, parent):
         # generated method, don't edit
-        parent.AddGrowableCol(3)
+        parent.AddGrowableCol(5)
         parent.AddGrowableRow(0)
         
     def _init_sizers(self):
@@ -184,7 +184,6 @@
         
         self.Datas = []
         self.StartTick = 0
-        self.EndTick = 0
         self.StartIdx = 0
         self.EndIdx = 0
         self.MinValue = None
@@ -192,7 +191,7 @@
         self.YCenter = 0
         self.CurrentZoom = 1
         self.Fixed = False
-        self.Ticktime = self.DataProducer.GetTicktime()
+        self.Ticktime = 0#self.DataProducer.GetTicktime()
         self.RefreshCanvasRange()
         
         for zoom_txt, zoom in ZOOM_VALUES:
@@ -222,13 +221,14 @@
     def ResetView(self, register=False):
         self.Datas = []
         self.StartTick = 0
-        self.EndTick = 0
         self.StartIdx = 0
         self.EndIdx = 0
+        self.CursorIdx = None
         self.Fixed = False
         self.Ticktime = self.DataProducer.GetTicktime()
         if register:
             self.AddDataConsumer(self.InstancePath.upper(), self)
+        self.ResetLastCursor()
         self.RefreshCanvasRange()
         self.RefreshView()
     
@@ -248,7 +248,7 @@
     def GetBounds(self):
         if self.StartIdx is None or self.EndIdx is None:
             self.StartIdx = self.GetNearestData(self.StartTick, -1)
-            self.EndIdx = self.GetNearestData(self.EndTick, 1)
+            self.EndIdx = self.GetNearestData(self.StartTick + self.CurrentRange, 1)
     
     def ResetBounds(self):
         self.StartIdx = None
@@ -272,7 +272,7 @@
         
     def RefreshView(self, force=True):
         self.Freeze()
-        if force or not self.Fixed:
+        if force or not self.Fixed or (len(self.Datas) > 0 and self.StartTick + self.CurrentRange > self.Datas[-1][0]):
             if (self.MinValue is not None and 
                 self.MaxValue is not None and 
                 self.MinValue != self.MaxValue):
@@ -291,20 +291,16 @@
             self.VariableGraphic = plot.PolyLine(self.Datas[self.StartIdx:self.EndIdx + 1], 
                                                  legend=var_name, colour=colours[0])
             self.GraphicsObject = plot.PlotGraphics([self.VariableGraphic], _("%s Graphics") % var_name, _("Tick"), _("Values"))
-            datas_length = len(self.Datas)
-            if datas_length > 1:
-                start = self.Datas[self.StartIdx][0]
-            else:
-                start = 0.
             self.Canvas.Draw(self.GraphicsObject, 
-                             xAxis=(start, start + self.CurrentRange),
+                             xAxis=(self.StartTick, self.StartTick + self.CurrentRange),
                              yAxis=(self.YCenter - Yrange * 1.1 / 2, self.YCenter + Yrange * 1.1 / 2))
+        
+            # Reset and draw cursor 
+            self.ResetLastCursor()
+            self.RefreshCursor()
+        
         self.RefreshScrollBar()
         
-        # Reset and draw cursor 
-        self.ResetLastCursor()
-        self.RefreshCursor()
-        
         self.Thaw()
     
     def GetInstancePath(self):
@@ -314,6 +310,7 @@
         return self.InstancePath == tagname
     
     def NewValue(self, tick, value, forced=False):
+        print tick, value
         self.Datas.append((float(tick), {True:1., False:0.}.get(value, float(value))))
         if self.MinValue is None:
             self.MinValue = value
@@ -323,13 +320,12 @@
             self.MaxValue = value
         else:
             self.MaxValue = max(self.MaxValue, value)
-        if not self.Fixed:
+        if not self.Fixed or tick < self.StartTick + self.CurrentRange:
             self.GetBounds()
             while int(self.Datas[self.StartIdx][0]) < tick - self.CurrentRange:
                 self.StartIdx += 1
             self.EndIdx += 1
             self.StartTick = self.Datas[self.StartIdx][0]
-            self.EndTick = self.StartTick + self.CurrentRange
         self.NewDataAvailable()
     
     def RefreshScrollBar(self):
@@ -350,8 +346,7 @@
             if self.Fixed:
                 self.StartTick = min(self.StartTick, self.Datas[-1][0] - self.CurrentRange)
             else:
-                self.StartTick = max(self.Datas[0][0], self.EndTick - self.CurrentRange - 1)
-            self.EndTick = self.StartTick + self.CurrentRange
+                self.StartTick = max(self.Datas[0][0], self.Datas[-1][0] - self.CurrentRange)
         self.NewDataAvailable(True)
 
     def OnRangeChanged(self, event):
@@ -373,7 +368,6 @@
     def OnPositionChanging(self, event):
         self.ResetBounds()
         self.StartTick = self.Datas[0][0] + event.GetPosition()
-        self.EndTick = self.StartTick + self.CurrentRange
         self.Fixed = True
         self.NewDataAvailable(True)
         event.Skip()
@@ -386,7 +380,6 @@
     def OnCurrentButton(self, event):
         self.ResetBounds()
         self.StartTick = max(self.Datas[0][0], self.Datas[-1][0] - self.CurrentRange)
-        self.EndTick = self.StartTick + self.CurrentRange
         self.Fixed = False
         self.NewDataAvailable(True)
         event.Skip()
@@ -394,15 +387,16 @@
     def OnCanvasLeftDown(self, event):
         self.Fixed = True
         self.Canvas.canvas.CaptureMouse()
-        if self.Mode == MODE_SELECTION:
-            self.Dragging = True
-            pos = self.Canvas.PositionScreenToUser(event.GetPosition())
-            self.CursorIdx = self.GetNearestData(pos[0], -1)
-            self.RefreshCursor()
-        elif self.Mode == MODE_MOTION:
-            self.GetBounds()
-            self.CurrentMousePos = event.GetPosition()
-            self.CurrentMotionValue = self.Datas[self.StartIdx][0]
+        if len(self.Datas) > 0:
+            if self.Mode == MODE_SELECTION:
+                self.Dragging = True
+                pos = self.Canvas.PositionScreenToUser(event.GetPosition())
+                self.CursorIdx = self.GetNearestData(pos[0], -1)
+                self.RefreshCursor()
+            elif self.Mode == MODE_MOTION:
+                self.GetBounds()
+                self.CurrentMousePos = event.GetPosition()
+                self.CurrentMotionValue = self.Datas[self.StartIdx][0]
         event.Skip()
         
     def OnCanvasLeftUp(self, event):
@@ -420,14 +414,13 @@
             graphics, xAxis, yAxis = self.Canvas.last_draw
             self.CursorIdx = self.GetNearestData(max(xAxis[0], min(pos[0], xAxis[1])), -1)
             self.RefreshCursor()
-        elif self.CurrentMousePos is not None:
+        elif self.CurrentMousePos is not None and len(self.Datas) > 0:
             oldpos = self.Canvas.PositionScreenToUser(self.CurrentMousePos)
             newpos = self.Canvas.PositionScreenToUser(event.GetPosition())
             self.CurrentMotionValue += oldpos[0] - newpos[0]
             self.YCenter += oldpos[1] - newpos[1]
             self.ResetBounds()
-            self.StartTick = self.CurrentMotionValue
-            self.EndTick = self.StartTick + self.CurrentRange
+            self.StartTick = max(self.Datas[0][0], min(self.CurrentMotionValue, self.Datas[-1][0] - self.CurrentRange))
             self.CurrentMousePos = event.GetPosition()
             self.NewDataAvailable(True)
         event.Skip()
@@ -462,7 +455,7 @@
     #  @param dc The draw canvas
     #  @param cursor The cursor parameters
     def DrawCursor(self, dc, cursor, value):
-        if self.StartTick <= cursor <= self.EndTick:
+        if self.StartTick <= cursor <= self.StartTick + self.CurrentRange:
             # Prepare temporary dc for drawing
             width = self.Canvas._Buffer.GetWidth()
             height = self.Canvas._Buffer.GetHeight()
@@ -487,10 +480,19 @@
             # Draw line cross drawing for diaplaying time cursor
             dcs.DrawLine(px, cy + 1, px, cy + cheight - 1)
             
-            text = "X:%d\nY:%f"%(cursor, value)
-            w, h = dcs.GetTextExtent(text)
-            # Draw time cursor date
-            dcs.DrawText(text, min(px + 3, cx + cwidth - w), cy + 3)
+            lines = ("X:%d\nY:%f" % (cursor, value)).splitlines()
+            
+            wtext = 0
+            for line in lines:
+                w, h = dcs.GetTextExtent(line)
+                wtext = max(wtext, w)
+            
+            offset = 0
+            for line in lines:
+                # Draw time cursor date
+                dcs.DrawText(line, min(px + 3, cx + cwidth - wtext), cy + 3 + offset)
+                w, h = dcs.GetTextExtent(line)
+                offset += h
             
             dcs.EndDrawing()