Move marker factory funcs to new mod
							parent
							
								
									55de079320
								
							
						
					
					
						commit
						5610807b8e
					
				| 
						 | 
					@ -0,0 +1,144 @@
 | 
				
			||||||
 | 
					# piker: trading gear for hackers
 | 
				
			||||||
 | 
					# Copyright (C) Tyler Goodlet (in stewardship for piker0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU Affero General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					# (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This program 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 Affero General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU Affero General Public License
 | 
				
			||||||
 | 
					# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					Annotations for ur faces.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from PyQt5 import QtCore, QtGui
 | 
				
			||||||
 | 
					from PyQt5.QtGui import QGraphicsPathItem
 | 
				
			||||||
 | 
					from pyqtgraph import Point, functions as fn, Color
 | 
				
			||||||
 | 
					import numpy as np
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def mk_marker(
 | 
				
			||||||
 | 
					    style,
 | 
				
			||||||
 | 
					    size: float = 20.0,
 | 
				
			||||||
 | 
					    use_qgpath: bool = True,
 | 
				
			||||||
 | 
					) -> QGraphicsPathItem:
 | 
				
			||||||
 | 
					    """Add a marker to be displayed on the line wrapped in a ``QGraphicsPathItem``
 | 
				
			||||||
 | 
					    ready to be placed using scene coordinates (not view).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    **Arguments**
 | 
				
			||||||
 | 
					    style        String indicating the style of marker to add:
 | 
				
			||||||
 | 
					                  ``'<|'``, ``'|>'``, ``'>|'``, ``'|<'``, ``'<|>'``,
 | 
				
			||||||
 | 
					                  ``'>|<'``, ``'^'``, ``'v'``, ``'o'``
 | 
				
			||||||
 | 
					    size          Size of the marker in pixels. Default is 10.0.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    path = QtGui.QPainterPath()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if style == 'o':
 | 
				
			||||||
 | 
					        path.addEllipse(QtCore.QRectF(-0.5, -0.5, 1, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # arrow pointing away-from the top of line
 | 
				
			||||||
 | 
					    if '<|' in style:
 | 
				
			||||||
 | 
					        p = QtGui.QPolygonF([Point(0.5, 0), Point(0, -0.5), Point(-0.5, 0)])
 | 
				
			||||||
 | 
					        path.addPolygon(p)
 | 
				
			||||||
 | 
					        path.closeSubpath()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # arrow pointing away-from the bottom of line
 | 
				
			||||||
 | 
					    if '|>' in style:
 | 
				
			||||||
 | 
					        p = QtGui.QPolygonF([Point(0.5, 0), Point(0, 0.5), Point(-0.5, 0)])
 | 
				
			||||||
 | 
					        path.addPolygon(p)
 | 
				
			||||||
 | 
					        path.closeSubpath()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # arrow pointing in-to the top of line
 | 
				
			||||||
 | 
					    if '>|' in style:
 | 
				
			||||||
 | 
					        p = QtGui.QPolygonF([Point(0.5, -0.5), Point(0, 0), Point(-0.5, -0.5)])
 | 
				
			||||||
 | 
					        path.addPolygon(p)
 | 
				
			||||||
 | 
					        path.closeSubpath()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # arrow pointing in-to the bottom of line
 | 
				
			||||||
 | 
					    if '|<' in style:
 | 
				
			||||||
 | 
					        p = QtGui.QPolygonF([Point(0.5, 0.5), Point(0, 0), Point(-0.5, 0.5)])
 | 
				
			||||||
 | 
					        path.addPolygon(p)
 | 
				
			||||||
 | 
					        path.closeSubpath()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if '^' in style:
 | 
				
			||||||
 | 
					        p = QtGui.QPolygonF([Point(0, -0.5), Point(0.5, 0), Point(0, 0.5)])
 | 
				
			||||||
 | 
					        path.addPolygon(p)
 | 
				
			||||||
 | 
					        path.closeSubpath()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if 'v' in style:
 | 
				
			||||||
 | 
					        p = QtGui.QPolygonF([Point(0, -0.5), Point(-0.5, 0), Point(0, 0.5)])
 | 
				
			||||||
 | 
					        path.addPolygon(p)
 | 
				
			||||||
 | 
					        path.closeSubpath()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # self._maxMarkerSize = max([m[2] / 2. for m in self.markers])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if use_qgpath:
 | 
				
			||||||
 | 
					        path = QGraphicsPathItem(path)
 | 
				
			||||||
 | 
					        path.scale(size, size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def qgo_draw_markers(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    markers: list,
 | 
				
			||||||
 | 
					    color: Color,
 | 
				
			||||||
 | 
					    p: QtGui.QPainter,
 | 
				
			||||||
 | 
					    left: float,
 | 
				
			||||||
 | 
					    right: float,
 | 
				
			||||||
 | 
					    right_offset: float,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					) -> float:
 | 
				
			||||||
 | 
					    """Paint markers in ``pg.GraphicsItem`` style by first
 | 
				
			||||||
 | 
					    removing the view transform for the painter, drawing the markers
 | 
				
			||||||
 | 
					    in scene coords, then restoring the view coords.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    # paint markers in native coordinate system
 | 
				
			||||||
 | 
					    orig_tr = p.transform()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    start = orig_tr.map(Point(left, 0))
 | 
				
			||||||
 | 
					    end = orig_tr.map(Point(right, 0))
 | 
				
			||||||
 | 
					    up = orig_tr.map(Point(left, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dif = end - start
 | 
				
			||||||
 | 
					    # length = Point(dif).length()
 | 
				
			||||||
 | 
					    angle = np.arctan2(dif.y(), dif.x()) * 180 / np.pi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    p.resetTransform()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    p.translate(start)
 | 
				
			||||||
 | 
					    p.rotate(angle)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    up = up - start
 | 
				
			||||||
 | 
					    det = up.x() * dif.y() - dif.x() * up.y()
 | 
				
			||||||
 | 
					    p.scale(1, 1 if det > 0 else -1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    p.setBrush(fn.mkBrush(color))
 | 
				
			||||||
 | 
					    # p.setBrush(fn.mkBrush(self.currentPen.color()))
 | 
				
			||||||
 | 
					    tr = p.transform()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sizes = []
 | 
				
			||||||
 | 
					    for path, pos, size in markers:
 | 
				
			||||||
 | 
					        p.setTransform(tr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # XXX: we drop the "scale / %" placement
 | 
				
			||||||
 | 
					        # x = length * pos
 | 
				
			||||||
 | 
					        x = right_offset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        p.translate(x, 0)
 | 
				
			||||||
 | 
					        p.scale(size, size)
 | 
				
			||||||
 | 
					        p.drawPath(path)
 | 
				
			||||||
 | 
					        sizes.append(size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    p.setTransform(orig_tr)
 | 
				
			||||||
 | 
					    return max(sizes)
 | 
				
			||||||
| 
						 | 
					@ -23,10 +23,9 @@ from typing import Tuple, Optional, List
 | 
				
			||||||
import pyqtgraph as pg
 | 
					import pyqtgraph as pg
 | 
				
			||||||
from pyqtgraph import Point, functions as fn
 | 
					from pyqtgraph import Point, functions as fn
 | 
				
			||||||
from PyQt5 import QtCore, QtGui, QtWidgets
 | 
					from PyQt5 import QtCore, QtGui, QtWidgets
 | 
				
			||||||
from PyQt5.QtGui import QGraphicsPathItem
 | 
					 | 
				
			||||||
from PyQt5.QtCore import QPointF
 | 
					from PyQt5.QtCore import QPointF
 | 
				
			||||||
import numpy as np
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .._annotate import mk_marker, qgo_draw_markers
 | 
				
			||||||
from .._label import Label, vbr_left, right_axis
 | 
					from .._label import Label, vbr_left, right_axis
 | 
				
			||||||
from .._style import (
 | 
					from .._style import (
 | 
				
			||||||
    hcolor,
 | 
					    hcolor,
 | 
				
			||||||
| 
						 | 
					@ -34,123 +33,6 @@ from .._style import (
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def mk_marker(
 | 
					 | 
				
			||||||
    style,
 | 
					 | 
				
			||||||
    size: float = 20.0,
 | 
					 | 
				
			||||||
    use_qgpath: bool = True,
 | 
					 | 
				
			||||||
) -> QGraphicsPathItem:
 | 
					 | 
				
			||||||
    """Add a marker to be displayed on the line wrapped in a ``QGraphicsPathItem``
 | 
					 | 
				
			||||||
    ready to be placed using scene coordinates (not view).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    **Arguments**
 | 
					 | 
				
			||||||
    style        String indicating the style of marker to add:
 | 
					 | 
				
			||||||
                  ``'<|'``, ``'|>'``, ``'>|'``, ``'|<'``, ``'<|>'``,
 | 
					 | 
				
			||||||
                  ``'>|<'``, ``'^'``, ``'v'``, ``'o'``
 | 
					 | 
				
			||||||
    size          Size of the marker in pixels. Default is 10.0.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    path = QtGui.QPainterPath()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if style == 'o':
 | 
					 | 
				
			||||||
        path.addEllipse(QtCore.QRectF(-0.5, -0.5, 1, 1))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # arrow pointing away-from the top of line
 | 
					 | 
				
			||||||
    if '<|' in style:
 | 
					 | 
				
			||||||
        p = QtGui.QPolygonF([Point(0.5, 0), Point(0, -0.5), Point(-0.5, 0)])
 | 
					 | 
				
			||||||
        path.addPolygon(p)
 | 
					 | 
				
			||||||
        path.closeSubpath()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # arrow pointing away-from the bottom of line
 | 
					 | 
				
			||||||
    if '|>' in style:
 | 
					 | 
				
			||||||
        p = QtGui.QPolygonF([Point(0.5, 0), Point(0, 0.5), Point(-0.5, 0)])
 | 
					 | 
				
			||||||
        path.addPolygon(p)
 | 
					 | 
				
			||||||
        path.closeSubpath()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # arrow pointing in-to the top of line
 | 
					 | 
				
			||||||
    if '>|' in style:
 | 
					 | 
				
			||||||
        p = QtGui.QPolygonF([Point(0.5, -0.5), Point(0, 0), Point(-0.5, -0.5)])
 | 
					 | 
				
			||||||
        path.addPolygon(p)
 | 
					 | 
				
			||||||
        path.closeSubpath()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # arrow pointing in-to the bottom of line
 | 
					 | 
				
			||||||
    if '|<' in style:
 | 
					 | 
				
			||||||
        p = QtGui.QPolygonF([Point(0.5, 0.5), Point(0, 0), Point(-0.5, 0.5)])
 | 
					 | 
				
			||||||
        path.addPolygon(p)
 | 
					 | 
				
			||||||
        path.closeSubpath()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if '^' in style:
 | 
					 | 
				
			||||||
        p = QtGui.QPolygonF([Point(0, -0.5), Point(0.5, 0), Point(0, 0.5)])
 | 
					 | 
				
			||||||
        path.addPolygon(p)
 | 
					 | 
				
			||||||
        path.closeSubpath()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if 'v' in style:
 | 
					 | 
				
			||||||
        p = QtGui.QPolygonF([Point(0, -0.5), Point(-0.5, 0), Point(0, 0.5)])
 | 
					 | 
				
			||||||
        path.addPolygon(p)
 | 
					 | 
				
			||||||
        path.closeSubpath()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # self._maxMarkerSize = max([m[2] / 2. for m in self.markers])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if use_qgpath:
 | 
					 | 
				
			||||||
        path = QGraphicsPathItem(path)
 | 
					 | 
				
			||||||
        path.scale(size, size)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def draw_markers(
 | 
					 | 
				
			||||||
    markers: list,
 | 
					 | 
				
			||||||
    color: pg.Color,
 | 
					 | 
				
			||||||
    p: QtGui.QPainter,
 | 
					 | 
				
			||||||
    left: float,
 | 
					 | 
				
			||||||
    right: float,
 | 
					 | 
				
			||||||
    right_offset: float,
 | 
					 | 
				
			||||||
) -> None:
 | 
					 | 
				
			||||||
    """Pain markers in ``pg.GraphicsItem`` style by first
 | 
					 | 
				
			||||||
    removing the view transform for the painter, drawing the markers
 | 
					 | 
				
			||||||
    in scene coords, then restoring the view coords.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    # paint markers in native coordinate system
 | 
					 | 
				
			||||||
    orig_tr = p.transform()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    start = orig_tr.map(Point(left, 0))
 | 
					 | 
				
			||||||
    end = orig_tr.map(Point(right, 0))
 | 
					 | 
				
			||||||
    up = orig_tr.map(Point(left, 1))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dif = end - start
 | 
					 | 
				
			||||||
    # length = Point(dif).length()
 | 
					 | 
				
			||||||
    angle = np.arctan2(dif.y(), dif.x()) * 180 / np.pi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    p.resetTransform()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    p.translate(start)
 | 
					 | 
				
			||||||
    p.rotate(angle)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    up = up - start
 | 
					 | 
				
			||||||
    det = up.x() * dif.y() - dif.x() * up.y()
 | 
					 | 
				
			||||||
    p.scale(1, 1 if det > 0 else -1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    p.setBrush(fn.mkBrush(color))
 | 
					 | 
				
			||||||
    # p.setBrush(fn.mkBrush(self.currentPen.color()))
 | 
					 | 
				
			||||||
    tr = p.transform()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sizes = []
 | 
					 | 
				
			||||||
    for path, pos, size in markers:
 | 
					 | 
				
			||||||
        p.setTransform(tr)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # XXX: we drop the "scale / %" placement
 | 
					 | 
				
			||||||
        # x = length * pos
 | 
					 | 
				
			||||||
        x = right_offset
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        p.translate(x, 0)
 | 
					 | 
				
			||||||
        p.scale(size, size)
 | 
					 | 
				
			||||||
        p.drawPath(path)
 | 
					 | 
				
			||||||
        sizes.append(size)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    p.setTransform(orig_tr)
 | 
					 | 
				
			||||||
    return max(sizes)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TODO: probably worth investigating if we can
 | 
					# TODO: probably worth investigating if we can
 | 
				
			||||||
# make .boundingRect() faster:
 | 
					# make .boundingRect() faster:
 | 
				
			||||||
# https://stackoverflow.com/questions/26156486/determine-bounding-rect-of-line-in-qt
 | 
					# https://stackoverflow.com/questions/26156486/determine-bounding-rect-of-line-in-qt
 | 
				
			||||||
| 
						 | 
					@ -506,7 +388,7 @@ class LevelLine(pg.InfiniteLine):
 | 
				
			||||||
            size = self.markers[0][2]
 | 
					            size = self.markers[0][2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            p.setPen(self.pen)
 | 
					            p.setPen(self.pen)
 | 
				
			||||||
            size = draw_markers(
 | 
					            size = qgo_draw_markers(
 | 
				
			||||||
                self.markers,
 | 
					                self.markers,
 | 
				
			||||||
                self.pen.color(),
 | 
					                self.pen.color(),
 | 
				
			||||||
                p,
 | 
					                p,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue