Mercurial > MadButterfly
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() |