author | lbessard |
Mon, 23 Mar 2009 16:48:32 +0100 | |
changeset 335 | c2c6db53a04f |
parent 331 | 9106d66bd204 |
child 338 | 87e5015330ae |
permissions | -rw-r--r-- |
301 | 1 |
#!/usr/bin/env python |
2 |
# -*- coding: utf-8 -*- |
|
3 |
||
4 |
#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor |
|
5 |
#based on the plcopen standard. |
|
6 |
# |
|
7 |
#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD |
|
8 |
# |
|
9 |
#See COPYING file for copyrights details. |
|
10 |
# |
|
11 |
#This library is free software; you can redistribute it and/or |
|
12 |
#modify it under the terms of the GNU General Public |
|
13 |
#License as published by the Free Software Foundation; either |
|
14 |
#version 2.1 of the License, or (at your option) any later version. |
|
15 |
# |
|
16 |
#This library is distributed in the hope that it will be useful, |
|
17 |
#but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
18 |
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
19 |
#General Public License for more details. |
|
20 |
# |
|
21 |
#You should have received a copy of the GNU General Public |
|
22 |
#License along with this library; if not, write to the Free Software |
|
23 |
#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
24 |
||
25 |
import wx |
|
26 |
import wx.lib.plot as plot |
|
27 |
||
28 |
||
29 |
colours = ['blue', 'red', 'green', 'yellow', 'orange', 'purple', 'brown', 'cyan', |
|
30 |
'pink', 'grey'] |
|
31 |
markers = ['circle', 'dot', 'square', 'triangle', 'triangle_down', 'cross', 'plus', 'circle'] |
|
32 |
||
33 |
||
34 |
#------------------------------------------------------------------------------- |
|
35 |
# Debug Variable Graphic Viewer class |
|
36 |
#------------------------------------------------------------------------------- |
|
37 |
||
38 |
||
39 |
RANGE_VALUES = [str(25 * 2 ** i) for i in xrange(6)] |
|
40 |
||
41 |
[ID_GRAPHICVIEWER, ID_GRAPHICVIEWERCANVAS, |
|
42 |
ID_GRAPHICVIEWERCANVASRANGE, ID_GRAPHICVIEWERCANVASPOSITION, |
|
43 |
ID_GRAPHICVIEWERRESETBUTTON, ID_GRAPHICVIEWERCURRENTBUTTON, |
|
44 |
ID_GRAPHICVIEWERSTATICTEXT1, ID_GRAPHICVIEWERSTATICTEXT2, |
|
45 |
] = [wx.NewId() for _init_ctrls in range(8)] |
|
46 |
||
47 |
class GraphicViewer(wx.Panel): |
|
48 |
||
49 |
def _init_coll_MainGridSizer_Items(self, parent): |
|
50 |
# generated method, don't edit |
|
51 |
parent.AddWindow(self.Canvas, 0, border=0, flag=wx.GROW) |
|
52 |
parent.AddSizer(self.RangeSizer, 0, border=0, flag=wx.GROW) |
|
53 |
||
54 |
def _init_coll_MainGridSizer_Growables(self, parent): |
|
55 |
# generated method, don't edit |
|
56 |
parent.AddGrowableCol(0) |
|
57 |
parent.AddGrowableRow(0) |
|
58 |
||
59 |
def _init_coll_RangeSizer_Items(self, parent): |
|
60 |
# generated method, don't edit |
|
61 |
parent.AddWindow(self.staticbox1, 0, border=5, flag=wx.ALL) |
|
62 |
parent.AddWindow(self.CanvasRange, 0, border=5, flag=wx.ALL) |
|
63 |
parent.AddWindow(self.staticText2, 0, border=5, flag=wx.ALL) |
|
64 |
parent.AddWindow(self.CanvasPosition, 0, border=5, flag=wx.GROW|wx.ALL) |
|
65 |
parent.AddWindow(self.ResetButton, 0, border=5, flag=wx.ALL) |
|
66 |
parent.AddWindow(self.CurrentButton, 0, border=5, flag=wx.ALL) |
|
67 |
||
68 |
def _init_coll_RangeSizer_Growables(self, parent): |
|
69 |
# generated method, don't edit |
|
70 |
parent.AddGrowableCol(3) |
|
71 |
parent.AddGrowableRow(0) |
|
72 |
||
73 |
def _init_sizers(self): |
|
74 |
# generated method, don't edit |
|
75 |
self.MainGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) |
|
76 |
self.RangeSizer = wx.FlexGridSizer(cols=6, hgap=0, rows=1, vgap=0) |
|
77 |
||
78 |
self._init_coll_MainGridSizer_Items(self.MainGridSizer) |
|
79 |
self._init_coll_MainGridSizer_Growables(self.MainGridSizer) |
|
80 |
self._init_coll_RangeSizer_Items(self.RangeSizer) |
|
81 |
self._init_coll_RangeSizer_Growables(self.RangeSizer) |
|
82 |
||
83 |
self.SetSizer(self.MainGridSizer) |
|
84 |
||
85 |
def _init_ctrls(self, prnt): |
|
86 |
wx.Panel.__init__(self, prnt, ID_GRAPHICVIEWER, wx.DefaultPosition, |
|
87 |
wx.DefaultSize, 0) |
|
88 |
||
89 |
self.Canvas = plot.PlotCanvas(id=ID_GRAPHICVIEWERCANVAS, |
|
90 |
name='Canvas', parent=self, pos=wx.Point(0, 0), |
|
91 |
size=wx.Size(0, 0), style=0) |
|
92 |
def _axisInterval(spec, lower, upper): |
|
93 |
if spec == 'border': |
|
94 |
if lower == upper: |
|
95 |
return lower - 0.5, upper + 0.5 |
|
96 |
else: |
|
97 |
border = (upper - lower) * 0.05 |
|
98 |
return lower - border, upper + border |
|
99 |
else: |
|
100 |
return plot.PlotCanvas._axisInterval(self.Canvas, spec, lower, upper) |
|
101 |
self.Canvas._axisInterval = _axisInterval |
|
102 |
self.Canvas.SetYSpec('border') |
|
103 |
||
104 |
self.staticbox1 = wx.StaticText(id=ID_GRAPHICVIEWERSTATICTEXT1, |
|
105 |
label='Range:', name='staticText1', parent=self, |
|
106 |
pos=wx.Point(0, 0), size=wx.Size(45, 17), style=0) |
|
107 |
||
108 |
self.CanvasRange = wx.ComboBox(id=ID_GRAPHICVIEWERCANVASRANGE, |
|
109 |
name='CanvasRange', parent=self, pos=wx.Point(0, 0), |
|
313 | 110 |
size=wx.Size(100, 28), choices=RANGE_VALUES, style=0) |
301 | 111 |
self.CanvasRange.SetStringSelection("25") |
112 |
self.Bind(wx.EVT_COMBOBOX, self.OnRangeChanged, id=ID_GRAPHICVIEWERCANVASRANGE) |
|
113 |
self.Bind(wx.EVT_TEXT_ENTER, self.OnRangeChanged, id=ID_GRAPHICVIEWERCANVASRANGE) |
|
114 |
||
115 |
self.staticText2 = wx.StaticText(id=ID_GRAPHICVIEWERSTATICTEXT2, |
|
116 |
label='Position:', name='staticText2', parent=self, |
|
117 |
pos=wx.Point(0, 0), size=wx.Size(60, 17), style=0) |
|
118 |
||
119 |
self.CanvasPosition = wx.ScrollBar(id=ID_GRAPHICVIEWERCANVASPOSITION, |
|
120 |
name='Position', parent=self, pos=wx.Point(0, 0), |
|
121 |
size=wx.Size(0, 16), style=wx.SB_HORIZONTAL) |
|
122 |
self.CanvasPosition.SetScrollbar(0, 10, 100, 10) |
|
123 |
self.CanvasPosition.Bind(wx.EVT_SCROLL_THUMBTRACK, self.OnPositionChanging, |
|
124 |
id = ID_GRAPHICVIEWERCANVASPOSITION) |
|
125 |
self.CanvasPosition.Bind(wx.EVT_SCROLL_LINEUP, self.OnPositionChanging, |
|
126 |
id = ID_GRAPHICVIEWERCANVASPOSITION) |
|
127 |
self.CanvasPosition.Bind(wx.EVT_SCROLL_LINEDOWN, self.OnPositionChanging, |
|
128 |
id = ID_GRAPHICVIEWERCANVASPOSITION) |
|
129 |
self.CanvasPosition.Bind(wx.EVT_SCROLL_PAGEUP, self.OnPositionChanging, |
|
130 |
id = ID_GRAPHICVIEWERCANVASPOSITION) |
|
131 |
self.CanvasPosition.Bind(wx.EVT_SCROLL_PAGEDOWN, self.OnPositionChanging, |
|
132 |
id = ID_GRAPHICVIEWERCANVASPOSITION) |
|
133 |
||
134 |
self.ResetButton = wx.Button(id=ID_GRAPHICVIEWERRESETBUTTON, label='Reset', |
|
135 |
name='ResetButton', parent=self, pos=wx.Point(0, 0), |
|
136 |
size=wx.Size(72, 24), style=0) |
|
137 |
self.Bind(wx.EVT_BUTTON, self.OnResetButton, id=ID_GRAPHICVIEWERRESETBUTTON) |
|
138 |
||
139 |
self.CurrentButton = wx.Button(id=ID_GRAPHICVIEWERCURRENTBUTTON, label='Current', |
|
140 |
name='CurrentButton', parent=self, pos=wx.Point(0, 0), |
|
141 |
size=wx.Size(72, 24), style=0) |
|
142 |
self.Bind(wx.EVT_BUTTON, self.OnCurrentButton, id=ID_GRAPHICVIEWERCURRENTBUTTON) |
|
143 |
||
144 |
self._init_sizers() |
|
145 |
||
146 |
def __init__(self, parent, window, controler, instancepath = ""): |
|
147 |
self._init_ctrls(parent) |
|
148 |
||
149 |
self.ParentWindow = window |
|
150 |
self.Controler = controler |
|
151 |
self.InstancePath = instancepath |
|
152 |
||
153 |
self.Datas = [] |
|
154 |
self.CurrentValue = 0 |
|
155 |
self.CurrentRange = 25 |
|
156 |
||
157 |
self.Controler.SubscribeDebugIECVariable(self.InstancePath.upper(), self) |
|
158 |
||
159 |
def RefreshView(self): |
|
160 |
var_name = self.InstancePath.split(".")[-1] |
|
161 |
||
162 |
self.VariableGraphic = plot.PolyLine(self.Datas[self.CurrentValue:self.CurrentValue + self.CurrentRange], |
|
163 |
legend=var_name, colour=colours[0]) |
|
164 |
self.GraphicsObject = plot.PlotGraphics([self.VariableGraphic], "%s Graphics" % var_name, "Tick", "Values") |
|
165 |
datas_length = len(self.Datas) |
|
166 |
if datas_length > 1: |
|
167 |
start = self.Datas[self.CurrentValue][0] |
|
168 |
if self.CurrentValue + self.CurrentRange > datas_length: |
|
169 |
end = start + (self.Datas[datas_length - 1][0] - start) * self.CurrentRange / (datas_length - self.CurrentValue - 1) |
|
170 |
else: |
|
171 |
end = self.Datas[self.CurrentValue + self.CurrentRange - 1][0] |
|
172 |
else: |
|
173 |
start = 0. |
|
174 |
end = 25. |
|
175 |
self.Canvas.Draw(self.GraphicsObject, xAxis=(start, end)) |
|
176 |
||
177 |
self.RefreshScrollBar() |
|
326 | 178 |
|
179 |
def SetMode(self, mode): |
|
180 |
pass |
|
181 |
||
301 | 182 |
def GetTagName(self): |
183 |
return "" |
|
184 |
||
185 |
def GetInstancePath(self): |
|
186 |
return self.InstancePath |
|
187 |
||
326 | 188 |
def IsViewing(self, tagname): |
189 |
return self.InstancePath == tagname |
|
190 |
||
191 |
def ResetBuffer(self): |
|
192 |
pass |
|
193 |
||
194 |
def RefreshScaling(self, refresh=True): |
|
195 |
pass |
|
196 |
||
331
9106d66bd204
Bug with Scaling, MiddleButton, Wire modifications fixed.
lbessard
parents:
326
diff
changeset
|
197 |
def SelectAll(self): |
9106d66bd204
Bug with Scaling, MiddleButton, Wire modifications fixed.
lbessard
parents:
326
diff
changeset
|
198 |
pass |
9106d66bd204
Bug with Scaling, MiddleButton, Wire modifications fixed.
lbessard
parents:
326
diff
changeset
|
199 |
|
301 | 200 |
def AddPoint(self, tick, value): |
201 |
self.Datas.append((float(tick), {True:1., False:0.}.get(value, float(value)))) |
|
202 |
if self.CurrentValue + self.CurrentRange == len(self.Datas) - 1: |
|
203 |
self.CurrentValue += 1 |
|
204 |
self.RefreshView() |
|
205 |
elif len(self.Datas) < self.CurrentValue + self.CurrentRange: |
|
206 |
self.RefreshView() |
|
207 |
||
208 |
def RefreshScrollBar(self): |
|
209 |
self.CanvasPosition.SetScrollbar(self.CurrentValue, self.CurrentRange, len(self.Datas), self.CurrentRange) |
|
210 |
||
211 |
def OnRangeChanged(self, event): |
|
212 |
old_range = self.CurrentRange |
|
213 |
try: |
|
214 |
self.CurrentRange = int(self.CanvasRange.GetValue()) |
|
215 |
except ValueError, e: |
|
216 |
self.CanvasRange.SetValue(str(self.CurrentRange)) |
|
217 |
self.CurrentValue = max(0, min(self.CurrentValue + old_range - self.CurrentRange, |
|
218 |
len(self.Datas) - self.CurrentRange)) |
|
219 |
self.RefreshView() |
|
220 |
event.Skip() |
|
221 |
||
222 |
def OnPositionChanging(self, event): |
|
223 |
self.CurrentValue = event.GetPosition() |
|
224 |
self.RefreshView() |
|
225 |
event.Skip() |
|
226 |
||
227 |
def OnResetButton(self, event): |
|
228 |
self.Datas = [] |
|
229 |
self.CurrentValue = 0 |
|
230 |
self.RefreshView() |
|
231 |
event.Skip() |
|
232 |
||
233 |
def OnCurrentButton(self, event): |
|
234 |
self.CurrentValue = max(0, len(self.Datas) - self.CurrentRange) |
|
235 |
self.RefreshView() |
|
236 |
event.Skip() |
|
237 |