comparison pyink/FSM_window.py @ 1469:c1e70540541c

Drawing functions for states and transitions
author Thinker K.F. Li <thinker@codemud.net>
date Sun, 24 Apr 2011 12:30:47 +0800
parents 6927debad4ee
children 055845649807
comparison
equal deleted inserted replaced
1468:c586981ecf1a 1469:c1e70540541c
66 super(FSM_window, self).__init__() 66 super(FSM_window, self).__init__()
67 67
68 self._locker = domview_ui 68 self._locker = domview_ui
69 69
70 self._domview = domview_ui 70 self._domview = domview_ui
71 self._state_nodes = {}
71 72
72 self._close_cb = close_cb # callback to close editor window (hide) 73 self._close_cb = close_cb # callback to close editor window (hide)
73 self._destroy_cb = destroy_cb # callback to destroy editor window 74 self._destroy_cb = destroy_cb # callback to destroy editor window
74 pass 75 pass
75 76
77 def _doc(self):
78 view_widget = self._view_widget
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
102 doc = self._doc()
103
104 path_node = doc.createElement('svg:path')
105 path_txt = 'M %f,%f C %f,%f %f,%f %f,%f' % tuple(path)
106 path_node.setAttribute('d', path_txt)
107 path_node.setAttribute('style', 'stroke: #000000; stroke-width: 1; '
108 'fill: none')
109 state_g.appendChild(path_node)
110
111 # c0 c1 c2 c3 of cubic curve
112 c3 = (path[6], path[7])
113 c2 = (path[4], path[5])
114 c23_v = (c3[0] - c2[0], c3[1] - c2[1])
115 c23_len = math.sqrt(c23_v[0] * c23_v[0] + c23_v[1] * c23_v[1])
116 adir = (c23_v[0] / c23_len, c23_v[1] / c23_len) # arrow direction
117 odir = (-adir[1], adir[0]) # othogonal direction
118 arrow_pts = (c3[0], c3[1],
119 -adir[0] * 10 + odir[0] * 4, -adir[1] * 10 + odir[1] * 4,
120 -odir[0] * 8, -odir[1] * 8)
121 arrow_txt = 'M %f,%f l %f,%f l %f,%f z' % arrow_pts
122 arrow_node = doc.createElement('svg:path')
123 arrow_node.setAttribute('d', arrow_txt)
124 arrow_node.setAttribute('style', 'stroke: #000000; stroke-width: 1; '
125 'fill: #000000')
126 state_g.appendChild(arrow_node)
127 pass
128
129 def _draw_state_real(self, state_name, r, x, y):
130 doc = self._doc()
131 root = self._root()
132
133 state_g = doc.createElement('svg:g')
134 state_g.setAttribute('inkscape:groupmode', 'layer')
135
136 circle = doc.createElement('svg:circle')
137 circle.setAttribute('r', str(r))
138 circle.setAttribute('cx', str(x))
139 circle.setAttribute('cy', str(y))
140 circle.setAttribute('style', 'stroke: #000000; stroke-width: 1; '
141 'fill: #ffffff')
142 state_g.appendChild(circle)
143
144 text = doc.createElement('svg:text')
145 text_content = doc.createTextNode(state_name)
146 text.appendChild(text_content)
147 text.setAttribute('font-size', '16')
148 text.setAttribute('style', 'stroke: #000000; fill: #000000')
149 state_g.appendChild(text)
150
151 root.appendChild(state_g)
152
153 tx, ty, tw, th = text.getBBox()
154 text.setAttribute('x', str(x - tw / 2))
155 text.setAttribute('y', str(y + th / 2))
156
157 return state_g
158
159 def _draw_state(self, state_name):
160 domview = self._domview
161
162 r = domview.get_state_r(state_name)
163 x, y = domview.get_state_xy(state_name)
164 state_g = self._draw_state_real(state_name, r, x, y)
165 self._state_nodes[state_name] = state_g
166
167 transitions = [domview.get_transition(state_name, trn_name)[3]
168 for trn_name in domview.all_transitions()]
169 for trn in transitions:
170 self._draw_transition_real(state_g, trn)
171 pass
172 pass
173
174 def _update_view(self):
175 self._clear_view()
176
177 domview = self._domview
178 state_names = domview.all_state_names()
179 for state_name in state_names:
180 self._draw_state(state_name)
181 pass
182 pass
183
76 def set_svg_view(self, view): 184 def set_svg_view(self, view):
77 self._view_box.add(view) 185 self._view_box.add(view)
186 self._view_widget = view
78 pass 187 pass
79 188
80 def on_close_window_activate(self, *args): 189 def on_close_window_activate(self, *args):
81 self._close_cb() 190 self._close_cb()
82 pass 191 pass
92 def on_add_state_toggled(self, *args): 201 def on_add_state_toggled(self, *args):
93 domview = self._domview 202 domview = self._domview
94 domview.add_state('test0') 203 domview.add_state('test0')
95 domview.add_state('test1') 204 domview.add_state('test1')
96 domview.add_transition('test0', 'event1', 'test1') 205 domview.add_transition('test0', 'event1', 'test1')
206
207 view = self._view_widget.view
208 doc = view.doc()
209 rdoc = doc.rdoc
210 root_node = doc.root().repr
211
212 line_node = rdoc.createElement('svg:line')
213 line_node.setAttribute('x1', '10')
214 line_node.setAttribute('y1', '10')
215 line_node.setAttribute('x2', '100')
216 line_node.setAttribute('y2', '100')
217 line_node.setAttribute('style', 'stroke: #000000; stroke-width:2')
218
219 print root_node.name()
220 print root_node.childList()[-1].name()
221 root_node.setAttribute('inkscape:groupmode', 'layer')
222 root_node.appendChild(line_node)
223
224 def show_msg(*args, **kws):
225 print 'mouse_event'
226 print args
227 pass
228 print 'before connect'
229 hdl_id = line_node.spitem.connect('mouse-event', show_msg)
230 print hdl_id
231
232 state_g = self._draw_state_real('test1', 40, 100, 50)
233 self._draw_transition_real(state_g, (100, 100, 140, 120, 160, 120, 200, 100))
97 pass 234 pass
98 pass 235 pass
99 236
100 if __name__ == '__main__': 237 if __name__ == '__main__':
101 win = FSM_window() 238 win = FSM_window()