Repository: pyqtgraph/pyqtgraph

Issue:
Allow pens to be set for ROI handles and hover
Small tweaks to allow pens to be passed when instantiating an ROI. The `handlePen` is the pen for the handles on the ROI, and `hoverPen` is the pen used while the mouse is hovering over the ROI shape (or its handles; i.e. the shape and its handles share the same hover pen).



Discussion:

Resolving patch:
diff --git a/pyqtgraph/graphicsItems/ROI.py b/pyqtgraph/graphicsItems/ROI.py
--- a/pyqtgraph/graphicsItems/ROI.py
+++ b/pyqtgraph/graphicsItems/ROI.py
@@ -86,6 +86,12 @@ class ROI(GraphicsObject):
                      is generally not necessary to specify the parent.
     pen              (QPen or argument to pg.mkPen) The pen to use when drawing
                      the shape of the ROI.
+    hoverPen         (QPen or argument to mkPen) The pen to use while the
+                     mouse is hovering over the ROI shape.
+    handlePen        (QPen or argument to mkPen) The pen to use when drawing
+                     the ROI handles.
+    handleHoverPen   (QPen or argument to mkPen) The pen to use while the mouse
+                     is hovering over an ROI handle.
     movable          (bool) If True, the ROI can be moved by dragging anywhere 
                      inside the ROI. Default is True.
     rotatable        (bool) If True, the ROI can be rotated by mouse drag + ALT
@@ -128,10 +134,11 @@ class ROI(GraphicsObject):
     sigClicked = QtCore.Signal(object, object)
     sigRemoveRequested = QtCore.Signal(object)
     
-    def __init__(self, pos, size=Point(1, 1), angle=0.0, invertible=False, maxBounds=None, 
-                 snapSize=1.0, scaleSnap=False, translateSnap=False, rotateSnap=False, 
-                 parent=None, pen=None, movable=True, rotatable=True, resizable=True, 
-                 removable=False):
+    def __init__(self, pos, size=Point(1, 1), angle=0.0, invertible=False,
+                 maxBounds=None, snapSize=1.0, scaleSnap=False,
+                 translateSnap=False, rotateSnap=False, parent=None, pen=None,
+                 hoverPen=None, handlePen=None, handleHoverPen=None,
+                 movable=True, rotatable=True, resizable=True, removable=False):
         GraphicsObject.__init__(self, parent)
         self.setAcceptedMouseButtons(QtCore.Qt.NoButton)
         pos = Point(pos)
@@ -145,11 +152,20 @@ def __init__(self, pos, size=Point(1, 1), angle=0.0, invertible=False, maxBounds
         
         self.freeHandleMoved = False ## keep track of whether free handles have moved since last change signal was emitted.
         self.mouseHovering = False
+
         if pen is None:
             pen = (255, 255, 255)
         self.setPen(pen)
-        
-        self.handlePen = QtGui.QPen(QtGui.QColor(150, 255, 255))
+        if hoverPen is None:
+            hoverPen = (255, 255, 0)
+        self.hoverPen = fn.mkPen(hoverPen)
+        if handlePen is None:
+            handlePen = (150, 255, 255)
+        self.handlePen = fn.mkPen(handlePen)
+        if handleHoverPen is None:
+            handleHoverPen = (255, 255, 0)
+        self.handleHoverPen = handleHoverPen
+
         self.handles = []
         self.state = {'pos': Point(0,0), 'size': Point(1,1), 'angle': 0}  ## angle is in degrees for ease of Qt integration
         self.lastState = None
@@ -589,7 +605,8 @@ def addRotateFreeHandle(self, pos, center, axes=None, item=None, name=None, inde
     def addHandle(self, info, index=None):
         ## If a Handle was not supplied, create it now
         if 'item' not in info or info['item'] is None:
-            h = Handle(self.handleSize, typ=info['type'], pen=self.handlePen, parent=self)
+            h = Handle(self.handleSize, typ=info['type'], pen=self.handlePen,
+                       hoverPen=self.handleHoverPen, parent=self)
             info['item'] = h
         else:
             h = info['item']
@@ -735,7 +752,7 @@ def _updateHoverColor(self):
     def _makePen(self):
         # Generate the pen color for this ROI based on its current state.
         if self.mouseHovering:
-            return fn.mkPen(255, 255, 0)
+            return self.hoverPen
         else:
             return self.pen
 
@@ -1273,12 +1290,13 @@ class Handle(UIGraphicsItem):
     sigClicked = QtCore.Signal(object, object)   # self, event
     sigRemoveRequested = QtCore.Signal(object)   # self
     
-    def __init__(self, radius, typ=None, pen=(200, 200, 220), parent=None, deletable=False, activePen=(255, 255, 0)):
+    def __init__(self, radius, typ=None, pen=(200, 200, 220),
+                 hoverPen=(255, 255, 0), parent=None, deletable=False):
         self.rois = []
         self.radius = radius
         self.typ = typ
         self.pen = fn.mkPen(pen)
-        self.activePen = fn.mkPen(activePen)
+        self.hoverPen = fn.mkPen(hoverPen)
         self.currentPen = self.pen
         self.pen.setWidth(0)
         self.pen.setCosmetic(True)
@@ -1308,7 +1326,7 @@ def setDeletable(self, b):
             self.setAcceptedMouseButtons(self.acceptedMouseButtons() | QtCore.Qt.RightButton)
         else:
             self.setAcceptedMouseButtons(self.acceptedMouseButtons() & ~QtCore.Qt.RightButton)
-            
+
     def removeClicked(self):
         self.sigRemoveRequested.emit(self)
 
@@ -1322,7 +1340,7 @@ def hoverEvent(self, ev):
                     hover=True
                     
         if hover:
-            self.currentPen = self.activePen
+            self.currentPen = self.hoverPen
         else:
             self.currentPen = self.pen
         self.update()
@@ -1383,11 +1401,11 @@ def mouseDragEvent(self, ev):
             self.isMoving = True
             self.startPos = self.scenePos()
             self.cursorOffset = self.scenePos() - ev.buttonDownScenePos()
-            self.currentPen = self.activePen
+            self.currentPen = self.hoverPen
             
         if self.isMoving:  ## note: isMoving may become False in mid-drag due to right-click.
             pos = ev.scenePos() + self.cursorOffset
-            self.currentPen = self.activePen
+            self.currentPen = self.hoverPen
             self.movePoint(pos, ev.modifiers(), finish=False)
 
     def movePoint(self, pos, modifiers=QtCore.Qt.KeyboardModifier(), finish=True):


Test patch: