# HG changeset patch # User Laurent Bessard # Date 1369405797 -7200 # Node ID ad09b4a755ce4dfb1ff27b556923d19066eeed33 # Parent dff0a4e408084064743d39fed5eb53e8b26a4835 Move RubberBand from GraphicCommons to individual file diff -r dff0a4e40808 -r ad09b4a755ce graphics/GraphicCommons.py --- a/graphics/GraphicCommons.py Fri May 24 11:17:35 2013 +0200 +++ b/graphics/GraphicCommons.py Fri May 24 16:29:57 2013 +0200 @@ -437,123 +437,6 @@ self.AccessLock.release() #------------------------------------------------------------------------------- -# Viewer Rubberband -#------------------------------------------------------------------------------- - -""" -Class that implements a rubberband -""" - -class RubberBand: - - # Create a rubberband by indicated on which window it must be drawn - def __init__(self, viewer): - self.Viewer = viewer - self.drawingSurface = viewer.Editor - self.Reset() - - # Method that initializes the internal attributes of the rubberband - def Reset(self): - self.startPoint = None - self.currentBox = None - self.lastBox = None - - # Method that return if a box is currently edited - def IsShown(self): - return self.currentBox != None - - # Method that returns the currently edited box - def GetCurrentExtent(self): - if self.currentBox is None: - return self.lastBox - return self.currentBox - - # Method called when a new box starts to be edited - def OnLeftDown(self, event, dc, scaling): - pos = GetScaledEventPosition(event, dc, scaling) - # Save the point for calculate the box position and size - self.startPoint = pos - self.currentBox = wx.Rect(pos.x, pos.y, 0, 0) - self.drawingSurface.SetCursor(wx.StockCursor(wx.CURSOR_CROSS)) - self.Redraw() - - # Method called when dragging with a box edited - def OnMotion(self, event, dc, scaling): - pos = GetScaledEventPosition(event, dc, scaling) - # Save the last position and size of the box for erasing it - self.lastBox = wx.Rect(self.currentBox.x, self.currentBox.y, self.currentBox.width, - self.currentBox.height) - # Calculate new position and size of the box - if pos.x >= self.startPoint.x: - self.currentBox.x = self.startPoint.x - self.currentBox.width = pos.x - self.startPoint.x + 1 - else: - self.currentBox.x = pos.x - self.currentBox.width = self.startPoint.x - pos.x + 1 - if pos.y >= self.startPoint.y: - self.currentBox.y = self.startPoint.y - self.currentBox.height = pos.y - self.startPoint.y + 1 - else: - self.currentBox.y = pos.y - self.currentBox.height = self.startPoint.y - pos.y + 1 - self.Redraw() - - # Method called when dragging is stopped - def OnLeftUp(self, event, dc, scaling): - self.drawingSurface.SetCursor(wx.NullCursor) - self.lastBox = self.currentBox - self.currentBox = None - self.Redraw() - - # Method that erase the last box and draw the new box - def Redraw(self, dc = None): - if dc is None: - dc = self.Viewer.GetLogicalDC() - scalex, scaley = dc.GetUserScale() - dc.SetUserScale(1, 1) - dc.SetPen(wx.Pen(wx.WHITE, 1, wx.DOT)) - dc.SetBrush(wx.TRANSPARENT_BRUSH) - dc.SetLogicalFunction(wx.XOR) - if self.lastBox: - # Erase last box - dc.DrawRectangle(self.lastBox.x * scalex, self.lastBox.y * scaley, - self.lastBox.width * scalex, self.lastBox.height * scaley) - if self.currentBox: - # Draw current box - dc.DrawRectangle(self.currentBox.x * scalex, self.currentBox.y * scaley, - self.currentBox.width * scalex, self.currentBox.height * scaley) - dc.SetUserScale(scalex, scaley) - - # Erase last box - def Erase(self, dc = None): - if dc is None: - dc = self.Viewer.GetLogicalDC() - scalex, scaley = dc.GetUserScale() - dc.SetUserScale(1, 1) - dc.SetPen(wx.Pen(wx.WHITE, 1, wx.DOT)) - dc.SetBrush(wx.TRANSPARENT_BRUSH) - dc.SetLogicalFunction(wx.XOR) - if self.lastBox: - dc.DrawRectangle(self.lastBox.x * scalex, self.lastBox.y * scaley, - self.lastBox.width * scalex, self.lastBox.height * scalex) - dc.SetUserScale(scalex, scaley) - - # Draw current box - def Draw(self, dc = None): - if dc is None: - dc = self.Viewer.GetLogicalDC() - scalex, scaley = dc.GetUserScale() - dc.SetUserScale(1, 1) - dc.SetPen(wx.Pen(wx.WHITE, 1, wx.DOT)) - dc.SetBrush(wx.TRANSPARENT_BRUSH) - dc.SetLogicalFunction(wx.XOR) - if self.currentBox: - # Draw current box - dc.DrawRectangle(self.currentBox.x * scalex, self.currentBox.y * scaley, - self.currentBox.width * scalex, self.currentBox.height * scaley) - dc.SetUserScale(scalex, scaley) - -#------------------------------------------------------------------------------- # Helpers for highlighting text #------------------------------------------------------------------------------- diff -r dff0a4e40808 -r ad09b4a755ce graphics/RubberBand.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphics/RubberBand.py Fri May 24 16:29:57 2013 +0200 @@ -0,0 +1,192 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor +#based on the plcopen standard. +# +#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD +# +#See COPYING file for copyrights details. +# +#This library is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public +#License as published by the Free Software Foundation; either +#version 2.1 of the License, or (at your option) any later version. +# +#This library is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +#General Public License for more details. +# +#You should have received a copy of the GNU General Public +#License along with this library; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import wx + +from graphics.GraphicCommons import GetScaledEventPosition + +#------------------------------------------------------------------------------- +# Viewer RubberBand +#------------------------------------------------------------------------------- + +""" +Class that implements a rubberband for graphic Viewers +""" + +class RubberBand: + + def __init__(self, viewer): + """ + Constructor + @param viewer: Viewer on which rubberband must be drawn + """ + self.Viewer = viewer + + # wx.Panel on which rubberband will be drawn + self.DrawingSurface = viewer.Editor + + self.Reset() + + def Reset(self): + """ + Initialize internal attributes of rubberband + """ + self.StartPoint = None + self.CurrentBBox = None + self.LastBBox = None + + def IsShown(self): + """ + Indicate if rubberband is drawn on viewer + @return: True if rubberband is drawn + """ + return self.CurrentBBox != None + + def GetCurrentExtent(self): + """ + Return the rubberband bounding box + @return: Rubberband bounding box (wx.Rect object) + """ + # In case of rubberband not shown, return the last rubberband + # bounding box + if self.IsShown(): + return self.CurrentBBox + return self.LastBBox + + def OnLeftDown(self, event, dc, scaling): + """ + Called when left mouse is pressed on Viewer. Starts to edit a new + rubberband bounding box + @param event: Mouse event + @param dc: Device Context of Viewer + @param scaling: PLCOpen scaling applied on Viewer + """ + # Save the point where mouse was pressed in Viewer unit, position may + # be modified by scroll and zoom applied on viewer + self.StartPoint = GetScaledEventPosition(event, dc, scaling) + + # Initialize rubberband bounding box + self.CurrentBBox = wx.Rect(self.StartPoint.x, self.StartPoint.y, 0, 0) + + # Change viewer mouse cursor to reflect a rubberband bounding box is + # edited + self.DrawingSurface.SetCursor(wx.StockCursor(wx.CURSOR_CROSS)) + + self.Redraw() + + def OnMotion(self, event, dc, scaling): + """ + Called when mouse is dragging over Viewer. Update the current edited + rubberband bounding box + @param event: Mouse event + @param dc: Device Context of Viewer + @param scaling: PLCOpen scaling applied on Viewer + """ + # Get mouse position in Viewer unit, position may be modified by scroll + # and zoom applied on viewer + pos = GetScaledEventPosition(event, dc, scaling) + + # Save the last bounding box drawn for erasing it later + self.LastBBox = wx.Rect(0, 0, 0, 0) + self.LastBBox.Union(self.CurrentBBox) + + # Calculate new position and size of the box + self.CurrentBBox.x = min(pos.x, self.StartPoint.x) + self.CurrentBBox.y = min(pos.y, self.StartPoint.y) + self.CurrentBBox.width = abs(pos.x - self.StartPoint.x) + 1 + self.CurrentBBox.height = abs(pos.y - self.StartPoint.y) + 1 + + self.Redraw() + + def OnLeftUp(self, event, dc, scaling): + """ + Called when mouse is release from Viewer. Erase the current edited + rubberband bounding box + @param event: Mouse event + @param dc: Device Context of Viewer + @param scaling: PLCOpen scaling applied on Viewer + """ + # Change viewer mouse cursor to default + self.DrawingSurface.SetCursor(wx.NullCursor) + + # Save the last edited bounding box + self.LastBBox = self.CurrentBBox + self.CurrentBBox = None + + self.Redraw() + + def DrawBoundingBoxes(self, bboxes, dc=None): + """ + Draw a list of bounding box on Viewer in the order given using XOR + logical function + @param bboxes: List of bounding boxes to draw on viewer + @param dc: Device Context of Viewer (default None) + """ + # Get viewer Device Context if not given + if dc is None: + dc = self.Viewer.GetLogicalDC() + + # Save current viewer scale factors before resetting them in order to + # avoid rubberband pen to be scaled + scalex, scaley = dc.GetUserScale() + dc.SetUserScale(1, 1) + + # Set DC drawing style + dc.SetPen(wx.Pen(wx.WHITE, style=wx.DOT)) + dc.SetBrush(wx.TRANSPARENT_BRUSH) + dc.SetLogicalFunction(wx.XOR) + + # Draw the bounding boxes using viewer scale factor + for bbox in bboxes: + if bbox is not None: + dc.DrawRectangle( + bbox.x * scalex, bbox.y * scaley, + bbox.width * scalex, bbox.height * scaley) + + # Restore Viewer scale factor + dc.SetUserScale(scalex, scaley) + + def Redraw(self, dc = None): + """ + Redraw rubberband on Viewer + @param dc: Device Context of Viewer (default None) + """ + # Erase last bbox and draw current bbox + self.DrawBoundingBoxes([self.LastBBox, self.CurrentBBox], dc) + + def Erase(self, dc = None): + """ + Erase rubberband from Viewer + @param dc: Device Context of Viewer (default None) + """ + # Erase last bbox + self.DrawBoundingBoxes([self.LastBBox], dc) + + def Draw(self, dc = None): + """ + Draw rubberband on Viewer + @param dc: Device Context of Viewer (default None) + """ + # Erase last bbox and draw current bbox + self.DrawBoundingBoxes([self.CurrentBBox], dc) diff -r dff0a4e40808 -r ad09b4a755ce graphics/__init__.py --- a/graphics/__init__.py Fri May 24 11:17:35 2013 +0200 +++ b/graphics/__init__.py Fri May 24 16:29:57 2013 +0200 @@ -27,4 +27,5 @@ from GraphicCommons import * from FBD_Objects import * from LD_Objects import * -from SFC_Objects import * \ No newline at end of file +from SFC_Objects import * +from RubberBand import RubberBand \ No newline at end of file