76 |
76 |
77 # Constants for defining the type of dragging that has been selected |
77 # Constants for defining the type of dragging that has been selected |
78 [HANDLE_MOVE, HANDLE_RESIZE, HANDLE_POINT, HANDLE_SEGMENT, HANDLE_CONNECTOR] = range(5) |
78 [HANDLE_MOVE, HANDLE_RESIZE, HANDLE_POINT, HANDLE_SEGMENT, HANDLE_CONNECTOR] = range(5) |
79 |
79 |
80 # List of value for resize handle that are valid |
80 # List of value for resize handle that are valid |
81 VALID_HANDLES = [(1,1), (1,2), (1,3), (2,3), (3,3), (3,2), (3,1), (2,1)] |
81 VALID_HANDLES = [(1, 1), (1, 2), (1, 3), (2, 3), (3, 3), (3, 2), (3, 1), (2, 1)] |
82 |
82 |
83 # Contants for defining the direction of a connector |
83 # Contants for defining the direction of a connector |
84 [EAST, NORTH, WEST, SOUTH] = [(1,0), (0,-1), (-1,0), (0,1)] |
84 [EAST, NORTH, WEST, SOUTH] = [(1, 0), (0, -1), (-1, 0), (0, 1)] |
85 |
85 |
86 # Contants for defining which mode is selected for each view |
86 # Contants for defining which mode is selected for each view |
87 [MODE_SELECTION, MODE_BLOCK, MODE_VARIABLE, MODE_CONNECTION, MODE_COMMENT, |
87 [MODE_SELECTION, MODE_BLOCK, MODE_VARIABLE, MODE_CONNECTION, MODE_COMMENT, |
88 MODE_COIL, MODE_CONTACT, MODE_POWERRAIL, MODE_INITIALSTEP, MODE_STEP, |
88 MODE_COIL, MODE_CONTACT, MODE_POWERRAIL, MODE_INITIALSTEP, MODE_STEP, |
89 MODE_TRANSITION, MODE_DIVERGENCE, MODE_JUMP, MODE_ACTION, MODE_MOTION] = range(15) |
89 MODE_TRANSITION, MODE_DIVERGENCE, MODE_JUMP, MODE_ACTION, MODE_MOTION] = range(15) |
90 |
90 |
91 # Contants for defining alignment types for graphic group |
91 # Contants for defining alignment types for graphic group |
92 [ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_TOP, ALIGN_MIDDLE, ALIGN_BOTTOM] = range(6) |
92 [ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_TOP, ALIGN_MIDDLE, ALIGN_BOTTOM] = range(6) |
93 |
93 |
94 # Contants for defining which drawing mode is selected for app |
94 # Contants for defining which drawing mode is selected for app |
95 [FREEDRAWING_MODE, DRIVENDRAWING_MODE] = [1, 2] |
95 [FREEDRAWING_MODE, DRIVENDRAWING_MODE] = [1, 2] |
96 |
96 |
103 |
103 |
104 # Define highlight refresh inhibition period in second |
104 # Define highlight refresh inhibition period in second |
105 REFRESH_HIGHLIGHT_PERIOD = 0.1 |
105 REFRESH_HIGHLIGHT_PERIOD = 0.1 |
106 |
106 |
107 HANDLE_CURSORS = { |
107 HANDLE_CURSORS = { |
108 (1, 1) : 2, |
108 (1, 1): 2, |
109 (3, 3) : 2, |
109 (3, 3): 2, |
110 (1, 3) : 3, |
110 (1, 3): 3, |
111 (3, 1) : 3, |
111 (3, 1): 3, |
112 (1, 2) : 4, |
112 (1, 2): 4, |
113 (3, 2) : 4, |
113 (3, 2): 4, |
114 (2, 1) : 5, |
114 (2, 1): 5, |
115 (2, 3) : 5 |
115 (2, 3): 5 |
116 } |
116 } |
|
117 |
117 |
118 |
118 def round_scaling(x, n, constraint=0): |
119 def round_scaling(x, n, constraint=0): |
119 fraction = float(x) / float(n) |
120 fraction = float(x) / float(n) |
120 if constraint == -1: |
121 if constraint == -1: |
121 xround = int(fraction) |
122 xround = int(fraction) |
122 else: |
123 else: |
123 xround = round(fraction) |
124 xround = round(fraction) |
124 if constraint == 1 and xround < fraction: |
125 if constraint == 1 and xround < fraction: |
125 xround += 1 |
126 xround += 1 |
126 return int(xround * n) |
127 return int(xround * n) |
|
128 |
127 |
129 |
128 """ |
130 """ |
129 Basic vector operations for calculate wire points |
131 Basic vector operations for calculate wire points |
130 """ |
132 """ |
131 |
133 |
132 # Create a vector from two points and define if vector must be normal |
134 |
133 def vector(p1, p2, normal = True): |
135 def vector(p1, p2, normal=True): |
|
136 """ |
|
137 Create a vector from two points and define if vector must be normal |
|
138 """ |
134 vector = (p2.x - p1.x, p2.y - p1.y) |
139 vector = (p2.x - p1.x, p2.y - p1.y) |
135 if normal: |
140 if normal: |
136 return normalize(vector) |
141 return normalize(vector) |
137 return vector |
142 return vector |
138 |
143 |
139 # Calculate the norm of a given vector |
144 |
140 def norm(v): |
145 def norm(v): |
|
146 """ |
|
147 Calculate the norm of a given vector |
|
148 """ |
141 return sqrt(v[0] * v[0] + v[1] * v[1]) |
149 return sqrt(v[0] * v[0] + v[1] * v[1]) |
142 |
150 |
143 # Normalize a given vector |
151 |
144 def normalize(v): |
152 def normalize(v): |
|
153 """ |
|
154 Normalize a given vector |
|
155 """ |
145 v_norm = norm(v) |
156 v_norm = norm(v) |
146 # Verifie if it is not a null vector |
157 # Verifie if it is not a null vector |
147 if v_norm > 0: |
158 if v_norm > 0: |
148 return (v[0] / v_norm, v[1] / v_norm) |
159 return (v[0] / v_norm, v[1] / v_norm) |
149 else: |
160 else: |
150 return v |
161 return v |
151 |
162 |
152 # Calculate the scalar product of two vectors |
163 |
153 def is_null_vector(v): |
164 def is_null_vector(v): |
|
165 """ |
|
166 Calculate the scalar product of two vectors |
|
167 """ |
154 return v == (0, 0) |
168 return v == (0, 0) |
155 |
169 |
156 # Calculate the scalar product of two vectors |
170 |
157 def add_vectors(v1, v2): |
171 def add_vectors(v1, v2): |
|
172 """ |
|
173 Calculate the scalar product of two vectors |
|
174 """ |
158 return (v1[0] + v2[0], v1[1] + v2[1]) |
175 return (v1[0] + v2[0], v1[1] + v2[1]) |
159 |
176 |
160 # Calculate the scalar product of two vectors |
177 |
161 def product(v1, v2): |
178 def product(v1, v2): |
|
179 """ |
|
180 Calculate the scalar product of two vectors |
|
181 """ |
162 return v1[0] * v2[0] + v1[1] * v2[1] |
182 return v1[0] * v2[0] + v1[1] * v2[1] |
163 |
183 |
164 |
184 |
165 """ |
|
166 Function that calculates the nearest point of the grid defined by scaling for the given point |
|
167 """ |
|
168 |
|
169 def GetScaledEventPosition(event, dc, scaling): |
185 def GetScaledEventPosition(event, dc, scaling): |
|
186 """ |
|
187 Function that calculates the nearest point of the grid defined by scaling for the given point |
|
188 """ |
170 pos = event.GetLogicalPosition(dc) |
189 pos = event.GetLogicalPosition(dc) |
171 if scaling: |
190 if scaling: |
172 pos.x = round(float(pos.x) / float(scaling[0])) * scaling[0] |
191 pos.x = round(float(pos.x) / float(scaling[0])) * scaling[0] |
173 pos.y = round(float(pos.y) / float(scaling[1])) * scaling[1] |
192 pos.y = round(float(pos.y) / float(scaling[1])) * scaling[1] |
174 return pos |
193 return pos |
175 |
194 |
176 |
195 |
177 """ |
|
178 Function that choose a direction during the wire points generation |
|
179 """ |
|
180 |
|
181 def DirectionChoice(v_base, v_target, dir_target): |
196 def DirectionChoice(v_base, v_target, dir_target): |
|
197 """ |
|
198 Function that choose a direction during the wire points generation |
|
199 """ |
182 dir_product = product(v_base, v_target) |
200 dir_product = product(v_base, v_target) |
183 if dir_product < 0: |
201 if dir_product < 0: |
184 return (-v_base[0], -v_base[1]) |
202 return (-v_base[0], -v_base[1]) |
185 elif dir_product == 0 and product(v_base, dir_target) != 0: |
203 elif dir_product == 0 and product(v_base, dir_target) != 0: |
186 return dir_target |
204 return dir_target |
187 return v_base |
205 return v_base |
188 |
206 |
|
207 |
189 def MiterPen(colour, width=1, style=wx.SOLID): |
208 def MiterPen(colour, width=1, style=wx.SOLID): |
190 pen = wx.Pen(colour, width, style) |
209 pen = wx.Pen(colour, width, style) |
191 pen.SetJoin(wx.JOIN_MITER) |
210 pen.SetJoin(wx.JOIN_MITER) |
192 pen.SetCap(wx.CAP_PROJECTING) |
211 pen.SetCap(wx.CAP_PROJECTING) |
193 return pen |
212 return pen |
194 |
213 |
195 #------------------------------------------------------------------------------- |
214 |
|
215 # ------------------------------------------------------------------------------- |
196 # Helpers for highlighting text |
216 # Helpers for highlighting text |
197 #------------------------------------------------------------------------------- |
217 # ------------------------------------------------------------------------------- |
|
218 |
198 |
219 |
199 def AddHighlight(highlights, infos): |
220 def AddHighlight(highlights, infos): |
200 RemoveHighlight(highlights, infos) |
221 RemoveHighlight(highlights, infos) |
201 highlights.append(infos) |
222 highlights.append(infos) |
|
223 |
202 |
224 |
203 def RemoveHighlight(highlights, infos): |
225 def RemoveHighlight(highlights, infos): |
204 if infos in highlights: |
226 if infos in highlights: |
205 highlights.remove(infos) |
227 highlights.remove(infos) |
206 return True |
228 return True |
207 return False |
229 return False |
208 |
230 |
|
231 |
209 def ClearHighlight(highlights, highlight_type=None): |
232 def ClearHighlight(highlights, highlight_type=None): |
210 if highlight_type is not None: |
233 if highlight_type is not None: |
211 return [highlight for highlight in highlights if highlight[2] != highlight_type] |
234 return [highlight for highlight in highlights if highlight[2] != highlight_type] |
212 return [] |
235 return [] |
|
236 |
213 |
237 |
214 def DrawHighlightedText(dc, text, highlights, x, y): |
238 def DrawHighlightedText(dc, text, highlights, x, y): |
215 current_pen = dc.GetPen() |
239 current_pen = dc.GetPen() |
216 dc.SetPen(wx.TRANSPARENT_PEN) |
240 dc.SetPen(wx.TRANSPARENT_PEN) |
217 for start, end, highlight_type in highlights: |
241 for start, end, highlight_type in highlights: |
222 dc.DrawRectangle(x + offset_width, y, part_width, part_height) |
246 dc.DrawRectangle(x + offset_width, y, part_width, part_height) |
223 dc.SetTextForeground(highlight_type[1]) |
247 dc.SetTextForeground(highlight_type[1]) |
224 dc.DrawText(part, x + offset_width, y) |
248 dc.DrawText(part, x + offset_width, y) |
225 dc.SetPen(current_pen) |
249 dc.SetPen(current_pen) |
226 dc.SetTextForeground(wx.BLACK) |
250 dc.SetTextForeground(wx.BLACK) |
227 |
251 |
228 #------------------------------------------------------------------------------- |
252 |
|
253 # ------------------------------------------------------------------------------- |
229 # Graphic element base class |
254 # Graphic element base class |
230 #------------------------------------------------------------------------------- |
255 # ------------------------------------------------------------------------------- |
231 |
256 |
232 """ |
|
233 Class that implements a generic graphic element |
|
234 """ |
|
235 |
257 |
236 class Graphic_Element(ToolTipProducer): |
258 class Graphic_Element(ToolTipProducer): |
237 |
259 """ |
|
260 Class that implements a generic graphic element |
|
261 """ |
|
262 |
238 # Create a new graphic element |
263 # Create a new graphic element |
239 def __init__(self, parent, id = None): |
264 def __init__(self, parent, id=None): |
240 ToolTipProducer.__init__(self, parent) |
265 ToolTipProducer.__init__(self, parent) |
241 self.Parent = parent |
266 self.Parent = parent |
242 self.Id = id |
267 self.Id = id |
243 self.oldPos = None |
268 self.oldPos = None |
244 self.StartPos = None |
269 self.StartPos = None |
245 self.CurrentDrag = None |
270 self.CurrentDrag = None |
246 self.Handle = (None,None) |
271 self.Handle = (None, None) |
247 self.Dragging = False |
272 self.Dragging = False |
248 self.Selected = False |
273 self.Selected = False |
249 self.Highlighted = False |
274 self.Highlighted = False |
250 self.Pos = wx.Point(0, 0) |
275 self.Pos = wx.Point(0, 0) |
251 self.Size = wx.Size(0, 0) |
276 self.Size = wx.Size(0, 0) |
252 self.BoundingBox = wx.Rect(0, 0, 0, 0) |
277 self.BoundingBox = wx.Rect(0, 0, 0, 0) |
253 self.Visible = False |
278 self.Visible = False |
254 |
279 |
255 def GetDefinition(self): |
280 def GetDefinition(self): |
256 return [self.Id], [] |
281 return [self.Id], [] |
257 |
282 |
258 def TestVisible(self, screen): |
283 def TestVisible(self, screen): |
259 self.Visible = self.Selected or self.GetRedrawRect().Intersects(screen) |
284 self.Visible = self.Selected or self.GetRedrawRect().Intersects(screen) |
260 |
285 |
261 def IsVisible(self): |
286 def IsVisible(self): |
262 return self.Visible |
287 return self.Visible |
263 |
288 |
264 def SpreadCurrent(self): |
289 def SpreadCurrent(self): |
265 pass |
290 pass |
266 |
291 |
267 def GetConnectorTranslation(self, element): |
292 def GetConnectorTranslation(self, element): |
268 return {} |
293 return {} |
269 |
294 |
270 def FindNearestConnector(self, position, connectors): |
295 def FindNearestConnector(self, position, connectors): |
271 distances = [] |
296 distances = [] |
272 for connector in connectors: |
297 for connector in connectors: |
273 connector_pos = connector.GetRelPosition() |
298 connector_pos = connector.GetRelPosition() |
274 distances.append((sqrt((self.Pos.x + connector_pos.x - position.x) ** 2 + |
299 distances.append((sqrt((self.Pos.x + connector_pos.x - position.x) ** 2 + |
276 connector)) |
301 connector)) |
277 distances.sort() |
302 distances.sort() |
278 if len(distances) > 0: |
303 if len(distances) > 0: |
279 return distances[0][1] |
304 return distances[0][1] |
280 return None |
305 return None |
281 |
306 |
282 def IsOfType(self, type, reference): |
307 def IsOfType(self, type, reference): |
283 return self.Parent.IsOfType(type, reference) |
308 return self.Parent.IsOfType(type, reference) |
284 |
309 |
285 def IsEndType(self, type): |
310 def IsEndType(self, type): |
286 return self.Parent.IsEndType(type) |
311 return self.Parent.IsEndType(type) |
287 |
312 |
288 def GetDragging(self): |
313 def GetDragging(self): |
289 return self.Dragging |
314 return self.Dragging |
290 |
315 |
291 # Make a clone of this element |
316 # Make a clone of this element |
292 def Clone(self, parent): |
317 def Clone(self, parent): |
293 return Graphic_Element(parent, self.Id) |
318 return Graphic_Element(parent, self.Id) |
294 |
319 |
295 # Changes the block position |
320 # Changes the block position |
296 def SetPosition(self, x, y): |
321 def SetPosition(self, x, y): |
297 self.Pos.x = x |
322 self.Pos.x = x |
298 self.Pos.y = y |
323 self.Pos.y = y |
299 self.RefreshConnected() |
324 self.RefreshConnected() |
300 self.RefreshBoundingBox() |
325 self.RefreshBoundingBox() |
301 |
326 |
302 # Returns the block position |
327 # Returns the block position |
303 def GetPosition(self): |
328 def GetPosition(self): |
304 return self.Pos.x, self.Pos.y |
329 return self.Pos.x, self.Pos.y |
305 |
330 |
306 # Changes the element size |
331 # Changes the element size |
307 def SetSize(self, width, height): |
332 def SetSize(self, width, height): |
308 self.Size.SetWidth(width) |
333 self.Size.SetWidth(width) |
309 self.Size.SetHeight(height) |
334 self.Size.SetHeight(height) |
310 self.RefreshConnectors() |
335 self.RefreshConnectors() |
311 self.RefreshBoundingBox() |
336 self.RefreshBoundingBox() |
312 |
337 |
313 # Returns the element size |
338 # Returns the element size |
314 def GetSize(self): |
339 def GetSize(self): |
315 return self.Size.GetWidth(), self.Size.GetHeight() |
340 return self.Size.GetWidth(), self.Size.GetHeight() |
316 |
341 |
317 # Returns the minimum element size |
342 # Returns the minimum element size |
318 def GetMinSize(self): |
343 def GetMinSize(self): |
319 return 0, 0 |
344 return 0, 0 |
320 |
345 |
321 # Set size of the element to the minimum size |
346 # Set size of the element to the minimum size |
322 def SetBestSize(self, scaling, x_factor=0.5, y_factor=0.5): |
347 def SetBestSize(self, scaling, x_factor=0.5, y_factor=0.5): |
323 width, height = self.GetSize() |
348 width, height = self.GetSize() |
324 posx, posy = self.GetPosition() |
349 posx, posy = self.GetPosition() |
325 min_width, min_height = self.GetMinSize() |
350 min_width, min_height = self.GetMinSize() |
334 self.Pos.y = round_scaling(self.Pos.y, scaling[1]) |
359 self.Pos.y = round_scaling(self.Pos.y, scaling[1]) |
335 width = round_scaling(width, scaling[0], 1) |
360 width = round_scaling(width, scaling[0], 1) |
336 height = round_scaling(height, scaling[1], 1) |
361 height = round_scaling(height, scaling[1], 1) |
337 self.SetSize(width, height) |
362 self.SetSize(width, height) |
338 return self.Pos.x - posx, self.Pos.y - posy |
363 return self.Pos.x - posx, self.Pos.y - posy |
339 |
364 |
340 # Refresh the element Bounding Box |
365 # Refresh the element Bounding Box |
341 def RefreshBoundingBox(self): |
366 def RefreshBoundingBox(self): |
342 self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1]) |
367 self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1]) |
343 |
368 |
344 # Refresh the element connectors position |
369 # Refresh the element connectors position |
345 def RefreshConnectors(self): |
370 def RefreshConnectors(self): |
346 pass |
371 pass |
347 |
372 |
348 # Refresh the position of wires connected to element inputs and outputs |
373 # Refresh the position of wires connected to element inputs and outputs |
349 def RefreshConnected(self): |
374 def RefreshConnected(self): |
350 pass |
375 pass |
351 |
376 |
352 # Change the parent |
377 # Change the parent |
353 def SetParent(self, parent): |
378 def SetParent(self, parent): |
354 self.Parent = parent |
379 self.Parent = parent |
355 |
380 |
356 # Override this method for defining the method to call for deleting this element |
381 # Override this method for defining the method to call for deleting this element |
357 def Delete(self): |
382 def Delete(self): |
358 pass |
383 pass |
359 |
384 |
360 # Returns the Id |
385 # Returns the Id |
361 def GetId(self): |
386 def GetId(self): |
362 return self.Id |
387 return self.Id |
363 |
388 |
364 # Returns if the point given is in the bounding box |
389 # Returns if the point given is in the bounding box |
365 def HitTest(self, pt, connectors=True): |
390 def HitTest(self, pt, connectors=True): |
366 if connectors: |
391 if connectors: |
367 rect = self.BoundingBox |
392 rect = self.BoundingBox |
368 else: |
393 else: |
369 rect = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1]) |
394 rect = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1]) |
370 return rect.InsideXY(pt.x, pt.y) |
395 return rect.InsideXY(pt.x, pt.y) |
371 |
396 |
372 # Returns if the point given is in the bounding box |
397 # Returns if the point given is in the bounding box |
373 def IsInSelection(self, rect): |
398 def IsInSelection(self, rect): |
374 return rect.InsideXY(self.BoundingBox.x, self.BoundingBox.y) and rect.InsideXY(self.BoundingBox.x + self.BoundingBox.width, self.BoundingBox.y + self.BoundingBox.height) |
399 return rect.InsideXY(self.BoundingBox.x, self.BoundingBox.y) and rect.InsideXY(self.BoundingBox.x + self.BoundingBox.width, self.BoundingBox.y + self.BoundingBox.height) |
375 |
400 |
376 # Override this method for refreshing the bounding box |
401 # Override this method for refreshing the bounding box |
377 def RefreshBoundingBox(self): |
402 def RefreshBoundingBox(self): |
378 pass |
403 pass |
379 |
404 |
380 # Returns the bounding box |
405 # Returns the bounding box |
381 def GetBoundingBox(self): |
406 def GetBoundingBox(self): |
382 return self.BoundingBox |
407 return self.BoundingBox |
383 |
408 |
384 # Returns the RedrawRect |
409 # Returns the RedrawRect |
385 def GetRedrawRect(self, movex = 0, movey = 0): |
410 def GetRedrawRect(self, movex=0, movey=0): |
386 scalex, scaley = self.Parent.GetViewScale() |
411 scalex, scaley = self.Parent.GetViewScale() |
387 rect = wx.Rect() |
412 rect = wx.Rect() |
388 rect.x = self.BoundingBox.x - int(HANDLE_SIZE / scalex) - 3 - abs(movex) |
413 rect.x = self.BoundingBox.x - int(HANDLE_SIZE / scalex) - 3 - abs(movex) |
389 rect.y = self.BoundingBox.y - int(HANDLE_SIZE / scaley) - 3 - abs(movey) |
414 rect.y = self.BoundingBox.y - int(HANDLE_SIZE / scaley) - 3 - abs(movey) |
390 rect.width = self.BoundingBox.width + 2 * (int(HANDLE_SIZE / scalex) + abs(movex) + 1) + 4 |
415 rect.width = self.BoundingBox.width + 2 * (int(HANDLE_SIZE / scalex) + abs(movex) + 1) + 4 |
391 rect.height = self.BoundingBox.height + 2 * (int(HANDLE_SIZE / scaley) + abs(movey) + 1) + 4 |
416 rect.height = self.BoundingBox.height + 2 * (int(HANDLE_SIZE / scaley) + abs(movey) + 1) + 4 |
392 return rect |
417 return rect |
393 |
418 |
394 def Refresh(self, rect = None): |
419 def Refresh(self, rect=None): |
395 if self.Visible: |
420 if self.Visible: |
396 if rect is not None: |
421 if rect is not None: |
397 self.Parent.RefreshRect(self.Parent.GetScrolledRect(rect), False) |
422 self.Parent.RefreshRect(self.Parent.GetScrolledRect(rect), False) |
398 else: |
423 else: |
399 self.Parent.RefreshRect(self.Parent.GetScrolledRect(self.GetRedrawRect()), False) |
424 self.Parent.RefreshRect(self.Parent.GetScrolledRect(self.GetRedrawRect()), False) |
400 |
425 |
401 # Change the variable that indicates if this element is selected |
426 # Change the variable that indicates if this element is selected |
402 def SetSelected(self, selected): |
427 def SetSelected(self, selected): |
403 self.Selected = selected |
428 self.Selected = selected |
404 self.Refresh() |
429 self.Refresh() |
405 |
430 |
406 # Change the variable that indicates if this element is highlighted |
431 # Change the variable that indicates if this element is highlighted |
407 def SetHighlighted(self, highlighted): |
432 def SetHighlighted(self, highlighted): |
408 self.Highlighted = highlighted |
433 self.Highlighted = highlighted |
409 self.Refresh() |
434 self.Refresh() |
410 |
435 |
411 # Test if the point is on a handle of this element |
436 # Test if the point is on a handle of this element |
412 def TestHandle(self, event): |
437 def TestHandle(self, event): |
413 dc = self.Parent.GetLogicalDC() |
438 dc = self.Parent.GetLogicalDC() |
414 scalex, scaley = dc.GetUserScale() |
439 scalex, scaley = dc.GetUserScale() |
415 pos = event.GetPosition() |
440 pos = event.GetPosition() |
416 pt = wx.Point(*self.Parent.CalcUnscrolledPosition(pos.x, pos.y)) |
441 pt = wx.Point(*self.Parent.CalcUnscrolledPosition(pos.x, pos.y)) |
417 |
442 |
418 left = (self.BoundingBox.x - 2) * scalex - HANDLE_SIZE |
443 left = (self.BoundingBox.x - 2) * scalex - HANDLE_SIZE |
419 center = (self.BoundingBox.x + self.BoundingBox.width / 2) * scalex - HANDLE_SIZE / 2 |
444 center = (self.BoundingBox.x + self.BoundingBox.width / 2) * scalex - HANDLE_SIZE / 2 |
420 right = (self.BoundingBox.x + self.BoundingBox.width + 2) * scalex |
445 right = (self.BoundingBox.x + self.BoundingBox.width + 2) * scalex |
421 |
446 |
422 top = (self.BoundingBox.y - 2) * scaley - HANDLE_SIZE |
447 top = (self.BoundingBox.y - 2) * scaley - HANDLE_SIZE |
423 middle = (self.BoundingBox.y + self.BoundingBox.height / 2) * scaley - HANDLE_SIZE / 2 |
448 middle = (self.BoundingBox.y + self.BoundingBox.height / 2) * scaley - HANDLE_SIZE / 2 |
424 bottom = (self.BoundingBox.y + self.BoundingBox.height + 2) * scaley |
449 bottom = (self.BoundingBox.y + self.BoundingBox.height + 2) * scaley |
425 |
450 |
426 extern_rect = wx.Rect(left, top, right + HANDLE_SIZE - left, bottom + HANDLE_SIZE - top) |
451 extern_rect = wx.Rect(left, top, right + HANDLE_SIZE - left, bottom + HANDLE_SIZE - top) |
427 intern_rect = wx.Rect(left + HANDLE_SIZE, top + HANDLE_SIZE, right - left - HANDLE_SIZE, bottom - top - HANDLE_SIZE) |
452 intern_rect = wx.Rect(left + HANDLE_SIZE, top + HANDLE_SIZE, right - left - HANDLE_SIZE, bottom - top - HANDLE_SIZE) |
428 |
453 |
429 # Verify that this element is selected |
454 # Verify that this element is selected |
430 if self.Selected and extern_rect.InsideXY(pt.x, pt.y) and not intern_rect.InsideXY(pt.x, pt.y): |
455 if self.Selected and extern_rect.InsideXY(pt.x, pt.y) and not intern_rect.InsideXY(pt.x, pt.y): |
431 # Find if point is on a handle horizontally |
456 # Find if point is on a handle horizontally |
432 if left <= pt.x < left + HANDLE_SIZE: |
457 if left <= pt.x < left + HANDLE_SIZE: |
433 handle_x = 1 |
458 handle_x = 1 |
530 cursor = HANDLE_CURSORS.get(handle, 0) |
555 cursor = HANDLE_CURSORS.get(handle, 0) |
531 wx.CallAfter(self.Parent.SetCurrentCursor, cursor) |
556 wx.CallAfter(self.Parent.SetCurrentCursor, cursor) |
532 return 0, 0 |
557 return 0, 0 |
533 |
558 |
534 # Moves the element |
559 # Moves the element |
535 def Move(self, dx, dy, exclude = []): |
560 def Move(self, dx, dy, exclude=[]): |
536 self.Pos.x += max(-self.BoundingBox.x, dx) |
561 self.Pos.x += max(-self.BoundingBox.x, dx) |
537 self.Pos.y += max(-self.BoundingBox.y, dy) |
562 self.Pos.y += max(-self.BoundingBox.y, dy) |
538 self.RefreshConnected(exclude) |
563 self.RefreshConnected(exclude) |
539 self.RefreshBoundingBox() |
564 self.RefreshBoundingBox() |
540 |
565 |
541 # Resizes the element from position and size given |
566 # Resizes the element from position and size given |
542 def Resize(self, x, y, width, height): |
567 def Resize(self, x, y, width, height): |
543 self.Move(x, y) |
568 self.Move(x, y) |
544 self.SetSize(width, height) |
569 self.SetSize(width, height) |
545 |
570 |
546 # Refreshes the element state according to move defined and handle selected |
571 # Refreshes the element state according to move defined and handle selected |
547 def ProcessDragging(self, movex, movey, event, scaling, width_fac = 1, height_fac = 1): |
572 def ProcessDragging(self, movex, movey, event, scaling, width_fac=1, height_fac=1): |
548 handle_type, handle = self.Handle |
573 handle_type, handle = self.Handle |
549 # If it is a resize handle, calculate the values from resizing |
574 # If it is a resize handle, calculate the values from resizing |
550 if handle_type == HANDLE_RESIZE: |
575 if handle_type == HANDLE_RESIZE: |
551 if scaling is not None: |
576 if scaling is not None: |
552 scaling = (scaling[0] * width_fac, scaling[1] * height_fac) |
577 scaling = (scaling[0] * width_fac, scaling[1] * height_fac) |
616 if abs(self.CurrentDrag.x) > abs(self.CurrentDrag.y): |
641 if abs(self.CurrentDrag.x) > abs(self.CurrentDrag.y): |
617 movex = self.StartPos.x + self.CurrentDrag.x - self.Pos.x |
642 movex = self.StartPos.x + self.CurrentDrag.x - self.Pos.x |
618 movey = self.StartPos.y - self.Pos.y |
643 movey = self.StartPos.y - self.Pos.y |
619 else: |
644 else: |
620 movex = self.StartPos.x - self.Pos.x |
645 movex = self.StartPos.x - self.Pos.x |
621 movey = self.StartPos.y + self.CurrentDrag.y - self.Pos.y |
646 movey = self.StartPos.y + self.CurrentDrag.y - self.Pos.y |
622 self.Move(movex, movey) |
647 self.Move(movex, movey) |
623 return movex, movey |
648 return movex, movey |
624 return 0, 0 |
649 return 0, 0 |
625 |
650 |
626 # Override this method for defining the method to call for adding an highlight to this element |
651 # Override this method for defining the method to call for adding an highlight to this element |
627 def AddHighlight(self, infos, start, end, highlight_type): |
652 def AddHighlight(self, infos, start, end, highlight_type): |
628 pass |
653 pass |
629 |
654 |
630 # Override this method for defining the method to call for removing an highlight from this element |
655 # Override this method for defining the method to call for removing an highlight from this element |
631 def RemoveHighlight(self, infos, start, end, highlight_type): |
656 def RemoveHighlight(self, infos, start, end, highlight_type): |
632 pass |
657 pass |
633 |
658 |
634 # Override this method for defining the method to call for removing all the highlights of one particular type from this element |
659 # Override this method for defining the method to call for removing all the highlights of one particular type from this element |
635 def ClearHighlight(self, highlight_type=None): |
660 def ClearHighlight(self, highlight_type=None): |
636 pass |
661 pass |
637 |
662 |
638 # Override this method for defining the method to call for refreshing the model of this element |
663 # Override this method for defining the method to call for refreshing the model of this element |
639 def RefreshModel(self, move=True): |
664 def RefreshModel(self, move=True): |
640 pass |
665 pass |
641 |
666 |
642 # Draws the highlightment of this element if it is highlighted (can be overwritten) |
667 # Draws the highlightment of this element if it is highlighted (can be overwritten) |
643 def DrawHighlightment(self, dc): |
668 def DrawHighlightment(self, dc): |
644 scalex, scaley = dc.GetUserScale() |
669 scalex, scaley = dc.GetUserScale() |
645 dc.SetUserScale(1, 1) |
670 dc.SetUserScale(1, 1) |
646 dc.SetPen(MiterPen(HIGHLIGHTCOLOR)) |
671 dc.SetPen(MiterPen(HIGHLIGHTCOLOR)) |
647 dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR)) |
672 dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR)) |
648 dc.SetLogicalFunction(wx.AND) |
673 dc.SetLogicalFunction(wx.AND) |
649 dc.DrawRectangle(int(round((self.Pos.x - 1) * scalex)) - 2, |
674 dc.DrawRectangle(int(round((self.Pos.x - 1) * scalex)) - 2, |
650 int(round((self.Pos.y - 1) * scaley)) - 2, |
675 int(round((self.Pos.y - 1) * scaley)) - 2, |
651 int(round((self.Size.width + 3) * scalex)) + 5, |
676 int(round((self.Size.width + 3) * scalex)) + 5, |
652 int(round((self.Size.height + 3) * scaley)) + 5) |
677 int(round((self.Size.height + 3) * scaley)) + 5) |
653 dc.SetLogicalFunction(wx.COPY) |
678 dc.SetLogicalFunction(wx.COPY) |
654 dc.SetUserScale(scalex, scaley) |
679 dc.SetUserScale(scalex, scaley) |
655 |
680 |
656 # Draws the handles of this element if it is selected |
681 # Draws the handles of this element if it is selected |
657 def Draw(self, dc): |
682 def Draw(self, dc): |
658 if not getattr(dc, "printing", False): |
683 if not getattr(dc, "printing", False): |
659 if self.Highlighted: |
684 if self.Highlighted: |
660 self.DrawHighlightment(dc) |
685 self.DrawHighlightment(dc) |
661 if self.Selected: |
686 if self.Selected: |
662 scalex, scaley = dc.GetUserScale() |
687 scalex, scaley = dc.GetUserScale() |
663 dc.SetUserScale(1, 1) |
688 dc.SetUserScale(1, 1) |
664 dc.SetPen(MiterPen(wx.BLACK)) |
689 dc.SetPen(MiterPen(wx.BLACK)) |
665 dc.SetBrush(wx.BLACK_BRUSH) |
690 dc.SetBrush(wx.BLACK_BRUSH) |
666 |
691 |
667 left = (self.BoundingBox.x - 2) * scalex - HANDLE_SIZE |
692 left = (self.BoundingBox.x - 2) * scalex - HANDLE_SIZE |
668 center = (self.BoundingBox.x + self.BoundingBox.width / 2) * scalex - HANDLE_SIZE / 2 |
693 center = (self.BoundingBox.x + self.BoundingBox.width / 2) * scalex - HANDLE_SIZE / 2 |
669 right = (self.BoundingBox.x + self.BoundingBox.width + 2) * scalex |
694 right = (self.BoundingBox.x + self.BoundingBox.width + 2) * scalex |
670 |
695 |
671 top = (self.BoundingBox.y - 2) * scaley - HANDLE_SIZE |
696 top = (self.BoundingBox.y - 2) * scaley - HANDLE_SIZE |
672 middle = (self.BoundingBox.y + self.BoundingBox.height / 2) * scaley - HANDLE_SIZE / 2 |
697 middle = (self.BoundingBox.y + self.BoundingBox.height / 2) * scaley - HANDLE_SIZE / 2 |
673 bottom = (self.BoundingBox.y + self.BoundingBox.height + 2) * scaley |
698 bottom = (self.BoundingBox.y + self.BoundingBox.height + 2) * scaley |
674 |
699 |
675 for x, y in [(left, top), (center, top), (right, top), |
700 for x, y in [(left, top), (center, top), (right, top), |
676 (left, middle), (right, middle), |
701 (left, middle), (right, middle), |
677 (left, bottom), (center, bottom), (right, bottom)]: |
702 (left, bottom), (center, bottom), (right, bottom)]: |
678 dc.DrawRectangle(x, y, HANDLE_SIZE, HANDLE_SIZE) |
703 dc.DrawRectangle(x, y, HANDLE_SIZE, HANDLE_SIZE) |
679 |
704 |
680 dc.SetUserScale(scalex, scaley) |
705 dc.SetUserScale(scalex, scaley) |
681 |
706 |
682 |
707 |
683 #------------------------------------------------------------------------------- |
708 # ------------------------------------------------------------------------------- |
684 # Group of graphic elements |
709 # Group of graphic elements |
685 #------------------------------------------------------------------------------- |
710 # ------------------------------------------------------------------------------- |
686 |
711 |
687 """ |
|
688 Class that implements a group of graphic elements |
|
689 """ |
|
690 |
712 |
691 class Graphic_Group(Graphic_Element): |
713 class Graphic_Group(Graphic_Element): |
692 |
714 """ |
|
715 Class that implements a group of graphic elements |
|
716 """ |
|
717 |
693 # Create a new group of graphic elements |
718 # Create a new group of graphic elements |
694 def __init__(self, parent): |
719 def __init__(self, parent): |
695 Graphic_Element.__init__(self, parent) |
720 Graphic_Element.__init__(self, parent) |
696 self.Elements = [] |
721 self.Elements = [] |
697 self.RefreshWireExclusion() |
722 self.RefreshWireExclusion() |
698 self.RefreshBoundingBox() |
723 self.RefreshBoundingBox() |
699 |
724 |
700 # Destructor |
725 # Destructor |
701 def __del__(self): |
726 def __del__(self): |
702 self.Elements = [] |
727 self.Elements = [] |
703 |
728 |
704 def GetDefinition(self): |
729 def GetDefinition(self): |
705 blocks = [] |
730 blocks = [] |
706 wires = [] |
731 wires = [] |
707 for element in self.Elements: |
732 for element in self.Elements: |
708 block, wire = element.GetDefinition() |
733 block, wire = element.GetDefinition() |
709 blocks.extend(block) |
734 blocks.extend(block) |
710 wires.extend(wire) |
735 wires.extend(wire) |
711 return blocks, wires |
736 return blocks, wires |
712 |
737 |
713 # Make a clone of this element |
738 # Make a clone of this element |
714 def Clone(self, parent, pos = None): |
739 def Clone(self, parent, pos=None): |
715 group = Graphic_Group(parent) |
740 group = Graphic_Group(parent) |
716 connectors = {} |
741 connectors = {} |
717 exclude_names = {} |
742 exclude_names = {} |
718 wires = [] |
743 wires = [] |
719 if pos is not None: |
744 if pos is not None: |
749 if pos is not None: |
774 if pos is not None: |
750 for element in group.Elements: |
775 for element in group.Elements: |
751 if not isinstance(element, Wire): |
776 if not isinstance(element, Wire): |
752 parent.AddBlockInModel(element) |
777 parent.AddBlockInModel(element) |
753 return group |
778 return group |
754 |
779 |
755 def CanAddBlocks(self, parent): |
780 def CanAddBlocks(self, parent): |
756 valid = True |
781 valid = True |
757 for element in self.Elements: |
782 for element in self.Elements: |
758 if not isinstance(element, Wire): |
783 if not isinstance(element, Wire): |
759 valid &= parent.CanAddElement(element) |
784 valid &= parent.CanAddElement(element) |
760 return valid |
785 return valid |
761 |
786 |
762 def IsVisible(self): |
787 def IsVisible(self): |
763 for element in self.Elements: |
788 for element in self.Elements: |
764 if element.IsVisible(): |
789 if element.IsVisible(): |
765 return True |
790 return True |
766 return False |
791 return False |
767 |
792 |
768 # Refresh the list of wire excluded |
793 # Refresh the list of wire excluded |
769 def RefreshWireExclusion(self): |
794 def RefreshWireExclusion(self): |
770 self.WireExcluded = [] |
795 self.WireExcluded = [] |
771 for element in self.Elements: |
796 for element in self.Elements: |
772 if isinstance(element, Wire): |
797 if isinstance(element, Wire): |
773 startblock = element.StartConnected.GetParentBlock() |
798 startblock = element.StartConnected.GetParentBlock() |
774 endblock = element.EndConnected.GetParentBlock() |
799 endblock = element.EndConnected.GetParentBlock() |
775 if startblock in self.Elements and endblock in self.Elements: |
800 if startblock in self.Elements and endblock in self.Elements: |
776 self.WireExcluded.append(element) |
801 self.WireExcluded.append(element) |
777 |
802 |
778 # Returns the RedrawRect |
803 # Returns the RedrawRect |
779 def GetRedrawRect(self, movex = 0, movey = 0): |
804 def GetRedrawRect(self, movex=0, movey=0): |
780 rect = None |
805 rect = None |
781 for element in self.Elements: |
806 for element in self.Elements: |
782 if rect is None: |
807 if rect is None: |
783 rect = element.GetRedrawRect(movex, movey) |
808 rect = element.GetRedrawRect(movex, movey) |
784 else: |
809 else: |
785 rect = rect.Union(element.GetRedrawRect(movex, movey)) |
810 rect = rect.Union(element.GetRedrawRect(movex, movey)) |
786 return rect |
811 return rect |
787 |
812 |
788 # Clean this group of elements |
813 # Clean this group of elements |
789 def Clean(self): |
814 def Clean(self): |
790 # Clean all the elements of the group |
815 # Clean all the elements of the group |
791 for element in self.Elements: |
816 for element in self.Elements: |
792 element.Clean() |
817 element.Clean() |
793 |
818 |
794 # Delete this group of elements |
819 # Delete this group of elements |
795 def Delete(self): |
820 def Delete(self): |
796 # Delete all the elements of the group |
821 # Delete all the elements of the group |
797 for element in self.Elements: |
822 for element in self.Elements: |
798 element.Delete() |
823 element.Delete() |
799 self.WireExcluded = [] |
824 self.WireExcluded = [] |
800 |
825 |
801 # Returns if the point given is in the bounding box of one of the elements of this group |
826 # Returns if the point given is in the bounding box of one of the elements of this group |
802 def HitTest(self, pt, connectors=True): |
827 def HitTest(self, pt, connectors=True): |
803 result = False |
828 result = False |
804 for element in self.Elements: |
829 for element in self.Elements: |
805 result |= element.HitTest(pt, connectors) |
830 result |= element.HitTest(pt, connectors) |
806 return result |
831 return result |
807 |
832 |
808 # Returns if the element given is in this group |
833 # Returns if the element given is in this group |
809 def IsElementIn(self, element): |
834 def IsElementIn(self, element): |
810 return element in self.Elements |
835 return element in self.Elements |
811 |
836 |
812 # Change the elements of the group |
837 # Change the elements of the group |
813 def SetElements(self, elements): |
838 def SetElements(self, elements): |
814 self.Elements = elements |
839 self.Elements = elements |
815 self.RefreshWireExclusion() |
840 self.RefreshWireExclusion() |
816 self.RefreshBoundingBox() |
841 self.RefreshBoundingBox() |
817 |
842 |
818 # Returns the elements of the group |
843 # Returns the elements of the group |
819 def GetElements(self): |
844 def GetElements(self): |
820 return self.Elements |
845 return self.Elements |
821 |
846 |
822 # Align the group elements |
847 # Align the group elements |
823 def AlignElements(self, horizontally, vertically): |
848 def AlignElements(self, horizontally, vertically): |
824 minx = self.BoundingBox.x + self.BoundingBox.width |
849 minx = self.BoundingBox.x + self.BoundingBox.width |
825 miny = self.BoundingBox.y + self.BoundingBox.height |
850 miny = self.BoundingBox.y + self.BoundingBox.height |
826 maxx = self.BoundingBox.x |
851 maxx = self.BoundingBox.x |
852 movey = maxy - height - posy |
877 movey = maxy - height - posy |
853 if movex != 0 or movey != 0: |
878 if movex != 0 or movey != 0: |
854 element.Move(movex, movey) |
879 element.Move(movex, movey) |
855 element.RefreshModel() |
880 element.RefreshModel() |
856 self.RefreshBoundingBox() |
881 self.RefreshBoundingBox() |
857 |
882 |
858 # Add the given element to the group of elements |
883 # Add the given element to the group of elements |
859 def AddElement(self, element): |
884 def AddElement(self, element): |
860 self.Elements.append(element) |
885 self.Elements.append(element) |
861 |
886 |
862 # Remove or select the given element if it is or not in the group |
887 # Remove or select the given element if it is or not in the group |
863 def SelectElement(self, element): |
888 def SelectElement(self, element): |
864 if element in self.Elements: |
889 if element in self.Elements: |
865 self.Elements.remove(element) |
890 self.Elements.remove(element) |
866 else: |
891 else: |
867 self.Elements.append(element) |
892 self.Elements.append(element) |
868 self.RefreshWireExclusion() |
893 self.RefreshWireExclusion() |
869 self.RefreshBoundingBox() |
894 self.RefreshBoundingBox() |
870 |
895 |
871 # Move this group of elements |
896 # Move this group of elements |
872 def Move(self, movex, movey): |
897 def Move(self, movex, movey): |
873 movex = max(-self.BoundingBox.x, movex) |
898 movex = max(-self.BoundingBox.x, movex) |
874 movey = max(-self.BoundingBox.y, movey) |
899 movey = max(-self.BoundingBox.y, movey) |
875 # Move all the elements of the group |
900 # Move all the elements of the group |
917 posy = min(posy, bbox.y) |
942 posy = min(posy, bbox.y) |
918 if posx is None and posy is None: |
943 if posx is None and posy is None: |
919 return 0, 0 |
944 return 0, 0 |
920 return posx, posy |
945 return posx, posy |
921 return self.BoundingBox.x, self.BoundingBox.y |
946 return self.BoundingBox.x, self.BoundingBox.y |
922 |
947 |
923 # Forbids to change the group size |
948 # Forbids to change the group size |
924 def SetSize(width, height): |
949 def SetSize(width, height): |
925 pass |
950 pass |
926 |
951 |
927 # Returns the size of this group |
952 # Returns the size of this group |
928 def GetSize(self): |
953 def GetSize(self): |
929 return self.BoundingBox.width, self.BoundingBox.height |
954 return self.BoundingBox.width, self.BoundingBox.height |
930 |
955 |
931 # Set size of the group elements to their minimum size |
956 # Set size of the group elements to their minimum size |
932 def SetBestSize(self, scaling): |
957 def SetBestSize(self, scaling): |
933 max_movex = max_movey = 0 |
958 max_movex = max_movey = 0 |
934 for element in self.Elements: |
959 for element in self.Elements: |
935 movex, movey = element.SetBestSize(scaling) |
960 movex, movey = element.SetBestSize(scaling) |
936 max_movex = max(max_movex, movex) |
961 max_movex = max(max_movex, movex) |
937 max_movey = max(max_movey, movey) |
962 max_movey = max(max_movey, movey) |
938 return max_movex, max_movey |
963 return max_movex, max_movey |
939 |
964 |
940 # Refreshes the group elements to move defined and handle selected |
965 # Refreshes the group elements to move defined and handle selected |
941 def ProcessDragging(self, movex, movey, event, scaling): |
966 def ProcessDragging(self, movex, movey, event, scaling): |
942 handle_type, handle = self.Handle |
967 handle_type, handle = self.Handle |
943 # If it is a move handle, Move this group elements |
968 # If it is a move handle, Move this group elements |
944 if handle_type == HANDLE_MOVE: |
969 if handle_type == HANDLE_MOVE: |
958 movex = self.StartPos.x - posx |
983 movex = self.StartPos.x - posx |
959 movey = self.StartPos.y + self.CurrentDrag.y - posy |
984 movey = self.StartPos.y + self.CurrentDrag.y - posy |
960 self.Move(movex, movey) |
985 self.Move(movex, movey) |
961 return movex, movey |
986 return movex, movey |
962 return 0, 0 |
987 return 0, 0 |
963 |
988 |
964 # Change the variable that indicates if this element is highlighted |
989 # Change the variable that indicates if this element is highlighted |
965 def SetHighlighted(self, highlighted): |
990 def SetHighlighted(self, highlighted): |
966 for element in self.Elements: |
991 for element in self.Elements: |
967 element.SetHighlighted(highlighted) |
992 element.SetHighlighted(highlighted) |
968 |
993 |
969 def HighlightPoint(self, pos): |
994 def HighlightPoint(self, pos): |
970 for element in self.Elements: |
995 for element in self.Elements: |
971 if isinstance(element, Wire): |
996 if isinstance(element, Wire): |
972 element.HighlightPoint(pos) |
997 element.HighlightPoint(pos) |
973 |
998 |
974 # Method called when a LeftDown event have been generated |
999 # Method called when a LeftDown event have been generated |
975 def OnLeftDown(self, event, dc, scaling): |
1000 def OnLeftDown(self, event, dc, scaling): |
976 Graphic_Element.OnLeftDown(self, event, dc, scaling) |
1001 Graphic_Element.OnLeftDown(self, event, dc, scaling) |
977 self.StartPos = wx.Point(*self.GetPosition(True)) |
1002 self.StartPos = wx.Point(*self.GetPosition(True)) |
978 for element in self.Elements: |
1003 for element in self.Elements: |
1058 else: |
1084 else: |
1059 height = CONNECTOR_SIZE |
1085 height = CONNECTOR_SIZE |
1060 if self.Edge == "rising" and self.Direction[1] == 1: |
1086 if self.Edge == "rising" and self.Direction[1] == 1: |
1061 y -= 5 |
1087 y -= 5 |
1062 height += 5 |
1088 height += 5 |
1063 rect = wx.Rect(x - abs(movex), y - abs(movey), width + 2 * abs(movex), height + 2 * abs(movey)) |
1089 rect = wx.Rect(x - abs(movex), y - abs(movey), width + 2 * abs(movex), height + 2 * abs(movey)) |
1064 if self.ValueSize is None and isinstance(self.ComputedValue, (StringType, UnicodeType)): |
1090 if self.ValueSize is None and isinstance(self.ComputedValue, (StringType, UnicodeType)): |
1065 self.ValueSize = self.ParentBlock.Parent.GetMiniTextExtent(self.ComputedValue) |
1091 self.ValueSize = self.ParentBlock.Parent.GetMiniTextExtent(self.ComputedValue) |
1066 if self.ValueSize is not None: |
1092 if self.ValueSize is not None: |
1067 width, height = self.ValueSize |
1093 width, height = self.ValueSize |
1068 rect = rect.Union(wx.Rect( |
1094 rect = rect.Union( |
1069 parent_pos[0] + self.Pos.x + CONNECTOR_SIZE * self.Direction[0] + \ |
1095 wx.Rect( |
1070 width * (self.Direction[0] - 1) / 2, |
1096 parent_pos[0] + self.Pos.x + CONNECTOR_SIZE * self.Direction[0] + |
1071 parent_pos[1] + self.Pos.y + CONNECTOR_SIZE * self.Direction[1] + \ |
1097 width * (self.Direction[0] - 1) / 2, |
1072 height * (self.Direction[1] - 1), |
1098 parent_pos[1] + self.Pos.y + CONNECTOR_SIZE * self.Direction[1] + |
|
1099 height * (self.Direction[1] - 1), |
1073 width, height)) |
1100 width, height)) |
1074 return rect |
1101 return rect |
1075 |
1102 |
1076 # Change the connector selection |
1103 # Change the connector selection |
1077 def SetSelected(self, selected): |
1104 def SetSelected(self, selected): |
1078 self.Selected = selected |
1105 self.Selected = selected |
1079 |
1106 |
1080 # Make a clone of the connector |
1107 # Make a clone of the connector |
1081 def Clone(self, parent = None): |
1108 def Clone(self, parent=None): |
1082 if parent is None: |
1109 if parent is None: |
1083 parent = self.ParentBlock |
1110 parent = self.ParentBlock |
1084 return Connector(parent, self.Name, self.Type, wx.Point(self.Pos[0], self.Pos[1]), |
1111 return Connector(parent, self.Name, self.Type, wx.Point(self.Pos[0], self.Pos[1]), |
1085 self.Direction, self.Negated) |
1112 self.Direction, self.Negated) |
1086 |
1113 |
1087 # Returns the connector parent block |
1114 # Returns the connector parent block |
1088 def GetParentBlock(self): |
1115 def GetParentBlock(self): |
1089 return self.ParentBlock |
1116 return self.ParentBlock |
1090 |
1117 |
1091 # Returns the connector type |
1118 # Returns the connector type |
1092 def GetType(self, raw = False): |
1119 def GetType(self, raw=False): |
1093 if self.ParentBlock.IsEndType(self.Type) or raw: |
1120 if self.ParentBlock.IsEndType(self.Type) or raw: |
1094 return self.Type |
1121 return self.Type |
1095 elif (self.Negated or self.Edge != "none") and self.ParentBlock.IsOfType("BOOL", self.Type): |
1122 elif (self.Negated or self.Edge != "none") and self.ParentBlock.IsOfType("BOOL", self.Type): |
1096 return "BOOL" |
1123 return "BOOL" |
1097 else: |
1124 else: |
1098 return self.ParentBlock.GetConnectionResultType(self, self.Type) |
1125 return self.ParentBlock.GetConnectionResultType(self, self.Type) |
1099 |
1126 |
1100 # Returns the connector type |
1127 # Returns the connector type |
1101 def GetConnectedType(self): |
1128 def GetConnectedType(self): |
1102 if self.ParentBlock.IsEndType(self.Type): |
1129 if self.ParentBlock.IsEndType(self.Type): |
1103 return self.Type |
1130 return self.Type |
1104 elif len(self.Wires) == 1: |
1131 elif len(self.Wires) == 1: |
1105 return self.Wires[0][0].GetOtherConnectedType(self.Wires[0][1]) |
1132 return self.Wires[0][0].GetOtherConnectedType(self.Wires[0][1]) |
1106 return self.Type |
1133 return self.Type |
1107 |
1134 |
1108 # Returns the connector type |
1135 # Returns the connector type |
1109 def GetConnectedRedrawRect(self, movex, movey): |
1136 def GetConnectedRedrawRect(self, movex, movey): |
1110 rect = None |
1137 rect = None |
1111 for wire, handle in self.Wires: |
1138 for wire, handle in self.Wires: |
1112 if rect is None: |
1139 if rect is None: |
1113 rect = wire.GetRedrawRect() |
1140 rect = wire.GetRedrawRect() |
1114 else: |
1141 else: |
1115 rect = rect.Union(wire.GetRedrawRect()) |
1142 rect = rect.Union(wire.GetRedrawRect()) |
1116 return rect |
1143 return rect |
1117 |
1144 |
1118 # Returns if connector type is compatible with type given |
1145 # Returns if connector type is compatible with type given |
1119 def IsCompatible(self, type): |
1146 def IsCompatible(self, type): |
1120 reference = self.GetType() |
1147 reference = self.GetType() |
1121 return self.ParentBlock.IsOfType(type, reference) or self.ParentBlock.IsOfType(reference, type) |
1148 return self.ParentBlock.IsOfType(type, reference) or self.ParentBlock.IsOfType(reference, type) |
1122 |
1149 |
1123 # Changes the connector name |
1150 # Changes the connector name |
1124 def SetType(self, type): |
1151 def SetType(self, type): |
1125 self.Type = type |
1152 self.Type = type |
1126 for wire, handle in self.Wires: |
1153 for wire, handle in self.Wires: |
1127 wire.SetValid(wire.IsConnectedCompatible()) |
1154 wire.SetValid(wire.IsConnectedCompatible()) |
1128 |
1155 |
1129 # Returns the connector name |
1156 # Returns the connector name |
1130 def GetName(self): |
1157 def GetName(self): |
1131 return self.Name |
1158 return self.Name |
1132 |
1159 |
1133 # Changes the connector name |
1160 # Changes the connector name |
1134 def SetName(self, name): |
1161 def SetName(self, name): |
1135 self.Name = name |
1162 self.Name = name |
1136 self.RefreshNameSize() |
1163 self.RefreshNameSize() |
1137 |
1164 |
1138 def SetForced(self, forced): |
1165 def SetForced(self, forced): |
1139 if self.Forced != forced: |
1166 if self.Forced != forced: |
1140 self.Forced = forced |
1167 self.Forced = forced |
1141 if self.Visible: |
1168 if self.Visible: |
1142 self.Parent.ElementNeedRefresh(self) |
1169 self.Parent.ElementNeedRefresh(self) |
1143 |
1170 |
1144 def GetComputedValue(self): |
1171 def GetComputedValue(self): |
1145 if self.Value is not None and self.Value != "undefined" and not isinstance(self.Value, BooleanType): |
1172 if self.Value is not None and self.Value != "undefined" and not isinstance(self.Value, BooleanType): |
1146 return self.Value |
1173 return self.Value |
1147 return None |
1174 return None |
1148 |
1175 |
1149 def GetToolTipValue(self): |
1176 def GetToolTipValue(self): |
1150 return self.GetComputedValue() |
1177 return self.GetComputedValue() |
1151 |
1178 |
1152 def SetValue(self, value): |
1179 def SetValue(self, value): |
1153 if self.Value != value: |
1180 if self.Value != value: |
1154 self.Value = value |
1181 self.Value = value |
1155 computed_value = self.GetComputedValue() |
1182 computed_value = self.GetComputedValue() |
1156 if computed_value is not None: |
1183 if computed_value is not None: |
1159 if len(self.ComputedValue) > 4: |
1186 if len(self.ComputedValue) > 4: |
1160 self.ComputedValue = self.ComputedValue[:4] + "..." |
1187 self.ComputedValue = self.ComputedValue[:4] + "..." |
1161 self.ValueSize = None |
1188 self.ValueSize = None |
1162 if self.ParentBlock.Visible: |
1189 if self.ParentBlock.Visible: |
1163 self.ParentBlock.Parent.ElementNeedRefresh(self) |
1190 self.ParentBlock.Parent.ElementNeedRefresh(self) |
1164 |
1191 |
1165 def RefreshForced(self): |
1192 def RefreshForced(self): |
1166 self.Forced = False |
1193 self.Forced = False |
1167 for wire, handle in self.Wires: |
1194 for wire, handle in self.Wires: |
1168 self.Forced |= wire.IsForced() |
1195 self.Forced |= wire.IsForced() |
1169 |
1196 |
1170 def RefreshValue(self): |
1197 def RefreshValue(self): |
1171 self.Value = self.ReceivingCurrent() |
1198 self.Value = self.ReceivingCurrent() |
1172 |
1199 |
1173 def RefreshValid(self): |
1200 def RefreshValid(self): |
1174 self.Valid = True |
1201 self.Valid = True |
1175 for wire, handle in self.Wires: |
1202 for wire, handle in self.Wires: |
1176 self.Valid &= wire.GetValid() |
1203 self.Valid &= wire.GetValid() |
1177 |
1204 |
1178 def ReceivingCurrent(self): |
1205 def ReceivingCurrent(self): |
1179 current = False |
1206 current = False |
1180 for wire, handle in self.Wires: |
1207 for wire, handle in self.Wires: |
1181 value = wire.GetValue() |
1208 value = wire.GetValue() |
1182 if current != "undefined" and isinstance(value, BooleanType): |
1209 if current != "undefined" and isinstance(value, BooleanType): |
1183 current |= wire.GetValue() |
1210 current |= wire.GetValue() |
1184 elif value == "undefined": |
1211 elif value == "undefined": |
1185 current = "undefined" |
1212 current = "undefined" |
1186 return current |
1213 return current |
1187 |
1214 |
1188 def SpreadCurrent(self, spreading): |
1215 def SpreadCurrent(self, spreading): |
1189 for wire, handle in self.Wires: |
1216 for wire, handle in self.Wires: |
1190 wire.SetValue(spreading) |
1217 wire.SetValue(spreading) |
1191 |
1218 |
1192 # Changes the connector name size |
1219 # Changes the connector name size |
1193 def RefreshNameSize(self): |
1220 def RefreshNameSize(self): |
1194 if self.Name != "": |
1221 if self.Name != "": |
1195 self.NameSize = self.ParentBlock.Parent.GetTextExtent(self.Name) |
1222 self.NameSize = self.ParentBlock.Parent.GetTextExtent(self.Name) |
1196 else: |
1223 else: |
1197 self.NameSize = 0, 0 |
1224 self.NameSize = 0, 0 |
1198 |
1225 |
1199 # Returns the connector name size |
1226 # Returns the connector name size |
1200 def GetNameSize(self): |
1227 def GetNameSize(self): |
1201 return self.NameSize |
1228 return self.NameSize |
1202 |
1229 |
1203 # Returns the wires connected to the connector |
1230 # Returns the wires connected to the connector |
1204 def GetWires(self): |
1231 def GetWires(self): |
1205 return self.Wires |
1232 return self.Wires |
1206 |
1233 |
1207 # Returns the parent block Id |
1234 # Returns the parent block Id |
1208 def GetBlockId(self): |
1235 def GetBlockId(self): |
1209 return self.ParentBlock.GetId() |
1236 return self.ParentBlock.GetId() |
1210 |
1237 |
1211 # Returns the connector relative position |
1238 # Returns the connector relative position |
1212 def GetRelPosition(self): |
1239 def GetRelPosition(self): |
1213 return self.Pos |
1240 return self.Pos |
1214 |
1241 |
1215 # Returns the connector absolute position |
1242 # Returns the connector absolute position |
1216 def GetPosition(self, size = True): |
1243 def GetPosition(self, size=True): |
1217 parent_pos = self.ParentBlock.GetPosition() |
1244 parent_pos = self.ParentBlock.GetPosition() |
1218 # If the position of the end of the connector is asked |
1245 # If the position of the end of the connector is asked |
1219 if size: |
1246 if size: |
1220 x = parent_pos[0] + self.Pos.x + self.Direction[0] * CONNECTOR_SIZE |
1247 x = parent_pos[0] + self.Pos.x + self.Direction[0] * CONNECTOR_SIZE |
1221 y = parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE |
1248 y = parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE |
1222 else: |
1249 else: |
1223 x = parent_pos[0] + self.Pos.x |
1250 x = parent_pos[0] + self.Pos.x |
1224 y = parent_pos[1] + self.Pos.y |
1251 y = parent_pos[1] + self.Pos.y |
1225 return wx.Point(x, y) |
1252 return wx.Point(x, y) |
1226 |
1253 |
1227 # Change the connector relative position |
1254 # Change the connector relative position |
1228 def SetPosition(self, pos): |
1255 def SetPosition(self, pos): |
1229 self.Pos = pos |
1256 self.Pos = pos |
1230 |
1257 |
1231 # Returns the connector direction |
1258 # Returns the connector direction |
1232 def GetDirection(self): |
1259 def GetDirection(self): |
1233 return self.Direction |
1260 return self.Direction |
1234 |
1261 |
1235 # Change the connector direction |
1262 # Change the connector direction |
1236 def SetDirection(self, direction): |
1263 def SetDirection(self, direction): |
1237 self.Direction = direction |
1264 self.Direction = direction |
1238 |
1265 |
1239 # Connect a wire to this connector at the last place |
1266 # Connect a wire to this connector at the last place |
1240 def Connect(self, wire, refresh = True): |
1267 def Connect(self, wire, refresh=True): |
1241 self.InsertConnect(len(self.Wires), wire, refresh) |
1268 self.InsertConnect(len(self.Wires), wire, refresh) |
1242 |
1269 |
1243 # Connect a wire to this connector at the place given |
1270 # Connect a wire to this connector at the place given |
1244 def InsertConnect(self, idx, wire, refresh = True): |
1271 def InsertConnect(self, idx, wire, refresh=True): |
1245 if wire not in self.Wires: |
1272 if wire not in self.Wires: |
1246 self.Wires.insert(idx, wire) |
1273 self.Wires.insert(idx, wire) |
1247 if wire[1] == 0: |
1274 if wire[1] == 0: |
1248 wire[0].ConnectStartPoint(None, self) |
1275 wire[0].ConnectStartPoint(None, self) |
1249 else: |
1276 else: |
1250 wire[0].ConnectEndPoint(None, self) |
1277 wire[0].ConnectEndPoint(None, self) |
1251 if refresh: |
1278 if refresh: |
1252 self.ParentBlock.RefreshModel(False) |
1279 self.ParentBlock.RefreshModel(False) |
1253 |
1280 |
1254 # Returns the index of the wire given in the list of connected |
1281 # Returns the index of the wire given in the list of connected |
1255 def GetWireIndex(self, wire): |
1282 def GetWireIndex(self, wire): |
1256 for i, (tmp_wire, handle) in enumerate(self.Wires): |
1283 for i, (tmp_wire, handle) in enumerate(self.Wires): |
1257 if tmp_wire == wire: |
1284 if tmp_wire == wire: |
1258 return i |
1285 return i |
1259 return None |
1286 return None |
1260 |
1287 |
1261 # Unconnect a wire or all wires connected to the connector |
1288 # Unconnect a wire or all wires connected to the connector |
1262 def UnConnect(self, wire = None, unconnect = True, delete = False): |
1289 def UnConnect(self, wire=None, unconnect=True, delete=False): |
1263 i = 0 |
1290 i = 0 |
1264 found = False |
1291 found = False |
1265 while i < len(self.Wires) and not found: |
1292 while i < len(self.Wires) and not found: |
1266 if not wire or self.Wires[i][0] == wire: |
1293 if not wire or self.Wires[i][0] == wire: |
1267 # If Unconnect haven't been called from a wire, disconnect the connector in the wire |
1294 # If Unconnect haven't been called from a wire, disconnect the connector in the wire |
1298 if wire not in exclude: |
1325 if wire not in exclude: |
1299 if index == 0: |
1326 if index == 0: |
1300 wire.MoveStartPoint(wx.Point(x, y)) |
1327 wire.MoveStartPoint(wx.Point(x, y)) |
1301 else: |
1328 else: |
1302 wire.MoveEndPoint(wx.Point(x, y)) |
1329 wire.MoveEndPoint(wx.Point(x, y)) |
1303 |
1330 |
1304 # Refreshes the model of all the wires connected |
1331 # Refreshes the model of all the wires connected |
1305 def RefreshWires(self): |
1332 def RefreshWires(self): |
1306 for wire in self.Wires: |
1333 for wire in self.Wires: |
1307 wire[0].RefreshModel() |
1334 wire[0].RefreshModel() |
1308 |
1335 |
1309 # Refreshes the parent block model |
1336 # Refreshes the parent block model |
1310 def RefreshParentBlock(self): |
1337 def RefreshParentBlock(self): |
1311 self.ParentBlock.RefreshModel(False) |
1338 self.ParentBlock.RefreshModel(False) |
1312 |
1339 |
1313 # Highlight the parent block |
1340 # Highlight the parent block |
1314 def HighlightParentBlock(self, highlight): |
1341 def HighlightParentBlock(self, highlight): |
1315 self.ParentBlock.SetHighlighted(highlight) |
1342 self.ParentBlock.SetHighlighted(highlight) |
1316 self.ParentBlock.Refresh() |
1343 self.ParentBlock.Refresh() |
1317 |
1344 |
1318 # Returns all the blocks connected to this connector |
1345 # Returns all the blocks connected to this connector |
1319 def GetConnectedBlocks(self): |
1346 def GetConnectedBlocks(self): |
1320 blocks = [] |
1347 blocks = [] |
1321 for wire, handle in self.Wires: |
1348 for wire, handle in self.Wires: |
1322 # Get other connector connected to each wire |
1349 # Get other connector connected to each wire |
1328 if connector: |
1355 if connector: |
1329 block = connector.GetParentBlock() |
1356 block = connector.GetParentBlock() |
1330 if block not in blocks: |
1357 if block not in blocks: |
1331 blocks.append(block) |
1358 blocks.append(block) |
1332 return blocks |
1359 return blocks |
1333 |
1360 |
1334 # Returns the connector negated property |
1361 # Returns the connector negated property |
1335 def IsNegated(self): |
1362 def IsNegated(self): |
1336 return self.Negated |
1363 return self.Negated |
1337 |
1364 |
1338 # Changes the connector negated property |
1365 # Changes the connector negated property |
1339 def SetNegated(self, negated): |
1366 def SetNegated(self, negated): |
1340 if self.ParentBlock.IsOfType("BOOL", self.Type): |
1367 if self.ParentBlock.IsOfType("BOOL", self.Type): |
1341 self.Negated = negated |
1368 self.Negated = negated |
1342 self.Edge = "none" |
1369 self.Edge = "none" |
1343 |
1370 |
1344 # Returns the connector edge property |
1371 # Returns the connector edge property |
1345 def GetEdge(self): |
1372 def GetEdge(self): |
1346 return self.Edge |
1373 return self.Edge |
1347 |
1374 |
1348 # Changes the connector edge property |
1375 # Changes the connector edge property |
1349 def SetEdge(self, edge): |
1376 def SetEdge(self, edge): |
1350 if self.ParentBlock.IsOfType("BOOL", self.Type): |
1377 if self.ParentBlock.IsOfType("BOOL", self.Type): |
1351 self.Edge = edge |
1378 self.Edge = edge |
1352 self.Negated = False |
1379 self.Negated = False |
1353 |
1380 |
1354 # assume that pointer is already inside of this connector |
1381 # assume that pointer is already inside of this connector |
1355 def ConnectionAvailable(self, direction=None, exclude=True): |
1382 def ConnectionAvailable(self, direction=None, exclude=True): |
1356 wire_nums = len(self.Wires) |
1383 wire_nums = len(self.Wires) |
1357 |
1384 |
1358 connector_free = (wire_nums<= 0) |
1385 connector_free = (wire_nums <= 0) |
1359 connector_max_used = ((wire_nums > 0) and self.OneConnected) |
1386 connector_max_used = ((wire_nums > 0) and self.OneConnected) |
1360 if (self.Parent.CurrentLanguage in ["SFC", "LD"]) and (self.Type == "BOOL"): |
1387 if (self.Parent.CurrentLanguage in ["SFC", "LD"]) and (self.Type == "BOOL"): |
1361 connector_max_used = False; |
1388 connector_max_used = False |
1362 |
1389 |
1363 # connector is available for new connection |
1390 # connector is available for new connection |
1364 connect = connector_free or not connector_max_used |
1391 connect = connector_free or not connector_max_used |
1365 return connect, connector_max_used |
1392 return connect, connector_max_used |
1366 |
1393 |
1367 # Tests if the point given is near from the end point of this connector |
1394 # Tests if the point given is near from the end point of this connector |
1368 def TestPoint(self, pt, direction=None, exclude=True): |
1395 def TestPoint(self, pt, direction=None, exclude=True): |
1369 inside = False; |
1396 inside = False |
1370 check_point = (not exclude) and (direction is None or self.Direction == direction); |
1397 check_point = (not exclude) and (direction is None or self.Direction == direction) |
1371 |
1398 |
1372 if check_point: |
1399 if check_point: |
1373 # Calculate a square around the end point of this connector |
1400 # Calculate a square around the end point of this connector |
1374 parent_pos = self.ParentBlock.GetPosition() |
1401 parent_pos = self.ParentBlock.GetPosition() |
1375 x = parent_pos[0] + self.Pos.x + self.Direction[0] * CONNECTOR_SIZE - ANCHOR_DISTANCE |
1402 x = parent_pos[0] + self.Pos.x + self.Direction[0] * CONNECTOR_SIZE - ANCHOR_DISTANCE |
1376 y = parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE - ANCHOR_DISTANCE |
1403 y = parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE - ANCHOR_DISTANCE |
1377 width = ANCHOR_DISTANCE * 2 + abs(self.Direction[0]) * CONNECTOR_SIZE |
1404 width = ANCHOR_DISTANCE * 2 + abs(self.Direction[0]) * CONNECTOR_SIZE |
1378 height = ANCHOR_DISTANCE * 2 + abs(self.Direction[1]) * CONNECTOR_SIZE |
1405 height = ANCHOR_DISTANCE * 2 + abs(self.Direction[1]) * CONNECTOR_SIZE |
1379 rect = wx.Rect(x, y, width, height) |
1406 rect = wx.Rect(x, y, width, height) |
1380 inside = rect.InsideXY(pt.x, pt.y); |
1407 inside = rect.InsideXY(pt.x, pt.y) |
1381 |
1408 |
1382 return inside |
1409 return inside |
1383 |
1410 |
1384 # Draws the highlightment of this element if it is highlighted |
1411 # Draws the highlightment of this element if it is highlighted |
1385 def DrawHighlightment(self, dc): |
1412 def DrawHighlightment(self, dc): |
1386 scalex, scaley = dc.GetUserScale() |
1413 scalex, scaley = dc.GetUserScale() |
1387 dc.SetUserScale(1, 1) |
1414 dc.SetUserScale(1, 1) |
1388 pen = MiterPen(HIGHLIGHTCOLOR, 2 * scalex + 5) |
1415 pen = MiterPen(HIGHLIGHTCOLOR, 2 * scalex + 5) |
1391 dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR)) |
1418 dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR)) |
1392 dc.SetLogicalFunction(wx.AND) |
1419 dc.SetLogicalFunction(wx.AND) |
1393 parent_pos = self.ParentBlock.GetPosition() |
1420 parent_pos = self.ParentBlock.GetPosition() |
1394 posx = parent_pos[0] + self.Pos.x |
1421 posx = parent_pos[0] + self.Pos.x |
1395 posy = parent_pos[1] + self.Pos.y |
1422 posy = parent_pos[1] + self.Pos.y |
1396 xstart = parent_pos[0] + self.Pos.x |
1423 xstart = parent_pos[0] + self.Pos.x |
1397 ystart = parent_pos[1] + self.Pos.y |
1424 ystart = parent_pos[1] + self.Pos.y |
1398 if self.Direction[0] < 0: |
1425 if self.Direction[0] < 0: |
1399 xstart += 1 |
1426 xstart += 1 |
1400 if self.Direction[1] < 0: |
1427 if self.Direction[1] < 0: |
1401 ystart += 1 |
1428 ystart += 1 |
1402 xend = xstart + CONNECTOR_SIZE * self.Direction[0] |
1429 xend = xstart + CONNECTOR_SIZE * self.Direction[0] |
1403 yend = ystart + CONNECTOR_SIZE * self.Direction[1] |
1430 yend = ystart + CONNECTOR_SIZE * self.Direction[1] |
1404 dc.DrawLine(round((xstart + self.Direction[0]) * scalex), round((ystart + self.Direction[1]) * scaley), |
1431 dc.DrawLine(round((xstart + self.Direction[0]) * scalex), round((ystart + self.Direction[1]) * scaley), |
1405 round(xend * scalex), round(yend * scaley)) |
1432 round(xend * scalex), round(yend * scaley)) |
1406 dc.SetLogicalFunction(wx.COPY) |
1433 dc.SetLogicalFunction(wx.COPY) |
1407 dc.SetUserScale(scalex, scaley) |
1434 dc.SetUserScale(scalex, scaley) |
1408 |
1435 |
1409 # Adds an highlight to the connector |
1436 # Adds an highlight to the connector |
1410 def AddHighlight(self, infos, start, end, highlight_type): |
1437 def AddHighlight(self, infos, start, end, highlight_type): |
1411 if highlight_type == ERROR_HIGHLIGHT: |
1438 if highlight_type == ERROR_HIGHLIGHT: |
1412 for wire, handle in self.Wires: |
1439 for wire, handle in self.Wires: |
1413 wire.SetValid(False) |
1440 wire.SetValid(False) |
1414 AddHighlight(self.Highlights, (start, end, highlight_type)) |
1441 AddHighlight(self.Highlights, (start, end, highlight_type)) |
1415 |
1442 |
1416 # Removes an highlight from the connector |
1443 # Removes an highlight from the connector |
1417 def RemoveHighlight(self, infos, start, end, highlight_type): |
1444 def RemoveHighlight(self, infos, start, end, highlight_type): |
1418 error = False |
1445 error = False |
1419 highlights = [] |
1446 highlights = [] |
1420 for highlight in self.Highlights: |
1447 for highlight in self.Highlights: |
1464 dc.SetPen(MiterPen(wx.BLUE)) |
1491 dc.SetPen(MiterPen(wx.BLUE)) |
1465 else: |
1492 else: |
1466 dc.SetPen(MiterPen(wx.BLACK)) |
1493 dc.SetPen(MiterPen(wx.BLACK)) |
1467 dc.SetBrush(wx.WHITE_BRUSH) |
1494 dc.SetBrush(wx.WHITE_BRUSH) |
1468 parent_pos = self.ParentBlock.GetPosition() |
1495 parent_pos = self.ParentBlock.GetPosition() |
1469 |
1496 |
1470 if getattr(dc, "printing", False): |
1497 if getattr(dc, "printing", False): |
1471 name_size = dc.GetTextExtent(self.Name) |
1498 name_size = dc.GetTextExtent(self.Name) |
1472 else: |
1499 else: |
1473 name_size = self.NameSize |
1500 name_size = self.NameSize |
1474 |
1501 |
1475 if self.Negated: |
1502 if self.Negated: |
1476 # If connector is negated, draw a circle |
1503 # If connector is negated, draw a circle |
1477 xcenter = parent_pos[0] + self.Pos.x + (CONNECTOR_SIZE * self.Direction[0]) / 2 |
1504 xcenter = parent_pos[0] + self.Pos.x + (CONNECTOR_SIZE * self.Direction[0]) / 2 |
1478 ycenter = parent_pos[1] + self.Pos.y + (CONNECTOR_SIZE * self.Direction[1]) / 2 |
1505 ycenter = parent_pos[1] + self.Pos.y + (CONNECTOR_SIZE * self.Direction[1]) / 2 |
1479 dc.DrawCircle(xcenter, ycenter, CONNECTOR_SIZE / 2) |
1506 dc.DrawCircle(xcenter, ycenter, CONNECTOR_SIZE / 2) |
1480 else: |
1507 else: |
1481 xstart = parent_pos[0] + self.Pos.x |
1508 xstart = parent_pos[0] + self.Pos.x |
1482 ystart = parent_pos[1] + self.Pos.y |
1509 ystart = parent_pos[1] + self.Pos.y |
1483 if self.Edge == "rising": |
1510 if self.Edge == "rising": |
1484 # If connector has a rising edge, draw a right arrow |
1511 # If connector has a rising edge, draw a right arrow |
1485 dc.DrawLine(xstart, ystart, xstart - 4, ystart - 4) |
1512 dc.DrawLine(xstart, ystart, xstart - 4, ystart - 4) |
1486 dc.DrawLine(xstart, ystart, xstart - 4, ystart + 4) |
1513 dc.DrawLine(xstart, ystart, xstart - 4, ystart + 4) |
1522 dc.SetTextForeground(wx.NamedColour("purple")) |
1549 dc.SetTextForeground(wx.NamedColour("purple")) |
1523 if self.ValueSize is None and isinstance(self.ComputedValue, (StringType, UnicodeType)): |
1550 if self.ValueSize is None and isinstance(self.ComputedValue, (StringType, UnicodeType)): |
1524 self.ValueSize = self.ParentBlock.Parent.GetMiniTextExtent(self.ComputedValue) |
1551 self.ValueSize = self.ParentBlock.Parent.GetMiniTextExtent(self.ComputedValue) |
1525 if self.ValueSize is not None: |
1552 if self.ValueSize is not None: |
1526 width, height = self.ValueSize |
1553 width, height = self.ValueSize |
1527 dc.DrawText(self.ComputedValue, |
1554 dc.DrawText(self.ComputedValue, |
1528 parent_pos[0] + self.Pos.x + CONNECTOR_SIZE * self.Direction[0] + \ |
1555 parent_pos[0] + self.Pos.x + CONNECTOR_SIZE * self.Direction[0] + |
1529 width * (self.Direction[0] - 1) / 2, |
1556 width * (self.Direction[0] - 1) / 2, |
1530 parent_pos[1] + self.Pos.y + CONNECTOR_SIZE * self.Direction[1] + \ |
1557 parent_pos[1] + self.Pos.y + CONNECTOR_SIZE * self.Direction[1] + |
1531 height * (self.Direction[1] - 1)) |
1558 height * (self.Direction[1] - 1)) |
1532 dc.SetFont(self.ParentBlock.Parent.GetFont()) |
1559 dc.SetFont(self.ParentBlock.Parent.GetFont()) |
1533 dc.SetTextForeground(wx.BLACK) |
1560 dc.SetTextForeground(wx.BLACK) |
1534 |
1561 |
1535 #------------------------------------------------------------------------------- |
1562 |
|
1563 # ------------------------------------------------------------------------------- |
1536 # Common Wire Element |
1564 # Common Wire Element |
1537 #------------------------------------------------------------------------------- |
1565 # ------------------------------------------------------------------------------- |
1538 |
1566 |
1539 """ |
|
1540 Class that implements a wire for connecting two blocks |
|
1541 """ |
|
1542 |
1567 |
1543 class Wire(Graphic_Element, DebugDataConsumer): |
1568 class Wire(Graphic_Element, DebugDataConsumer): |
1544 |
1569 """ |
|
1570 Class that implements a wire for connecting two blocks |
|
1571 """ |
|
1572 |
1545 # Create a new wire |
1573 # Create a new wire |
1546 def __init__(self, parent, start = None, end = None): |
1574 def __init__(self, parent, start=None, end=None): |
1547 Graphic_Element.__init__(self, parent) |
1575 Graphic_Element.__init__(self, parent) |
1548 DebugDataConsumer.__init__(self) |
1576 DebugDataConsumer.__init__(self) |
1549 self.StartPoint = start |
1577 self.StartPoint = start |
1550 self.EndPoint = end |
1578 self.EndPoint = end |
1551 self.StartConnected = None |
1579 self.StartConnected = None |
1566 self.OverStart = False |
1594 self.OverStart = False |
1567 self.OverEnd = False |
1595 self.OverEnd = False |
1568 self.ComputingType = False |
1596 self.ComputingType = False |
1569 self.Font = parent.GetMiniFont() |
1597 self.Font = parent.GetMiniFont() |
1570 self.ErrHighlight = False |
1598 self.ErrHighlight = False |
1571 |
1599 |
1572 def GetDefinition(self): |
1600 def GetDefinition(self): |
1573 if self.StartConnected is not None and self.EndConnected is not None: |
1601 if self.StartConnected is not None and self.EndConnected is not None: |
1574 startblock = self.StartConnected.GetParentBlock() |
1602 startblock = self.StartConnected.GetParentBlock() |
1575 endblock = self.EndConnected.GetParentBlock() |
1603 endblock = self.EndConnected.GetParentBlock() |
1576 return [], [(startblock.GetId(), endblock.GetId())] |
1604 return [], [(startblock.GetId(), endblock.GetId())] |
1577 return [], [] |
1605 return [], [] |
1578 |
1606 |
1579 def Flush(self): |
1607 def Flush(self): |
1580 self.StartConnected = None |
1608 self.StartConnected = None |
1581 self.EndConnected = None |
1609 self.EndConnected = None |
1582 |
1610 |
1583 # Returns the RedrawRect |
1611 # Returns the RedrawRect |
1584 def GetRedrawRect(self, movex = 0, movey = 0): |
1612 def GetRedrawRect(self, movex=0, movey=0): |
1585 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
1613 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
1586 if self.StartConnected: |
1614 if self.StartConnected: |
1587 rect = rect.Union(self.StartConnected.GetRedrawRect(movex, movey)) |
1615 rect = rect.Union(self.StartConnected.GetRedrawRect(movex, movey)) |
1588 if self.EndConnected: |
1616 if self.EndConnected: |
1589 rect = rect.Union(self.EndConnected.GetRedrawRect(movex, movey)) |
1617 rect = rect.Union(self.EndConnected.GetRedrawRect(movex, movey)) |
1662 movey_max = max(movey_max, movey) |
1690 movey_max = max(movey_max, movey) |
1663 point.x += movex |
1691 point.x += movex |
1664 point.y += movey |
1692 point.y += movey |
1665 return movex_max, movey_max |
1693 return movex_max, movey_max |
1666 return 0, 0 |
1694 return 0, 0 |
1667 |
1695 |
1668 # Returns connector to which start point is connected |
1696 # Returns connector to which start point is connected |
1669 def GetStartConnected(self): |
1697 def GetStartConnected(self): |
1670 return self.StartConnected |
1698 return self.StartConnected |
1671 |
1699 |
1672 # Returns connector to which start point is connected |
1700 # Returns connector to which start point is connected |
1673 def GetStartConnectedType(self): |
1701 def GetStartConnectedType(self): |
1674 if self.StartConnected and not self.ComputingType: |
1702 if self.StartConnected and not self.ComputingType: |
1675 self.ComputingType = True |
1703 self.ComputingType = True |
1676 computed_type = self.StartConnected.GetType() |
1704 computed_type = self.StartConnected.GetType() |
1677 self.ComputingType = False |
1705 self.ComputingType = False |
1678 return computed_type |
1706 return computed_type |
1679 return None |
1707 return None |
1680 |
1708 |
1681 # Returns connector to which end point is connected |
1709 # Returns connector to which end point is connected |
1682 def GetEndConnected(self): |
1710 def GetEndConnected(self): |
1683 return self.EndConnected |
1711 return self.EndConnected |
1684 |
1712 |
1685 # Returns connector to which end point is connected |
1713 # Returns connector to which end point is connected |
1686 def GetEndConnectedType(self): |
1714 def GetEndConnectedType(self): |
1687 if self.EndConnected and not self.ComputingType: |
1715 if self.EndConnected and not self.ComputingType: |
1688 self.ComputingType = True |
1716 self.ComputingType = True |
1689 computed_type = self.EndConnected.GetType() |
1717 computed_type = self.EndConnected.GetType() |
1690 self.ComputingType = False |
1718 self.ComputingType = False |
1691 return computed_type |
1719 return computed_type |
1692 return None |
1720 return None |
1693 |
1721 |
1694 def GetConnectionDirection(self): |
1722 def GetConnectionDirection(self): |
1695 if self.StartConnected is None and self.EndConnected is None: |
1723 if self.StartConnected is None and self.EndConnected is None: |
1696 return None |
1724 return None |
1697 elif self.StartConnected is not None and self.EndConnected is None: |
1725 elif self.StartConnected is not None and self.EndConnected is None: |
1698 return (-self.StartPoint[1][0], -self.StartPoint[1][1]) |
1726 return (-self.StartPoint[1][0], -self.StartPoint[1][1]) |
1705 if handle == 0: |
1733 if handle == 0: |
1706 return self.EndPoint |
1734 return self.EndPoint |
1707 else: |
1735 else: |
1708 return (-self.StartPoint[1][0], -self.StartPoint[1][1]) |
1736 return (-self.StartPoint[1][0], -self.StartPoint[1][1]) |
1709 return None |
1737 return None |
1710 |
1738 |
1711 def GetOtherConnected(self, connector): |
1739 def GetOtherConnected(self, connector): |
1712 if self.StartConnected == connector: |
1740 if self.StartConnected == connector: |
1713 return self.EndConnected |
1741 return self.EndConnected |
1714 else: |
1742 else: |
1715 return self.StartConnected |
1743 return self.StartConnected |
1716 |
1744 |
1717 def GetOtherConnectedType(self, handle): |
1745 def GetOtherConnectedType(self, handle): |
1718 if handle == 0: |
1746 if handle == 0: |
1719 return self.GetEndConnectedType() |
1747 return self.GetEndConnectedType() |
1720 else: |
1748 else: |
1721 return self.GetStartConnectedType() |
1749 return self.GetStartConnectedType() |
1722 |
1750 |
1723 def IsConnectedCompatible(self): |
1751 def IsConnectedCompatible(self): |
1724 if self.StartConnected: |
1752 if self.StartConnected: |
1725 return self.StartConnected.IsCompatible(self.GetEndConnectedType()) |
1753 return self.StartConnected.IsCompatible(self.GetEndConnectedType()) |
1726 elif self.EndConnected: |
1754 elif self.EndConnected: |
1727 return True |
1755 return True |
1728 return False |
1756 return False |
1729 |
1757 |
1730 def SetForced(self, forced): |
1758 def SetForced(self, forced): |
1731 if self.Forced != forced: |
1759 if self.Forced != forced: |
1732 self.Forced = forced |
1760 self.Forced = forced |
1733 if self.StartConnected: |
1761 if self.StartConnected: |
1734 self.StartConnected.RefreshForced() |
1762 self.StartConnected.RefreshForced() |
1771 if self.Visible: |
1799 if self.Visible: |
1772 self.Parent.ElementNeedRefresh(self) |
1800 self.Parent.ElementNeedRefresh(self) |
1773 if isinstance(value, BooleanType) and self.StartConnected is not None: |
1801 if isinstance(value, BooleanType) and self.StartConnected is not None: |
1774 block = self.StartConnected.GetParentBlock() |
1802 block = self.StartConnected.GetParentBlock() |
1775 block.SpreadCurrent() |
1803 block.SpreadCurrent() |
1776 |
1804 |
1777 # Unconnect the start and end points |
1805 # Unconnect the start and end points |
1778 def Clean(self): |
1806 def Clean(self): |
1779 if self.StartConnected: |
1807 if self.StartConnected: |
1780 self.UnConnectStartPoint() |
1808 self.UnConnectStartPoint() |
1781 if self.EndConnected: |
1809 if self.EndConnected: |
1782 self.UnConnectEndPoint() |
1810 self.UnConnectEndPoint() |
1783 |
1811 |
1784 # Delete this wire by calling the corresponding method |
1812 # Delete this wire by calling the corresponding method |
1785 def Delete(self): |
1813 def Delete(self): |
1786 self.Parent.DeleteWire(self) |
1814 self.Parent.DeleteWire(self) |
1787 |
1815 |
1788 # Select a segment and not the whole wire. It's useful for Ladder Diagram |
1816 # Select a segment and not the whole wire. It's useful for Ladder Diagram |
1789 def SetSelectedSegment(self, segment): |
1817 def SetSelectedSegment(self, segment): |
1790 # The last segment is indicated |
1818 # The last segment is indicated |
1791 if segment == -1: |
1819 if segment == -1: |
1792 segment = len(self.Segments) - 1 |
1820 segment = len(self.Segments) - 1 |
1793 # The selected segment is reinitialised |
1821 # The selected segment is reinitialised |
1794 if segment == None: |
1822 if segment is None: |
1795 if self.StartConnected: |
1823 if self.StartConnected: |
1796 self.StartConnected.SetSelected(False) |
1824 self.StartConnected.SetSelected(False) |
1797 if self.EndConnected: |
1825 if self.EndConnected: |
1798 self.EndConnected.SetSelected(False) |
1826 self.EndConnected.SetSelected(False) |
1799 # The segment selected is the first |
1827 # The segment selected is the first |
1812 self.StartConnected.SetSelected(False) |
1840 self.StartConnected.SetSelected(False) |
1813 if self.EndConnected: |
1841 if self.EndConnected: |
1814 self.EndConnected.SetSelected(True) |
1842 self.EndConnected.SetSelected(True) |
1815 self.SelectedSegment = segment |
1843 self.SelectedSegment = segment |
1816 self.Refresh() |
1844 self.Refresh() |
1817 |
1845 |
1818 def SetValid(self, valid): |
1846 def SetValid(self, valid): |
1819 self.Valid = valid |
1847 self.Valid = valid |
1820 if self.StartConnected: |
1848 if self.StartConnected: |
1821 self.StartConnected.RefreshValid() |
1849 self.StartConnected.RefreshValid() |
1822 if self.EndConnected: |
1850 if self.EndConnected: |
1823 self.EndConnected.RefreshValid() |
1851 self.EndConnected.RefreshValid() |
1824 |
1852 |
1825 def GetValid(self): |
1853 def GetValid(self): |
1826 return self.Valid |
1854 return self.Valid |
1827 |
1855 |
1828 # Reinitialize the wire points |
1856 # Reinitialize the wire points |
1829 def ResetPoints(self): |
1857 def ResetPoints(self): |
1830 if self.StartPoint and self.EndPoint: |
1858 if self.StartPoint and self.EndPoint: |
1831 self.Points = [self.StartPoint[0], self.EndPoint[0]] |
1859 self.Points = [self.StartPoint[0], self.EndPoint[0]] |
1832 self.Segments = [self.StartPoint[1]] |
1860 self.Segments = [self.StartPoint[1]] |
1833 else: |
1861 else: |
1834 self.Points = [] |
1862 self.Points = [] |
1835 self.Segments = [] |
1863 self.Segments = [] |
1836 |
1864 |
1837 # Refresh the wire bounding box |
1865 # Refresh the wire bounding box |
1838 def RefreshBoundingBox(self): |
1866 def RefreshBoundingBox(self): |
1839 if len(self.Points) > 0: |
1867 if len(self.Points) > 0: |
1840 # If startpoint or endpoint is connected, save the point radius |
1868 # If startpoint or endpoint is connected, save the point radius |
1841 start_radius = end_radius = 0 |
1869 start_radius = end_radius = 0 |
1860 miny, minbbxy = min(miny, self.Points[-1].y), min(minbbxy, self.Points[-1].y - end_radius) |
1888 miny, minbbxy = min(miny, self.Points[-1].y), min(minbbxy, self.Points[-1].y - end_radius) |
1861 maxy, maxbbxy = max(maxy, self.Points[-1].y), max(maxbbxy, self.Points[-1].y + end_radius) |
1889 maxy, maxbbxy = max(maxy, self.Points[-1].y), max(maxbbxy, self.Points[-1].y + end_radius) |
1862 self.Pos.x, self.Pos.y = minx, miny |
1890 self.Pos.x, self.Pos.y = minx, miny |
1863 self.Size = wx.Size(maxx - minx, maxy - miny) |
1891 self.Size = wx.Size(maxx - minx, maxy - miny) |
1864 self.BoundingBox = wx.Rect(minbbxx, minbbxy, maxbbxx - minbbxx + 1, maxbbxy - minbbxy + 1) |
1892 self.BoundingBox = wx.Rect(minbbxx, minbbxy, maxbbxx - minbbxx + 1, maxbbxy - minbbxy + 1) |
1865 |
1893 |
1866 # Refresh the realpoints that permits to keep the proportionality in wire during resizing |
1894 # Refresh the realpoints that permits to keep the proportionality in wire during resizing |
1867 def RefreshRealPoints(self): |
1895 def RefreshRealPoints(self): |
1868 if len(self.Points) > 0: |
1896 if len(self.Points) > 0: |
1869 self.RealPoints = [] |
1897 self.RealPoints = [] |
1870 # Calculate float relative position of each point with the minimum point |
1898 # Calculate float relative position of each point with the minimum point |
1871 for point in self.Points: |
1899 for point in self.Points: |
1872 self.RealPoints.append([float(point.x - self.Pos.x), float(point.y - self.Pos.y)]) |
1900 self.RealPoints.append([float(point.x - self.Pos.x), float(point.y - self.Pos.y)]) |
1873 |
1901 |
1874 # Returns the wire minimum size |
1902 # Returns the wire minimum size |
1875 def GetMinSize(self): |
1903 def GetMinSize(self): |
1876 width = 1 |
1904 width = 1 |
1877 height = 1 |
1905 height = 1 |
1878 dir_product = product(self.StartPoint[1], self.EndPoint[1]) |
1906 dir_product = product(self.StartPoint[1], self.EndPoint[1]) |
1879 # The directions are opposed |
1907 # The directions are opposed |
1891 # The directions are perpendiculars |
1919 # The directions are perpendiculars |
1892 else: |
1920 else: |
1893 width = MIN_SEGMENT_SIZE |
1921 width = MIN_SEGMENT_SIZE |
1894 height = MIN_SEGMENT_SIZE |
1922 height = MIN_SEGMENT_SIZE |
1895 return width + 1, height + 1 |
1923 return width + 1, height + 1 |
1896 |
1924 |
1897 # Returns if the point given is on one of the wire segments |
1925 # Returns if the point given is on one of the wire segments |
1898 def HitTest(self, pt, connectors=True): |
1926 def HitTest(self, pt, connectors=True): |
1899 test = False |
1927 test = False |
1900 for i in xrange(len(self.Points) - 1): |
1928 for i in xrange(len(self.Points) - 1): |
1901 rect = wx.Rect(0, 0, 0, 0) |
1929 rect = wx.Rect(0, 0, 0, 0) |
1902 if i == 0 and self.StartConnected is not None: |
1930 if i == 0 and self.StartConnected is not None: |
1903 x1 = self.Points[i].x - self.Segments[0][0] * CONNECTOR_SIZE |
1931 x1 = self.Points[i].x - self.Segments[0][0] * CONNECTOR_SIZE |
1904 y1 = self.Points[i].y - self.Segments[0][1] * CONNECTOR_SIZE |
1932 y1 = self.Points[i].y - self.Segments[0][1] * CONNECTOR_SIZE |
1905 else: |
1933 else: |
1906 x1, y1 = self.Points[i].x, self.Points[i].y |
1934 x1, y1 = self.Points[i].x, self.Points[i].y |
1907 if i == len(self.Points) - 2 and self.EndConnected is not None: |
1935 if i == len(self.Points) - 2 and self.EndConnected is not None: |
1908 x2 = self.Points[i + 1].x + self.Segments[-1][0] * CONNECTOR_SIZE |
1936 x2 = self.Points[i + 1].x + self.Segments[-1][0] * CONNECTOR_SIZE |
1909 y2 = self.Points[i + 1].y + self.Segments[-1][1] * CONNECTOR_SIZE |
1937 y2 = self.Points[i + 1].y + self.Segments[-1][1] * CONNECTOR_SIZE |
1910 else: |
1938 else: |
1911 x2, y2 = self.Points[i + 1].x, self.Points[i + 1].y |
1939 x2, y2 = self.Points[i + 1].x, self.Points[i + 1].y |
1912 # Calculate a rectangle around the segment |
1940 # Calculate a rectangle around the segment |
1913 rect = wx.Rect(min(x1, x2) - ANCHOR_DISTANCE, min(y1, y2) - ANCHOR_DISTANCE, |
1941 rect = wx.Rect(min(x1, x2) - ANCHOR_DISTANCE, min(y1, y2) - ANCHOR_DISTANCE, |
1914 abs(x1 - x2) + 2 * ANCHOR_DISTANCE, abs(y1 - y2) + 2 * ANCHOR_DISTANCE) |
1942 abs(x1 - x2) + 2 * ANCHOR_DISTANCE, abs(y1 - y2) + 2 * ANCHOR_DISTANCE) |
1915 test |= rect.InsideXY(pt.x, pt.y) |
1943 test |= rect.InsideXY(pt.x, pt.y) |
1916 return test |
1944 return test |
1917 |
1945 |
1918 # Returns the wire start or end point if the point given is on one of them |
1946 # Returns the wire start or end point if the point given is on one of them |
1919 def TestPoint(self, pt): |
1947 def TestPoint(self, pt): |
1920 # Test the wire start point |
1948 # Test the wire start point |
1921 rect = wx.Rect(self.Points[0].x - ANCHOR_DISTANCE, self.Points[0].y - ANCHOR_DISTANCE, |
1949 rect = wx.Rect(self.Points[0].x - ANCHOR_DISTANCE, self.Points[0].y - ANCHOR_DISTANCE, |
1922 2 * ANCHOR_DISTANCE, 2 * ANCHOR_DISTANCE) |
1950 2 * ANCHOR_DISTANCE, 2 * ANCHOR_DISTANCE) |
1923 if rect.InsideXY(pt.x, pt.y): |
1951 if rect.InsideXY(pt.x, pt.y): |
1924 return 0 |
1952 return 0 |
1925 # Test the wire end point |
1953 # Test the wire end point |
1926 if len(self.Points) > 1: |
1954 if len(self.Points) > 1: |
1927 rect = wx.Rect(self.Points[-1].x - ANCHOR_DISTANCE, self.Points[-1].y - ANCHOR_DISTANCE, |
1955 rect = wx.Rect(self.Points[-1].x - ANCHOR_DISTANCE, self.Points[-1].y - ANCHOR_DISTANCE, |
1928 2 * ANCHOR_DISTANCE, 2 * ANCHOR_DISTANCE) |
1956 2 * ANCHOR_DISTANCE, 2 * ANCHOR_DISTANCE) |
1929 if rect.InsideXY(pt.x, pt.y): |
1957 if rect.InsideXY(pt.x, pt.y): |
1930 return -1 |
1958 return -1 |
1931 return None |
1959 return None |
1932 |
1960 |
1933 # Returns the wire segment if the point given is on it |
1961 # Returns the wire segment if the point given is on it |
1934 def TestSegment(self, pt, all=False): |
1962 def TestSegment(self, pt, all=False): |
1935 for i in xrange(len(self.Segments)): |
1963 for i in xrange(len(self.Segments)): |
1936 # If wire is not in a Ladder Diagram, first and last segments are excluded |
1964 # If wire is not in a Ladder Diagram, first and last segments are excluded |
1937 if all or 0 < i < len(self.Segments) - 1: |
1965 if all or 0 < i < len(self.Segments) - 1: |
1938 x1, y1 = self.Points[i].x, self.Points[i].y |
1966 x1, y1 = self.Points[i].x, self.Points[i].y |
1939 x2, y2 = self.Points[i + 1].x, self.Points[i + 1].y |
1967 x2, y2 = self.Points[i + 1].x, self.Points[i + 1].y |
1940 # Calculate a rectangle around the segment |
1968 # Calculate a rectangle around the segment |
1941 rect = wx.Rect(min(x1, x2) - ANCHOR_DISTANCE, min(y1, y2) - ANCHOR_DISTANCE, |
1969 rect = wx.Rect(min(x1, x2) - ANCHOR_DISTANCE, min(y1, y2) - ANCHOR_DISTANCE, |
1942 abs(x1 - x2) + 2 * ANCHOR_DISTANCE, abs(y1 - y2) + 2 * ANCHOR_DISTANCE) |
1970 abs(x1 - x2) + 2 * ANCHOR_DISTANCE, abs(y1 - y2) + 2 * ANCHOR_DISTANCE) |
1943 if rect.InsideXY(pt.x, pt.y): |
1971 if rect.InsideXY(pt.x, pt.y): |
1944 return i, self.Segments[i] |
1972 return i, self.Segments[i] |
1945 return None |
1973 return None |
1946 |
1974 |
1947 # Define the wire points |
1975 # Define the wire points |
1948 def SetPoints(self, points, verify=True): |
1976 def SetPoints(self, points, verify=True): |
1949 if len(points) > 1: |
1977 if len(points) > 1: |
1950 self.Points = [wx.Point(x, y) for x, y in points] |
1978 self.Points = [wx.Point(x, y) for x, y in points] |
1951 # Calculate the start and end directions |
1979 # Calculate the start and end directions |
1952 self.StartPoint = [None, vector(self.Points[0], self.Points[1])] |
1980 self.StartPoint = [None, vector(self.Points[0], self.Points[1])] |
1953 self.EndPoint = [None, vector(self.Points[-1], self.Points[-2])] |
1981 self.EndPoint = [None, vector(self.Points[-1], self.Points[-2])] |
1954 # Calculate the start and end points |
1982 # Calculate the start and end points |
1955 self.StartPoint[0] = wx.Point(self.Points[0].x + CONNECTOR_SIZE * self.StartPoint[1][0], |
1983 self.StartPoint[0] = wx.Point(self.Points[0].x + CONNECTOR_SIZE * self.StartPoint[1][0], |
1956 self.Points[0].y + CONNECTOR_SIZE * self.StartPoint[1][1]) |
1984 self.Points[0].y + CONNECTOR_SIZE * self.StartPoint[1][1]) |
1957 self.EndPoint[0] = wx.Point(self.Points[-1].x + CONNECTOR_SIZE * self.EndPoint[1][0], |
1985 self.EndPoint[0] = wx.Point(self.Points[-1].x + CONNECTOR_SIZE * self.EndPoint[1][0], |
1958 self.Points[-1].y + CONNECTOR_SIZE * self.EndPoint[1][1]) |
1986 self.Points[-1].y + CONNECTOR_SIZE * self.EndPoint[1][1]) |
1959 self.Points[0] = self.StartPoint[0] |
1987 self.Points[0] = self.StartPoint[0] |
1960 self.Points[-1] = self.EndPoint[0] |
1988 self.Points[-1] = self.EndPoint[0] |
1961 # Calculate the segments directions |
1989 # Calculate the segments directions |
1962 self.Segments = [] |
1990 self.Segments = [] |
1963 i = 0 |
1991 i = 0 |
1977 self.Points.insert(i + 1, wx.Point(self.Points[i + 1].x, self.Points[i + 1].y)) |
2005 self.Points.insert(i + 1, wx.Point(self.Points[i + 1].x, self.Points[i + 1].y)) |
1978 self.Segments.append(segment) |
2006 self.Segments.append(segment) |
1979 i += 1 |
2007 i += 1 |
1980 self.RefreshBoundingBox() |
2008 self.RefreshBoundingBox() |
1981 self.RefreshRealPoints() |
2009 self.RefreshRealPoints() |
1982 |
2010 |
1983 # Returns the position of the point indicated |
2011 # Returns the position of the point indicated |
1984 def GetPoint(self, index): |
2012 def GetPoint(self, index): |
1985 if index < len(self.Points): |
2013 if index < len(self.Points): |
1986 return self.Points[index].x, self.Points[index].y |
2014 return self.Points[index].x, self.Points[index].y |
1987 return None |
2015 return None |
1988 |
2016 |
1989 # Returns a list of the position of all wire points |
2017 # Returns a list of the position of all wire points |
1990 def GetPoints(self, invert = False): |
2018 def GetPoints(self, invert=False): |
1991 points = self.VerifyPoints() |
2019 points = self.VerifyPoints() |
1992 points[0] = wx.Point(points[0].x - CONNECTOR_SIZE * self.StartPoint[1][0], |
2020 points[0] = wx.Point(points[0].x - CONNECTOR_SIZE * self.StartPoint[1][0], |
1993 points[0].y - CONNECTOR_SIZE * self.StartPoint[1][1]) |
2021 points[0].y - CONNECTOR_SIZE * self.StartPoint[1][1]) |
1994 points[-1] = wx.Point(points[-1].x - CONNECTOR_SIZE * self.EndPoint[1][0], |
2022 points[-1] = wx.Point(points[-1].x - CONNECTOR_SIZE * self.EndPoint[1][0], |
1995 points[-1].y - CONNECTOR_SIZE * self.EndPoint[1][1]) |
2023 points[-1].y - CONNECTOR_SIZE * self.EndPoint[1][1]) |
1996 # An inversion of the list is asked |
2024 # An inversion of the list is asked |
1997 if invert: |
2025 if invert: |
1998 points.reverse() |
2026 points.reverse() |
1999 return points |
2027 return points |
2000 |
2028 |
2001 # Returns the position of the two selected segment points |
2029 # Returns the position of the two selected segment points |
2002 def GetSelectedSegmentPoints(self): |
2030 def GetSelectedSegmentPoints(self): |
2003 if self.SelectedSegment != None and len(self.Points) > 1: |
2031 if self.SelectedSegment is not None and len(self.Points) > 1: |
2004 return self.Points[self.SelectedSegment:self.SelectedSegment + 2] |
2032 return self.Points[self.SelectedSegment:self.SelectedSegment + 2] |
2005 return [] |
2033 return [] |
2006 |
2034 |
2007 # Returns if the selected segment is the first and/or the last of the wire |
2035 # Returns if the selected segment is the first and/or the last of the wire |
2008 def GetSelectedSegmentConnections(self): |
2036 def GetSelectedSegmentConnections(self): |
2009 if self.SelectedSegment != None and len(self.Points) > 1: |
2037 if self.SelectedSegment is not None and len(self.Points) > 1: |
2010 return self.SelectedSegment == 0, self.SelectedSegment == len(self.Segments) - 1 |
2038 return self.SelectedSegment == 0, self.SelectedSegment == len(self.Segments) - 1 |
2011 return (True, True) |
2039 return (True, True) |
2012 |
2040 |
2013 # Returns the connectors on which the wire is connected |
2041 # Returns the connectors on which the wire is connected |
2014 def GetConnected(self): |
2042 def GetConnected(self): |
2015 connected = [] |
2043 connected = [] |
2016 if self.StartConnected and self.StartPoint[1] == WEST: |
2044 if self.StartConnected and self.StartPoint[1] == WEST: |
2017 connected.append(self.StartConnected) |
2045 connected.append(self.StartConnected) |
2018 if self.EndConnected and self.EndPoint[1] == WEST: |
2046 if self.EndConnected and self.EndPoint[1] == WEST: |
2019 connected.append(self.EndConnected) |
2047 connected.append(self.EndConnected) |
2020 return connected |
2048 return connected |
2021 |
2049 |
2022 # Returns the id of the block connected to the first or the last wire point |
2050 # Returns the id of the block connected to the first or the last wire point |
2023 def GetConnectedInfos(self, index): |
2051 def GetConnectedInfos(self, index): |
2024 if index == 0 and self.StartConnected: |
2052 if index == 0 and self.StartConnected: |
2025 return self.StartConnected.GetBlockId(), self.StartConnected.GetName() |
2053 return self.StartConnected.GetBlockId(), self.StartConnected.GetName() |
2026 elif index == -1 and self.EndConnected: |
2054 elif index == -1 and self.EndConnected: |
2027 return self.EndConnected.GetBlockId(), self.EndConnected.GetName() |
2055 return self.EndConnected.GetBlockId(), self.EndConnected.GetName() |
2028 return None |
2056 return None |
2029 |
2057 |
2030 # Update the wire points position by keeping at most possible the current positions |
2058 # Update the wire points position by keeping at most possible the current positions |
2031 def GeneratePoints(self, realpoints = True): |
2059 def GeneratePoints(self, realpoints=True): |
2032 i = 0 |
2060 i = 0 |
2033 # Calculate the start enad end points with the minimum segment size in the right direction |
2061 # Calculate the start enad end points with the minimum segment size in the right direction |
2034 end = wx.Point(self.EndPoint[0].x + self.EndPoint[1][0] * MIN_SEGMENT_SIZE, |
2062 end = wx.Point(self.EndPoint[0].x + self.EndPoint[1][0] * MIN_SEGMENT_SIZE, |
2035 self.EndPoint[0].y + self.EndPoint[1][1] * MIN_SEGMENT_SIZE) |
2063 self.EndPoint[0].y + self.EndPoint[1][1] * MIN_SEGMENT_SIZE) |
2036 start = wx.Point(self.StartPoint[0].x + self.StartPoint[1][0] * MIN_SEGMENT_SIZE, |
2064 start = wx.Point(self.StartPoint[0].x + self.StartPoint[1][0] * MIN_SEGMENT_SIZE, |
2037 self.StartPoint[0].y + self.StartPoint[1][1] * MIN_SEGMENT_SIZE) |
2065 self.StartPoint[0].y + self.StartPoint[1][1] * MIN_SEGMENT_SIZE) |
2038 # Evaluate the point till it's the last |
2066 # Evaluate the point till it's the last |
2039 while i < len(self.Points) - 1: |
2067 while i < len(self.Points) - 1: |
2040 # The next point is the last |
2068 # The next point is the last |
2041 if i + 1 == len(self.Points) - 1: |
2069 if i + 1 == len(self.Points) - 1: |
2042 # Calculate the direction from current point to end point |
2070 # Calculate the direction from current point to end point |
2044 # The current point is the first |
2072 # The current point is the first |
2045 if i == 0: |
2073 if i == 0: |
2046 # If the end point is not in the start direction, a point is added |
2074 # If the end point is not in the start direction, a point is added |
2047 if v_end != self.Segments[0] or v_end == self.EndPoint[1]: |
2075 if v_end != self.Segments[0] or v_end == self.EndPoint[1]: |
2048 self.Points.insert(1, wx.Point(start.x, start.y)) |
2076 self.Points.insert(1, wx.Point(start.x, start.y)) |
2049 self.Segments.insert(1, DirectionChoice((self.Segments[0][1], |
2077 self.Segments.insert(1, DirectionChoice( |
2050 self.Segments[0][0]), v_end, self.EndPoint[1])) |
2078 (self.Segments[0][1], |
|
2079 self.Segments[0][0]), v_end, self.EndPoint[1])) |
2051 # The current point is the second |
2080 # The current point is the second |
2052 elif i == 1: |
2081 elif i == 1: |
2053 # The previous direction and the target direction are mainly opposed, a point is added |
2082 # The previous direction and the target direction are mainly opposed, a point is added |
2054 if product(v_end, self.Segments[0]) < 0: |
2083 if product(v_end, self.Segments[0]) < 0: |
2055 self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y)) |
2084 self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y)) |
2056 self.Segments.insert(2, DirectionChoice((self.Segments[1][1], |
2085 self.Segments.insert(2, DirectionChoice( |
2057 self.Segments[1][0]), v_end, self.EndPoint[1])) |
2086 (self.Segments[1][1], |
|
2087 self.Segments[1][0]), v_end, self.EndPoint[1])) |
2058 # The previous direction and the end direction are the same or they are |
2088 # The previous direction and the end direction are the same or they are |
2059 # perpendiculars and the end direction points towards current segment |
2089 # perpendiculars and the end direction points towards current segment |
2060 elif product(self.Segments[0], self.EndPoint[1]) >= 0 and product(self.Segments[1], self.EndPoint[1]) <= 0: |
2090 elif product(self.Segments[0], self.EndPoint[1]) >= 0 and product(self.Segments[1], self.EndPoint[1]) <= 0: |
2061 # Current point and end point are aligned |
2091 # Current point and end point are aligned |
2062 if self.Segments[0][0] != 0: |
2092 if self.Segments[0][0] != 0: |
2064 if self.Segments[0][1] != 0: |
2094 if self.Segments[0][1] != 0: |
2065 self.Points[1].y = end.y |
2095 self.Points[1].y = end.y |
2066 # If the previous direction and the end direction are the same, a point is added |
2096 # If the previous direction and the end direction are the same, a point is added |
2067 if product(self.Segments[0], self.EndPoint[1]) > 0: |
2097 if product(self.Segments[0], self.EndPoint[1]) > 0: |
2068 self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y)) |
2098 self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y)) |
2069 self.Segments.insert(2, DirectionChoice((self.Segments[1][1], |
2099 self.Segments.insert(2, DirectionChoice( |
2070 self.Segments[1][0]), v_end, self.EndPoint[1])) |
2100 (self.Segments[1][1], |
|
2101 self.Segments[1][0]), v_end, self.EndPoint[1])) |
2071 else: |
2102 else: |
2072 # Current point is positioned in the middle of start point |
2103 # Current point is positioned in the middle of start point |
2073 # and end point on the current direction and a point is added |
2104 # and end point on the current direction and a point is added |
2074 if self.Segments[0][0] != 0: |
2105 if self.Segments[0][0] != 0: |
2075 self.Points[1].x = (end.x + start.x) / 2 |
2106 self.Points[1].x = (end.x + start.x) / 2 |
2076 if self.Segments[0][1] != 0: |
2107 if self.Segments[0][1] != 0: |
2077 self.Points[1].y = (end.y + start.y) / 2 |
2108 self.Points[1].y = (end.y + start.y) / 2 |
2078 self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y)) |
2109 self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y)) |
2079 self.Segments.insert(2, DirectionChoice((self.Segments[1][1], |
2110 self.Segments.insert(2, DirectionChoice( |
2080 self.Segments[1][0]), v_end, self.EndPoint[1])) |
2111 (self.Segments[1][1], |
|
2112 self.Segments[1][0]), v_end, self.EndPoint[1])) |
2081 else: |
2113 else: |
2082 # The previous direction and the end direction are perpendiculars |
2114 # The previous direction and the end direction are perpendiculars |
2083 if product(self.Segments[i - 1], self.EndPoint[1]) == 0: |
2115 if product(self.Segments[i - 1], self.EndPoint[1]) == 0: |
2084 # The target direction and the end direction aren't mainly the same |
2116 # The target direction and the end direction aren't mainly the same |
2085 if product(v_end, self.EndPoint[1]) <= 0: |
2117 if product(v_end, self.EndPoint[1]) <= 0: |
2138 self.Points[i].x = (end.x + self.Points[i - 1].x) / 2 |
2174 self.Points[i].x = (end.x + self.Points[i - 1].x) / 2 |
2139 if self.Segments[i - 1][1] != 0: |
2175 if self.Segments[i - 1][1] != 0: |
2140 self.Points[i].y = (end.y + self.Points[i - 1].y) / 2 |
2176 self.Points[i].y = (end.y + self.Points[i - 1].y) / 2 |
2141 # A point is added |
2177 # A point is added |
2142 self.Points.insert(i + 1, wx.Point(self.Points[i].x, self.Points[i].y)) |
2178 self.Points.insert(i + 1, wx.Point(self.Points[i].x, self.Points[i].y)) |
2143 self.Segments.insert(i + 1, DirectionChoice((self.Segments[i][1], |
2179 self.Segments.insert( |
2144 self.Segments[i][0]), v_end, self.EndPoint[1])) |
2180 i + 1, |
|
2181 DirectionChoice((self.Segments[i][1], |
|
2182 self.Segments[i][0]), v_end, self.EndPoint[1])) |
2145 else: |
2183 else: |
2146 # Current point is the first, and second is not mainly in the first direction |
2184 # Current point is the first, and second is not mainly in the first direction |
2147 if i == 0 and product(vector(start, self.Points[1]), self.Segments[0]) < 0: |
2185 if i == 0 and product(vector(start, self.Points[1]), self.Segments[0]) < 0: |
2148 # If first and second directions aren't perpendiculars, a point is added |
2186 # If first and second directions aren't perpendiculars, a point is added |
2149 if product(self.Segments[0], self.Segments[1]) != 0: |
2187 if product(self.Segments[0], self.Segments[1]) != 0: |
2150 self.Points.insert(1, wx.Point(start.x, start.y)) |
2188 self.Points.insert(1, wx.Point(start.x, start.y)) |
2151 self.Segments.insert(1, DirectionChoice((self.Segments[0][1], |
2189 self.Segments.insert( |
2152 self.Segments[0][0]), vector(start, self.Points[1]), self.Segments[1])) |
2190 1, |
|
2191 DirectionChoice((self.Segments[0][1], |
|
2192 self.Segments[0][0]), |
|
2193 vector(start, self.Points[1]), |
|
2194 self.Segments[1])) |
2153 else: |
2195 else: |
2154 self.Points[1].x, self.Points[1].y = start.x, start.y |
2196 self.Points[1].x, self.Points[1].y = start.x, start.y |
2155 else: |
2197 else: |
2156 # Next point is aligned with current point |
2198 # Next point is aligned with current point |
2157 if self.Segments[i][0] != 0: |
2199 if self.Segments[i][0] != 0: |
2183 self.Points = [point for point in points] |
2225 self.Points = [point for point in points] |
2184 self.Segments = [segment for segment in segments] |
2226 self.Segments = [segment for segment in segments] |
2185 self.RefreshBoundingBox() |
2227 self.RefreshBoundingBox() |
2186 self.RefreshRealPoints() |
2228 self.RefreshRealPoints() |
2187 return points |
2229 return points |
2188 |
2230 |
2189 # Moves all the wire points except the first and the last if they are connected |
2231 # Moves all the wire points except the first and the last if they are connected |
2190 def Move(self, dx, dy, endpoints = False): |
2232 def Move(self, dx, dy, endpoints=False): |
2191 for i, point in enumerate(self.Points): |
2233 for i, point in enumerate(self.Points): |
2192 if endpoints or not (i == 0 and self.StartConnected) and not (i == len(self.Points) - 1 and self.EndConnected): |
2234 if endpoints or not (i == 0 and self.StartConnected) and not (i == len(self.Points) - 1 and self.EndConnected): |
2193 point.x += dx |
2235 point.x += dx |
2194 point.y += dy |
2236 point.y += dy |
2195 self.StartPoint[0] = self.Points[0] |
2237 self.StartPoint[0] = self.Points[0] |
2196 self.EndPoint[0] = self.Points[-1] |
2238 self.EndPoint[0] = self.Points[-1] |
2197 self.GeneratePoints() |
2239 self.GeneratePoints() |
2198 |
2240 |
2199 # Resize the wire from position and size given |
2241 # Resize the wire from position and size given |
2200 def Resize(self, x, y, width, height): |
2242 def Resize(self, x, y, width, height): |
2201 if len(self.Points) > 1: |
2243 if len(self.Points) > 1: |
2202 # Calculate the new position of each point for testing the new size |
2244 # Calculate the new position of each point for testing the new size |
2203 minx, miny = self.Pos.x, self.Pos.y |
2245 minx, miny = self.Pos.x, self.Pos.y |
2244 dir = self.StartPoint[1] |
2286 dir = self.StartPoint[1] |
2245 elif i == len(self.Points) - 1: |
2287 elif i == len(self.Points) - 1: |
2246 dir = self.EndPoint[1] |
2288 dir = self.EndPoint[1] |
2247 else: |
2289 else: |
2248 dir = (0, 0) |
2290 dir = (0, 0) |
2249 realpointx = max(-dir[0] * MIN_SEGMENT_SIZE, min(int(round(point[0])), |
2291 realpointx = max(-dir[0] * MIN_SEGMENT_SIZE, |
2250 width - dir[0] * MIN_SEGMENT_SIZE)) |
2292 min(int(round(point[0])), |
2251 realpointy = max(-dir[1] * MIN_SEGMENT_SIZE, min(int(round(point[1])), |
2293 width - dir[0] * MIN_SEGMENT_SIZE)) |
2252 height - dir[1] * MIN_SEGMENT_SIZE)) |
2294 realpointy = max(-dir[1] * MIN_SEGMENT_SIZE, |
|
2295 min(int(round(point[1])), |
|
2296 height - dir[1] * MIN_SEGMENT_SIZE)) |
2253 self.Points[i] = wx.Point(minx + x + realpointx, miny + y + realpointy) |
2297 self.Points[i] = wx.Point(minx + x + realpointx, miny + y + realpointy) |
2254 self.StartPoint[0] = self.Points[0] |
2298 self.StartPoint[0] = self.Points[0] |
2255 self.EndPoint[0] = self.Points[-1] |
2299 self.EndPoint[0] = self.Points[-1] |
2256 self.GeneratePoints(False) |
2300 self.GeneratePoints(False) |
2257 |
2301 |
2258 # Moves the wire start point and update the wire points |
2302 # Moves the wire start point and update the wire points |
2259 def MoveStartPoint(self, point): |
2303 def MoveStartPoint(self, point): |
2260 if len(self.Points) > 1: |
2304 if len(self.Points) > 1: |
2261 self.StartPoint[0] = point |
2305 self.StartPoint[0] = point |
2262 self.Points[0] = point |
2306 self.Points[0] = point |
2263 self.GeneratePoints() |
2307 self.GeneratePoints() |
2264 |
2308 |
2265 # Changes the wire start direction and update the wire points |
2309 # Changes the wire start direction and update the wire points |
2266 def SetStartPointDirection(self, dir): |
2310 def SetStartPointDirection(self, dir): |
2267 if len(self.Points) > 1: |
2311 if len(self.Points) > 1: |
2268 self.StartPoint[1] = dir |
2312 self.StartPoint[1] = dir |
2269 self.Segments[0] = dir |
2313 self.Segments[0] = dir |
2270 self.GeneratePoints() |
2314 self.GeneratePoints() |
2271 |
2315 |
2272 # Rotates the wire start direction by an angle of 90 degrees anticlockwise |
2316 # Rotates the wire start direction by an angle of 90 degrees anticlockwise |
2273 def RotateStartPoint(self): |
2317 def RotateStartPoint(self): |
2274 self.SetStartPointDirection((self.StartPoint[1][1], -self.StartPoint[1][0])) |
2318 self.SetStartPointDirection((self.StartPoint[1][1], -self.StartPoint[1][0])) |
2275 |
2319 |
2276 # Connects wire start point to the connector given and moves wire start point |
2320 # Connects wire start point to the connector given and moves wire start point |
2277 # to given point |
2321 # to given point |
2278 def ConnectStartPoint(self, point, connector): |
2322 def ConnectStartPoint(self, point, connector): |
2279 if point: |
2323 if point: |
2280 self.MoveStartPoint(point) |
2324 self.MoveStartPoint(point) |
2281 self.StartConnected = connector |
2325 self.StartConnected = connector |
2282 self.RefreshBoundingBox() |
2326 self.RefreshBoundingBox() |
2283 |
2327 |
2284 # Unconnects wire start point |
2328 # Unconnects wire start point |
2285 def UnConnectStartPoint(self, delete = False): |
2329 def UnConnectStartPoint(self, delete=False): |
2286 if delete: |
2330 if delete: |
2287 self.StartConnected = None |
2331 self.StartConnected = None |
2288 self.Delete() |
2332 self.Delete() |
2289 elif self.StartConnected: |
2333 elif self.StartConnected: |
2290 self.StartConnected.UnConnect(self, unconnect = False) |
2334 self.StartConnected.UnConnect(self, unconnect=False) |
2291 self.StartConnected = None |
2335 self.StartConnected = None |
2292 self.RefreshBoundingBox() |
2336 self.RefreshBoundingBox() |
2293 |
2337 |
2294 # Moves the wire end point and update the wire points |
2338 # Moves the wire end point and update the wire points |
2295 def MoveEndPoint(self, point): |
2339 def MoveEndPoint(self, point): |
2296 if len(self.Points) > 1: |
2340 if len(self.Points) > 1: |
2297 self.EndPoint[0] = point |
2341 self.EndPoint[0] = point |
2298 self.Points[-1] = point |
2342 self.Points[-1] = point |
2313 def ConnectEndPoint(self, point, connector): |
2357 def ConnectEndPoint(self, point, connector): |
2314 if point: |
2358 if point: |
2315 self.MoveEndPoint(point) |
2359 self.MoveEndPoint(point) |
2316 self.EndConnected = connector |
2360 self.EndConnected = connector |
2317 self.RefreshBoundingBox() |
2361 self.RefreshBoundingBox() |
2318 |
2362 |
2319 # Unconnects wire end point |
2363 # Unconnects wire end point |
2320 def UnConnectEndPoint(self, delete = False): |
2364 def UnConnectEndPoint(self, delete=False): |
2321 if delete: |
2365 if delete: |
2322 self.EndConnected = None |
2366 self.EndConnected = None |
2323 self.Delete() |
2367 self.Delete() |
2324 elif self.EndConnected: |
2368 elif self.EndConnected: |
2325 self.EndConnected.UnConnect(self, unconnect = False) |
2369 self.EndConnected.UnConnect(self, unconnect=False) |
2326 self.EndConnected = None |
2370 self.EndConnected = None |
2327 self.RefreshBoundingBox() |
2371 self.RefreshBoundingBox() |
2328 |
2372 |
2329 # Moves the wire segment given by its index |
2373 # Moves the wire segment given by its index |
2330 def MoveSegment(self, idx, movex, movey, scaling): |
2374 def MoveSegment(self, idx, movex, movey, scaling): |
2331 if 0 < idx < len(self.Segments) - 1: |
2375 if 0 < idx < len(self.Segments) - 1: |
2332 if self.Segments[idx] in (NORTH, SOUTH): |
2376 if self.Segments[idx] in (NORTH, SOUTH): |
2333 start_x = self.Points[idx].x |
2377 start_x = self.Points[idx].x |
2389 self.Points.insert(segment + 3, wx.Point(p2x, p2y)) |
2433 self.Points.insert(segment + 3, wx.Point(p2x, p2y)) |
2390 self.Segments.insert(segment + 3, (dir[1], dir[0])) |
2434 self.Segments.insert(segment + 3, (dir[1], dir[0])) |
2391 self.Points.insert(segment + 4, wx.Point(p2x, p2y)) |
2435 self.Points.insert(segment + 4, wx.Point(p2x, p2y)) |
2392 self.Segments.insert(segment + 4, dir) |
2436 self.Segments.insert(segment + 4, dir) |
2393 self.GeneratePoints() |
2437 self.GeneratePoints() |
2394 |
2438 |
2395 # Delete the handled segment by removing the two segment points |
2439 # Delete the handled segment by removing the two segment points |
2396 def DeleteSegment(self): |
2440 def DeleteSegment(self): |
2397 handle_type, handle = self.Handle |
2441 handle_type, handle = self.Handle |
2398 if handle_type == HANDLE_SEGMENT: |
2442 if handle_type == HANDLE_SEGMENT: |
2399 segment, dir = handle |
2443 segment, dir = handle |
2400 for i in xrange(2): |
2444 for i in xrange(2): |
2401 self.Points.pop(segment) |
2445 self.Points.pop(segment) |
2402 self.Segments.pop(segment) |
2446 self.Segments.pop(segment) |
2403 self.GeneratePoints() |
2447 self.GeneratePoints() |
2404 self.RefreshModel() |
2448 self.RefreshModel() |
2405 |
2449 |
2406 # Method called when a LeftDown event have been generated |
2450 # Method called when a LeftDown event have been generated |
2407 def OnLeftDown(self, event, dc, scaling): |
2451 def OnLeftDown(self, event, dc, scaling): |
2408 pos = GetScaledEventPosition(event, dc, scaling) |
2452 pos = GetScaledEventPosition(event, dc, scaling) |
2409 # Test if a point have been handled |
2453 # Test if a point have been handled |
2410 #result = self.TestPoint(pos) |
2454 # result = self.TestPoint(pos) |
2411 #if result != None: |
2455 # if result != None: |
2412 # self.Handle = (HANDLE_POINT, result) |
2456 # self.Handle = (HANDLE_POINT, result) |
2413 # wx.CallAfter(self.Parent.SetCurrentCursor, 1) |
2457 # wx.CallAfter(self.Parent.SetCurrentCursor, 1) |
2414 #else: |
2458 # else: |
2415 # Test if a segment have been handled |
2459 # Test if a segment have been handled |
2416 result = self.TestSegment(pos) |
2460 result = self.TestSegment(pos) |
2417 if result != None: |
2461 if result is not None: |
2418 if result[1] in (NORTH, SOUTH): |
2462 if result[1] in (NORTH, SOUTH): |
2419 wx.CallAfter(self.Parent.SetCurrentCursor, 4) |
2463 wx.CallAfter(self.Parent.SetCurrentCursor, 4) |
2420 elif result[1] in (EAST, WEST): |
2464 elif result[1] in (EAST, WEST): |
2421 wx.CallAfter(self.Parent.SetCurrentCursor, 5) |
2465 wx.CallAfter(self.Parent.SetCurrentCursor, 5) |
2422 self.Handle = (HANDLE_SEGMENT, result) |
2466 self.Handle = (HANDLE_SEGMENT, result) |
2423 # Execute the default method for a graphic element |
2467 # Execute the default method for a graphic element |
2424 else: |
2468 else: |
2425 Graphic_Element.OnLeftDown(self, event, dc, scaling) |
2469 Graphic_Element.OnLeftDown(self, event, dc, scaling) |
2426 self.oldPos = pos |
2470 self.oldPos = pos |
2427 |
2471 |
2428 # Method called when a RightUp event has been generated |
2472 # Method called when a RightUp event has been generated |
2429 def OnRightUp(self, event, dc, scaling): |
2473 def OnRightUp(self, event, dc, scaling): |
2430 pos = GetScaledEventPosition(event, dc, scaling) |
2474 pos = GetScaledEventPosition(event, dc, scaling) |
2431 # Test if a segment has been handled |
2475 # Test if a segment has been handled |
2432 result = self.TestSegment(pos, True) |
2476 result = self.TestSegment(pos, True) |
2433 if result != None: |
2477 if result is not None: |
2434 self.Handle = (HANDLE_SEGMENT, result) |
2478 self.Handle = (HANDLE_SEGMENT, result) |
2435 # Popup the menu with special items for a wire |
2479 # Popup the menu with special items for a wire |
2436 self.Parent.PopupWireMenu(0 < result[0] < len(self.Segments) - 1) |
2480 self.Parent.PopupWireMenu(0 < result[0] < len(self.Segments) - 1) |
2437 else: |
2481 else: |
2438 # Execute the default method for a graphic element |
2482 # Execute the default method for a graphic element |
2439 Graphic_Element.OnRightUp(self, event, dc, scaling) |
2483 Graphic_Element.OnRightUp(self, event, dc, scaling) |
2440 |
2484 |
2441 # Method called when a LeftDClick event has been generated |
2485 # Method called when a LeftDClick event has been generated |
2442 def OnLeftDClick(self, event, dc, scaling): |
2486 def OnLeftDClick(self, event, dc, scaling): |
2443 rect = self.GetRedrawRect() |
2487 rect = self.GetRedrawRect() |
2444 if event.ControlDown(): |
2488 if event.ControlDown(): |
2445 direction = (self.StartPoint[1], self.EndPoint[1]) |
2489 direction = (self.StartPoint[1], self.EndPoint[1]) |
2570 elif handle_type == HANDLE_SEGMENT: |
2614 elif handle_type == HANDLE_SEGMENT: |
2571 return self.MoveSegment(handle[0], movex, movey, scaling) |
2615 return self.MoveSegment(handle[0], movex, movey, scaling) |
2572 # Execute the default method for a graphic element |
2616 # Execute the default method for a graphic element |
2573 else: |
2617 else: |
2574 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling) |
2618 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling) |
2575 |
2619 |
2576 # Refreshes the wire model |
2620 # Refreshes the wire model |
2577 def RefreshModel(self, move=True): |
2621 def RefreshModel(self, move=True): |
2578 if self.StartConnected and self.StartPoint[1] in [WEST, NORTH]: |
2622 if self.StartConnected and self.StartPoint[1] in [WEST, NORTH]: |
2579 self.StartConnected.RefreshParentBlock() |
2623 self.StartConnected.RefreshParentBlock() |
2580 if self.EndConnected and self.EndPoint[1] in [WEST, NORTH]: |
2624 if self.EndConnected and self.EndPoint[1] in [WEST, NORTH]: |
2581 self.EndConnected.RefreshParentBlock() |
2625 self.EndConnected.RefreshParentBlock() |
2582 |
2626 |
2583 # Change the variable that indicates if this element is highlighted |
2627 # Change the variable that indicates if this element is highlighted |
2584 def SetHighlighted(self, highlighted): |
2628 def SetHighlighted(self, highlighted): |
2585 self.Highlighted = highlighted |
2629 self.Highlighted = highlighted |
2586 if not highlighted: |
2630 if not highlighted: |
2587 self.OverStart = False |
2631 self.OverStart = False |
2588 self.OverEnd = False |
2632 self.OverEnd = False |
2589 self.Refresh() |
2633 self.Refresh() |
2590 |
2634 |
2591 def HighlightPoint(self, pos): |
2635 def HighlightPoint(self, pos): |
2592 refresh = False |
2636 refresh = False |
2593 start, end = self.OverStart, self.OverEnd |
2637 start, end = self.OverStart, self.OverEnd |
2594 self.OverStart = False |
2638 self.OverStart = False |
2595 self.OverEnd = False |
2639 self.OverEnd = False |
2596 # Test if a point has been handled |
2640 # Test if a point has been handled |
2597 result = self.TestPoint(pos) |
2641 result = self.TestPoint(pos) |
2598 if result != None: |
2642 if result is not None: |
2599 if result == 0 and self.StartConnected is not None: |
2643 if result == 0 and self.StartConnected is not None: |
2600 self.OverStart = True |
2644 self.OverStart = True |
2601 elif result != 0 and self.EndConnected is not None: |
2645 elif result != 0 and self.EndConnected is not None: |
2602 self.OverEnd = True |
2646 self.OverEnd = True |
2603 if start != self.OverStart or end != self.OverEnd: |
2647 if start != self.OverStart or end != self.OverEnd: |
2604 self.Refresh() |
2648 self.Refresh() |
2605 |
2649 |
2606 # Draws the highlightment of this element if it is highlighted |
2650 # Draws the highlightment of this element if it is highlighted |
2607 def DrawHighlightment(self, dc): |
2651 def DrawHighlightment(self, dc): |
2608 scalex, scaley = dc.GetUserScale() |
2652 scalex, scaley = dc.GetUserScale() |
2609 dc.SetUserScale(1, 1) |
2653 dc.SetUserScale(1, 1) |
2610 # If user trying to connect wire with wrong input, highlight will become red. |
2654 # If user trying to connect wire with wrong input, highlight will become red. |
2611 if self.ErrHighlight == True and not (self.EndConnected): |
2655 if self.ErrHighlight and not (self.EndConnected): |
2612 highlightcolor = wx.RED |
2656 highlightcolor = wx.RED |
2613 else: |
2657 else: |
2614 highlightcolor = HIGHLIGHTCOLOR |
2658 highlightcolor = HIGHLIGHTCOLOR |
2615 dc.SetPen(MiterPen(highlightcolor, (2 * scalex + 5))) |
2659 dc.SetPen(MiterPen(highlightcolor, (2 * scalex + 5))) |
2616 dc.SetBrush(wx.Brush(highlightcolor)) |
2660 dc.SetBrush(wx.Brush(highlightcolor)) |
2617 dc.SetLogicalFunction(wx.AND) |
2661 dc.SetLogicalFunction(wx.AND) |
2618 # Draw the start and end points if they are not connected or the mouse is over them |
2662 # Draw the start and end points if they are not connected or the mouse is over them |
2619 if len(self.Points) > 0 and (not self.StartConnected or self.OverStart): |
2663 if len(self.Points) > 0 and (not self.StartConnected or self.OverStart): |
2620 dc.DrawCircle(round(self.Points[0].x * scalex), |
2664 dc.DrawCircle(round(self.Points[0].x * scalex), |
2621 round(self.Points[0].y * scaley), |
2665 round(self.Points[0].y * scaley), |
2622 (POINT_RADIUS + 1) * scalex + 2) |
2666 (POINT_RADIUS + 1) * scalex + 2) |
2623 if len(self.Points) > 1 and (not self.EndConnected or self.OverEnd): |
2667 if len(self.Points) > 1 and (not self.EndConnected or self.OverEnd): |
2624 dc.DrawCircle(self.Points[-1].x * scalex, self.Points[-1].y * scaley, (POINT_RADIUS + 1) * scalex + 2) |
2668 dc.DrawCircle(self.Points[-1].x * scalex, self.Points[-1].y * scaley, (POINT_RADIUS + 1) * scalex + 2) |
2625 # Draw the wire lines and the last point (it seems that DrawLines stop before the last point) |
2669 # Draw the wire lines and the last point (it seems that DrawLines stop before the last point) |
2626 if len(self.Points) > 1: |
2670 if len(self.Points) > 1: |
2627 points = [wx.Point(round((self.Points[0].x - self.Segments[0][0]) * scalex), |
2671 points = [wx.Point(round((self.Points[0].x - self.Segments[0][0]) * scalex), |
2628 round((self.Points[0].y - self.Segments[0][1]) * scaley))] |
2672 round((self.Points[0].y - self.Segments[0][1]) * scaley))] |
2629 points.extend([wx.Point(round(point.x * scalex), round(point.y * scaley)) for point in self.Points[1:-1]]) |
2673 points.extend([wx.Point(round(point.x * scalex), round(point.y * scaley)) for point in self.Points[1:-1]]) |
2630 points.append(wx.Point(round((self.Points[-1].x + self.Segments[-1][0]) * scalex), |
2674 points.append(wx.Point(round((self.Points[-1].x + self.Segments[-1][0]) * scalex), |
2631 round((self.Points[-1].y + self.Segments[-1][1]) * scaley))) |
2675 round((self.Points[-1].y + self.Segments[-1][1]) * scaley))) |
2632 else: |
2676 else: |
2633 points = [] |
2677 points = [] |
2634 dc.DrawLines(points) |
2678 dc.DrawLines(points) |
2635 dc.SetLogicalFunction(wx.COPY) |
2679 dc.SetLogicalFunction(wx.COPY) |
2636 dc.SetUserScale(scalex, scaley) |
2680 dc.SetUserScale(scalex, scaley) |
2637 |
2681 |
2638 if self.StartConnected is not None: |
2682 if self.StartConnected is not None: |
2639 self.StartConnected.DrawHighlightment(dc) |
2683 self.StartConnected.DrawHighlightment(dc) |
2640 self.StartConnected.Draw(dc) |
2684 self.StartConnected.Draw(dc) |
2641 if self.EndConnected is not None: |
2685 if self.EndConnected is not None: |
2642 self.EndConnected.DrawHighlightment(dc) |
2686 self.EndConnected.DrawHighlightment(dc) |
2643 self.EndConnected.Draw(dc) |
2687 self.EndConnected.Draw(dc) |
2644 |
2688 |
2645 # Draws the wire lines and points |
2689 # Draws the wire lines and points |
2646 def Draw(self, dc): |
2690 def Draw(self, dc): |
2647 Graphic_Element.Draw(self, dc) |
2691 Graphic_Element.Draw(self, dc) |
2648 if not self.Valid: |
2692 if not self.Valid: |
2649 dc.SetPen(MiterPen(wx.RED)) |
2693 dc.SetPen(MiterPen(wx.RED)) |
2725 if end[0] > row: |
2770 if end[0] > row: |
2726 end = (row, length) |
2771 end = (row, length) |
2727 _highlights.append((start, end, highlight_type)) |
2772 _highlights.append((start, end, highlight_type)) |
2728 return _highlights |
2773 return _highlights |
2729 |
2774 |
|
2775 |
2730 def FilterHighlightsByColumn(highlights, start_col, end_col): |
2776 def FilterHighlightsByColumn(highlights, start_col, end_col): |
2731 _highlights = [] |
2777 _highlights = [] |
2732 for start, end, highlight_type in highlights: |
2778 for start, end, highlight_type in highlights: |
2733 if end[1] > start_col and start[1] < end_col: |
2779 if end[1] > start_col and start[1] < end_col: |
2734 start = (start[0], max(start[1], start_col) - start_col) |
2780 start = (start[0], max(start[1], start_col) - start_col) |
2735 end = (end[0], min(end[1], end_col) - start_col) |
2781 end = (end[0], min(end[1], end_col) - start_col) |
2736 _highlights.append((start, end, highlight_type)) |
2782 _highlights.append((start, end, highlight_type)) |
2737 return _highlights |
2783 return _highlights |
2738 |
2784 |
2739 """ |
|
2740 Class that implements a comment |
|
2741 """ |
|
2742 |
2785 |
2743 class Comment(Graphic_Element): |
2786 class Comment(Graphic_Element): |
|
2787 """ |
|
2788 Class that implements a comment |
|
2789 """ |
2744 |
2790 |
2745 # Create a new comment |
2791 # Create a new comment |
2746 def __init__(self, parent, content, id = None): |
2792 def __init__(self, parent, content, id=None): |
2747 Graphic_Element.__init__(self, parent) |
2793 Graphic_Element.__init__(self, parent) |
2748 self.Id = id |
2794 self.Id = id |
2749 self.Content = content |
2795 self.Content = content |
2750 self.Pos = wx.Point(0, 0) |
2796 self.Pos = wx.Point(0, 0) |
2751 self.Size = wx.Size(0, 0) |
2797 self.Size = wx.Size(0, 0) |
2752 self.Highlights = [] |
2798 self.Highlights = [] |
2753 |
2799 |
2754 # Make a clone of this comment |
2800 # Make a clone of this comment |
2755 def Clone(self, parent, id = None, pos = None): |
2801 def Clone(self, parent, id=None, pos=None): |
2756 comment = Comment(parent, self.Content, id) |
2802 comment = Comment(parent, self.Content, id) |
2757 if pos is not None: |
2803 if pos is not None: |
2758 comment.SetPosition(pos.x, pos.y) |
2804 comment.SetPosition(pos.x, pos.y) |
2759 comment.SetSize(self.Size[0], self.Size[1]) |
2805 comment.SetSize(self.Size[0], self.Size[1]) |
2760 return comment |
2806 return comment |
2761 |
2807 |
2762 # Method for keeping compatibility with others |
2808 # Method for keeping compatibility with others |
2763 def Clean(self): |
2809 def Clean(self): |
2764 pass |
2810 pass |
2765 |
2811 |
2766 # Delete this comment by calling the corresponding method |
2812 # Delete this comment by calling the corresponding method |
2767 def Delete(self): |
2813 def Delete(self): |
2768 self.Parent.DeleteComment(self) |
2814 self.Parent.DeleteComment(self) |
2769 |
2815 |
2770 # Refresh the comment bounding box |
2816 # Refresh the comment bounding box |
2771 def RefreshBoundingBox(self): |
2817 def RefreshBoundingBox(self): |
2772 self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) |
2818 self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) |
2773 |
2819 |
2774 # Changes the comment size |
2820 # Changes the comment size |
2775 def SetSize(self, width, height): |
2821 def SetSize(self, width, height): |
2776 self.Size.SetWidth(width) |
2822 self.Size.SetWidth(width) |
2777 self.Size.SetHeight(height) |
2823 self.Size.SetHeight(height) |
2778 self.RefreshBoundingBox() |
2824 self.RefreshBoundingBox() |
2779 |
2825 |
2780 # Returns the comment size |
2826 # Returns the comment size |
2781 def GetSize(self): |
2827 def GetSize(self): |
2782 return self.Size.GetWidth(), self.Size.GetHeight() |
2828 return self.Size.GetWidth(), self.Size.GetHeight() |
2783 |
2829 |
2784 # Returns the comment minimum size |
2830 # Returns the comment minimum size |
2785 def GetMinSize(self): |
2831 def GetMinSize(self): |
2786 dc = wx.ClientDC(self.Parent) |
2832 dc = wx.ClientDC(self.Parent) |
2787 min_width = 0 |
2833 min_width = 0 |
2788 min_height = 0 |
2834 min_height = 0 |
2813 return self.Content |
2859 return self.Content |
2814 |
2860 |
2815 # Returns the comment position |
2861 # Returns the comment position |
2816 def GetPosition(self): |
2862 def GetPosition(self): |
2817 return self.Pos.x, self.Pos.y |
2863 return self.Pos.x, self.Pos.y |
2818 |
2864 |
2819 # Moves the comment |
2865 # Moves the comment |
2820 def Move(self, dx, dy, connected = True): |
2866 def Move(self, dx, dy, connected=True): |
2821 self.Pos.x += dx |
2867 self.Pos.x += dx |
2822 self.Pos.y += dy |
2868 self.Pos.y += dy |
2823 self.RefreshBoundingBox() |
2869 self.RefreshBoundingBox() |
2824 |
2870 |
2825 # Resizes the comment with the position and the size given |
2871 # Resizes the comment with the position and the size given |
2826 def Resize(self, x, y, width, height): |
2872 def Resize(self, x, y, width, height): |
2827 self.Move(x, y) |
2873 self.Move(x, y) |
2828 self.SetSize(width, height) |
2874 self.SetSize(width, height) |
2829 |
2875 |
2830 # Method called when a RightUp event have been generated |
2876 # Method called when a RightUp event have been generated |
2831 def OnRightUp(self, event, dc, scaling): |
2877 def OnRightUp(self, event, dc, scaling): |
2832 # Popup the default menu |
2878 # Popup the default menu |
2833 self.Parent.PopupDefaultMenu() |
2879 self.Parent.PopupDefaultMenu() |
2834 |
2880 |
2835 # Refreshes the wire state according to move defined and handle selected |
2881 # Refreshes the wire state according to move defined and handle selected |
2836 def ProcessDragging(self, movex, movey, event, scaling): |
2882 def ProcessDragging(self, movex, movey, event, scaling): |
2837 if self.Parent.GetDrawingMode() != FREEDRAWING_MODE and self.Parent.CurrentLanguage == "LD": |
2883 if self.Parent.GetDrawingMode() != FREEDRAWING_MODE and self.Parent.CurrentLanguage == "LD": |
2838 movex = movey = 0 |
2884 movex = movey = 0 |
2839 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling) |
2885 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling) |
2840 |
2886 |
2841 # Refreshes the comment model |
2887 # Refreshes the comment model |
2842 def RefreshModel(self, move=True): |
2888 def RefreshModel(self, move=True): |
2843 self.Parent.RefreshCommentModel(self) |
2889 self.Parent.RefreshCommentModel(self) |
2844 |
2890 |
2845 # Method called when a LeftDClick event have been generated |
2891 # Method called when a LeftDClick event have been generated |
2846 def OnLeftDClick(self, event, dc, scaling): |
2892 def OnLeftDClick(self, event, dc, scaling): |
2847 # Edit the comment content |
2893 # Edit the comment content |
2848 self.Parent.EditCommentContent(self) |
2894 self.Parent.EditCommentContent(self) |
2849 |
2895 |
2850 # Adds an highlight to the comment |
2896 # Adds an highlight to the comment |
2851 def AddHighlight(self, infos, start, end, highlight_type): |
2897 def AddHighlight(self, infos, start, end, highlight_type): |
2852 if infos[0] == "content": |
2898 if infos[0] == "content": |
2853 AddHighlight(self.Highlights, (start, end, highlight_type)) |
2899 AddHighlight(self.Highlights, (start, end, highlight_type)) |
2854 |
2900 |
2855 # Removes an highlight from the comment |
2901 # Removes an highlight from the comment |
2856 def RemoveHighlight(self, infos, start, end, highlight_type): |
2902 def RemoveHighlight(self, infos, start, end, highlight_type): |
2857 RemoveHighlight(self.Highlights, (start, end, highlight_type)) |
2903 RemoveHighlight(self.Highlights, (start, end, highlight_type)) |
2858 |
2904 |
2859 # Removes all the highlights of one particular type from the comment |
2905 # Removes all the highlights of one particular type from the comment |
2860 def ClearHighlight(self, highlight_type=None): |
2906 def ClearHighlight(self, highlight_type=None): |
2861 self.Highlights = ClearHighlights(self.Highlights, highlight_type) |
2907 self.Highlights = ClearHighlights(self.Highlights, highlight_type) |
2862 |
2908 |
2863 # Draws the highlightment of this element if it is highlighted |
2909 # Draws the highlightment of this element if it is highlighted |
2864 def DrawHighlightment(self, dc): |
2910 def DrawHighlightment(self, dc): |
2865 scalex, scaley = dc.GetUserScale() |
2911 scalex, scaley = dc.GetUserScale() |
2866 dc.SetUserScale(1, 1) |
2912 dc.SetUserScale(1, 1) |
2867 dc.SetPen(MiterPen(HIGHLIGHTCOLOR)) |
2913 dc.SetPen(MiterPen(HIGHLIGHTCOLOR)) |
2868 dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR)) |
2914 dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR)) |
2869 dc.SetLogicalFunction(wx.AND) |
2915 dc.SetLogicalFunction(wx.AND) |
2870 |
2916 |
2871 left = (self.Pos.x - 1) * scalex - 2 |
2917 left = (self.Pos.x - 1) * scalex - 2 |
2872 right = (self.Pos.x + self.Size[0] + 1) * scalex + 2 |
2918 right = (self.Pos.x + self.Size[0] + 1) * scalex + 2 |
2873 top = (self.Pos.y - 1) * scaley - 2 |
2919 top = (self.Pos.y - 1) * scaley - 2 |
2874 bottom = (self.Pos.y + self.Size[1] + 1) * scaley + 2 |
2920 bottom = (self.Pos.y + self.Size[1] + 1) * scaley + 2 |
2875 angle_top = (self.Pos.x + self.Size[0] - 9) * scalex + 2 |
2921 angle_top = (self.Pos.x + self.Size[0] - 9) * scalex + 2 |
2876 angle_right = (self.Pos.y + 9) * scaley - 2 |
2922 angle_right = (self.Pos.y + 9) * scaley - 2 |
2877 |
2923 |
2878 polygon = [wx.Point(left, top), wx.Point(angle_top, top), |
2924 polygon = [wx.Point(left, top), wx.Point(angle_top, top), |
2879 wx.Point(right, angle_right), wx.Point(right, bottom), |
2925 wx.Point(right, angle_right), wx.Point(right, bottom), |
2880 wx.Point(left, bottom)] |
2926 wx.Point(left, bottom)] |
2881 dc.DrawPolygon(polygon) |
2927 dc.DrawPolygon(polygon) |
2882 |
2928 |
2883 dc.SetLogicalFunction(wx.COPY) |
2929 dc.SetLogicalFunction(wx.COPY) |
2884 dc.SetUserScale(scalex, scaley) |
2930 dc.SetUserScale(scalex, scaley) |
2885 |
2931 |
2886 # Draws the comment and its content |
2932 # Draws the comment and its content |
2887 def Draw(self, dc): |
2933 def Draw(self, dc): |
2888 Graphic_Element.Draw(self, dc) |
2934 Graphic_Element.Draw(self, dc) |
2889 dc.SetPen(MiterPen(wx.BLACK)) |
2935 dc.SetPen(MiterPen(wx.BLACK)) |
2890 dc.SetBrush(wx.WHITE_BRUSH) |
2936 dc.SetBrush(wx.WHITE_BRUSH) |
2891 # Draws the comment shape |
2937 # Draws the comment shape |
2892 polygon = [wx.Point(self.Pos.x, self.Pos.y), |
2938 polygon = [wx.Point(self.Pos.x, self.Pos.y), |
2893 wx.Point(self.Pos.x + self.Size[0] - 10, self.Pos.y), |
2939 wx.Point(self.Pos.x + self.Size[0] - 10, self.Pos.y), |
2894 wx.Point(self.Pos.x + self.Size[0], self.Pos.y + 10), |
2940 wx.Point(self.Pos.x + self.Size[0], self.Pos.y + 10), |
2895 wx.Point(self.Pos.x + self.Size[0], self.Pos.y + self.Size[1]), |
2941 wx.Point(self.Pos.x + self.Size[0], self.Pos.y + self.Size[1]), |
2896 wx.Point(self.Pos.x, self.Pos.y + self.Size[1])] |
2942 wx.Point(self.Pos.x, self.Pos.y + self.Size[1])] |
2897 dc.DrawPolygon(polygon) |
2943 dc.DrawPolygon(polygon) |