From 5610807b8efc1716402f0e13b17d2cc698a047d9 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Thu, 18 Mar 2021 16:59:22 -0400 Subject: [PATCH] Move marker factory funcs to new mod --- piker/ui/_annotate.py | 144 +++++++++++++++++++++++++++++++++++ piker/ui/_graphics/_lines.py | 122 +---------------------------- 2 files changed, 146 insertions(+), 120 deletions(-) create mode 100644 piker/ui/_annotate.py diff --git a/piker/ui/_annotate.py b/piker/ui/_annotate.py new file mode 100644 index 00000000..e1711bf1 --- /dev/null +++ b/piker/ui/_annotate.py @@ -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 . + +""" +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) diff --git a/piker/ui/_graphics/_lines.py b/piker/ui/_graphics/_lines.py index 4dadc033..63ca4f53 100644 --- a/piker/ui/_graphics/_lines.py +++ b/piker/ui/_graphics/_lines.py @@ -23,10 +23,9 @@ from typing import Tuple, Optional, List import pyqtgraph as pg from pyqtgraph import Point, functions as fn from PyQt5 import QtCore, QtGui, QtWidgets -from PyQt5.QtGui import QGraphicsPathItem 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 .._style import ( 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 # make .boundingRect() faster: # 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] p.setPen(self.pen) - size = draw_markers( + size = qgo_draw_markers( self.markers, self.pen.color(), p,