# HG changeset patch # User lbessard # Date 1214239729 -7200 # Node ID 4931959ea256d58fc9200b22019c101add21ee90 # Parent e36ba4f15fc88f5c50dc6243dad7b5ea2353ff90 Adding support for printing graphical languages diff -r e36ba4f15fc8 -r 4931959ea256 PLCOpenEditor.py --- a/PLCOpenEditor.py Wed Jun 04 17:48:26 2008 +0200 +++ b/PLCOpenEditor.py Mon Jun 23 18:48:49 2008 +0200 @@ -221,6 +221,13 @@ AppendMenu(parent, help='', id=ID_PLCOPENEDITORFILEMENUGENERATE, kind=wx.ITEM_NORMAL, text=u'Generate Program\tCTRL+G') parent.AppendSeparator() + AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP, + kind=wx.ITEM_NORMAL, text=u'Page Setup') + AppendMenu(parent, help='', id=wx.ID_PREVIEW, + kind=wx.ITEM_NORMAL, text=u'Preview') + AppendMenu(parent, help='', id=wx.ID_PRINT, + kind=wx.ITEM_NORMAL, text=u'Print') + parent.AppendSeparator() AppendMenu(parent, help='', id=wx.ID_PROPERTIES, kind=wx.ITEM_NORMAL, text=u'Properties') parent.AppendSeparator() @@ -234,6 +241,9 @@ self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu, id=wx.ID_SAVEAS) self.Bind(wx.EVT_MENU, self.OnGenerateProgramMenu, id=ID_PLCOPENEDITORFILEMENUGENERATE) + self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP) + self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW) + self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT) self.Bind(wx.EVT_MENU, self.OnPropertiesMenu, id=wx.ID_PROPERTIES) self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT) @@ -477,6 +487,13 @@ self.DrawingMode = FREEDRAWING_MODE #self.DrawingMode = DRIVENDRAWING_MODE + self.PrintData = wx.PrintData() + self.PrintData.SetPaperId(wx.PAPER_A4) + self.PrintData.SetPrintMode(wx.PRINT_MODE_PRINTER) + self.PageSetupData = wx.PageSetupDialogData(self.PrintData) + self.PageSetupData.SetMarginTopLeft(wx.Point(10, 15)) + self.PageSetupData.SetMarginBottomRight(wx.Point(10, 20)) + if not self.ModeSolo or fileOpen is not None: self.RefreshProjectTree() @@ -652,14 +669,28 @@ def RefreshFileMenu(self): if self.FileMenu: if self.Controler.HasOpenedProject(): + selected = self.GetPageSelection() + if selected >= 0: + graphic_viewer = isinstance(self.GetPage(selected), Viewer) + else: + graphic_viewer = False if self.GetPageCount() > 0: self.FileMenu.Enable(wx.ID_CLOSE, True) + if graphic_viewer: + self.FileMenu.Enable(wx.ID_PREVIEW, True) + self.FileMenu.Enable(wx.ID_PRINT, True) + else: + self.FileMenu.Enable(wx.ID_PREVIEW, False) + self.FileMenu.Enable(wx.ID_PRINT, False) else: self.FileMenu.Enable(wx.ID_CLOSE, False) + self.FileMenu.Enable(wx.ID_PREVIEW, False) + self.FileMenu.Enable(wx.ID_PRINT, False) self.FileMenu.Enable(wx.ID_CLOSE_ALL, True) self.FileMenu.Enable(wx.ID_SAVE, True) self.FileMenu.Enable(wx.ID_SAVEAS, True) self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, True) + self.FileMenu.Enable(wx.ID_PAGE_SETUP, True) self.FileMenu.Enable(wx.ID_PROPERTIES, True) else: self.FileMenu.Enable(wx.ID_CLOSE, False) @@ -667,6 +698,9 @@ self.FileMenu.Enable(wx.ID_SAVE, False) self.FileMenu.Enable(wx.ID_SAVEAS, False) self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, False) + self.FileMenu.Enable(wx.ID_PAGE_SETUP, False) + self.FileMenu.Enable(wx.ID_PREVIEW, False) + self.FileMenu.Enable(wx.ID_PRINT, False) self.FileMenu.Enable(wx.ID_PROPERTIES, False) def OnNewProjectMenu(self, event): @@ -806,6 +840,49 @@ self.RefreshTitle() dialog.Destroy() + def OnPageSetupMenu(self, event): + dialog = wx.PageSetupDialog(self, self.PageSetupData) + if dialog.ShowModal() == wx.ID_OK: + self.PageSetupData = wx.PageSetupDialogData(dialog.GetPageSetupData()) + self.PrintData = wx.PrintData(self.PageSetupData.GetPrintData()) + dialog.Destroy() + event.Skip() + + def OnPreviewMenu(self, event): + selected = self.GetPageSelection() + if selected != -1: + data = wx.PrintDialogData(self.PrintData) + properties = self.Controler.GetProjectProperties() + page_size = map(int, properties["pageSize"]) + margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight()) + printout = GraphicPrintout(self.GetPage(selected), page_size, margins, True) + printout2 = GraphicPrintout(self.GetPage(selected), page_size, margins, True) + preview = wx.PrintPreview(printout, printout2, data) + + if preview.Ok(): + preview_frame = wx.PreviewFrame(preview, frame, "Print preview") + + preview_frame.Initialize() + + preview_frame.Show(True) + event.Skip() + + def OnPrintMenu(self, event): + selected = self.GetPageSelection() + if selected != -1: + dialog_data = wx.PrintDialogData(self.PrintData) + dialog_data.SetToPage(1) + properties = self.Controler.GetProjectProperties() + page_size = map(int, properties["pageSize"]) + margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight()) + printer = wx.Printer(dialog_data) + printout = GraphicPrintout(self.GetPage(selected), page_size, margins) + + if not printer.Print(self, printout, True): + wx.MessageBox("There was a problem printing.\nPerhaps your current printer is not set correctly?", "Printing", wx.OK) + printout.Destroy() + event.Skip() + def OnPropertiesMenu(self, event): self.ShowProperties() event.Skip() @@ -3804,6 +3881,86 @@ self.ParentWindow.RefreshTitle() self.ParentWindow.RefreshEditMenu() +UPPER_DIV = lambda x, y: (x / y) + {True : 0, False : 1}[(x % y) == 0] + +class GraphicPrintout(wx.Printout): + def __init__(self, viewer, page_size, margins, preview = False): + wx.Printout.__init__(self) + self.Viewer = viewer + self.PageSize = page_size + self.Preview = preview + self.Margins = margins + self.FontSize = 14 + self.TextMargin = 5 + + maxx, maxy = viewer.GetMaxSize() + self.PageGrid = (UPPER_DIV(maxx, page_size[0]), UPPER_DIV(maxy, page_size[1])) + + def GetPageNumber(self): + return self.PageGrid[0] * self.PageGrid[1] + + def HasPage(self, page): + return page <= self.GetPageNumber() + + def GetPageInfo(self): + page_number = self.GetPageNumber() + return (1, page_number, 1, page_number) + + def OnBeginDocument(self, startPage, endPage): + dc = self.GetDC() + if not self.Preview and isinstance(dc, wx.PostScriptDC): + dc.SetResolution(720) + self.FontSize = 140 + self.TextMargin = 50 + super(GraphicPrintout, self).OnBeginDocument(startPage, endPage) + + def OnPrintPage(self, page): + dc = self.GetDC() + dc.printing = not self.Preview + + # Get the size of the DC in pixels + ppiPrinterX, ppiPrinterY = self.GetPPIPrinter() + ppiScreenX, ppiScreenY = self.GetPPIScreen() + pw, ph = self.GetPageSizePixels() + dw, dh = dc.GetSizeTuple() + Xscale = (float(dw) * float(ppiPrinterX)) / (float(pw) * 25.4) + Yscale = (float(dh) * float(ppiPrinterY)) / (float(ph) * 25.4) + + margin_left = self.Margins[0].x * Xscale + margin_top = self.Margins[0].y * Yscale + area_width = dw - self.Margins[1].x * Xscale - margin_left + area_height = dh - self.Margins[1].y * Yscale - margin_top + + dc.SetPen(wx.BLACK_PEN) + dc.SetBrush(wx.TRANSPARENT_BRUSH) + dc.DrawRectangle(margin_left, margin_top, area_width, area_height) + + dc.SetFont(wx.Font(self.FontSize, wx.DEFAULT, wx.NORMAL, wx.NORMAL)) + dc.SetTextForeground(wx.BLACK) + block_name = " - ".join(self.Viewer.GetTagName().split("::")[1:]) + text_width, text_height = dc.GetTextExtent(block_name) + dc.DrawText(block_name, margin_left, margin_top - text_height - self.TextMargin) + dc.DrawText("Page: %d" % page, margin_left, margin_top + area_height + self.TextMargin) + + # Calculate the position on the DC for centering the graphic + posX = area_width * ((page - 1) % self.PageGrid[0]) + posY = area_height * ((page - 1) / self.PageGrid[0]) + + scaleX = float(area_width) / float(self.PageSize[0]) + scaleY = float(area_height) / float(self.PageSize[1]) + scale = min(scaleX, scaleY) + + # Set the scale and origin + dc.SetDeviceOrigin(-posX + margin_left, -posY + margin_top) + dc.SetUserScale(scale, scale) + dc.SetClippingRegion(posX, posY, self.PageSize[0], self.PageSize[1]) + + #------------------------------------------- + + self.Viewer.DoDrawing(dc, True) + + return True + #------------------------------------------------------------------------------- # Exception Handler #------------------------------------------------------------------------------- diff -r e36ba4f15fc8 -r 4931959ea256 Viewer.py --- a/Viewer.py Wed Jun 04 17:48:26 2008 +0200 +++ b/Viewer.py Mon Jun 23 18:48:49 2008 +0200 @@ -306,6 +306,8 @@ self.Scaling = None self.DrawGrid = True self.GridBrush = wx.TRANSPARENT_BRUSH + self.PageSize = None + self.PagePen = wx.TRANSPARENT_PEN self.DrawingWire = False self.current_id = 0 self.TagName = tagname @@ -324,12 +326,12 @@ self.SetDropTarget(ViewerDropTarget(self)) dc = wx.ClientDC(self) - font = wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = faces["mono"]) + font = wx.Font(faces["size"], wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["mono"]) dc.SetFont(font) width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ") while width > 260: faces["size"] -= 1 - font = wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = faces["mono"]) + font = wx.Font(faces["size"], wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["mono"]) dc.SetFont(font) width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ") self.SetFont(font) @@ -344,7 +346,7 @@ self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveViewer) self.Bind(wx.EVT_MOTION, self.OnViewerMotion) self.Bind(wx.EVT_CHAR, self.OnChar) - self.Bind(wx.EVT_SCROLLWIN, self.OnMoveWindow) + #self.Bind(wx.EVT_SCROLLWIN, self.OnMoveWindow) self.Bind(wx.EVT_SIZE, self.OnMoveWindow) def GetScrolledRect(self, rect): @@ -374,7 +376,7 @@ def GetLogicalDC(self, buffered=False): if buffered: - dc = wx.BufferedPaintDC(self) + dc = wx.AutoBufferedPaintDC(self) else: dc = wx.ClientDC(self) dc.SetFont(self.GetFont()) @@ -489,6 +491,13 @@ else: self.Scaling = None self.GridBrush = wx.TRANSPARENT_BRUSH + page_size = properties["pageSize"] + if page_size != (0, 0): + self.PageSize = map(int, page_size) + self.PagePen = wx.Pen(wx.Colour(180, 180, 180)) + else: + self.PageSize = None + self.PagePen = wx.TRANSPARENT_PEN if refresh: self.Refresh(False) @@ -524,14 +533,18 @@ self.Refresh(False) - def RefreshScrollBars(self): - xstart, ystart = self.GetViewStart() - window_size = self.GetClientSize() + def GetMaxSize(self): maxx = maxy = 0 for element in self.GetElements(): bbox = element.GetBoundingBox() maxx = max(maxx, bbox.x + bbox.width) maxy = max(maxy, bbox.y + bbox.height) + return maxx, maxy + + def RefreshScrollBars(self): + xstart, ystart = self.GetViewStart() + window_size = self.GetClientSize() + maxx, maxy = self.GetMaxSize() maxx = max(maxx + WINDOW_BORDER, xstart * SCROLLBAR_UNIT + window_size[0]) maxy = max(maxy + WINDOW_BORDER, ystart * SCROLLBAR_UNIT + window_size[1]) if self.rubberBand.IsShown(): @@ -539,7 +552,8 @@ maxx = max(maxx, extent.x + extent.width) maxy = max(maxy, extent.y + extent.height) self.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT, - maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, xstart, ystart, True) + round(maxx / SCROLLBAR_UNIT), round(maxy / SCROLLBAR_UNIT), + xstart, ystart, True) # Load instance from given informations def loadInstance(self, instance, ids): @@ -2320,16 +2334,36 @@ self.RefreshScrollBars() event.Skip() - def OnPaint(self, event): - dc = self.GetLogicalDC(True) - dc.SetBackground(wx.Brush(self.GetBackgroundColour())) - dc.Clear() - dc.BeginDrawing() - if self.Scaling and self.DrawGrid: + def DoDrawing(self, dc, printing = False): + if printing: + if getattr(dc, "printing", False): + font = wx.Font(self.GetFont().GetPointSize(), wx.MODERN, wx.NORMAL, wx.NORMAL) + dc.SetFont(font) + else: + dc.SetFont(self.GetFont()) + else: + dc.SetBackground(wx.Brush(self.GetBackgroundColour())) + dc.Clear() + dc.BeginDrawing() + if self.Scaling is not None and self.DrawGrid and not printing: dc.SetPen(wx.TRANSPARENT_PEN) dc.SetBrush(self.GridBrush) + xstart, ystart = self.GetViewStart() + window_size = self.GetClientSize() width, height = self.GetVirtualSize() + width = max(width, xstart * SCROLLBAR_UNIT + window_size[0]) + height = max(height, ystart * SCROLLBAR_UNIT + window_size[1]) dc.DrawRectangle(0, 0, width, height) + if self.PageSize is not None and not printing: + dc.SetPen(self.PagePen) + xstart, ystart = self.GetViewStart() + window_size = self.GetClientSize() + for x in xrange(self.PageSize[0] - (xstart * SCROLLBAR_UNIT) % self.PageSize[0], window_size[0], self.PageSize[0]): + dc.DrawLine(xstart * SCROLLBAR_UNIT + x + 1, ystart * SCROLLBAR_UNIT, + xstart * SCROLLBAR_UNIT + x + 1, ystart * SCROLLBAR_UNIT + window_size[1]) + for y in xrange(self.PageSize[1] - (ystart * SCROLLBAR_UNIT) % self.PageSize[1], window_size[1], self.PageSize[1]): + dc.DrawLine(xstart * SCROLLBAR_UNIT, ystart * SCROLLBAR_UNIT + y + 1, + xstart * SCROLLBAR_UNIT + window_size[0], ystart * SCROLLBAR_UNIT + y + 1) # Draw all elements for comment in self.Comments: @@ -2343,11 +2377,15 @@ block.Draw(dc) if self.SelectedElement: - self.SelectedElement.Draw(dc) - - if self.rubberBand.IsShown(): - self.rubberBand.Draw(dc) - dc.EndDrawing() - event.Skip() - - + self.SelectedElement.Draw(dc) + + if not printing: + if self.rubberBand.IsShown(): + self.rubberBand.Draw(dc) + dc.EndDrawing() + + def OnPaint(self, event): + self.DoDrawing(self.GetLogicalDC(True)) + event.Skip() + + diff -r e36ba4f15fc8 -r 4931959ea256 examples/example.xml --- a/examples/example.xml Wed Jun 04 17:48:26 2008 +0200 +++ b/examples/example.xml Mon Jun 23 18:48:49 2008 +0200 @@ -12,11 +12,11 @@ contentDescription="Example of PLCOpenEditor usage"/> - + @@ -245,7 +245,7 @@ - + diff -r e36ba4f15fc8 -r 4931959ea256 graphics/FBD_Objects.py --- a/graphics/FBD_Objects.py Wed Jun 04 17:48:26 2008 +0200 +++ b/graphics/FBD_Objects.py Mon Jun 23 18:48:49 2008 +0200 @@ -356,12 +356,22 @@ dc.SetPen(self.Pen) dc.SetBrush(wx.WHITE_BRUSH) dc.SetTextForeground(self.Colour) + + if getattr(dc, "printing", False): + name_size = dc.GetTextExtent(self.Name) + type_size = dc.GetTextExtent(self.Type) + executionorder_size = dc.GetTextExtent(str(self.ExecutionOrder)) + else: + name_size = self.NameSize + type_size = self.TypeSize + executionorder_size = self.ExecutionOrderSize + # Draw a rectangle with the block size dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) # Draw block name and block type - dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - self.NameSize[0]) / 2, - self.Pos.y - (self.NameSize[1] + 2)) - dc.DrawText(self.Type, self.Pos.x + (self.Size[0] - self.TypeSize[0]) / 2, + dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - name_size[0]) / 2, + self.Pos.y - (name_size[1] + 2)) + dc.DrawText(self.Type, self.Pos.x + (self.Size[0] - type_size[0]) / 2, self.Pos.y + 5) # Draw inputs and outputs connectors for input in self.Inputs: @@ -370,7 +380,7 @@ output.Draw(dc) if self.ExecutionOrder != 0: # Draw block execution order - dc.DrawText(str(self.ExecutionOrder), self.Pos.x + self.Size[0] - self.ExecutionOrderSize[0], + dc.DrawText(str(self.ExecutionOrder), self.Pos.x + self.Size[0] - executionorder_size[0], self.Pos.y + self.Size[1] + 2) dc.SetTextForeground(wx.BLACK) @@ -589,11 +599,19 @@ Graphic_Element.Draw(self, dc) dc.SetPen(wx.BLACK_PEN) dc.SetBrush(wx.WHITE_BRUSH) + + if getattr(dc, "printing", False): + name_size = dc.GetTextExtent(self.Name) + executionorder_size = dc.GetTextExtent(str(self.ExecutionOrder)) + else: + name_size = self.NameSize + executionorder_size = self.ExecutionOrderSize + # Draw a rectangle with the variable size dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) # Draw variable name - dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - self.NameSize[0]) / 2, - self.Pos.y + (self.Size[1] - self.NameSize[1]) / 2) + dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - name_size[0]) / 2, + self.Pos.y + (self.Size[1] - name_size[1]) / 2) # Draw connectors if self.Input: self.Input.Draw(dc) @@ -601,7 +619,7 @@ self.Output.Draw(dc) if self.ExecutionOrder != 0: # Draw variable execution order - dc.DrawText(str(self.ExecutionOrder), self.Pos.x + self.Size[0] - self.ExecutionOrderSize[0], + dc.DrawText(str(self.ExecutionOrder), self.Pos.x + self.Size[0] - executionorder_size[0], self.Pos.y + self.Size[1] + 2) @@ -761,9 +779,15 @@ Graphic_Element.Draw(self, dc) dc.SetPen(wx.BLACK_PEN) dc.SetBrush(wx.WHITE_BRUSH) + + if getattr(dc, "printing", False): + name_size = dc.GetTextExtent(self.Name) + else: + name_size = self.NameSize + # Draw a rectangle with the connection size with arrows in dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) - arrowsize = min(self.Size[1] / 2, (self.Size[0] - self.NameSize[0] - 10) / 2) + arrowsize = min(self.Size[1] / 2, (self.Size[0] - name_size[0] - 10) / 2) dc.DrawLine(self.Pos.x, self.Pos.y, self.Pos.x + arrowsize, self.Pos.y + self.Size[1] / 2) dc.DrawLine(self.Pos.x + arrowsize, self.Pos.y + self.Size[1] / 2, @@ -773,8 +797,8 @@ dc.DrawLine(self.Pos.x + self.Size[0], self.Pos.y + self.Size[1] / 2, self.Pos.x + self.Size[0] - arrowsize, self.Pos.y + self.Size[1]) # Draw connection name - dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - self.NameSize[0]) / 2, - self.Pos.y + (self.Size[1] - self.NameSize[1]) / 2) + dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - name_size[0]) / 2, + self.Pos.y + (self.Size[1] - name_size[1]) / 2) # Draw connector if self.Connector: self.Connector.Draw(dc) diff -r e36ba4f15fc8 -r 4931959ea256 graphics/GraphicCommons.py --- a/graphics/GraphicCommons.py Wed Jun 04 17:48:26 2008 +0200 +++ b/graphics/GraphicCommons.py Mon Jun 23 18:48:49 2008 +0200 @@ -1120,6 +1120,12 @@ dc.SetPen(self.Pen) dc.SetBrush(wx.WHITE_BRUSH) parent_pos = self.ParentBlock.GetPosition() + + if getattr(dc, "printing", False): + name_size = dc.GetTextExtent(self.Name) + else: + name_size = self.NameSize + if self.Negated: # If connector is negated, draw a circle xcenter = parent_pos[0] + self.Pos.x + (CONNECTOR_SIZE * self.Direction[0]) / 2 @@ -1140,17 +1146,17 @@ yend = ystart + CONNECTOR_SIZE * self.Direction[1] dc.DrawLine(xstart + self.Direction[0], ystart + self.Direction[1], xend, yend) if self.Direction[0] != 0: - ytext = parent_pos[1] + self.Pos.y - self.NameSize[1] / 2 + ytext = parent_pos[1] + self.Pos.y - name_size[1] / 2 if self.Direction[0] < 0: xtext = parent_pos[0] + self.Pos.x + 5 else: - xtext = parent_pos[0] + self.Pos.x - (self.NameSize[0] + 5) + xtext = parent_pos[0] + self.Pos.x - (name_size[0] + 5) if self.Direction[1] != 0: - xtext = parent_pos[0] + self.Pos.x - self.NameSize[0] / 2 + xtext = parent_pos[0] + self.Pos.x - name_size[0] / 2 if self.Direction[1] < 0: ytext = parent_pos[1] + self.Pos.y + 5 else: - ytext = parent_pos[1] + self.Pos.y - (self.NameSize[1] + 5) + ytext = parent_pos[1] + self.Pos.y - (name_size[1] + 5) # Draw the text dc.DrawText(self.Name, xtext, ytext) diff -r e36ba4f15fc8 -r 4931959ea256 graphics/LD_Objects.py --- a/graphics/LD_Objects.py Wed Jun 04 17:48:26 2008 +0200 +++ b/graphics/LD_Objects.py Mon Jun 23 18:48:49 2008 +0200 @@ -563,13 +563,8 @@ Graphic_Element.Draw(self, dc) dc.SetPen(wx.BLACK_PEN) dc.SetBrush(wx.BLACK_BRUSH) - # Draw two rectangles for representing the contact - dc.DrawRectangle(self.Pos.x, self.Pos.y, 2, self.Size[1] + 1) - dc.DrawRectangle(self.Pos.x + self.Size[0] - 1, self.Pos.y, 2, self.Size[1] + 1) - # Draw contact name - dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - self.NameSize[0]) / 2, - self.Pos.y - (self.NameSize[1] + 2)) - # Draw the modifier symbol in the middle of contact + + # Compiling contact type modifier symbol typetext = "" if self.Type == CONTACT_REVERSE: typetext = "/" @@ -577,9 +572,26 @@ typetext = "P" elif self.Type == CONTACT_FALLING: typetext = "N" + + if getattr(dc, "printing", False): + name_size = dc.GetTextExtent(self.Name) + if typetext != "": + type_size = dc.GetTextExtent(typetext) + else: + name_size = self.NameSize + if typetext != "": + type_size = self.TypeSize + + # Draw two rectangles for representing the contact + dc.DrawRectangle(self.Pos.x, self.Pos.y, 2, self.Size[1] + 1) + dc.DrawRectangle(self.Pos.x + self.Size[0] - 1, self.Pos.y, 2, self.Size[1] + 1) + # Draw contact name + dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - name_size[0]) / 2, + self.Pos.y - (name_size[1] + 2)) + # Draw the modifier symbol in the middle of contact if typetext != "": - dc.DrawText(typetext, self.Pos.x + (self.Size[0] - self.TypeSize[0]) / 2 + 1, - self.Pos.y + (self.Size[1] - self.TypeSize[1]) / 2) + dc.DrawText(typetext, self.Pos.x + (self.Size[0] - type_size[0]) / 2 + 1, + self.Pos.y + (self.Size[1] - type_size[1]) / 2) # Draw input and output connectors self.Input.Draw(dc) self.Output.Draw(dc) @@ -793,15 +805,8 @@ Graphic_Element.Draw(self, dc) dc.SetPen(wx.Pen(wx.BLACK, 2, wx.SOLID)) dc.SetBrush(wx.TRANSPARENT_BRUSH) - # Draw a two circle arcs for representing the coil - dc.DrawEllipticArc(self.Pos.x, self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1, self.Size[0], int(self.Size[1] * sqrt(2)) - 1, 135, 225) - dc.DrawEllipticArc(self.Pos.x, self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1, self.Size[0], int(self.Size[1] * sqrt(2)) - 1, -45, 45) - dc.SetPen(wx.BLACK_PEN) - dc.DrawPoint(self.Pos.x + 1, self.Pos.y + self.Size[1] / 2 + 1) - # Draw coil name - dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - self.NameSize[0]) / 2, - self.Pos.y - (self.NameSize[1] + 2)) - # Draw the modifier symbol in the middle of coil + + # Compiling coil type modifier symbol typetext = "" if self.Type == COIL_REVERSE: typetext = "/" @@ -809,9 +814,37 @@ typetext = "S" elif self.Type == COIL_RESET: typetext = "R" + + if getattr(dc, "printing", False) and not isinstance(dc, wx.PostScriptDC): + # Draw an clipped ellipse for representing the coil + clipping_box = dc.GetClippingBox() + dc.SetClippingRegion(self.Pos.x - 1, self.Pos.y, self.Size[0] + 2, self.Size[1] + 1) + dc.DrawEllipse(self.Pos.x, self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1, self.Size[0], int(self.Size[1] * sqrt(2)) - 1) + dc.DestroyClippingRegion() + if clipping_box != (0, 0, 0, 0): + dc.SetClippingRegion(*clipping_box) + name_size = dc.GetTextExtent(self.Name) + if typetext != "": + type_size = dc.GetTextExtent(typetext) + else: + # Draw a two ellipse arcs for representing the coil + dc.DrawEllipticArc(self.Pos.x, self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1, self.Size[0], int(self.Size[1] * sqrt(2)) - 1, 135, 225) + dc.DrawEllipticArc(self.Pos.x, self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1, self.Size[0], int(self.Size[1] * sqrt(2)) - 1, -45, 45) + # Draw a point to avoid hole in left arc + if not getattr(dc, "printing", False): + dc.SetPen(wx.BLACK_PEN) + dc.DrawPoint(self.Pos.x + 1, self.Pos.y + self.Size[1] / 2 + 1) + name_size = self.NameSize + if typetext != "": + type_size = self.TypeSize + + # Draw coil name + dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - name_size[0]) / 2, + self.Pos.y - (name_size[1] + 2)) + # Draw the modifier symbol in the middle of coil if typetext != "": - dc.DrawText(typetext, self.Pos.x + (self.Size[0] - self.TypeSize[0]) / 2 + 1, - self.Pos.y + (self.Size[1] - self.TypeSize[1]) / 2) + dc.DrawText(typetext, self.Pos.x + (self.Size[0] - type_size[0]) / 2 + 1, + self.Pos.y + (self.Size[1] - type_size[1]) / 2) # Draw input and output connectors self.Input.Draw(dc) self.Output.Draw(dc) diff -r e36ba4f15fc8 -r 4931959ea256 graphics/SFC_Objects.py --- a/graphics/SFC_Objects.py Wed Jun 04 17:48:26 2008 +0200 +++ b/graphics/SFC_Objects.py Mon Jun 23 18:48:49 2008 +0200 @@ -46,7 +46,7 @@ # Create a new step def __init__(self, parent, name, initial = False, id = None): Graphic_Element.__init__(self, parent) - self.Name = name + self.SetName(name) self.Initial = initial self.Id = id self.Size = wx.Size(SFC_STEP_DEFAULT_SIZE[0], SFC_STEP_DEFAULT_SIZE[1]) @@ -109,6 +109,10 @@ if self.Action: self.Action.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) + # Refresh the size of text for name + def RefreshNameSize(self): + self.NameSize = self.Parent.GetTextExtent(self.Name) + # Add output connector to step def AddInput(self): if not self.Input: @@ -244,6 +248,7 @@ # Changes the step name def SetName(self, name): self.Name = name + self.RefreshNameSize() # Returns the step name def GetName(self): @@ -459,14 +464,19 @@ Graphic_Element.Draw(self, dc) dc.SetPen(wx.BLACK_PEN) dc.SetBrush(wx.WHITE_BRUSH) + + if getattr(dc, "printing", False): + name_size = dc.GetTextExtent(self.Name) + else: + name_size = self.NameSize + # Draw two rectangles for representing the step dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) if self.Initial: dc.DrawRectangle(self.Pos.x + 2, self.Pos.y + 2, self.Size[0] - 3, self.Size[1] - 3) # Draw step name - namewidth, nameheight = dc.GetTextExtent(self.Name) - dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - namewidth) / 2, - self.Pos.y + (self.Size[1] - nameheight) / 2) + dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - name_size[0]) / 2, + self.Pos.y + (self.Size[1] - name_size[1]) / 2) # Draw input and output connectors if self.Input: self.Input.Draw(dc) @@ -815,6 +825,18 @@ Graphic_Element.Draw(self, dc) dc.SetPen(wx.BLACK_PEN) dc.SetBrush(wx.BLACK_BRUSH) + + if getattr(dc, "printing", False): + if self.Type != "connection": + condition_size = dc.GetTextExtent(self.Condition) + if self.Priority != 0: + priority_size = dc.GetTextExtent(str(self.Priority)) + else: + if self.Type != "connection": + condition_size = self.ConditionSize + if self.Priority != 0: + priority_size = self.PrioritySize + # Draw plain rectangle for representing the transition dc.DrawRectangle(self.Pos.x, self.Pos.y + (self.Size[1] - SFC_TRANSITION_SIZE[1])/2, @@ -824,17 +846,15 @@ dc.DrawLine(vertical_line_x, self.Pos.y, vertical_line_x, self.Pos.y + self.Size[1] + 1) # Draw transition condition if self.Type != "connection": - text_width, text_height = self.ConditionSize if self.Condition != "": condition = self.Condition else: condition = "Transition" dc.DrawText(condition, self.Pos.x + self.Size[0] + 5, - self.Pos.y + (self.Size[1] - text_height) / 2) + self.Pos.y + (self.Size[1] - condition_size[1]) / 2) # Draw priority number if self.Priority != 0: - priority_width, priority_height = self.PrioritySize - dc.DrawText(str(self.Priority), self.Pos.x, self.Pos.y - self.PrioritySize[1] - 2) + dc.DrawText(str(self.Priority), self.Pos.x, self.Pos.y - priority_size[1] - 2) # Draw input and output connectors self.Input.Draw(dc) self.Output.Draw(dc) @@ -1283,7 +1303,7 @@ # Create a new jump def __init__(self, parent, target, id = None): Graphic_Element.__init__(self, parent) - self.Target = target + self.SetTarget(target) self.Id = id self.Size = wx.Size(SFC_JUMP_SIZE[0], SFC_JUMP_SIZE[1]) # Create an input and output connector @@ -1329,6 +1349,10 @@ def Clean(self): self.Input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) + # Refresh the size of text for target + def RefreshTargetSize(self): + self.TargetSize = self.Parent.GetTextExtent(self.Target) + # Refresh the jump bounding box def RefreshBoundingBox(self): text_width, text_height = self.Parent.GetTextExtent(self.Target) @@ -1372,6 +1396,7 @@ # Changes the jump target def SetTarget(self, target): self.Target = target + self.RefreshTargetSize() self.RefreshBoundingBox() # Returns the jump target @@ -1462,6 +1487,12 @@ Graphic_Element.Draw(self, dc) dc.SetPen(wx.BLACK_PEN) dc.SetBrush(wx.BLACK_BRUSH) + + if getattr(dc, "printing", False): + target_size = dc.GetTextExtent(self.Target) + else: + target_size = self.TargetSize + # Draw plain rectangle for representing the divergence dc.DrawLine(self.Pos.x + self.Size[0] / 2, self.Pos.y, self.Pos.x + self.Size[0] / 2, self.Pos.y + self.Size[1]) points = [wx.Point(self.Pos.x, self.Pos.y), @@ -1469,9 +1500,8 @@ wx.Point(self.Pos.x + self.Size[0], self.Pos.y), wx.Point(self.Pos.x + self.Size[0] / 2, self.Pos.y + self.Size[1])] dc.DrawPolygon(points) - text_width, text_height = dc.GetTextExtent(self.Target) dc.DrawText(self.Target, self.Pos.x + self.Size[0] + 2, - self.Pos.y + (self.Size[1] - text_height) / 2) + self.Pos.y + (self.Size[1] - target_size[1]) / 2) # Draw input connector if self.Input: self.Input.Draw(dc)