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 |
276 connector)) |
276 connector)) |
277 distances.sort() |
277 distances.sort() |
278 if len(distances) > 0: |
278 if len(distances) > 0: |
279 return distances[0][1] |
279 return distances[0][1] |
280 return None |
280 return None |
281 |
281 |
282 def IsOfType(self, type, reference): |
282 def IsOfType(self, type, reference): |
283 return self.Parent.IsOfType(type, reference) |
283 return self.Parent.IsOfType(type, reference) |
284 |
284 |
285 def IsEndType(self, type): |
285 def IsEndType(self, type): |
286 return self.Parent.IsEndType(type) |
286 return self.Parent.IsEndType(type) |
287 |
287 |
288 def GetDragging(self): |
288 def GetDragging(self): |
289 return self.Dragging |
289 return self.Dragging |
290 |
290 |
291 # Make a clone of this element |
291 # Make a clone of this element |
292 def Clone(self, parent): |
292 def Clone(self, parent): |
293 return Graphic_Element(parent, self.Id) |
293 return Graphic_Element(parent, self.Id) |
294 |
294 |
295 # Changes the block position |
295 # Changes the block position |
296 def SetPosition(self, x, y): |
296 def SetPosition(self, x, y): |
297 self.Pos.x = x |
297 self.Pos.x = x |
298 self.Pos.y = y |
298 self.Pos.y = y |
299 self.RefreshConnected() |
299 self.RefreshConnected() |
300 self.RefreshBoundingBox() |
300 self.RefreshBoundingBox() |
301 |
301 |
302 # Returns the block position |
302 # Returns the block position |
303 def GetPosition(self): |
303 def GetPosition(self): |
304 return self.Pos.x, self.Pos.y |
304 return self.Pos.x, self.Pos.y |
305 |
305 |
306 # Changes the element size |
306 # Changes the element size |
307 def SetSize(self, width, height): |
307 def SetSize(self, width, height): |
308 self.Size.SetWidth(width) |
308 self.Size.SetWidth(width) |
309 self.Size.SetHeight(height) |
309 self.Size.SetHeight(height) |
310 self.RefreshConnectors() |
310 self.RefreshConnectors() |
311 self.RefreshBoundingBox() |
311 self.RefreshBoundingBox() |
312 |
312 |
313 # Returns the element size |
313 # Returns the element size |
314 def GetSize(self): |
314 def GetSize(self): |
315 return self.Size.GetWidth(), self.Size.GetHeight() |
315 return self.Size.GetWidth(), self.Size.GetHeight() |
316 |
316 |
317 # Returns the minimum element size |
317 # Returns the minimum element size |
318 def GetMinSize(self): |
318 def GetMinSize(self): |
319 return 0, 0 |
319 return 0, 0 |
320 |
320 |
321 # Set size of the element to the minimum size |
321 # Set size of the element to the minimum size |
322 def SetBestSize(self, scaling, x_factor=0.5, y_factor=0.5): |
322 def SetBestSize(self, scaling, x_factor=0.5, y_factor=0.5): |
323 width, height = self.GetSize() |
323 width, height = self.GetSize() |
324 posx, posy = self.GetPosition() |
324 posx, posy = self.GetPosition() |
325 min_width, min_height = self.GetMinSize() |
325 min_width, min_height = self.GetMinSize() |
334 self.Pos.y = round_scaling(self.Pos.y, scaling[1]) |
334 self.Pos.y = round_scaling(self.Pos.y, scaling[1]) |
335 width = round_scaling(width, scaling[0], 1) |
335 width = round_scaling(width, scaling[0], 1) |
336 height = round_scaling(height, scaling[1], 1) |
336 height = round_scaling(height, scaling[1], 1) |
337 self.SetSize(width, height) |
337 self.SetSize(width, height) |
338 return self.Pos.x - posx, self.Pos.y - posy |
338 return self.Pos.x - posx, self.Pos.y - posy |
339 |
339 |
340 # Refresh the element Bounding Box |
340 # Refresh the element Bounding Box |
341 def RefreshBoundingBox(self): |
341 def RefreshBoundingBox(self): |
342 self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1]) |
342 self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1]) |
343 |
343 |
344 # Refresh the element connectors position |
344 # Refresh the element connectors position |
345 def RefreshConnectors(self): |
345 def RefreshConnectors(self): |
346 pass |
346 pass |
347 |
347 |
348 # Refresh the position of wires connected to element inputs and outputs |
348 # Refresh the position of wires connected to element inputs and outputs |
349 def RefreshConnected(self): |
349 def RefreshConnected(self): |
350 pass |
350 pass |
351 |
351 |
352 # Change the parent |
352 # Change the parent |
353 def SetParent(self, parent): |
353 def SetParent(self, parent): |
354 self.Parent = parent |
354 self.Parent = parent |
355 |
355 |
356 # Override this method for defining the method to call for deleting this element |
356 # Override this method for defining the method to call for deleting this element |
357 def Delete(self): |
357 def Delete(self): |
358 pass |
358 pass |
359 |
359 |
360 # Returns the Id |
360 # Returns the Id |
361 def GetId(self): |
361 def GetId(self): |
362 return self.Id |
362 return self.Id |
363 |
363 |
364 # Returns if the point given is in the bounding box |
364 # Returns if the point given is in the bounding box |
365 def HitTest(self, pt, connectors=True): |
365 def HitTest(self, pt, connectors=True): |
366 if connectors: |
366 if connectors: |
367 rect = self.BoundingBox |
367 rect = self.BoundingBox |
368 else: |
368 else: |
369 rect = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1]) |
369 rect = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1]) |
370 return rect.InsideXY(pt.x, pt.y) |
370 return rect.InsideXY(pt.x, pt.y) |
371 |
371 |
372 # Returns if the point given is in the bounding box |
372 # Returns if the point given is in the bounding box |
373 def IsInSelection(self, rect): |
373 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) |
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) |
375 |
375 |
376 # Override this method for refreshing the bounding box |
376 # Override this method for refreshing the bounding box |
377 def RefreshBoundingBox(self): |
377 def RefreshBoundingBox(self): |
378 pass |
378 pass |
379 |
379 |
380 # Returns the bounding box |
380 # Returns the bounding box |
381 def GetBoundingBox(self): |
381 def GetBoundingBox(self): |
382 return self.BoundingBox |
382 return self.BoundingBox |
383 |
383 |
384 # Returns the RedrawRect |
384 # Returns the RedrawRect |
385 def GetRedrawRect(self, movex = 0, movey = 0): |
385 def GetRedrawRect(self, movex = 0, movey = 0): |
386 scalex, scaley = self.Parent.GetViewScale() |
386 scalex, scaley = self.Parent.GetViewScale() |
387 rect = wx.Rect() |
387 rect = wx.Rect() |
388 rect.x = self.BoundingBox.x - int(HANDLE_SIZE / scalex) - 3 - abs(movex) |
388 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) |
389 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 |
390 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 |
391 rect.height = self.BoundingBox.height + 2 * (int(HANDLE_SIZE / scaley) + abs(movey) + 1) + 4 |
392 return rect |
392 return rect |
393 |
393 |
394 def Refresh(self, rect = None): |
394 def Refresh(self, rect = None): |
395 if self.Visible: |
395 if self.Visible: |
396 if rect is not None: |
396 if rect is not None: |
397 self.Parent.RefreshRect(self.Parent.GetScrolledRect(rect), False) |
397 self.Parent.RefreshRect(self.Parent.GetScrolledRect(rect), False) |
398 else: |
398 else: |
399 self.Parent.RefreshRect(self.Parent.GetScrolledRect(self.GetRedrawRect()), False) |
399 self.Parent.RefreshRect(self.Parent.GetScrolledRect(self.GetRedrawRect()), False) |
400 |
400 |
401 # Change the variable that indicates if this element is selected |
401 # Change the variable that indicates if this element is selected |
402 def SetSelected(self, selected): |
402 def SetSelected(self, selected): |
403 self.Selected = selected |
403 self.Selected = selected |
404 self.Refresh() |
404 self.Refresh() |
405 |
405 |
406 # Change the variable that indicates if this element is highlighted |
406 # Change the variable that indicates if this element is highlighted |
407 def SetHighlighted(self, highlighted): |
407 def SetHighlighted(self, highlighted): |
408 self.Highlighted = highlighted |
408 self.Highlighted = highlighted |
409 self.Refresh() |
409 self.Refresh() |
410 |
410 |
411 # Test if the point is on a handle of this element |
411 # Test if the point is on a handle of this element |
412 def TestHandle(self, event): |
412 def TestHandle(self, event): |
413 dc = self.Parent.GetLogicalDC() |
413 dc = self.Parent.GetLogicalDC() |
414 scalex, scaley = dc.GetUserScale() |
414 scalex, scaley = dc.GetUserScale() |
415 pos = event.GetPosition() |
415 pos = event.GetPosition() |
416 pt = wx.Point(*self.Parent.CalcUnscrolledPosition(pos.x, pos.y)) |
416 pt = wx.Point(*self.Parent.CalcUnscrolledPosition(pos.x, pos.y)) |
417 |
417 |
418 left = (self.BoundingBox.x - 2) * scalex - HANDLE_SIZE |
418 left = (self.BoundingBox.x - 2) * scalex - HANDLE_SIZE |
419 center = (self.BoundingBox.x + self.BoundingBox.width / 2) * scalex - HANDLE_SIZE / 2 |
419 center = (self.BoundingBox.x + self.BoundingBox.width / 2) * scalex - HANDLE_SIZE / 2 |
420 right = (self.BoundingBox.x + self.BoundingBox.width + 2) * scalex |
420 right = (self.BoundingBox.x + self.BoundingBox.width + 2) * scalex |
421 |
421 |
422 top = (self.BoundingBox.y - 2) * scaley - HANDLE_SIZE |
422 top = (self.BoundingBox.y - 2) * scaley - HANDLE_SIZE |
423 middle = (self.BoundingBox.y + self.BoundingBox.height / 2) * scaley - HANDLE_SIZE / 2 |
423 middle = (self.BoundingBox.y + self.BoundingBox.height / 2) * scaley - HANDLE_SIZE / 2 |
424 bottom = (self.BoundingBox.y + self.BoundingBox.height + 2) * scaley |
424 bottom = (self.BoundingBox.y + self.BoundingBox.height + 2) * scaley |
425 |
425 |
426 extern_rect = wx.Rect(left, top, right + HANDLE_SIZE - left, bottom + HANDLE_SIZE - top) |
426 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) |
427 intern_rect = wx.Rect(left + HANDLE_SIZE, top + HANDLE_SIZE, right - left - HANDLE_SIZE, bottom - top - HANDLE_SIZE) |
428 |
428 |
429 # Verify that this element is selected |
429 # 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): |
430 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 |
431 # Find if point is on a handle horizontally |
432 if left <= pt.x < left + HANDLE_SIZE: |
432 if left <= pt.x < left + HANDLE_SIZE: |
433 handle_x = 1 |
433 handle_x = 1 |
535 def Move(self, dx, dy, exclude = []): |
535 def Move(self, dx, dy, exclude = []): |
536 self.Pos.x += max(-self.BoundingBox.x, dx) |
536 self.Pos.x += max(-self.BoundingBox.x, dx) |
537 self.Pos.y += max(-self.BoundingBox.y, dy) |
537 self.Pos.y += max(-self.BoundingBox.y, dy) |
538 self.RefreshConnected(exclude) |
538 self.RefreshConnected(exclude) |
539 self.RefreshBoundingBox() |
539 self.RefreshBoundingBox() |
540 |
540 |
541 # Resizes the element from position and size given |
541 # Resizes the element from position and size given |
542 def Resize(self, x, y, width, height): |
542 def Resize(self, x, y, width, height): |
543 self.Move(x, y) |
543 self.Move(x, y) |
544 self.SetSize(width, height) |
544 self.SetSize(width, height) |
545 |
545 |
546 # Refreshes the element state according to move defined and handle selected |
546 # 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): |
547 def ProcessDragging(self, movex, movey, event, scaling, width_fac = 1, height_fac = 1): |
548 handle_type, handle = self.Handle |
548 handle_type, handle = self.Handle |
549 # If it is a resize handle, calculate the values from resizing |
549 # If it is a resize handle, calculate the values from resizing |
550 if handle_type == HANDLE_RESIZE: |
550 if handle_type == HANDLE_RESIZE: |
616 if abs(self.CurrentDrag.x) > abs(self.CurrentDrag.y): |
616 if abs(self.CurrentDrag.x) > abs(self.CurrentDrag.y): |
617 movex = self.StartPos.x + self.CurrentDrag.x - self.Pos.x |
617 movex = self.StartPos.x + self.CurrentDrag.x - self.Pos.x |
618 movey = self.StartPos.y - self.Pos.y |
618 movey = self.StartPos.y - self.Pos.y |
619 else: |
619 else: |
620 movex = self.StartPos.x - self.Pos.x |
620 movex = self.StartPos.x - self.Pos.x |
621 movey = self.StartPos.y + self.CurrentDrag.y - self.Pos.y |
621 movey = self.StartPos.y + self.CurrentDrag.y - self.Pos.y |
622 self.Move(movex, movey) |
622 self.Move(movex, movey) |
623 return movex, movey |
623 return movex, movey |
624 return 0, 0 |
624 return 0, 0 |
625 |
625 |
626 # Override this method for defining the method to call for adding an highlight to this element |
626 # 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): |
627 def AddHighlight(self, infos, start, end, highlight_type): |
628 pass |
628 pass |
629 |
629 |
630 # Override this method for defining the method to call for removing an highlight from this element |
630 # 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): |
631 def RemoveHighlight(self, infos, start, end, highlight_type): |
632 pass |
632 pass |
633 |
633 |
634 # Override this method for defining the method to call for removing all the highlights of one particular type from this element |
634 # 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): |
635 def ClearHighlight(self, highlight_type=None): |
636 pass |
636 pass |
637 |
637 |
638 # Override this method for defining the method to call for refreshing the model of this element |
638 # Override this method for defining the method to call for refreshing the model of this element |
639 def RefreshModel(self, move=True): |
639 def RefreshModel(self, move=True): |
640 pass |
640 pass |
641 |
641 |
642 # Draws the highlightment of this element if it is highlighted (can be overwritten) |
642 # Draws the highlightment of this element if it is highlighted (can be overwritten) |
643 def DrawHighlightment(self, dc): |
643 def DrawHighlightment(self, dc): |
644 scalex, scaley = dc.GetUserScale() |
644 scalex, scaley = dc.GetUserScale() |
645 dc.SetUserScale(1, 1) |
645 dc.SetUserScale(1, 1) |
646 dc.SetPen(MiterPen(HIGHLIGHTCOLOR)) |
646 dc.SetPen(MiterPen(HIGHLIGHTCOLOR)) |
647 dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR)) |
647 dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR)) |
648 dc.SetLogicalFunction(wx.AND) |
648 dc.SetLogicalFunction(wx.AND) |
649 dc.DrawRectangle(int(round((self.Pos.x - 1) * scalex)) - 2, |
649 dc.DrawRectangle(int(round((self.Pos.x - 1) * scalex)) - 2, |
650 int(round((self.Pos.y - 1) * scaley)) - 2, |
650 int(round((self.Pos.y - 1) * scaley)) - 2, |
651 int(round((self.Size.width + 3) * scalex)) + 5, |
651 int(round((self.Size.width + 3) * scalex)) + 5, |
652 int(round((self.Size.height + 3) * scaley)) + 5) |
652 int(round((self.Size.height + 3) * scaley)) + 5) |
653 dc.SetLogicalFunction(wx.COPY) |
653 dc.SetLogicalFunction(wx.COPY) |
654 dc.SetUserScale(scalex, scaley) |
654 dc.SetUserScale(scalex, scaley) |
655 |
655 |
656 # Draws the handles of this element if it is selected |
656 # Draws the handles of this element if it is selected |
657 def Draw(self, dc): |
657 def Draw(self, dc): |
658 if not getattr(dc, "printing", False): |
658 if not getattr(dc, "printing", False): |
659 if self.Highlighted: |
659 if self.Highlighted: |
660 self.DrawHighlightment(dc) |
660 self.DrawHighlightment(dc) |
661 if self.Selected: |
661 if self.Selected: |
662 scalex, scaley = dc.GetUserScale() |
662 scalex, scaley = dc.GetUserScale() |
663 dc.SetUserScale(1, 1) |
663 dc.SetUserScale(1, 1) |
664 dc.SetPen(MiterPen(wx.BLACK)) |
664 dc.SetPen(MiterPen(wx.BLACK)) |
665 dc.SetBrush(wx.BLACK_BRUSH) |
665 dc.SetBrush(wx.BLACK_BRUSH) |
666 |
666 |
667 left = (self.BoundingBox.x - 2) * scalex - HANDLE_SIZE |
667 left = (self.BoundingBox.x - 2) * scalex - HANDLE_SIZE |
668 center = (self.BoundingBox.x + self.BoundingBox.width / 2) * scalex - HANDLE_SIZE / 2 |
668 center = (self.BoundingBox.x + self.BoundingBox.width / 2) * scalex - HANDLE_SIZE / 2 |
669 right = (self.BoundingBox.x + self.BoundingBox.width + 2) * scalex |
669 right = (self.BoundingBox.x + self.BoundingBox.width + 2) * scalex |
670 |
670 |
671 top = (self.BoundingBox.y - 2) * scaley - HANDLE_SIZE |
671 top = (self.BoundingBox.y - 2) * scaley - HANDLE_SIZE |
672 middle = (self.BoundingBox.y + self.BoundingBox.height / 2) * scaley - HANDLE_SIZE / 2 |
672 middle = (self.BoundingBox.y + self.BoundingBox.height / 2) * scaley - HANDLE_SIZE / 2 |
673 bottom = (self.BoundingBox.y + self.BoundingBox.height + 2) * scaley |
673 bottom = (self.BoundingBox.y + self.BoundingBox.height + 2) * scaley |
674 |
674 |
675 for x, y in [(left, top), (center, top), (right, top), |
675 for x, y in [(left, top), (center, top), (right, top), |
676 (left, middle), (right, middle), |
676 (left, middle), (right, middle), |
677 (left, bottom), (center, bottom), (right, bottom)]: |
677 (left, bottom), (center, bottom), (right, bottom)]: |
678 dc.DrawRectangle(x, y, HANDLE_SIZE, HANDLE_SIZE) |
678 dc.DrawRectangle(x, y, HANDLE_SIZE, HANDLE_SIZE) |
679 |
679 |
680 dc.SetUserScale(scalex, scaley) |
680 dc.SetUserScale(scalex, scaley) |
681 |
681 |
682 |
682 |
683 #------------------------------------------------------------------------------- |
683 #------------------------------------------------------------------------------- |
684 # Group of graphic elements |
684 # Group of graphic elements |
749 if pos is not None: |
749 if pos is not None: |
750 for element in group.Elements: |
750 for element in group.Elements: |
751 if not isinstance(element, Wire): |
751 if not isinstance(element, Wire): |
752 parent.AddBlockInModel(element) |
752 parent.AddBlockInModel(element) |
753 return group |
753 return group |
754 |
754 |
755 def CanAddBlocks(self, parent): |
755 def CanAddBlocks(self, parent): |
756 valid = True |
756 valid = True |
757 for element in self.Elements: |
757 for element in self.Elements: |
758 if not isinstance(element, Wire): |
758 if not isinstance(element, Wire): |
759 valid &= parent.CanAddElement(element) |
759 valid &= parent.CanAddElement(element) |
760 return valid |
760 return valid |
761 |
761 |
762 def IsVisible(self): |
762 def IsVisible(self): |
763 for element in self.Elements: |
763 for element in self.Elements: |
764 if element.IsVisible(): |
764 if element.IsVisible(): |
765 return True |
765 return True |
766 return False |
766 return False |
767 |
767 |
768 # Refresh the list of wire excluded |
768 # Refresh the list of wire excluded |
769 def RefreshWireExclusion(self): |
769 def RefreshWireExclusion(self): |
770 self.WireExcluded = [] |
770 self.WireExcluded = [] |
771 for element in self.Elements: |
771 for element in self.Elements: |
772 if isinstance(element, Wire): |
772 if isinstance(element, Wire): |
773 startblock = element.StartConnected.GetParentBlock() |
773 startblock = element.StartConnected.GetParentBlock() |
774 endblock = element.EndConnected.GetParentBlock() |
774 endblock = element.EndConnected.GetParentBlock() |
775 if startblock in self.Elements and endblock in self.Elements: |
775 if startblock in self.Elements and endblock in self.Elements: |
776 self.WireExcluded.append(element) |
776 self.WireExcluded.append(element) |
777 |
777 |
778 # Returns the RedrawRect |
778 # Returns the RedrawRect |
779 def GetRedrawRect(self, movex = 0, movey = 0): |
779 def GetRedrawRect(self, movex = 0, movey = 0): |
780 rect = None |
780 rect = None |
781 for element in self.Elements: |
781 for element in self.Elements: |
782 if rect is None: |
782 if rect is None: |
783 rect = element.GetRedrawRect(movex, movey) |
783 rect = element.GetRedrawRect(movex, movey) |
784 else: |
784 else: |
785 rect = rect.Union(element.GetRedrawRect(movex, movey)) |
785 rect = rect.Union(element.GetRedrawRect(movex, movey)) |
786 return rect |
786 return rect |
787 |
787 |
788 # Clean this group of elements |
788 # Clean this group of elements |
789 def Clean(self): |
789 def Clean(self): |
790 # Clean all the elements of the group |
790 # Clean all the elements of the group |
791 for element in self.Elements: |
791 for element in self.Elements: |
792 element.Clean() |
792 element.Clean() |
793 |
793 |
794 # Delete this group of elements |
794 # Delete this group of elements |
795 def Delete(self): |
795 def Delete(self): |
796 # Delete all the elements of the group |
796 # Delete all the elements of the group |
797 for element in self.Elements: |
797 for element in self.Elements: |
798 element.Delete() |
798 element.Delete() |
799 self.WireExcluded = [] |
799 self.WireExcluded = [] |
800 |
800 |
801 # Returns if the point given is in the bounding box of one of the elements of this group |
801 # 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): |
802 def HitTest(self, pt, connectors=True): |
803 result = False |
803 result = False |
804 for element in self.Elements: |
804 for element in self.Elements: |
805 result |= element.HitTest(pt, connectors) |
805 result |= element.HitTest(pt, connectors) |
806 return result |
806 return result |
807 |
807 |
808 # Returns if the element given is in this group |
808 # Returns if the element given is in this group |
809 def IsElementIn(self, element): |
809 def IsElementIn(self, element): |
810 return element in self.Elements |
810 return element in self.Elements |
811 |
811 |
812 # Change the elements of the group |
812 # Change the elements of the group |
813 def SetElements(self, elements): |
813 def SetElements(self, elements): |
814 self.Elements = elements |
814 self.Elements = elements |
815 self.RefreshWireExclusion() |
815 self.RefreshWireExclusion() |
816 self.RefreshBoundingBox() |
816 self.RefreshBoundingBox() |
817 |
817 |
818 # Returns the elements of the group |
818 # Returns the elements of the group |
819 def GetElements(self): |
819 def GetElements(self): |
820 return self.Elements |
820 return self.Elements |
821 |
821 |
822 # Align the group elements |
822 # Align the group elements |
823 def AlignElements(self, horizontally, vertically): |
823 def AlignElements(self, horizontally, vertically): |
824 minx = self.BoundingBox.x + self.BoundingBox.width |
824 minx = self.BoundingBox.x + self.BoundingBox.width |
825 miny = self.BoundingBox.y + self.BoundingBox.height |
825 miny = self.BoundingBox.y + self.BoundingBox.height |
826 maxx = self.BoundingBox.x |
826 maxx = self.BoundingBox.x |
852 movey = maxy - height - posy |
852 movey = maxy - height - posy |
853 if movex != 0 or movey != 0: |
853 if movex != 0 or movey != 0: |
854 element.Move(movex, movey) |
854 element.Move(movex, movey) |
855 element.RefreshModel() |
855 element.RefreshModel() |
856 self.RefreshBoundingBox() |
856 self.RefreshBoundingBox() |
857 |
857 |
858 # Add the given element to the group of elements |
858 # Add the given element to the group of elements |
859 def AddElement(self, element): |
859 def AddElement(self, element): |
860 self.Elements.append(element) |
860 self.Elements.append(element) |
861 |
861 |
862 # Remove or select the given element if it is or not in the group |
862 # Remove or select the given element if it is or not in the group |
863 def SelectElement(self, element): |
863 def SelectElement(self, element): |
864 if element in self.Elements: |
864 if element in self.Elements: |
865 self.Elements.remove(element) |
865 self.Elements.remove(element) |
866 else: |
866 else: |
867 self.Elements.append(element) |
867 self.Elements.append(element) |
868 self.RefreshWireExclusion() |
868 self.RefreshWireExclusion() |
869 self.RefreshBoundingBox() |
869 self.RefreshBoundingBox() |
870 |
870 |
871 # Move this group of elements |
871 # Move this group of elements |
872 def Move(self, movex, movey): |
872 def Move(self, movex, movey): |
873 movex = max(-self.BoundingBox.x, movex) |
873 movex = max(-self.BoundingBox.x, movex) |
874 movey = max(-self.BoundingBox.y, movey) |
874 movey = max(-self.BoundingBox.y, movey) |
875 # Move all the elements of the group |
875 # Move all the elements of the group |
917 posy = min(posy, bbox.y) |
917 posy = min(posy, bbox.y) |
918 if posx is None and posy is None: |
918 if posx is None and posy is None: |
919 return 0, 0 |
919 return 0, 0 |
920 return posx, posy |
920 return posx, posy |
921 return self.BoundingBox.x, self.BoundingBox.y |
921 return self.BoundingBox.x, self.BoundingBox.y |
922 |
922 |
923 # Forbids to change the group size |
923 # Forbids to change the group size |
924 def SetSize(width, height): |
924 def SetSize(width, height): |
925 pass |
925 pass |
926 |
926 |
927 # Returns the size of this group |
927 # Returns the size of this group |
928 def GetSize(self): |
928 def GetSize(self): |
929 return self.BoundingBox.width, self.BoundingBox.height |
929 return self.BoundingBox.width, self.BoundingBox.height |
930 |
930 |
931 # Set size of the group elements to their minimum size |
931 # Set size of the group elements to their minimum size |
932 def SetBestSize(self, scaling): |
932 def SetBestSize(self, scaling): |
933 max_movex = max_movey = 0 |
933 max_movex = max_movey = 0 |
934 for element in self.Elements: |
934 for element in self.Elements: |
935 movex, movey = element.SetBestSize(scaling) |
935 movex, movey = element.SetBestSize(scaling) |
936 max_movex = max(max_movex, movex) |
936 max_movex = max(max_movex, movex) |
937 max_movey = max(max_movey, movey) |
937 max_movey = max(max_movey, movey) |
938 return max_movex, max_movey |
938 return max_movex, max_movey |
939 |
939 |
940 # Refreshes the group elements to move defined and handle selected |
940 # Refreshes the group elements to move defined and handle selected |
941 def ProcessDragging(self, movex, movey, event, scaling): |
941 def ProcessDragging(self, movex, movey, event, scaling): |
942 handle_type, handle = self.Handle |
942 handle_type, handle = self.Handle |
943 # If it is a move handle, Move this group elements |
943 # If it is a move handle, Move this group elements |
944 if handle_type == HANDLE_MOVE: |
944 if handle_type == HANDLE_MOVE: |
958 movex = self.StartPos.x - posx |
958 movex = self.StartPos.x - posx |
959 movey = self.StartPos.y + self.CurrentDrag.y - posy |
959 movey = self.StartPos.y + self.CurrentDrag.y - posy |
960 self.Move(movex, movey) |
960 self.Move(movex, movey) |
961 return movex, movey |
961 return movex, movey |
962 return 0, 0 |
962 return 0, 0 |
963 |
963 |
964 # Change the variable that indicates if this element is highlighted |
964 # Change the variable that indicates if this element is highlighted |
965 def SetHighlighted(self, highlighted): |
965 def SetHighlighted(self, highlighted): |
966 for element in self.Elements: |
966 for element in self.Elements: |
967 element.SetHighlighted(highlighted) |
967 element.SetHighlighted(highlighted) |
968 |
968 |
969 def HighlightPoint(self, pos): |
969 def HighlightPoint(self, pos): |
970 for element in self.Elements: |
970 for element in self.Elements: |
971 if isinstance(element, Wire): |
971 if isinstance(element, Wire): |
972 element.HighlightPoint(pos) |
972 element.HighlightPoint(pos) |
973 |
973 |
974 # Method called when a LeftDown event have been generated |
974 # Method called when a LeftDown event have been generated |
975 def OnLeftDown(self, event, dc, scaling): |
975 def OnLeftDown(self, event, dc, scaling): |
976 Graphic_Element.OnLeftDown(self, event, dc, scaling) |
976 Graphic_Element.OnLeftDown(self, event, dc, scaling) |
977 self.StartPos = wx.Point(*self.GetPosition(True)) |
977 self.StartPos = wx.Point(*self.GetPosition(True)) |
978 for element in self.Elements: |
978 for element in self.Elements: |
1070 width * (self.Direction[0] - 1) / 2, |
1070 width * (self.Direction[0] - 1) / 2, |
1071 parent_pos[1] + self.Pos.y + CONNECTOR_SIZE * self.Direction[1] + \ |
1071 parent_pos[1] + self.Pos.y + CONNECTOR_SIZE * self.Direction[1] + \ |
1072 height * (self.Direction[1] - 1), |
1072 height * (self.Direction[1] - 1), |
1073 width, height)) |
1073 width, height)) |
1074 return rect |
1074 return rect |
1075 |
1075 |
1076 # Change the connector selection |
1076 # Change the connector selection |
1077 def SetSelected(self, selected): |
1077 def SetSelected(self, selected): |
1078 self.Selected = selected |
1078 self.Selected = selected |
1079 |
1079 |
1080 # Make a clone of the connector |
1080 # Make a clone of the connector |
1081 def Clone(self, parent = None): |
1081 def Clone(self, parent = None): |
1082 if parent is None: |
1082 if parent is None: |
1083 parent = self.ParentBlock |
1083 parent = self.ParentBlock |
1084 return Connector(parent, self.Name, self.Type, wx.Point(self.Pos[0], self.Pos[1]), |
1084 return Connector(parent, self.Name, self.Type, wx.Point(self.Pos[0], self.Pos[1]), |
1085 self.Direction, self.Negated) |
1085 self.Direction, self.Negated) |
1086 |
1086 |
1087 # Returns the connector parent block |
1087 # Returns the connector parent block |
1088 def GetParentBlock(self): |
1088 def GetParentBlock(self): |
1089 return self.ParentBlock |
1089 return self.ParentBlock |
1090 |
1090 |
1091 # Returns the connector type |
1091 # Returns the connector type |
1092 def GetType(self, raw = False): |
1092 def GetType(self, raw = False): |
1093 if self.ParentBlock.IsEndType(self.Type) or raw: |
1093 if self.ParentBlock.IsEndType(self.Type) or raw: |
1094 return self.Type |
1094 return self.Type |
1095 elif (self.Negated or self.Edge != "none") and self.ParentBlock.IsOfType("BOOL", self.Type): |
1095 elif (self.Negated or self.Edge != "none") and self.ParentBlock.IsOfType("BOOL", self.Type): |
1096 return "BOOL" |
1096 return "BOOL" |
1097 else: |
1097 else: |
1098 return self.ParentBlock.GetConnectionResultType(self, self.Type) |
1098 return self.ParentBlock.GetConnectionResultType(self, self.Type) |
1099 |
1099 |
1100 # Returns the connector type |
1100 # Returns the connector type |
1101 def GetConnectedType(self): |
1101 def GetConnectedType(self): |
1102 if self.ParentBlock.IsEndType(self.Type): |
1102 if self.ParentBlock.IsEndType(self.Type): |
1103 return self.Type |
1103 return self.Type |
1104 elif len(self.Wires) == 1: |
1104 elif len(self.Wires) == 1: |
1105 return self.Wires[0][0].GetOtherConnectedType(self.Wires[0][1]) |
1105 return self.Wires[0][0].GetOtherConnectedType(self.Wires[0][1]) |
1106 return self.Type |
1106 return self.Type |
1107 |
1107 |
1108 # Returns the connector type |
1108 # Returns the connector type |
1109 def GetConnectedRedrawRect(self, movex, movey): |
1109 def GetConnectedRedrawRect(self, movex, movey): |
1110 rect = None |
1110 rect = None |
1111 for wire, handle in self.Wires: |
1111 for wire, handle in self.Wires: |
1112 if rect is None: |
1112 if rect is None: |
1113 rect = wire.GetRedrawRect() |
1113 rect = wire.GetRedrawRect() |
1114 else: |
1114 else: |
1115 rect = rect.Union(wire.GetRedrawRect()) |
1115 rect = rect.Union(wire.GetRedrawRect()) |
1116 return rect |
1116 return rect |
1117 |
1117 |
1118 # Returns if connector type is compatible with type given |
1118 # Returns if connector type is compatible with type given |
1119 def IsCompatible(self, type): |
1119 def IsCompatible(self, type): |
1120 reference = self.GetType() |
1120 reference = self.GetType() |
1121 return self.ParentBlock.IsOfType(type, reference) or self.ParentBlock.IsOfType(reference, type) |
1121 return self.ParentBlock.IsOfType(type, reference) or self.ParentBlock.IsOfType(reference, type) |
1122 |
1122 |
1123 # Changes the connector name |
1123 # Changes the connector name |
1124 def SetType(self, type): |
1124 def SetType(self, type): |
1125 self.Type = type |
1125 self.Type = type |
1126 for wire, handle in self.Wires: |
1126 for wire, handle in self.Wires: |
1127 wire.SetValid(wire.IsConnectedCompatible()) |
1127 wire.SetValid(wire.IsConnectedCompatible()) |
1128 |
1128 |
1129 # Returns the connector name |
1129 # Returns the connector name |
1130 def GetName(self): |
1130 def GetName(self): |
1131 return self.Name |
1131 return self.Name |
1132 |
1132 |
1133 # Changes the connector name |
1133 # Changes the connector name |
1134 def SetName(self, name): |
1134 def SetName(self, name): |
1135 self.Name = name |
1135 self.Name = name |
1136 self.RefreshNameSize() |
1136 self.RefreshNameSize() |
1137 |
1137 |
1138 def SetForced(self, forced): |
1138 def SetForced(self, forced): |
1139 if self.Forced != forced: |
1139 if self.Forced != forced: |
1140 self.Forced = forced |
1140 self.Forced = forced |
1141 if self.Visible: |
1141 if self.Visible: |
1142 self.Parent.ElementNeedRefresh(self) |
1142 self.Parent.ElementNeedRefresh(self) |
1143 |
1143 |
1144 def GetComputedValue(self): |
1144 def GetComputedValue(self): |
1145 if self.Value is not None and self.Value != "undefined" and not isinstance(self.Value, BooleanType): |
1145 if self.Value is not None and self.Value != "undefined" and not isinstance(self.Value, BooleanType): |
1146 return self.Value |
1146 return self.Value |
1147 return None |
1147 return None |
1148 |
1148 |
1149 def GetToolTipValue(self): |
1149 def GetToolTipValue(self): |
1150 return self.GetComputedValue() |
1150 return self.GetComputedValue() |
1151 |
1151 |
1152 def SetValue(self, value): |
1152 def SetValue(self, value): |
1153 if self.Value != value: |
1153 if self.Value != value: |
1154 self.Value = value |
1154 self.Value = value |
1155 computed_value = self.GetComputedValue() |
1155 computed_value = self.GetComputedValue() |
1156 if computed_value is not None: |
1156 if computed_value is not None: |
1159 if len(self.ComputedValue) > 4: |
1159 if len(self.ComputedValue) > 4: |
1160 self.ComputedValue = self.ComputedValue[:4] + "..." |
1160 self.ComputedValue = self.ComputedValue[:4] + "..." |
1161 self.ValueSize = None |
1161 self.ValueSize = None |
1162 if self.ParentBlock.Visible: |
1162 if self.ParentBlock.Visible: |
1163 self.ParentBlock.Parent.ElementNeedRefresh(self) |
1163 self.ParentBlock.Parent.ElementNeedRefresh(self) |
1164 |
1164 |
1165 def RefreshForced(self): |
1165 def RefreshForced(self): |
1166 self.Forced = False |
1166 self.Forced = False |
1167 for wire, handle in self.Wires: |
1167 for wire, handle in self.Wires: |
1168 self.Forced |= wire.IsForced() |
1168 self.Forced |= wire.IsForced() |
1169 |
1169 |
1170 def RefreshValue(self): |
1170 def RefreshValue(self): |
1171 self.Value = self.ReceivingCurrent() |
1171 self.Value = self.ReceivingCurrent() |
1172 |
1172 |
1173 def RefreshValid(self): |
1173 def RefreshValid(self): |
1174 self.Valid = True |
1174 self.Valid = True |
1175 for wire, handle in self.Wires: |
1175 for wire, handle in self.Wires: |
1176 self.Valid &= wire.GetValid() |
1176 self.Valid &= wire.GetValid() |
1177 |
1177 |
1178 def ReceivingCurrent(self): |
1178 def ReceivingCurrent(self): |
1179 current = False |
1179 current = False |
1180 for wire, handle in self.Wires: |
1180 for wire, handle in self.Wires: |
1181 value = wire.GetValue() |
1181 value = wire.GetValue() |
1182 if current != "undefined" and isinstance(value, BooleanType): |
1182 if current != "undefined" and isinstance(value, BooleanType): |
1183 current |= wire.GetValue() |
1183 current |= wire.GetValue() |
1184 elif value == "undefined": |
1184 elif value == "undefined": |
1185 current = "undefined" |
1185 current = "undefined" |
1186 return current |
1186 return current |
1187 |
1187 |
1188 def SpreadCurrent(self, spreading): |
1188 def SpreadCurrent(self, spreading): |
1189 for wire, handle in self.Wires: |
1189 for wire, handle in self.Wires: |
1190 wire.SetValue(spreading) |
1190 wire.SetValue(spreading) |
1191 |
1191 |
1192 # Changes the connector name size |
1192 # Changes the connector name size |
1193 def RefreshNameSize(self): |
1193 def RefreshNameSize(self): |
1194 if self.Name != "": |
1194 if self.Name != "": |
1195 self.NameSize = self.ParentBlock.Parent.GetTextExtent(self.Name) |
1195 self.NameSize = self.ParentBlock.Parent.GetTextExtent(self.Name) |
1196 else: |
1196 else: |
1197 self.NameSize = 0, 0 |
1197 self.NameSize = 0, 0 |
1198 |
1198 |
1199 # Returns the connector name size |
1199 # Returns the connector name size |
1200 def GetNameSize(self): |
1200 def GetNameSize(self): |
1201 return self.NameSize |
1201 return self.NameSize |
1202 |
1202 |
1203 # Returns the wires connected to the connector |
1203 # Returns the wires connected to the connector |
1204 def GetWires(self): |
1204 def GetWires(self): |
1205 return self.Wires |
1205 return self.Wires |
1206 |
1206 |
1207 # Returns the parent block Id |
1207 # Returns the parent block Id |
1208 def GetBlockId(self): |
1208 def GetBlockId(self): |
1209 return self.ParentBlock.GetId() |
1209 return self.ParentBlock.GetId() |
1210 |
1210 |
1211 # Returns the connector relative position |
1211 # Returns the connector relative position |
1212 def GetRelPosition(self): |
1212 def GetRelPosition(self): |
1213 return self.Pos |
1213 return self.Pos |
1214 |
1214 |
1215 # Returns the connector absolute position |
1215 # Returns the connector absolute position |
1216 def GetPosition(self, size = True): |
1216 def GetPosition(self, size = True): |
1217 parent_pos = self.ParentBlock.GetPosition() |
1217 parent_pos = self.ParentBlock.GetPosition() |
1218 # If the position of the end of the connector is asked |
1218 # If the position of the end of the connector is asked |
1219 if size: |
1219 if size: |
1221 y = parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE |
1221 y = parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE |
1222 else: |
1222 else: |
1223 x = parent_pos[0] + self.Pos.x |
1223 x = parent_pos[0] + self.Pos.x |
1224 y = parent_pos[1] + self.Pos.y |
1224 y = parent_pos[1] + self.Pos.y |
1225 return wx.Point(x, y) |
1225 return wx.Point(x, y) |
1226 |
1226 |
1227 # Change the connector relative position |
1227 # Change the connector relative position |
1228 def SetPosition(self, pos): |
1228 def SetPosition(self, pos): |
1229 self.Pos = pos |
1229 self.Pos = pos |
1230 |
1230 |
1231 # Returns the connector direction |
1231 # Returns the connector direction |
1232 def GetDirection(self): |
1232 def GetDirection(self): |
1233 return self.Direction |
1233 return self.Direction |
1234 |
1234 |
1235 # Change the connector direction |
1235 # Change the connector direction |
1236 def SetDirection(self, direction): |
1236 def SetDirection(self, direction): |
1237 self.Direction = direction |
1237 self.Direction = direction |
1238 |
1238 |
1239 # Connect a wire to this connector at the last place |
1239 # Connect a wire to this connector at the last place |
1240 def Connect(self, wire, refresh = True): |
1240 def Connect(self, wire, refresh = True): |
1241 self.InsertConnect(len(self.Wires), wire, refresh) |
1241 self.InsertConnect(len(self.Wires), wire, refresh) |
1242 |
1242 |
1243 # Connect a wire to this connector at the place given |
1243 # Connect a wire to this connector at the place given |
1244 def InsertConnect(self, idx, wire, refresh = True): |
1244 def InsertConnect(self, idx, wire, refresh = True): |
1245 if wire not in self.Wires: |
1245 if wire not in self.Wires: |
1246 self.Wires.insert(idx, wire) |
1246 self.Wires.insert(idx, wire) |
1247 if wire[1] == 0: |
1247 if wire[1] == 0: |
1248 wire[0].ConnectStartPoint(None, self) |
1248 wire[0].ConnectStartPoint(None, self) |
1249 else: |
1249 else: |
1250 wire[0].ConnectEndPoint(None, self) |
1250 wire[0].ConnectEndPoint(None, self) |
1251 if refresh: |
1251 if refresh: |
1252 self.ParentBlock.RefreshModel(False) |
1252 self.ParentBlock.RefreshModel(False) |
1253 |
1253 |
1254 # Returns the index of the wire given in the list of connected |
1254 # Returns the index of the wire given in the list of connected |
1255 def GetWireIndex(self, wire): |
1255 def GetWireIndex(self, wire): |
1256 for i, (tmp_wire, handle) in enumerate(self.Wires): |
1256 for i, (tmp_wire, handle) in enumerate(self.Wires): |
1257 if tmp_wire == wire: |
1257 if tmp_wire == wire: |
1258 return i |
1258 return i |
1259 return None |
1259 return None |
1260 |
1260 |
1261 # Unconnect a wire or all wires connected to the connector |
1261 # Unconnect a wire or all wires connected to the connector |
1262 def UnConnect(self, wire = None, unconnect = True, delete = False): |
1262 def UnConnect(self, wire = None, unconnect = True, delete = False): |
1263 i = 0 |
1263 i = 0 |
1264 found = False |
1264 found = False |
1265 while i < len(self.Wires) and not found: |
1265 while i < len(self.Wires) and not found: |
1298 if wire not in exclude: |
1298 if wire not in exclude: |
1299 if index == 0: |
1299 if index == 0: |
1300 wire.MoveStartPoint(wx.Point(x, y)) |
1300 wire.MoveStartPoint(wx.Point(x, y)) |
1301 else: |
1301 else: |
1302 wire.MoveEndPoint(wx.Point(x, y)) |
1302 wire.MoveEndPoint(wx.Point(x, y)) |
1303 |
1303 |
1304 # Refreshes the model of all the wires connected |
1304 # Refreshes the model of all the wires connected |
1305 def RefreshWires(self): |
1305 def RefreshWires(self): |
1306 for wire in self.Wires: |
1306 for wire in self.Wires: |
1307 wire[0].RefreshModel() |
1307 wire[0].RefreshModel() |
1308 |
1308 |
1309 # Refreshes the parent block model |
1309 # Refreshes the parent block model |
1310 def RefreshParentBlock(self): |
1310 def RefreshParentBlock(self): |
1311 self.ParentBlock.RefreshModel(False) |
1311 self.ParentBlock.RefreshModel(False) |
1312 |
1312 |
1313 # Highlight the parent block |
1313 # Highlight the parent block |
1314 def HighlightParentBlock(self, highlight): |
1314 def HighlightParentBlock(self, highlight): |
1315 self.ParentBlock.SetHighlighted(highlight) |
1315 self.ParentBlock.SetHighlighted(highlight) |
1316 self.ParentBlock.Refresh() |
1316 self.ParentBlock.Refresh() |
1317 |
1317 |
1318 # Returns all the blocks connected to this connector |
1318 # Returns all the blocks connected to this connector |
1319 def GetConnectedBlocks(self): |
1319 def GetConnectedBlocks(self): |
1320 blocks = [] |
1320 blocks = [] |
1321 for wire, handle in self.Wires: |
1321 for wire, handle in self.Wires: |
1322 # Get other connector connected to each wire |
1322 # Get other connector connected to each wire |
1328 if connector: |
1328 if connector: |
1329 block = connector.GetParentBlock() |
1329 block = connector.GetParentBlock() |
1330 if block not in blocks: |
1330 if block not in blocks: |
1331 blocks.append(block) |
1331 blocks.append(block) |
1332 return blocks |
1332 return blocks |
1333 |
1333 |
1334 # Returns the connector negated property |
1334 # Returns the connector negated property |
1335 def IsNegated(self): |
1335 def IsNegated(self): |
1336 return self.Negated |
1336 return self.Negated |
1337 |
1337 |
1338 # Changes the connector negated property |
1338 # Changes the connector negated property |
1339 def SetNegated(self, negated): |
1339 def SetNegated(self, negated): |
1340 if self.ParentBlock.IsOfType("BOOL", self.Type): |
1340 if self.ParentBlock.IsOfType("BOOL", self.Type): |
1341 self.Negated = negated |
1341 self.Negated = negated |
1342 self.Edge = "none" |
1342 self.Edge = "none" |
1343 |
1343 |
1344 # Returns the connector edge property |
1344 # Returns the connector edge property |
1345 def GetEdge(self): |
1345 def GetEdge(self): |
1346 return self.Edge |
1346 return self.Edge |
1347 |
1347 |
1348 # Changes the connector edge property |
1348 # Changes the connector edge property |
1349 def SetEdge(self, edge): |
1349 def SetEdge(self, edge): |
1350 if self.ParentBlock.IsOfType("BOOL", self.Type): |
1350 if self.ParentBlock.IsOfType("BOOL", self.Type): |
1351 self.Edge = edge |
1351 self.Edge = edge |
1352 self.Negated = False |
1352 self.Negated = False |
1353 |
1353 |
1354 # assume that pointer is already inside of this connector |
1354 # assume that pointer is already inside of this connector |
1355 def ConnectionAvailable(self, direction=None, exclude=True): |
1355 def ConnectionAvailable(self, direction=None, exclude=True): |
1356 wire_nums = len(self.Wires) |
1356 wire_nums = len(self.Wires) |
1357 |
1357 |
1358 connector_free = (wire_nums<= 0) |
1358 connector_free = (wire_nums<= 0) |
1359 connector_max_used = ((wire_nums > 0) and self.OneConnected) |
1359 connector_max_used = ((wire_nums > 0) and self.OneConnected) |
1360 if (self.Parent.CurrentLanguage in ["SFC", "LD"]) and (self.Type == "BOOL"): |
1360 if (self.Parent.CurrentLanguage in ["SFC", "LD"]) and (self.Type == "BOOL"): |
1361 connector_max_used = False; |
1361 connector_max_used = False; |
1362 |
1362 |
1363 # connector is available for new connection |
1363 # connector is available for new connection |
1364 connect = connector_free or not connector_max_used |
1364 connect = connector_free or not connector_max_used |
1365 return connect, connector_max_used |
1365 return connect, connector_max_used |
1366 |
1366 |
1367 # Tests if the point given is near from the end point of this connector |
1367 # Tests if the point given is near from the end point of this connector |
1368 def TestPoint(self, pt, direction=None, exclude=True): |
1368 def TestPoint(self, pt, direction=None, exclude=True): |
1369 inside = False; |
1369 inside = False; |
1370 check_point = (not exclude) and (direction is None or self.Direction == direction); |
1370 check_point = (not exclude) and (direction is None or self.Direction == direction); |
1371 |
1371 |
1391 dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR)) |
1391 dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR)) |
1392 dc.SetLogicalFunction(wx.AND) |
1392 dc.SetLogicalFunction(wx.AND) |
1393 parent_pos = self.ParentBlock.GetPosition() |
1393 parent_pos = self.ParentBlock.GetPosition() |
1394 posx = parent_pos[0] + self.Pos.x |
1394 posx = parent_pos[0] + self.Pos.x |
1395 posy = parent_pos[1] + self.Pos.y |
1395 posy = parent_pos[1] + self.Pos.y |
1396 xstart = parent_pos[0] + self.Pos.x |
1396 xstart = parent_pos[0] + self.Pos.x |
1397 ystart = parent_pos[1] + self.Pos.y |
1397 ystart = parent_pos[1] + self.Pos.y |
1398 if self.Direction[0] < 0: |
1398 if self.Direction[0] < 0: |
1399 xstart += 1 |
1399 xstart += 1 |
1400 if self.Direction[1] < 0: |
1400 if self.Direction[1] < 0: |
1401 ystart += 1 |
1401 ystart += 1 |
1402 xend = xstart + CONNECTOR_SIZE * self.Direction[0] |
1402 xend = xstart + CONNECTOR_SIZE * self.Direction[0] |
1403 yend = ystart + CONNECTOR_SIZE * self.Direction[1] |
1403 yend = ystart + CONNECTOR_SIZE * self.Direction[1] |
1404 dc.DrawLine(round((xstart + self.Direction[0]) * scalex), round((ystart + self.Direction[1]) * scaley), |
1404 dc.DrawLine(round((xstart + self.Direction[0]) * scalex), round((ystart + self.Direction[1]) * scaley), |
1405 round(xend * scalex), round(yend * scaley)) |
1405 round(xend * scalex), round(yend * scaley)) |
1406 dc.SetLogicalFunction(wx.COPY) |
1406 dc.SetLogicalFunction(wx.COPY) |
1407 dc.SetUserScale(scalex, scaley) |
1407 dc.SetUserScale(scalex, scaley) |
1408 |
1408 |
1409 # Adds an highlight to the connector |
1409 # Adds an highlight to the connector |
1410 def AddHighlight(self, infos, start, end, highlight_type): |
1410 def AddHighlight(self, infos, start, end, highlight_type): |
1411 if highlight_type == ERROR_HIGHLIGHT: |
1411 if highlight_type == ERROR_HIGHLIGHT: |
1412 for wire, handle in self.Wires: |
1412 for wire, handle in self.Wires: |
1413 wire.SetValid(False) |
1413 wire.SetValid(False) |
1414 AddHighlight(self.Highlights, (start, end, highlight_type)) |
1414 AddHighlight(self.Highlights, (start, end, highlight_type)) |
1415 |
1415 |
1416 # Removes an highlight from the connector |
1416 # Removes an highlight from the connector |
1417 def RemoveHighlight(self, infos, start, end, highlight_type): |
1417 def RemoveHighlight(self, infos, start, end, highlight_type): |
1418 error = False |
1418 error = False |
1419 highlights = [] |
1419 highlights = [] |
1420 for highlight in self.Highlights: |
1420 for highlight in self.Highlights: |
1464 dc.SetPen(MiterPen(wx.BLUE)) |
1464 dc.SetPen(MiterPen(wx.BLUE)) |
1465 else: |
1465 else: |
1466 dc.SetPen(MiterPen(wx.BLACK)) |
1466 dc.SetPen(MiterPen(wx.BLACK)) |
1467 dc.SetBrush(wx.WHITE_BRUSH) |
1467 dc.SetBrush(wx.WHITE_BRUSH) |
1468 parent_pos = self.ParentBlock.GetPosition() |
1468 parent_pos = self.ParentBlock.GetPosition() |
1469 |
1469 |
1470 if getattr(dc, "printing", False): |
1470 if getattr(dc, "printing", False): |
1471 name_size = dc.GetTextExtent(self.Name) |
1471 name_size = dc.GetTextExtent(self.Name) |
1472 else: |
1472 else: |
1473 name_size = self.NameSize |
1473 name_size = self.NameSize |
1474 |
1474 |
1475 if self.Negated: |
1475 if self.Negated: |
1476 # If connector is negated, draw a circle |
1476 # If connector is negated, draw a circle |
1477 xcenter = parent_pos[0] + self.Pos.x + (CONNECTOR_SIZE * self.Direction[0]) / 2 |
1477 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 |
1478 ycenter = parent_pos[1] + self.Pos.y + (CONNECTOR_SIZE * self.Direction[1]) / 2 |
1479 dc.DrawCircle(xcenter, ycenter, CONNECTOR_SIZE / 2) |
1479 dc.DrawCircle(xcenter, ycenter, CONNECTOR_SIZE / 2) |
1480 else: |
1480 else: |
1481 xstart = parent_pos[0] + self.Pos.x |
1481 xstart = parent_pos[0] + self.Pos.x |
1482 ystart = parent_pos[1] + self.Pos.y |
1482 ystart = parent_pos[1] + self.Pos.y |
1483 if self.Edge == "rising": |
1483 if self.Edge == "rising": |
1484 # If connector has a rising edge, draw a right arrow |
1484 # If connector has a rising edge, draw a right arrow |
1485 dc.DrawLine(xstart, ystart, xstart - 4, ystart - 4) |
1485 dc.DrawLine(xstart, ystart, xstart - 4, ystart - 4) |
1486 dc.DrawLine(xstart, ystart, xstart - 4, ystart + 4) |
1486 dc.DrawLine(xstart, ystart, xstart - 4, ystart + 4) |
1566 self.OverStart = False |
1566 self.OverStart = False |
1567 self.OverEnd = False |
1567 self.OverEnd = False |
1568 self.ComputingType = False |
1568 self.ComputingType = False |
1569 self.Font = parent.GetMiniFont() |
1569 self.Font = parent.GetMiniFont() |
1570 self.ErrHighlight = False |
1570 self.ErrHighlight = False |
1571 |
1571 |
1572 def GetDefinition(self): |
1572 def GetDefinition(self): |
1573 if self.StartConnected is not None and self.EndConnected is not None: |
1573 if self.StartConnected is not None and self.EndConnected is not None: |
1574 startblock = self.StartConnected.GetParentBlock() |
1574 startblock = self.StartConnected.GetParentBlock() |
1575 endblock = self.EndConnected.GetParentBlock() |
1575 endblock = self.EndConnected.GetParentBlock() |
1576 return [], [(startblock.GetId(), endblock.GetId())] |
1576 return [], [(startblock.GetId(), endblock.GetId())] |
1577 return [], [] |
1577 return [], [] |
1578 |
1578 |
1579 def Flush(self): |
1579 def Flush(self): |
1580 self.StartConnected = None |
1580 self.StartConnected = None |
1581 self.EndConnected = None |
1581 self.EndConnected = None |
1582 |
1582 |
1583 # Returns the RedrawRect |
1583 # Returns the RedrawRect |
1584 def GetRedrawRect(self, movex = 0, movey = 0): |
1584 def GetRedrawRect(self, movex = 0, movey = 0): |
1585 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
1585 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
1586 if self.StartConnected: |
1586 if self.StartConnected: |
1587 rect = rect.Union(self.StartConnected.GetRedrawRect(movex, movey)) |
1587 rect = rect.Union(self.StartConnected.GetRedrawRect(movex, movey)) |
1662 movey_max = max(movey_max, movey) |
1662 movey_max = max(movey_max, movey) |
1663 point.x += movex |
1663 point.x += movex |
1664 point.y += movey |
1664 point.y += movey |
1665 return movex_max, movey_max |
1665 return movex_max, movey_max |
1666 return 0, 0 |
1666 return 0, 0 |
1667 |
1667 |
1668 # Returns connector to which start point is connected |
1668 # Returns connector to which start point is connected |
1669 def GetStartConnected(self): |
1669 def GetStartConnected(self): |
1670 return self.StartConnected |
1670 return self.StartConnected |
1671 |
1671 |
1672 # Returns connector to which start point is connected |
1672 # Returns connector to which start point is connected |
1673 def GetStartConnectedType(self): |
1673 def GetStartConnectedType(self): |
1674 if self.StartConnected and not self.ComputingType: |
1674 if self.StartConnected and not self.ComputingType: |
1675 self.ComputingType = True |
1675 self.ComputingType = True |
1676 computed_type = self.StartConnected.GetType() |
1676 computed_type = self.StartConnected.GetType() |
1677 self.ComputingType = False |
1677 self.ComputingType = False |
1678 return computed_type |
1678 return computed_type |
1679 return None |
1679 return None |
1680 |
1680 |
1681 # Returns connector to which end point is connected |
1681 # Returns connector to which end point is connected |
1682 def GetEndConnected(self): |
1682 def GetEndConnected(self): |
1683 return self.EndConnected |
1683 return self.EndConnected |
1684 |
1684 |
1685 # Returns connector to which end point is connected |
1685 # Returns connector to which end point is connected |
1686 def GetEndConnectedType(self): |
1686 def GetEndConnectedType(self): |
1687 if self.EndConnected and not self.ComputingType: |
1687 if self.EndConnected and not self.ComputingType: |
1688 self.ComputingType = True |
1688 self.ComputingType = True |
1689 computed_type = self.EndConnected.GetType() |
1689 computed_type = self.EndConnected.GetType() |
1690 self.ComputingType = False |
1690 self.ComputingType = False |
1691 return computed_type |
1691 return computed_type |
1692 return None |
1692 return None |
1693 |
1693 |
1694 def GetConnectionDirection(self): |
1694 def GetConnectionDirection(self): |
1695 if self.StartConnected is None and self.EndConnected is None: |
1695 if self.StartConnected is None and self.EndConnected is None: |
1696 return None |
1696 return None |
1697 elif self.StartConnected is not None and self.EndConnected is None: |
1697 elif self.StartConnected is not None and self.EndConnected is None: |
1698 return (-self.StartPoint[1][0], -self.StartPoint[1][1]) |
1698 return (-self.StartPoint[1][0], -self.StartPoint[1][1]) |
1705 if handle == 0: |
1705 if handle == 0: |
1706 return self.EndPoint |
1706 return self.EndPoint |
1707 else: |
1707 else: |
1708 return (-self.StartPoint[1][0], -self.StartPoint[1][1]) |
1708 return (-self.StartPoint[1][0], -self.StartPoint[1][1]) |
1709 return None |
1709 return None |
1710 |
1710 |
1711 def GetOtherConnected(self, connector): |
1711 def GetOtherConnected(self, connector): |
1712 if self.StartConnected == connector: |
1712 if self.StartConnected == connector: |
1713 return self.EndConnected |
1713 return self.EndConnected |
1714 else: |
1714 else: |
1715 return self.StartConnected |
1715 return self.StartConnected |
1716 |
1716 |
1717 def GetOtherConnectedType(self, handle): |
1717 def GetOtherConnectedType(self, handle): |
1718 if handle == 0: |
1718 if handle == 0: |
1719 return self.GetEndConnectedType() |
1719 return self.GetEndConnectedType() |
1720 else: |
1720 else: |
1721 return self.GetStartConnectedType() |
1721 return self.GetStartConnectedType() |
1722 |
1722 |
1723 def IsConnectedCompatible(self): |
1723 def IsConnectedCompatible(self): |
1724 if self.StartConnected: |
1724 if self.StartConnected: |
1725 return self.StartConnected.IsCompatible(self.GetEndConnectedType()) |
1725 return self.StartConnected.IsCompatible(self.GetEndConnectedType()) |
1726 elif self.EndConnected: |
1726 elif self.EndConnected: |
1727 return True |
1727 return True |
1728 return False |
1728 return False |
1729 |
1729 |
1730 def SetForced(self, forced): |
1730 def SetForced(self, forced): |
1731 if self.Forced != forced: |
1731 if self.Forced != forced: |
1732 self.Forced = forced |
1732 self.Forced = forced |
1733 if self.StartConnected: |
1733 if self.StartConnected: |
1734 self.StartConnected.RefreshForced() |
1734 self.StartConnected.RefreshForced() |
1812 self.StartConnected.SetSelected(False) |
1812 self.StartConnected.SetSelected(False) |
1813 if self.EndConnected: |
1813 if self.EndConnected: |
1814 self.EndConnected.SetSelected(True) |
1814 self.EndConnected.SetSelected(True) |
1815 self.SelectedSegment = segment |
1815 self.SelectedSegment = segment |
1816 self.Refresh() |
1816 self.Refresh() |
1817 |
1817 |
1818 def SetValid(self, valid): |
1818 def SetValid(self, valid): |
1819 self.Valid = valid |
1819 self.Valid = valid |
1820 if self.StartConnected: |
1820 if self.StartConnected: |
1821 self.StartConnected.RefreshValid() |
1821 self.StartConnected.RefreshValid() |
1822 if self.EndConnected: |
1822 if self.EndConnected: |
1823 self.EndConnected.RefreshValid() |
1823 self.EndConnected.RefreshValid() |
1824 |
1824 |
1825 def GetValid(self): |
1825 def GetValid(self): |
1826 return self.Valid |
1826 return self.Valid |
1827 |
1827 |
1828 # Reinitialize the wire points |
1828 # Reinitialize the wire points |
1829 def ResetPoints(self): |
1829 def ResetPoints(self): |
1830 if self.StartPoint and self.EndPoint: |
1830 if self.StartPoint and self.EndPoint: |
1831 self.Points = [self.StartPoint[0], self.EndPoint[0]] |
1831 self.Points = [self.StartPoint[0], self.EndPoint[0]] |
1832 self.Segments = [self.StartPoint[1]] |
1832 self.Segments = [self.StartPoint[1]] |
1833 else: |
1833 else: |
1834 self.Points = [] |
1834 self.Points = [] |
1835 self.Segments = [] |
1835 self.Segments = [] |
1836 |
1836 |
1837 # Refresh the wire bounding box |
1837 # Refresh the wire bounding box |
1838 def RefreshBoundingBox(self): |
1838 def RefreshBoundingBox(self): |
1839 if len(self.Points) > 0: |
1839 if len(self.Points) > 0: |
1840 # If startpoint or endpoint is connected, save the point radius |
1840 # If startpoint or endpoint is connected, save the point radius |
1841 start_radius = end_radius = 0 |
1841 start_radius = end_radius = 0 |
1860 miny, minbbxy = min(miny, self.Points[-1].y), min(minbbxy, self.Points[-1].y - end_radius) |
1860 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) |
1861 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 |
1862 self.Pos.x, self.Pos.y = minx, miny |
1863 self.Size = wx.Size(maxx - minx, maxy - miny) |
1863 self.Size = wx.Size(maxx - minx, maxy - miny) |
1864 self.BoundingBox = wx.Rect(minbbxx, minbbxy, maxbbxx - minbbxx + 1, maxbbxy - minbbxy + 1) |
1864 self.BoundingBox = wx.Rect(minbbxx, minbbxy, maxbbxx - minbbxx + 1, maxbbxy - minbbxy + 1) |
1865 |
1865 |
1866 # Refresh the realpoints that permits to keep the proportionality in wire during resizing |
1866 # Refresh the realpoints that permits to keep the proportionality in wire during resizing |
1867 def RefreshRealPoints(self): |
1867 def RefreshRealPoints(self): |
1868 if len(self.Points) > 0: |
1868 if len(self.Points) > 0: |
1869 self.RealPoints = [] |
1869 self.RealPoints = [] |
1870 # Calculate float relative position of each point with the minimum point |
1870 # Calculate float relative position of each point with the minimum point |
1871 for point in self.Points: |
1871 for point in self.Points: |
1872 self.RealPoints.append([float(point.x - self.Pos.x), float(point.y - self.Pos.y)]) |
1872 self.RealPoints.append([float(point.x - self.Pos.x), float(point.y - self.Pos.y)]) |
1873 |
1873 |
1874 # Returns the wire minimum size |
1874 # Returns the wire minimum size |
1875 def GetMinSize(self): |
1875 def GetMinSize(self): |
1876 width = 1 |
1876 width = 1 |
1877 height = 1 |
1877 height = 1 |
1878 dir_product = product(self.StartPoint[1], self.EndPoint[1]) |
1878 dir_product = product(self.StartPoint[1], self.EndPoint[1]) |
1879 # The directions are opposed |
1879 # The directions are opposed |
1891 # The directions are perpendiculars |
1891 # The directions are perpendiculars |
1892 else: |
1892 else: |
1893 width = MIN_SEGMENT_SIZE |
1893 width = MIN_SEGMENT_SIZE |
1894 height = MIN_SEGMENT_SIZE |
1894 height = MIN_SEGMENT_SIZE |
1895 return width + 1, height + 1 |
1895 return width + 1, height + 1 |
1896 |
1896 |
1897 # Returns if the point given is on one of the wire segments |
1897 # Returns if the point given is on one of the wire segments |
1898 def HitTest(self, pt, connectors=True): |
1898 def HitTest(self, pt, connectors=True): |
1899 test = False |
1899 test = False |
1900 for i in xrange(len(self.Points) - 1): |
1900 for i in xrange(len(self.Points) - 1): |
1901 rect = wx.Rect(0, 0, 0, 0) |
1901 rect = wx.Rect(0, 0, 0, 0) |
1902 if i == 0 and self.StartConnected is not None: |
1902 if i == 0 and self.StartConnected is not None: |
1903 x1 = self.Points[i].x - self.Segments[0][0] * CONNECTOR_SIZE |
1903 x1 = self.Points[i].x - self.Segments[0][0] * CONNECTOR_SIZE |
1904 y1 = self.Points[i].y - self.Segments[0][1] * CONNECTOR_SIZE |
1904 y1 = self.Points[i].y - self.Segments[0][1] * CONNECTOR_SIZE |
1905 else: |
1905 else: |
1906 x1, y1 = self.Points[i].x, self.Points[i].y |
1906 x1, y1 = self.Points[i].x, self.Points[i].y |
1907 if i == len(self.Points) - 2 and self.EndConnected is not None: |
1907 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 |
1908 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 |
1909 y2 = self.Points[i + 1].y + self.Segments[-1][1] * CONNECTOR_SIZE |
1910 else: |
1910 else: |
1911 x2, y2 = self.Points[i + 1].x, self.Points[i + 1].y |
1911 x2, y2 = self.Points[i + 1].x, self.Points[i + 1].y |
1912 # Calculate a rectangle around the segment |
1912 # Calculate a rectangle around the segment |
1913 rect = wx.Rect(min(x1, x2) - ANCHOR_DISTANCE, min(y1, y2) - ANCHOR_DISTANCE, |
1913 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) |
1914 abs(x1 - x2) + 2 * ANCHOR_DISTANCE, abs(y1 - y2) + 2 * ANCHOR_DISTANCE) |
1915 test |= rect.InsideXY(pt.x, pt.y) |
1915 test |= rect.InsideXY(pt.x, pt.y) |
1916 return test |
1916 return test |
1917 |
1917 |
1918 # Returns the wire start or end point if the point given is on one of them |
1918 # Returns the wire start or end point if the point given is on one of them |
1919 def TestPoint(self, pt): |
1919 def TestPoint(self, pt): |
1920 # Test the wire start point |
1920 # Test the wire start point |
1921 rect = wx.Rect(self.Points[0].x - ANCHOR_DISTANCE, self.Points[0].y - ANCHOR_DISTANCE, |
1921 rect = wx.Rect(self.Points[0].x - ANCHOR_DISTANCE, self.Points[0].y - ANCHOR_DISTANCE, |
1922 2 * ANCHOR_DISTANCE, 2 * ANCHOR_DISTANCE) |
1922 2 * ANCHOR_DISTANCE, 2 * ANCHOR_DISTANCE) |
1923 if rect.InsideXY(pt.x, pt.y): |
1923 if rect.InsideXY(pt.x, pt.y): |
1941 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, |
1942 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) |
1943 if rect.InsideXY(pt.x, pt.y): |
1943 if rect.InsideXY(pt.x, pt.y): |
1944 return i, self.Segments[i] |
1944 return i, self.Segments[i] |
1945 return None |
1945 return None |
1946 |
1946 |
1947 # Define the wire points |
1947 # Define the wire points |
1948 def SetPoints(self, points, verify=True): |
1948 def SetPoints(self, points, verify=True): |
1949 if len(points) > 1: |
1949 if len(points) > 1: |
1950 self.Points = [wx.Point(x, y) for x, y in points] |
1950 self.Points = [wx.Point(x, y) for x, y in points] |
1951 # Calculate the start and end directions |
1951 # Calculate the start and end directions |
1952 self.StartPoint = [None, vector(self.Points[0], self.Points[1])] |
1952 self.StartPoint = [None, vector(self.Points[0], self.Points[1])] |
1953 self.EndPoint = [None, vector(self.Points[-1], self.Points[-2])] |
1953 self.EndPoint = [None, vector(self.Points[-1], self.Points[-2])] |
1954 # Calculate the start and end points |
1954 # Calculate the start and end points |
1955 self.StartPoint[0] = wx.Point(self.Points[0].x + CONNECTOR_SIZE * self.StartPoint[1][0], |
1955 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]) |
1956 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], |
1957 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]) |
1958 self.Points[-1].y + CONNECTOR_SIZE * self.EndPoint[1][1]) |
1959 self.Points[0] = self.StartPoint[0] |
1959 self.Points[0] = self.StartPoint[0] |
1960 self.Points[-1] = self.EndPoint[0] |
1960 self.Points[-1] = self.EndPoint[0] |
1961 # Calculate the segments directions |
1961 # Calculate the segments directions |
1962 self.Segments = [] |
1962 self.Segments = [] |
1977 self.Points.insert(i + 1, wx.Point(self.Points[i + 1].x, self.Points[i + 1].y)) |
1977 self.Points.insert(i + 1, wx.Point(self.Points[i + 1].x, self.Points[i + 1].y)) |
1978 self.Segments.append(segment) |
1978 self.Segments.append(segment) |
1979 i += 1 |
1979 i += 1 |
1980 self.RefreshBoundingBox() |
1980 self.RefreshBoundingBox() |
1981 self.RefreshRealPoints() |
1981 self.RefreshRealPoints() |
1982 |
1982 |
1983 # Returns the position of the point indicated |
1983 # Returns the position of the point indicated |
1984 def GetPoint(self, index): |
1984 def GetPoint(self, index): |
1985 if index < len(self.Points): |
1985 if index < len(self.Points): |
1986 return self.Points[index].x, self.Points[index].y |
1986 return self.Points[index].x, self.Points[index].y |
1987 return None |
1987 return None |
1988 |
1988 |
1989 # Returns a list of the position of all wire points |
1989 # Returns a list of the position of all wire points |
1990 def GetPoints(self, invert = False): |
1990 def GetPoints(self, invert = False): |
1991 points = self.VerifyPoints() |
1991 points = self.VerifyPoints() |
1992 points[0] = wx.Point(points[0].x - CONNECTOR_SIZE * self.StartPoint[1][0], |
1992 points[0] = wx.Point(points[0].x - CONNECTOR_SIZE * self.StartPoint[1][0], |
1993 points[0].y - CONNECTOR_SIZE * self.StartPoint[1][1]) |
1993 points[0].y - CONNECTOR_SIZE * self.StartPoint[1][1]) |
1994 points[-1] = wx.Point(points[-1].x - CONNECTOR_SIZE * self.EndPoint[1][0], |
1994 points[-1] = wx.Point(points[-1].x - CONNECTOR_SIZE * self.EndPoint[1][0], |
1995 points[-1].y - CONNECTOR_SIZE * self.EndPoint[1][1]) |
1995 points[-1].y - CONNECTOR_SIZE * self.EndPoint[1][1]) |
1996 # An inversion of the list is asked |
1996 # An inversion of the list is asked |
1997 if invert: |
1997 if invert: |
1998 points.reverse() |
1998 points.reverse() |
1999 return points |
1999 return points |
2000 |
2000 |
2001 # Returns the position of the two selected segment points |
2001 # Returns the position of the two selected segment points |
2002 def GetSelectedSegmentPoints(self): |
2002 def GetSelectedSegmentPoints(self): |
2003 if self.SelectedSegment != None and len(self.Points) > 1: |
2003 if self.SelectedSegment != None and len(self.Points) > 1: |
2004 return self.Points[self.SelectedSegment:self.SelectedSegment + 2] |
2004 return self.Points[self.SelectedSegment:self.SelectedSegment + 2] |
2005 return [] |
2005 return [] |
2006 |
2006 |
2007 # Returns if the selected segment is the first and/or the last of the wire |
2007 # Returns if the selected segment is the first and/or the last of the wire |
2008 def GetSelectedSegmentConnections(self): |
2008 def GetSelectedSegmentConnections(self): |
2009 if self.SelectedSegment != None and len(self.Points) > 1: |
2009 if self.SelectedSegment != None and len(self.Points) > 1: |
2010 return self.SelectedSegment == 0, self.SelectedSegment == len(self.Segments) - 1 |
2010 return self.SelectedSegment == 0, self.SelectedSegment == len(self.Segments) - 1 |
2011 return (True, True) |
2011 return (True, True) |
2012 |
2012 |
2013 # Returns the connectors on which the wire is connected |
2013 # Returns the connectors on which the wire is connected |
2014 def GetConnected(self): |
2014 def GetConnected(self): |
2015 connected = [] |
2015 connected = [] |
2016 if self.StartConnected and self.StartPoint[1] == WEST: |
2016 if self.StartConnected and self.StartPoint[1] == WEST: |
2017 connected.append(self.StartConnected) |
2017 connected.append(self.StartConnected) |
2018 if self.EndConnected and self.EndPoint[1] == WEST: |
2018 if self.EndConnected and self.EndPoint[1] == WEST: |
2019 connected.append(self.EndConnected) |
2019 connected.append(self.EndConnected) |
2020 return connected |
2020 return connected |
2021 |
2021 |
2022 # Returns the id of the block connected to the first or the last wire point |
2022 # Returns the id of the block connected to the first or the last wire point |
2023 def GetConnectedInfos(self, index): |
2023 def GetConnectedInfos(self, index): |
2024 if index == 0 and self.StartConnected: |
2024 if index == 0 and self.StartConnected: |
2025 return self.StartConnected.GetBlockId(), self.StartConnected.GetName() |
2025 return self.StartConnected.GetBlockId(), self.StartConnected.GetName() |
2026 elif index == -1 and self.EndConnected: |
2026 elif index == -1 and self.EndConnected: |
2027 return self.EndConnected.GetBlockId(), self.EndConnected.GetName() |
2027 return self.EndConnected.GetBlockId(), self.EndConnected.GetName() |
2028 return None |
2028 return None |
2029 |
2029 |
2030 # Update the wire points position by keeping at most possible the current positions |
2030 # Update the wire points position by keeping at most possible the current positions |
2031 def GeneratePoints(self, realpoints = True): |
2031 def GeneratePoints(self, realpoints = True): |
2032 i = 0 |
2032 i = 0 |
2033 # Calculate the start enad end points with the minimum segment size in the right direction |
2033 # 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, |
2034 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) |
2035 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, |
2036 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) |
2037 self.StartPoint[0].y + self.StartPoint[1][1] * MIN_SEGMENT_SIZE) |
2038 # Evaluate the point till it's the last |
2038 # Evaluate the point till it's the last |
2039 while i < len(self.Points) - 1: |
2039 while i < len(self.Points) - 1: |
2040 # The next point is the last |
2040 # The next point is the last |
2041 if i + 1 == len(self.Points) - 1: |
2041 if i + 1 == len(self.Points) - 1: |
2044 # The current point is the first |
2044 # The current point is the first |
2045 if i == 0: |
2045 if i == 0: |
2046 # If the end point is not in the start direction, a point is added |
2046 # 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]: |
2047 if v_end != self.Segments[0] or v_end == self.EndPoint[1]: |
2048 self.Points.insert(1, wx.Point(start.x, start.y)) |
2048 self.Points.insert(1, wx.Point(start.x, start.y)) |
2049 self.Segments.insert(1, DirectionChoice((self.Segments[0][1], |
2049 self.Segments.insert(1, DirectionChoice((self.Segments[0][1], |
2050 self.Segments[0][0]), v_end, self.EndPoint[1])) |
2050 self.Segments[0][0]), v_end, self.EndPoint[1])) |
2051 # The current point is the second |
2051 # The current point is the second |
2052 elif i == 1: |
2052 elif i == 1: |
2053 # The previous direction and the target direction are mainly opposed, a point is added |
2053 # The previous direction and the target direction are mainly opposed, a point is added |
2054 if product(v_end, self.Segments[0]) < 0: |
2054 if product(v_end, self.Segments[0]) < 0: |
2055 self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y)) |
2055 self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y)) |
2056 self.Segments.insert(2, DirectionChoice((self.Segments[1][1], |
2056 self.Segments.insert(2, DirectionChoice((self.Segments[1][1], |
2057 self.Segments[1][0]), v_end, self.EndPoint[1])) |
2057 self.Segments[1][0]), v_end, self.EndPoint[1])) |
2058 # The previous direction and the end direction are the same or they are |
2058 # The previous direction and the end direction are the same or they are |
2059 # perpendiculars and the end direction points towards current segment |
2059 # 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: |
2060 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 |
2061 # Current point and end point are aligned |
2064 if self.Segments[0][1] != 0: |
2064 if self.Segments[0][1] != 0: |
2065 self.Points[1].y = end.y |
2065 self.Points[1].y = end.y |
2066 # If the previous direction and the end direction are the same, a point is added |
2066 # 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: |
2067 if product(self.Segments[0], self.EndPoint[1]) > 0: |
2068 self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y)) |
2068 self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y)) |
2069 self.Segments.insert(2, DirectionChoice((self.Segments[1][1], |
2069 self.Segments.insert(2, DirectionChoice((self.Segments[1][1], |
2070 self.Segments[1][0]), v_end, self.EndPoint[1])) |
2070 self.Segments[1][0]), v_end, self.EndPoint[1])) |
2071 else: |
2071 else: |
2072 # Current point is positioned in the middle of start point |
2072 # Current point is positioned in the middle of start point |
2073 # and end point on the current direction and a point is added |
2073 # and end point on the current direction and a point is added |
2074 if self.Segments[0][0] != 0: |
2074 if self.Segments[0][0] != 0: |
2075 self.Points[1].x = (end.x + start.x) / 2 |
2075 self.Points[1].x = (end.x + start.x) / 2 |
2076 if self.Segments[0][1] != 0: |
2076 if self.Segments[0][1] != 0: |
2077 self.Points[1].y = (end.y + start.y) / 2 |
2077 self.Points[1].y = (end.y + start.y) / 2 |
2078 self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y)) |
2078 self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y)) |
2079 self.Segments.insert(2, DirectionChoice((self.Segments[1][1], |
2079 self.Segments.insert(2, DirectionChoice((self.Segments[1][1], |
2080 self.Segments[1][0]), v_end, self.EndPoint[1])) |
2080 self.Segments[1][0]), v_end, self.EndPoint[1])) |
2081 else: |
2081 else: |
2082 # The previous direction and the end direction are perpendiculars |
2082 # The previous direction and the end direction are perpendiculars |
2083 if product(self.Segments[i - 1], self.EndPoint[1]) == 0: |
2083 if product(self.Segments[i - 1], self.EndPoint[1]) == 0: |
2084 # The target direction and the end direction aren't mainly the same |
2084 # The target direction and the end direction aren't mainly the same |
2138 self.Points[i].x = (end.x + self.Points[i - 1].x) / 2 |
2138 self.Points[i].x = (end.x + self.Points[i - 1].x) / 2 |
2139 if self.Segments[i - 1][1] != 0: |
2139 if self.Segments[i - 1][1] != 0: |
2140 self.Points[i].y = (end.y + self.Points[i - 1].y) / 2 |
2140 self.Points[i].y = (end.y + self.Points[i - 1].y) / 2 |
2141 # A point is added |
2141 # A point is added |
2142 self.Points.insert(i + 1, wx.Point(self.Points[i].x, self.Points[i].y)) |
2142 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], |
2143 self.Segments.insert(i + 1, DirectionChoice((self.Segments[i][1], |
2144 self.Segments[i][0]), v_end, self.EndPoint[1])) |
2144 self.Segments[i][0]), v_end, self.EndPoint[1])) |
2145 else: |
2145 else: |
2146 # Current point is the first, and second is not mainly in the first direction |
2146 # 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: |
2147 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 |
2148 # If first and second directions aren't perpendiculars, a point is added |
2149 if product(self.Segments[0], self.Segments[1]) != 0: |
2149 if product(self.Segments[0], self.Segments[1]) != 0: |
2150 self.Points.insert(1, wx.Point(start.x, start.y)) |
2150 self.Points.insert(1, wx.Point(start.x, start.y)) |
2151 self.Segments.insert(1, DirectionChoice((self.Segments[0][1], |
2151 self.Segments.insert(1, DirectionChoice((self.Segments[0][1], |
2152 self.Segments[0][0]), vector(start, self.Points[1]), self.Segments[1])) |
2152 self.Segments[0][0]), vector(start, self.Points[1]), self.Segments[1])) |
2153 else: |
2153 else: |
2154 self.Points[1].x, self.Points[1].y = start.x, start.y |
2154 self.Points[1].x, self.Points[1].y = start.x, start.y |
2155 else: |
2155 else: |
2156 # Next point is aligned with current point |
2156 # Next point is aligned with current point |
2183 self.Points = [point for point in points] |
2183 self.Points = [point for point in points] |
2184 self.Segments = [segment for segment in segments] |
2184 self.Segments = [segment for segment in segments] |
2185 self.RefreshBoundingBox() |
2185 self.RefreshBoundingBox() |
2186 self.RefreshRealPoints() |
2186 self.RefreshRealPoints() |
2187 return points |
2187 return points |
2188 |
2188 |
2189 # Moves all the wire points except the first and the last if they are connected |
2189 # Moves all the wire points except the first and the last if they are connected |
2190 def Move(self, dx, dy, endpoints = False): |
2190 def Move(self, dx, dy, endpoints = False): |
2191 for i, point in enumerate(self.Points): |
2191 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): |
2192 if endpoints or not (i == 0 and self.StartConnected) and not (i == len(self.Points) - 1 and self.EndConnected): |
2193 point.x += dx |
2193 point.x += dx |
2194 point.y += dy |
2194 point.y += dy |
2195 self.StartPoint[0] = self.Points[0] |
2195 self.StartPoint[0] = self.Points[0] |
2196 self.EndPoint[0] = self.Points[-1] |
2196 self.EndPoint[0] = self.Points[-1] |
2197 self.GeneratePoints() |
2197 self.GeneratePoints() |
2198 |
2198 |
2199 # Resize the wire from position and size given |
2199 # Resize the wire from position and size given |
2200 def Resize(self, x, y, width, height): |
2200 def Resize(self, x, y, width, height): |
2201 if len(self.Points) > 1: |
2201 if len(self.Points) > 1: |
2202 # Calculate the new position of each point for testing the new size |
2202 # Calculate the new position of each point for testing the new size |
2203 minx, miny = self.Pos.x, self.Pos.y |
2203 minx, miny = self.Pos.x, self.Pos.y |
2252 height - dir[1] * MIN_SEGMENT_SIZE)) |
2252 height - dir[1] * MIN_SEGMENT_SIZE)) |
2253 self.Points[i] = wx.Point(minx + x + realpointx, miny + y + realpointy) |
2253 self.Points[i] = wx.Point(minx + x + realpointx, miny + y + realpointy) |
2254 self.StartPoint[0] = self.Points[0] |
2254 self.StartPoint[0] = self.Points[0] |
2255 self.EndPoint[0] = self.Points[-1] |
2255 self.EndPoint[0] = self.Points[-1] |
2256 self.GeneratePoints(False) |
2256 self.GeneratePoints(False) |
2257 |
2257 |
2258 # Moves the wire start point and update the wire points |
2258 # Moves the wire start point and update the wire points |
2259 def MoveStartPoint(self, point): |
2259 def MoveStartPoint(self, point): |
2260 if len(self.Points) > 1: |
2260 if len(self.Points) > 1: |
2261 self.StartPoint[0] = point |
2261 self.StartPoint[0] = point |
2262 self.Points[0] = point |
2262 self.Points[0] = point |
2263 self.GeneratePoints() |
2263 self.GeneratePoints() |
2264 |
2264 |
2265 # Changes the wire start direction and update the wire points |
2265 # Changes the wire start direction and update the wire points |
2266 def SetStartPointDirection(self, dir): |
2266 def SetStartPointDirection(self, dir): |
2267 if len(self.Points) > 1: |
2267 if len(self.Points) > 1: |
2268 self.StartPoint[1] = dir |
2268 self.StartPoint[1] = dir |
2269 self.Segments[0] = dir |
2269 self.Segments[0] = dir |
2270 self.GeneratePoints() |
2270 self.GeneratePoints() |
2271 |
2271 |
2272 # Rotates the wire start direction by an angle of 90 degrees anticlockwise |
2272 # Rotates the wire start direction by an angle of 90 degrees anticlockwise |
2273 def RotateStartPoint(self): |
2273 def RotateStartPoint(self): |
2274 self.SetStartPointDirection((self.StartPoint[1][1], -self.StartPoint[1][0])) |
2274 self.SetStartPointDirection((self.StartPoint[1][1], -self.StartPoint[1][0])) |
2275 |
2275 |
2276 # Connects wire start point to the connector given and moves wire start point |
2276 # Connects wire start point to the connector given and moves wire start point |
2277 # to given point |
2277 # to given point |
2278 def ConnectStartPoint(self, point, connector): |
2278 def ConnectStartPoint(self, point, connector): |
2279 if point: |
2279 if point: |
2280 self.MoveStartPoint(point) |
2280 self.MoveStartPoint(point) |
2281 self.StartConnected = connector |
2281 self.StartConnected = connector |
2282 self.RefreshBoundingBox() |
2282 self.RefreshBoundingBox() |
2283 |
2283 |
2284 # Unconnects wire start point |
2284 # Unconnects wire start point |
2285 def UnConnectStartPoint(self, delete = False): |
2285 def UnConnectStartPoint(self, delete = False): |
2286 if delete: |
2286 if delete: |
2287 self.StartConnected = None |
2287 self.StartConnected = None |
2288 self.Delete() |
2288 self.Delete() |
2289 elif self.StartConnected: |
2289 elif self.StartConnected: |
2290 self.StartConnected.UnConnect(self, unconnect = False) |
2290 self.StartConnected.UnConnect(self, unconnect = False) |
2291 self.StartConnected = None |
2291 self.StartConnected = None |
2292 self.RefreshBoundingBox() |
2292 self.RefreshBoundingBox() |
2293 |
2293 |
2294 # Moves the wire end point and update the wire points |
2294 # Moves the wire end point and update the wire points |
2295 def MoveEndPoint(self, point): |
2295 def MoveEndPoint(self, point): |
2296 if len(self.Points) > 1: |
2296 if len(self.Points) > 1: |
2297 self.EndPoint[0] = point |
2297 self.EndPoint[0] = point |
2298 self.Points[-1] = point |
2298 self.Points[-1] = point |
2313 def ConnectEndPoint(self, point, connector): |
2313 def ConnectEndPoint(self, point, connector): |
2314 if point: |
2314 if point: |
2315 self.MoveEndPoint(point) |
2315 self.MoveEndPoint(point) |
2316 self.EndConnected = connector |
2316 self.EndConnected = connector |
2317 self.RefreshBoundingBox() |
2317 self.RefreshBoundingBox() |
2318 |
2318 |
2319 # Unconnects wire end point |
2319 # Unconnects wire end point |
2320 def UnConnectEndPoint(self, delete = False): |
2320 def UnConnectEndPoint(self, delete = False): |
2321 if delete: |
2321 if delete: |
2322 self.EndConnected = None |
2322 self.EndConnected = None |
2323 self.Delete() |
2323 self.Delete() |
2324 elif self.EndConnected: |
2324 elif self.EndConnected: |
2325 self.EndConnected.UnConnect(self, unconnect = False) |
2325 self.EndConnected.UnConnect(self, unconnect = False) |
2326 self.EndConnected = None |
2326 self.EndConnected = None |
2327 self.RefreshBoundingBox() |
2327 self.RefreshBoundingBox() |
2328 |
2328 |
2329 # Moves the wire segment given by its index |
2329 # Moves the wire segment given by its index |
2330 def MoveSegment(self, idx, movex, movey, scaling): |
2330 def MoveSegment(self, idx, movex, movey, scaling): |
2331 if 0 < idx < len(self.Segments) - 1: |
2331 if 0 < idx < len(self.Segments) - 1: |
2332 if self.Segments[idx] in (NORTH, SOUTH): |
2332 if self.Segments[idx] in (NORTH, SOUTH): |
2333 start_x = self.Points[idx].x |
2333 start_x = self.Points[idx].x |
2389 self.Points.insert(segment + 3, wx.Point(p2x, p2y)) |
2389 self.Points.insert(segment + 3, wx.Point(p2x, p2y)) |
2390 self.Segments.insert(segment + 3, (dir[1], dir[0])) |
2390 self.Segments.insert(segment + 3, (dir[1], dir[0])) |
2391 self.Points.insert(segment + 4, wx.Point(p2x, p2y)) |
2391 self.Points.insert(segment + 4, wx.Point(p2x, p2y)) |
2392 self.Segments.insert(segment + 4, dir) |
2392 self.Segments.insert(segment + 4, dir) |
2393 self.GeneratePoints() |
2393 self.GeneratePoints() |
2394 |
2394 |
2395 # Delete the handled segment by removing the two segment points |
2395 # Delete the handled segment by removing the two segment points |
2396 def DeleteSegment(self): |
2396 def DeleteSegment(self): |
2397 handle_type, handle = self.Handle |
2397 handle_type, handle = self.Handle |
2398 if handle_type == HANDLE_SEGMENT: |
2398 if handle_type == HANDLE_SEGMENT: |
2399 segment, dir = handle |
2399 segment, dir = handle |
2400 for i in xrange(2): |
2400 for i in xrange(2): |
2401 self.Points.pop(segment) |
2401 self.Points.pop(segment) |
2402 self.Segments.pop(segment) |
2402 self.Segments.pop(segment) |
2403 self.GeneratePoints() |
2403 self.GeneratePoints() |
2404 self.RefreshModel() |
2404 self.RefreshModel() |
2405 |
2405 |
2406 # Method called when a LeftDown event have been generated |
2406 # Method called when a LeftDown event have been generated |
2407 def OnLeftDown(self, event, dc, scaling): |
2407 def OnLeftDown(self, event, dc, scaling): |
2408 pos = GetScaledEventPosition(event, dc, scaling) |
2408 pos = GetScaledEventPosition(event, dc, scaling) |
2409 # Test if a point have been handled |
2409 # Test if a point have been handled |
2410 #result = self.TestPoint(pos) |
2410 #result = self.TestPoint(pos) |
2570 elif handle_type == HANDLE_SEGMENT: |
2570 elif handle_type == HANDLE_SEGMENT: |
2571 return self.MoveSegment(handle[0], movex, movey, scaling) |
2571 return self.MoveSegment(handle[0], movex, movey, scaling) |
2572 # Execute the default method for a graphic element |
2572 # Execute the default method for a graphic element |
2573 else: |
2573 else: |
2574 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling) |
2574 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling) |
2575 |
2575 |
2576 # Refreshes the wire model |
2576 # Refreshes the wire model |
2577 def RefreshModel(self, move=True): |
2577 def RefreshModel(self, move=True): |
2578 if self.StartConnected and self.StartPoint[1] in [WEST, NORTH]: |
2578 if self.StartConnected and self.StartPoint[1] in [WEST, NORTH]: |
2579 self.StartConnected.RefreshParentBlock() |
2579 self.StartConnected.RefreshParentBlock() |
2580 if self.EndConnected and self.EndPoint[1] in [WEST, NORTH]: |
2580 if self.EndConnected and self.EndPoint[1] in [WEST, NORTH]: |
2581 self.EndConnected.RefreshParentBlock() |
2581 self.EndConnected.RefreshParentBlock() |
2582 |
2582 |
2583 # Change the variable that indicates if this element is highlighted |
2583 # Change the variable that indicates if this element is highlighted |
2584 def SetHighlighted(self, highlighted): |
2584 def SetHighlighted(self, highlighted): |
2585 self.Highlighted = highlighted |
2585 self.Highlighted = highlighted |
2586 if not highlighted: |
2586 if not highlighted: |
2587 self.OverStart = False |
2587 self.OverStart = False |
2588 self.OverEnd = False |
2588 self.OverEnd = False |
2589 self.Refresh() |
2589 self.Refresh() |
2590 |
2590 |
2591 def HighlightPoint(self, pos): |
2591 def HighlightPoint(self, pos): |
2592 refresh = False |
2592 refresh = False |
2593 start, end = self.OverStart, self.OverEnd |
2593 start, end = self.OverStart, self.OverEnd |
2594 self.OverStart = False |
2594 self.OverStart = False |
2595 self.OverEnd = False |
2595 self.OverEnd = False |
2615 dc.SetPen(MiterPen(highlightcolor, (2 * scalex + 5))) |
2615 dc.SetPen(MiterPen(highlightcolor, (2 * scalex + 5))) |
2616 dc.SetBrush(wx.Brush(highlightcolor)) |
2616 dc.SetBrush(wx.Brush(highlightcolor)) |
2617 dc.SetLogicalFunction(wx.AND) |
2617 dc.SetLogicalFunction(wx.AND) |
2618 # Draw the start and end points if they are not connected or the mouse is over them |
2618 # 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): |
2619 if len(self.Points) > 0 and (not self.StartConnected or self.OverStart): |
2620 dc.DrawCircle(round(self.Points[0].x * scalex), |
2620 dc.DrawCircle(round(self.Points[0].x * scalex), |
2621 round(self.Points[0].y * scaley), |
2621 round(self.Points[0].y * scaley), |
2622 (POINT_RADIUS + 1) * scalex + 2) |
2622 (POINT_RADIUS + 1) * scalex + 2) |
2623 if len(self.Points) > 1 and (not self.EndConnected or self.OverEnd): |
2623 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) |
2624 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) |
2625 # Draw the wire lines and the last point (it seems that DrawLines stop before the last point) |
2626 if len(self.Points) > 1: |
2626 if len(self.Points) > 1: |
2627 points = [wx.Point(round((self.Points[0].x - self.Segments[0][0]) * scalex), |
2627 points = [wx.Point(round((self.Points[0].x - self.Segments[0][0]) * scalex), |
2628 round((self.Points[0].y - self.Segments[0][1]) * scaley))] |
2628 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]]) |
2629 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), |
2630 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))) |
2631 round((self.Points[-1].y + self.Segments[-1][1]) * scaley))) |
2632 else: |
2632 else: |
2633 points = [] |
2633 points = [] |
2634 dc.DrawLines(points) |
2634 dc.DrawLines(points) |
2635 dc.SetLogicalFunction(wx.COPY) |
2635 dc.SetLogicalFunction(wx.COPY) |
2636 dc.SetUserScale(scalex, scaley) |
2636 dc.SetUserScale(scalex, scaley) |
2637 |
2637 |
2638 if self.StartConnected is not None: |
2638 if self.StartConnected is not None: |
2639 self.StartConnected.DrawHighlightment(dc) |
2639 self.StartConnected.DrawHighlightment(dc) |
2640 self.StartConnected.Draw(dc) |
2640 self.StartConnected.Draw(dc) |
2641 if self.EndConnected is not None: |
2641 if self.EndConnected is not None: |
2642 self.EndConnected.DrawHighlightment(dc) |
2642 self.EndConnected.DrawHighlightment(dc) |
2643 self.EndConnected.Draw(dc) |
2643 self.EndConnected.Draw(dc) |
2644 |
2644 |
2645 # Draws the wire lines and points |
2645 # Draws the wire lines and points |
2646 def Draw(self, dc): |
2646 def Draw(self, dc): |
2647 Graphic_Element.Draw(self, dc) |
2647 Graphic_Element.Draw(self, dc) |
2648 if not self.Valid: |
2648 if not self.Valid: |
2649 dc.SetPen(MiterPen(wx.RED)) |
2649 dc.SetPen(MiterPen(wx.RED)) |
2748 self.Id = id |
2748 self.Id = id |
2749 self.Content = content |
2749 self.Content = content |
2750 self.Pos = wx.Point(0, 0) |
2750 self.Pos = wx.Point(0, 0) |
2751 self.Size = wx.Size(0, 0) |
2751 self.Size = wx.Size(0, 0) |
2752 self.Highlights = [] |
2752 self.Highlights = [] |
2753 |
2753 |
2754 # Make a clone of this comment |
2754 # Make a clone of this comment |
2755 def Clone(self, parent, id = None, pos = None): |
2755 def Clone(self, parent, id = None, pos = None): |
2756 comment = Comment(parent, self.Content, id) |
2756 comment = Comment(parent, self.Content, id) |
2757 if pos is not None: |
2757 if pos is not None: |
2758 comment.SetPosition(pos.x, pos.y) |
2758 comment.SetPosition(pos.x, pos.y) |
2759 comment.SetSize(self.Size[0], self.Size[1]) |
2759 comment.SetSize(self.Size[0], self.Size[1]) |
2760 return comment |
2760 return comment |
2761 |
2761 |
2762 # Method for keeping compatibility with others |
2762 # Method for keeping compatibility with others |
2763 def Clean(self): |
2763 def Clean(self): |
2764 pass |
2764 pass |
2765 |
2765 |
2766 # Delete this comment by calling the corresponding method |
2766 # Delete this comment by calling the corresponding method |
2767 def Delete(self): |
2767 def Delete(self): |
2768 self.Parent.DeleteComment(self) |
2768 self.Parent.DeleteComment(self) |
2769 |
2769 |
2770 # Refresh the comment bounding box |
2770 # Refresh the comment bounding box |
2771 def RefreshBoundingBox(self): |
2771 def RefreshBoundingBox(self): |
2772 self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) |
2772 self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) |
2773 |
2773 |
2774 # Changes the comment size |
2774 # Changes the comment size |
2775 def SetSize(self, width, height): |
2775 def SetSize(self, width, height): |
2776 self.Size.SetWidth(width) |
2776 self.Size.SetWidth(width) |
2777 self.Size.SetHeight(height) |
2777 self.Size.SetHeight(height) |
2778 self.RefreshBoundingBox() |
2778 self.RefreshBoundingBox() |
2779 |
2779 |
2780 # Returns the comment size |
2780 # Returns the comment size |
2781 def GetSize(self): |
2781 def GetSize(self): |
2782 return self.Size.GetWidth(), self.Size.GetHeight() |
2782 return self.Size.GetWidth(), self.Size.GetHeight() |
2783 |
2783 |
2784 # Returns the comment minimum size |
2784 # Returns the comment minimum size |
2785 def GetMinSize(self): |
2785 def GetMinSize(self): |
2786 dc = wx.ClientDC(self.Parent) |
2786 dc = wx.ClientDC(self.Parent) |
2787 min_width = 0 |
2787 min_width = 0 |
2788 min_height = 0 |
2788 min_height = 0 |
2813 return self.Content |
2813 return self.Content |
2814 |
2814 |
2815 # Returns the comment position |
2815 # Returns the comment position |
2816 def GetPosition(self): |
2816 def GetPosition(self): |
2817 return self.Pos.x, self.Pos.y |
2817 return self.Pos.x, self.Pos.y |
2818 |
2818 |
2819 # Moves the comment |
2819 # Moves the comment |
2820 def Move(self, dx, dy, connected = True): |
2820 def Move(self, dx, dy, connected = True): |
2821 self.Pos.x += dx |
2821 self.Pos.x += dx |
2822 self.Pos.y += dy |
2822 self.Pos.y += dy |
2823 self.RefreshBoundingBox() |
2823 self.RefreshBoundingBox() |
2824 |
2824 |
2825 # Resizes the comment with the position and the size given |
2825 # Resizes the comment with the position and the size given |
2826 def Resize(self, x, y, width, height): |
2826 def Resize(self, x, y, width, height): |
2827 self.Move(x, y) |
2827 self.Move(x, y) |
2828 self.SetSize(width, height) |
2828 self.SetSize(width, height) |
2829 |
2829 |
2830 # Method called when a RightUp event have been generated |
2830 # Method called when a RightUp event have been generated |
2831 def OnRightUp(self, event, dc, scaling): |
2831 def OnRightUp(self, event, dc, scaling): |
2832 # Popup the default menu |
2832 # Popup the default menu |
2833 self.Parent.PopupDefaultMenu() |
2833 self.Parent.PopupDefaultMenu() |
2834 |
2834 |
2835 # Refreshes the wire state according to move defined and handle selected |
2835 # Refreshes the wire state according to move defined and handle selected |
2836 def ProcessDragging(self, movex, movey, event, scaling): |
2836 def ProcessDragging(self, movex, movey, event, scaling): |
2837 if self.Parent.GetDrawingMode() != FREEDRAWING_MODE and self.Parent.CurrentLanguage == "LD": |
2837 if self.Parent.GetDrawingMode() != FREEDRAWING_MODE and self.Parent.CurrentLanguage == "LD": |
2838 movex = movey = 0 |
2838 movex = movey = 0 |
2839 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling) |
2839 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling) |
2840 |
2840 |
2841 # Refreshes the comment model |
2841 # Refreshes the comment model |
2842 def RefreshModel(self, move=True): |
2842 def RefreshModel(self, move=True): |
2843 self.Parent.RefreshCommentModel(self) |
2843 self.Parent.RefreshCommentModel(self) |
2844 |
2844 |
2845 # Method called when a LeftDClick event have been generated |
2845 # Method called when a LeftDClick event have been generated |
2846 def OnLeftDClick(self, event, dc, scaling): |
2846 def OnLeftDClick(self, event, dc, scaling): |
2847 # Edit the comment content |
2847 # Edit the comment content |
2848 self.Parent.EditCommentContent(self) |
2848 self.Parent.EditCommentContent(self) |
2849 |
2849 |
2850 # Adds an highlight to the comment |
2850 # Adds an highlight to the comment |
2851 def AddHighlight(self, infos, start, end, highlight_type): |
2851 def AddHighlight(self, infos, start, end, highlight_type): |
2852 if infos[0] == "content": |
2852 if infos[0] == "content": |
2853 AddHighlight(self.Highlights, (start, end, highlight_type)) |
2853 AddHighlight(self.Highlights, (start, end, highlight_type)) |
2854 |
2854 |
2855 # Removes an highlight from the comment |
2855 # Removes an highlight from the comment |
2856 def RemoveHighlight(self, infos, start, end, highlight_type): |
2856 def RemoveHighlight(self, infos, start, end, highlight_type): |
2857 RemoveHighlight(self.Highlights, (start, end, highlight_type)) |
2857 RemoveHighlight(self.Highlights, (start, end, highlight_type)) |
2858 |
2858 |
2859 # Removes all the highlights of one particular type from the comment |
2859 # Removes all the highlights of one particular type from the comment |
2860 def ClearHighlight(self, highlight_type=None): |
2860 def ClearHighlight(self, highlight_type=None): |
2861 self.Highlights = ClearHighlights(self.Highlights, highlight_type) |
2861 self.Highlights = ClearHighlights(self.Highlights, highlight_type) |
2862 |
2862 |
2863 # Draws the highlightment of this element if it is highlighted |
2863 # Draws the highlightment of this element if it is highlighted |
2864 def DrawHighlightment(self, dc): |
2864 def DrawHighlightment(self, dc): |
2865 scalex, scaley = dc.GetUserScale() |
2865 scalex, scaley = dc.GetUserScale() |
2866 dc.SetUserScale(1, 1) |
2866 dc.SetUserScale(1, 1) |
2867 dc.SetPen(MiterPen(HIGHLIGHTCOLOR)) |
2867 dc.SetPen(MiterPen(HIGHLIGHTCOLOR)) |
2868 dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR)) |
2868 dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR)) |
2869 dc.SetLogicalFunction(wx.AND) |
2869 dc.SetLogicalFunction(wx.AND) |
2870 |
2870 |
2871 left = (self.Pos.x - 1) * scalex - 2 |
2871 left = (self.Pos.x - 1) * scalex - 2 |
2872 right = (self.Pos.x + self.Size[0] + 1) * scalex + 2 |
2872 right = (self.Pos.x + self.Size[0] + 1) * scalex + 2 |
2873 top = (self.Pos.y - 1) * scaley - 2 |
2873 top = (self.Pos.y - 1) * scaley - 2 |
2874 bottom = (self.Pos.y + self.Size[1] + 1) * scaley + 2 |
2874 bottom = (self.Pos.y + self.Size[1] + 1) * scaley + 2 |
2875 angle_top = (self.Pos.x + self.Size[0] - 9) * scalex + 2 |
2875 angle_top = (self.Pos.x + self.Size[0] - 9) * scalex + 2 |
2876 angle_right = (self.Pos.y + 9) * scaley - 2 |
2876 angle_right = (self.Pos.y + 9) * scaley - 2 |
2877 |
2877 |
2878 polygon = [wx.Point(left, top), wx.Point(angle_top, top), |
2878 polygon = [wx.Point(left, top), wx.Point(angle_top, top), |
2879 wx.Point(right, angle_right), wx.Point(right, bottom), |
2879 wx.Point(right, angle_right), wx.Point(right, bottom), |
2880 wx.Point(left, bottom)] |
2880 wx.Point(left, bottom)] |
2881 dc.DrawPolygon(polygon) |
2881 dc.DrawPolygon(polygon) |
2882 |
2882 |
2883 dc.SetLogicalFunction(wx.COPY) |
2883 dc.SetLogicalFunction(wx.COPY) |
2884 dc.SetUserScale(scalex, scaley) |
2884 dc.SetUserScale(scalex, scaley) |
2885 |
2885 |
2886 # Draws the comment and its content |
2886 # Draws the comment and its content |
2887 def Draw(self, dc): |
2887 def Draw(self, dc): |
2888 Graphic_Element.Draw(self, dc) |
2888 Graphic_Element.Draw(self, dc) |
2889 dc.SetPen(MiterPen(wx.BLACK)) |
2889 dc.SetPen(MiterPen(wx.BLACK)) |
2890 dc.SetBrush(wx.WHITE_BRUSH) |
2890 dc.SetBrush(wx.WHITE_BRUSH) |
2891 # Draws the comment shape |
2891 # Draws the comment shape |
2892 polygon = [wx.Point(self.Pos.x, self.Pos.y), |
2892 polygon = [wx.Point(self.Pos.x, self.Pos.y), |
2893 wx.Point(self.Pos.x + self.Size[0] - 10, self.Pos.y), |
2893 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), |
2894 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]), |
2895 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])] |
2896 wx.Point(self.Pos.x, self.Pos.y + self.Size[1])] |
2897 dc.DrawPolygon(polygon) |
2897 dc.DrawPolygon(polygon) |