GraphicViewer.py
changeset 665 6a376615142e
parent 660 30c0371ac086
child 668 e858ff2f7862
equal deleted inserted replaced
664:02e8c6e882af 665:6a376615142e
    78         parent.AddWindow(self.ResetButton, 0, border=5, flag=wx.ALL)
    78         parent.AddWindow(self.ResetButton, 0, border=5, flag=wx.ALL)
    79         parent.AddWindow(self.CurrentButton, 0, border=5, flag=wx.ALL)
    79         parent.AddWindow(self.CurrentButton, 0, border=5, flag=wx.ALL)
    80         
    80         
    81     def _init_coll_RangeSizer_Growables(self, parent):
    81     def _init_coll_RangeSizer_Growables(self, parent):
    82         # generated method, don't edit
    82         # generated method, don't edit
    83         parent.AddGrowableCol(3)
    83         parent.AddGrowableCol(5)
    84         parent.AddGrowableRow(0)
    84         parent.AddGrowableRow(0)
    85         
    85         
    86     def _init_sizers(self):
    86     def _init_sizers(self):
    87         # generated method, don't edit
    87         # generated method, don't edit
    88         self.MainGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
    88         self.MainGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
   182         # Initialize Viewer mode to Selection mode
   182         # Initialize Viewer mode to Selection mode
   183         self.Mode = MODE_SELECTION
   183         self.Mode = MODE_SELECTION
   184         
   184         
   185         self.Datas = []
   185         self.Datas = []
   186         self.StartTick = 0
   186         self.StartTick = 0
   187         self.EndTick = 0
       
   188         self.StartIdx = 0
   187         self.StartIdx = 0
   189         self.EndIdx = 0
   188         self.EndIdx = 0
   190         self.MinValue = None
   189         self.MinValue = None
   191         self.MaxValue = None
   190         self.MaxValue = None
   192         self.YCenter = 0
   191         self.YCenter = 0
   193         self.CurrentZoom = 1
   192         self.CurrentZoom = 1
   194         self.Fixed = False
   193         self.Fixed = False
   195         self.Ticktime = self.DataProducer.GetTicktime()
   194         self.Ticktime = 0#self.DataProducer.GetTicktime()
   196         self.RefreshCanvasRange()
   195         self.RefreshCanvasRange()
   197         
   196         
   198         for zoom_txt, zoom in ZOOM_VALUES:
   197         for zoom_txt, zoom in ZOOM_VALUES:
   199             self.CanvasZoom.Append(zoom_txt)
   198             self.CanvasZoom.Append(zoom_txt)
   200         self.CanvasZoom.SetSelection(0)
   199         self.CanvasZoom.SetSelection(0)
   220             wx.CallAfter(self.Canvas.canvas.SetCursor, wx.StockCursor(wx.CURSOR_HAND))
   219             wx.CallAfter(self.Canvas.canvas.SetCursor, wx.StockCursor(wx.CURSOR_HAND))
   221         
   220         
   222     def ResetView(self, register=False):
   221     def ResetView(self, register=False):
   223         self.Datas = []
   222         self.Datas = []
   224         self.StartTick = 0
   223         self.StartTick = 0
   225         self.EndTick = 0
       
   226         self.StartIdx = 0
   224         self.StartIdx = 0
   227         self.EndIdx = 0
   225         self.EndIdx = 0
       
   226         self.CursorIdx = None
   228         self.Fixed = False
   227         self.Fixed = False
   229         self.Ticktime = self.DataProducer.GetTicktime()
   228         self.Ticktime = self.DataProducer.GetTicktime()
   230         if register:
   229         if register:
   231             self.AddDataConsumer(self.InstancePath.upper(), self)
   230             self.AddDataConsumer(self.InstancePath.upper(), self)
       
   231         self.ResetLastCursor()
   232         self.RefreshCanvasRange()
   232         self.RefreshCanvasRange()
   233         self.RefreshView()
   233         self.RefreshView()
   234     
   234     
   235     def RefreshNewData(self, *args, **kwargs):
   235     def RefreshNewData(self, *args, **kwargs):
   236         self.RefreshView(*args, **kwargs)
   236         self.RefreshView(*args, **kwargs)
   246         return new_cursor
   246         return new_cursor
   247     
   247     
   248     def GetBounds(self):
   248     def GetBounds(self):
   249         if self.StartIdx is None or self.EndIdx is None:
   249         if self.StartIdx is None or self.EndIdx is None:
   250             self.StartIdx = self.GetNearestData(self.StartTick, -1)
   250             self.StartIdx = self.GetNearestData(self.StartTick, -1)
   251             self.EndIdx = self.GetNearestData(self.EndTick, 1)
   251             self.EndIdx = self.GetNearestData(self.StartTick + self.CurrentRange, 1)
   252     
   252     
   253     def ResetBounds(self):
   253     def ResetBounds(self):
   254         self.StartIdx = None
   254         self.StartIdx = None
   255         self.EndIdx = None
   255         self.EndIdx = None
   256     
   256     
   270             self.CanvasRange.SetStringSelection(TIME_RANGE_VALUES[0][0])
   270             self.CanvasRange.SetStringSelection(TIME_RANGE_VALUES[0][0])
   271             self.CurrentRange = TIME_RANGE_VALUES[0][1] / self.Ticktime
   271             self.CurrentRange = TIME_RANGE_VALUES[0][1] / self.Ticktime
   272         
   272         
   273     def RefreshView(self, force=True):
   273     def RefreshView(self, force=True):
   274         self.Freeze()
   274         self.Freeze()
   275         if force or not self.Fixed:
   275         if force or not self.Fixed or (len(self.Datas) > 0 and self.StartTick + self.CurrentRange > self.Datas[-1][0]):
   276             if (self.MinValue is not None and 
   276             if (self.MinValue is not None and 
   277                 self.MaxValue is not None and 
   277                 self.MaxValue is not None and 
   278                 self.MinValue != self.MaxValue):
   278                 self.MinValue != self.MaxValue):
   279                 Yrange = float(self.MaxValue - self.MinValue) / self.CurrentZoom
   279                 Yrange = float(self.MaxValue - self.MinValue) / self.CurrentZoom
   280             else:
   280             else:
   289             
   289             
   290             self.GetBounds()
   290             self.GetBounds()
   291             self.VariableGraphic = plot.PolyLine(self.Datas[self.StartIdx:self.EndIdx + 1], 
   291             self.VariableGraphic = plot.PolyLine(self.Datas[self.StartIdx:self.EndIdx + 1], 
   292                                                  legend=var_name, colour=colours[0])
   292                                                  legend=var_name, colour=colours[0])
   293             self.GraphicsObject = plot.PlotGraphics([self.VariableGraphic], _("%s Graphics") % var_name, _("Tick"), _("Values"))
   293             self.GraphicsObject = plot.PlotGraphics([self.VariableGraphic], _("%s Graphics") % var_name, _("Tick"), _("Values"))
   294             datas_length = len(self.Datas)
       
   295             if datas_length > 1:
       
   296                 start = self.Datas[self.StartIdx][0]
       
   297             else:
       
   298                 start = 0.
       
   299             self.Canvas.Draw(self.GraphicsObject, 
   294             self.Canvas.Draw(self.GraphicsObject, 
   300                              xAxis=(start, start + self.CurrentRange),
   295                              xAxis=(self.StartTick, self.StartTick + self.CurrentRange),
   301                              yAxis=(self.YCenter - Yrange * 1.1 / 2, self.YCenter + Yrange * 1.1 / 2))
   296                              yAxis=(self.YCenter - Yrange * 1.1 / 2, self.YCenter + Yrange * 1.1 / 2))
       
   297         
       
   298             # Reset and draw cursor 
       
   299             self.ResetLastCursor()
       
   300             self.RefreshCursor()
       
   301         
   302         self.RefreshScrollBar()
   302         self.RefreshScrollBar()
   303         
       
   304         # Reset and draw cursor 
       
   305         self.ResetLastCursor()
       
   306         self.RefreshCursor()
       
   307         
   303         
   308         self.Thaw()
   304         self.Thaw()
   309     
   305     
   310     def GetInstancePath(self):
   306     def GetInstancePath(self):
   311         return self.InstancePath
   307         return self.InstancePath
   312     
   308     
   313     def IsViewing(self, tagname):
   309     def IsViewing(self, tagname):
   314         return self.InstancePath == tagname
   310         return self.InstancePath == tagname
   315     
   311     
   316     def NewValue(self, tick, value, forced=False):
   312     def NewValue(self, tick, value, forced=False):
       
   313         print tick, value
   317         self.Datas.append((float(tick), {True:1., False:0.}.get(value, float(value))))
   314         self.Datas.append((float(tick), {True:1., False:0.}.get(value, float(value))))
   318         if self.MinValue is None:
   315         if self.MinValue is None:
   319             self.MinValue = value
   316             self.MinValue = value
   320         else:
   317         else:
   321             self.MinValue = min(self.MinValue, value)
   318             self.MinValue = min(self.MinValue, value)
   322         if self.MaxValue is None:
   319         if self.MaxValue is None:
   323             self.MaxValue = value
   320             self.MaxValue = value
   324         else:
   321         else:
   325             self.MaxValue = max(self.MaxValue, value)
   322             self.MaxValue = max(self.MaxValue, value)
   326         if not self.Fixed:
   323         if not self.Fixed or tick < self.StartTick + self.CurrentRange:
   327             self.GetBounds()
   324             self.GetBounds()
   328             while int(self.Datas[self.StartIdx][0]) < tick - self.CurrentRange:
   325             while int(self.Datas[self.StartIdx][0]) < tick - self.CurrentRange:
   329                 self.StartIdx += 1
   326                 self.StartIdx += 1
   330             self.EndIdx += 1
   327             self.EndIdx += 1
   331             self.StartTick = self.Datas[self.StartIdx][0]
   328             self.StartTick = self.Datas[self.StartIdx][0]
   332             self.EndTick = self.StartTick + self.CurrentRange
       
   333         self.NewDataAvailable()
   329         self.NewDataAvailable()
   334     
   330     
   335     def RefreshScrollBar(self):
   331     def RefreshScrollBar(self):
   336         if len(self.Datas) > 0:
   332         if len(self.Datas) > 0:
   337             self.GetBounds()
   333             self.GetBounds()
   348                 self.Fixed = False
   344                 self.Fixed = False
   349             self.ResetBounds()
   345             self.ResetBounds()
   350             if self.Fixed:
   346             if self.Fixed:
   351                 self.StartTick = min(self.StartTick, self.Datas[-1][0] - self.CurrentRange)
   347                 self.StartTick = min(self.StartTick, self.Datas[-1][0] - self.CurrentRange)
   352             else:
   348             else:
   353                 self.StartTick = max(self.Datas[0][0], self.EndTick - self.CurrentRange - 1)
   349                 self.StartTick = max(self.Datas[0][0], self.Datas[-1][0] - self.CurrentRange)
   354             self.EndTick = self.StartTick + self.CurrentRange
       
   355         self.NewDataAvailable(True)
   350         self.NewDataAvailable(True)
   356 
   351 
   357     def OnRangeChanged(self, event):
   352     def OnRangeChanged(self, event):
   358         try:
   353         try:
   359             if self.Ticktime == 0:
   354             if self.Ticktime == 0:
   371         event.Skip()
   366         event.Skip()
   372     
   367     
   373     def OnPositionChanging(self, event):
   368     def OnPositionChanging(self, event):
   374         self.ResetBounds()
   369         self.ResetBounds()
   375         self.StartTick = self.Datas[0][0] + event.GetPosition()
   370         self.StartTick = self.Datas[0][0] + event.GetPosition()
   376         self.EndTick = self.StartTick + self.CurrentRange
       
   377         self.Fixed = True
   371         self.Fixed = True
   378         self.NewDataAvailable(True)
   372         self.NewDataAvailable(True)
   379         event.Skip()
   373         event.Skip()
   380 
   374 
   381     def OnResetButton(self, event):
   375     def OnResetButton(self, event):
   384         event.Skip()
   378         event.Skip()
   385 
   379 
   386     def OnCurrentButton(self, event):
   380     def OnCurrentButton(self, event):
   387         self.ResetBounds()
   381         self.ResetBounds()
   388         self.StartTick = max(self.Datas[0][0], self.Datas[-1][0] - self.CurrentRange)
   382         self.StartTick = max(self.Datas[0][0], self.Datas[-1][0] - self.CurrentRange)
   389         self.EndTick = self.StartTick + self.CurrentRange
       
   390         self.Fixed = False
   383         self.Fixed = False
   391         self.NewDataAvailable(True)
   384         self.NewDataAvailable(True)
   392         event.Skip()
   385         event.Skip()
   393 
   386 
   394     def OnCanvasLeftDown(self, event):
   387     def OnCanvasLeftDown(self, event):
   395         self.Fixed = True
   388         self.Fixed = True
   396         self.Canvas.canvas.CaptureMouse()
   389         self.Canvas.canvas.CaptureMouse()
   397         if self.Mode == MODE_SELECTION:
   390         if len(self.Datas) > 0:
   398             self.Dragging = True
   391             if self.Mode == MODE_SELECTION:
   399             pos = self.Canvas.PositionScreenToUser(event.GetPosition())
   392                 self.Dragging = True
   400             self.CursorIdx = self.GetNearestData(pos[0], -1)
   393                 pos = self.Canvas.PositionScreenToUser(event.GetPosition())
   401             self.RefreshCursor()
   394                 self.CursorIdx = self.GetNearestData(pos[0], -1)
   402         elif self.Mode == MODE_MOTION:
   395                 self.RefreshCursor()
   403             self.GetBounds()
   396             elif self.Mode == MODE_MOTION:
   404             self.CurrentMousePos = event.GetPosition()
   397                 self.GetBounds()
   405             self.CurrentMotionValue = self.Datas[self.StartIdx][0]
   398                 self.CurrentMousePos = event.GetPosition()
       
   399                 self.CurrentMotionValue = self.Datas[self.StartIdx][0]
   406         event.Skip()
   400         event.Skip()
   407         
   401         
   408     def OnCanvasLeftUp(self, event):
   402     def OnCanvasLeftUp(self, event):
   409         self.Dragging = False
   403         self.Dragging = False
   410         if self.Mode == MODE_MOTION:
   404         if self.Mode == MODE_MOTION:
   418         if self.Mode == MODE_SELECTION and self.Dragging:
   412         if self.Mode == MODE_SELECTION and self.Dragging:
   419             pos = self.Canvas.PositionScreenToUser(event.GetPosition())
   413             pos = self.Canvas.PositionScreenToUser(event.GetPosition())
   420             graphics, xAxis, yAxis = self.Canvas.last_draw
   414             graphics, xAxis, yAxis = self.Canvas.last_draw
   421             self.CursorIdx = self.GetNearestData(max(xAxis[0], min(pos[0], xAxis[1])), -1)
   415             self.CursorIdx = self.GetNearestData(max(xAxis[0], min(pos[0], xAxis[1])), -1)
   422             self.RefreshCursor()
   416             self.RefreshCursor()
   423         elif self.CurrentMousePos is not None:
   417         elif self.CurrentMousePos is not None and len(self.Datas) > 0:
   424             oldpos = self.Canvas.PositionScreenToUser(self.CurrentMousePos)
   418             oldpos = self.Canvas.PositionScreenToUser(self.CurrentMousePos)
   425             newpos = self.Canvas.PositionScreenToUser(event.GetPosition())
   419             newpos = self.Canvas.PositionScreenToUser(event.GetPosition())
   426             self.CurrentMotionValue += oldpos[0] - newpos[0]
   420             self.CurrentMotionValue += oldpos[0] - newpos[0]
   427             self.YCenter += oldpos[1] - newpos[1]
   421             self.YCenter += oldpos[1] - newpos[1]
   428             self.ResetBounds()
   422             self.ResetBounds()
   429             self.StartTick = self.CurrentMotionValue
   423             self.StartTick = max(self.Datas[0][0], min(self.CurrentMotionValue, self.Datas[-1][0] - self.CurrentRange))
   430             self.EndTick = self.StartTick + self.CurrentRange
       
   431             self.CurrentMousePos = event.GetPosition()
   424             self.CurrentMousePos = event.GetPosition()
   432             self.NewDataAvailable(True)
   425             self.NewDataAvailable(True)
   433         event.Skip()
   426         event.Skip()
   434 
   427 
   435     def OnCanvasMouseWheel(self, event):
   428     def OnCanvasMouseWheel(self, event):
   460 
   453 
   461     ## Draw the cursor on graphic
   454     ## Draw the cursor on graphic
   462     #  @param dc The draw canvas
   455     #  @param dc The draw canvas
   463     #  @param cursor The cursor parameters
   456     #  @param cursor The cursor parameters
   464     def DrawCursor(self, dc, cursor, value):
   457     def DrawCursor(self, dc, cursor, value):
   465         if self.StartTick <= cursor <= self.EndTick:
   458         if self.StartTick <= cursor <= self.StartTick + self.CurrentRange:
   466             # Prepare temporary dc for drawing
   459             # Prepare temporary dc for drawing
   467             width = self.Canvas._Buffer.GetWidth()
   460             width = self.Canvas._Buffer.GetWidth()
   468             height = self.Canvas._Buffer.GetHeight()
   461             height = self.Canvas._Buffer.GetHeight()
   469             tmp_Buffer = wx.EmptyBitmap(width, height)
   462             tmp_Buffer = wx.EmptyBitmap(width, height)
   470             dcs = wx.MemoryDC()
   463             dcs = wx.MemoryDC()
   485             px, py = self.Canvas.PositionUserToScreen((float(cursor), 0.))
   478             px, py = self.Canvas.PositionUserToScreen((float(cursor), 0.))
   486             
   479             
   487             # Draw line cross drawing for diaplaying time cursor
   480             # Draw line cross drawing for diaplaying time cursor
   488             dcs.DrawLine(px, cy + 1, px, cy + cheight - 1)
   481             dcs.DrawLine(px, cy + 1, px, cy + cheight - 1)
   489             
   482             
   490             text = "X:%d\nY:%f"%(cursor, value)
   483             lines = ("X:%d\nY:%f" % (cursor, value)).splitlines()
   491             w, h = dcs.GetTextExtent(text)
   484             
   492             # Draw time cursor date
   485             wtext = 0
   493             dcs.DrawText(text, min(px + 3, cx + cwidth - w), cy + 3)
   486             for line in lines:
       
   487                 w, h = dcs.GetTextExtent(line)
       
   488                 wtext = max(wtext, w)
       
   489             
       
   490             offset = 0
       
   491             for line in lines:
       
   492                 # Draw time cursor date
       
   493                 dcs.DrawText(line, min(px + 3, cx + cwidth - wtext), cy + 3 + offset)
       
   494                 w, h = dcs.GetTextExtent(line)
       
   495                 offset += h
   494             
   496             
   495             dcs.EndDrawing()
   497             dcs.EndDrawing()
   496     
   498     
   497             #this will erase if called twice
   499             #this will erase if called twice
   498             dc.Blit(0, 0, width, height, dcs, 0, 0, wx.EQUIV)  #(NOT src) XOR dst
   500             dc.Blit(0, 0, width, height, dcs, 0, 0, wx.EQUIV)  #(NOT src) XOR dst