comparison pyink/FSM_window.py @ 1472:7cb7abb5063b

Refactory drawing functions into classes for state and transition
author Thinker K.F. Li <thinker@codemud.net>
date Sun, 24 Apr 2011 15:13:41 +0800
parents 055845649807
children e807ad5aeb91
comparison
equal deleted inserted replaced
1471:055845649807 1472:7cb7abb5063b
56 56
57 def on_FSM_main_win_destroy_event(self, *args): 57 def on_FSM_main_win_destroy_event(self, *args):
58 pass 58 pass
59 pass 59 pass
60 60
61 class FSM_window(FSM_window_base): 61 class FSM_transition(object):
62 __metaclass__ = data_monitor.data_monitor 62 _doc = None
63 __data_monitor_prefix__ = 'on_' 63 _domview = None
64 64 _state = None
65 def __init__(self, domview_ui, close_cb, destroy_cb): 65 trn_cond = None
66 super(FSM_window, self).__init__() 66 trn_g = None
67 67
68 self._locker = domview_ui 68 def __init__(self, trn_cond):
69 69 self.trn_cond = trn_cond
70 self._domview = domview_ui 70 pass
71 self._state_nodes = {} 71
72 72 def init(self, doc, domview, state):
73 self._close_cb = close_cb # callback to close editor window (hide) 73 self._doc = doc
74 self._destroy_cb = destroy_cb # callback to destroy editor window 74 self._domview = domview
75 pass 75 self._state = state
76 76 pass
77 def _doc(self): 77
78 view_widget = self._view_widget 78 def _draw_transition_real(self, parent, path):
79 view = view_widget.view
80 doc = view.doc().rdoc
81 return doc
82
83 def _root(self):
84 doc = self._doc()
85 root = doc.root()
86 return root
87
88 def _clear_view(self):
89 root = self._root()
90
91 children = [child for child in root.childList()
92 if child.name() == 'svg:g']
93 for child in children:
94 root.removeChild(child)
95 pass
96
97 self._state_nodes = {}
98 pass
99
100 def _draw_transition_real(self, state_g, path):
101 import math 79 import math
102 doc = self._doc() 80 doc = self._doc
81
82 trn_g = doc.createElement('svg:g')
103 83
104 path_node = doc.createElement('svg:path') 84 path_node = doc.createElement('svg:path')
105 path_txt = 'M %f,%f C %f,%f %f,%f %f,%f' % tuple(path) 85 path_txt = 'M %f,%f C %f,%f %f,%f %f,%f' % tuple(path)
106 path_node.setAttribute('d', path_txt) 86 path_node.setAttribute('d', path_txt)
107 path_node.setAttribute('style', 'stroke: #000000; stroke-width: 1; ' 87 path_node.setAttribute('style', 'stroke: #000000; stroke-width: 1; '
108 'fill: none') 88 'fill: none')
109 state_g.appendChild(path_node) 89 trn_g.appendChild(path_node)
110 90
111 # c0 c1 c2 c3 of cubic curve 91 # c0 c1 c2 c3 of cubic curve
112 c3 = (path[6], path[7]) 92 c3 = (path[6], path[7])
113 c2 = (path[4], path[5]) 93 c2 = (path[4], path[5])
114 c23_v = (c3[0] - c2[0], c3[1] - c2[1]) 94 c23_v = (c3[0] - c2[0], c3[1] - c2[1])
121 arrow_txt = 'M %f,%f l %f,%f l %f,%f z' % arrow_pts 101 arrow_txt = 'M %f,%f l %f,%f l %f,%f z' % arrow_pts
122 arrow_node = doc.createElement('svg:path') 102 arrow_node = doc.createElement('svg:path')
123 arrow_node.setAttribute('d', arrow_txt) 103 arrow_node.setAttribute('d', arrow_txt)
124 arrow_node.setAttribute('style', 'stroke: #000000; stroke-width: 1; ' 104 arrow_node.setAttribute('style', 'stroke: #000000; stroke-width: 1; '
125 'fill: #000000') 105 'fill: #000000')
126 state_g.appendChild(arrow_node) 106 trn_g.appendChild(arrow_node)
127 pass 107
128 108 parent.appendChild(trn_g)
129 def _draw_state_real(self, state_name, r, x, y): 109
130 doc = self._doc() 110 self.trn_g = trn_g
131 root = self._root() 111 pass
112
113 @property
114 def path(self):
115 domview = self._domview
116 state_name = self._state.state_name
117 trn_cond = self.trn_cond
118 trn = domview.get_transition(state_name, trn_cond)
119 return trn[3]
120
121 def draw(self, parent):
122 path = self.path
123 self._draw_transition_real(parent, path)
124 pass
125 pass
126
127 class FSM_state(object):
128 _doc = None
129 _domview = None
130 state_name = None
131 state_g = None
132 transitions = None
133
134 def __init__(self, state_name):
135 self.state_name = state_name
136 self.transitions = {}
137 pass
138
139 def init(self, doc, domview):
140 self._doc = doc
141 self._domview = domview
142 pass
143
144 def _draw_state_real(self, parent, state_name, r, x, y):
145 doc = self._doc
132 146
133 state_g = doc.createElement('svg:g') 147 state_g = doc.createElement('svg:g')
134 state_g.setAttribute('inkscape:groupmode', 'layer') 148 state_g.setAttribute('inkscape:groupmode', 'layer')
135 149
136 circle = doc.createElement('svg:circle') 150 circle = doc.createElement('svg:circle')
146 text.appendChild(text_content) 160 text.appendChild(text_content)
147 text.setAttribute('font-size', '16') 161 text.setAttribute('font-size', '16')
148 text.setAttribute('style', 'stroke: #000000; fill: #000000') 162 text.setAttribute('style', 'stroke: #000000; fill: #000000')
149 state_g.appendChild(text) 163 state_g.appendChild(text)
150 164
151 root.appendChild(state_g) 165 parent.appendChild(state_g)
152 166
153 tx, ty, tw, th = text.getBBox() 167 tx, ty, tw, th = text.getBBox()
154 text.setAttribute('x', str(x - tw / 2)) 168 text.setAttribute('x', str(x - tw / 2))
155 text.setAttribute('y', str(y + th / 2)) 169 text.setAttribute('y', str(y + th / 2))
156 170
157 return state_g 171 return state_g
158 172
159 def _draw_state(self, state_name): 173 @property
160 domview = self._domview 174 def r(self):
161 175 domview = self._domview
176 state_name = self.state_name
162 r = domview.get_state_r(state_name) 177 r = domview.get_state_r(state_name)
163 x, y = domview.get_state_xy(state_name) 178 return r
164 state_g = self._draw_state_real(state_name, r, x, y) 179
165 self._state_nodes[state_name] = state_g 180 @property
166 181 def xy(self):
167 transitions = [domview.get_transition(state_name, trn_name)[3] 182 domview = self._domview
168 for trn_name in domview.all_transitions(state_name)] 183 state_name = self.state_name
169 for trn in transitions: 184 xy = domview.get_state_xy(state_name)
170 self._draw_transition_real(state_g, trn) 185 return xy
186
187 @property
188 def all_transitions(self):
189 domview = self._domview
190 state_name = self.state_name
191 conds = domview.all_transitions(state_name)
192 return conds
193
194 def draw(self, parent):
195 domview = self._domview
196 state_name = self.state_name
197
198 r = self.r
199 x, y = self.xy
200 state_g = self._draw_state_real(parent, state_name, r, x, y)
201 self.state_g = state_g
202
203 for trn_cond in self.all_transitions:
204 trn = FSM_transition(trn_cond)
205 trn.init(self._doc, domview, self)
206 trn.draw(parent)
207 self.transitions[trn_cond] = trn
171 pass 208 pass
209 pass
210 pass
211
212 class FSM_window(FSM_window_base):
213 __metaclass__ = data_monitor.data_monitor
214 __data_monitor_prefix__ = 'on_'
215
216 def __init__(self, domview_ui, close_cb, destroy_cb):
217 super(FSM_window, self).__init__()
218
219 self._locker = domview_ui
220
221 self._domview = domview_ui
222 self._states = {}
223
224 self._close_cb = close_cb # callback to close editor window (hide)
225 self._destroy_cb = destroy_cb # callback to destroy editor window
226 pass
227
228 def _doc(self):
229 view_widget = self._view_widget
230 view = view_widget.view
231 doc = view.doc().rdoc
232 return doc
233
234 def _root(self):
235 doc = self._doc()
236 root = doc.root()
237 return root
238
239 def _clear_view(self):
240 root = self._root()
241
242 children = [child for child in root.childList()
243 if child.name() == 'svg:g']
244 for child in children:
245 root.removeChild(child)
246 pass
247
248 self._states = {}
172 pass 249 pass
173 250
174 def _update_view(self): 251 def _update_view(self):
175 self._clear_view() 252 self._clear_view()
176 253
177 domview = self._domview 254 domview = self._domview
255 doc = self._doc()
256 root = self._root()
257
178 state_names = domview.all_state_names() 258 state_names = domview.all_state_names()
179 for state_name in state_names: 259 for state_name in state_names:
180 self._draw_state(state_name) 260 state = FSM_state(state_name)
261 state.init(doc, domview)
262 self._states[state_name] = state
263
264 state.draw(root)
181 pass 265 pass
182 pass 266 pass
183 267
184 def set_svg_view(self, view): 268 def set_svg_view(self, view):
185 self._view_box.add(view) 269 self._view_box.add(view)
239 240, 180, 323 240, 180,
240 260, 180, 324 260, 180,
241 300, 130)) 325 300, 130))
242 self._update_view() 326 self._update_view()
243 327
244 state_g = self._draw_state_real('test1', 40, 100, 50) 328 state = FSM_state('test1')
245 self._draw_transition_real(state_g, (100, 100, 140, 120, 160, 120, 200, 100)) 329 state.init(rdoc, domview)
330 state._draw_state_real(root_node, 'test1', 40, 100, 50)
331
332 trn = FSM_transition('event1')
333 trn.init(rdoc, domview, state)
334 trn._draw_transition_real(root_node, (100, 100,
335 140, 120,
336 160, 120,
337 200, 100))
246 pass 338 pass
247 pass 339 pass
248 340
249 if __name__ == '__main__': 341 if __name__ == '__main__':
250 win = FSM_window() 342 win = FSM_window()