diff --git a/piker/ui/_anchors.py b/piker/ui/_anchors.py index 37d0af3a..4a78f375 100644 --- a/piker/ui/_anchors.py +++ b/piker/ui/_anchors.py @@ -18,6 +18,11 @@ Anchor funtions for UI placement of annotions. ''' +from typing import Callable + +from PyQt5.QtCore import QPointF + +from ._label import Label def marker_right_points( @@ -26,8 +31,13 @@ def marker_right_points( marker_size: int = 20, ) -> (float, float, float): + '''Return x-dimension, y-axis-aware, level-line marker oriented scene values. - # chart = self._chart + X values correspond to set the end of a level line, end of + a paried level line marker, and the right most side of the "right" + axis respectively. + + ''' l1_len = chart._max_l1_line_len ryaxis = chart.getAxis('right') @@ -38,3 +48,110 @@ def marker_right_points( line_end = marker_right - (6/16 * marker_size) return line_end, marker_right, r_axis_x + + +def vbr_left( + label: Label, + +) -> Callable[..., float]: + """Return a closure which gives the scene x-coordinate for the + leftmost point of the containing view box. + + """ + return label.vbr().left + + +def right_axis( + + chart: 'ChartPlotWidget', # noqa + label: Label, + + side: str = 'left', + offset: float = 10, + avoid_book: bool = True, + # width: float = None, + +) -> Callable[..., float]: + '''Return a position closure which gives the scene x-coordinate for + the x point on the right y-axis minus the width of the label given + it's contents. + + ''' + ryaxis = chart.getAxis('right') + + if side == 'left': + + if avoid_book: + def right_axis_offset_by_w() -> float: + + # l1 spread graphics x-size + l1_len = chart._max_l1_line_len + + # sum of all distances "from" the y-axis + right_offset = l1_len + label.w + offset + + return ryaxis.pos().x() - right_offset + + else: + def right_axis_offset_by_w() -> float: + + return ryaxis.pos().x() - (label.w + offset) + + return right_axis_offset_by_w + + elif 'right': + + # axis_offset = ryaxis.style['tickTextOffset'][0] + + def on_axis() -> float: + + return ryaxis.pos().x() # + axis_offset - 2 + + return on_axis + + +def update_pp_nav( + + chartview: 'ChartView', # noqa + line: 'LevelLine', # noqa + +) -> None: + '''Show a pp off-screen indicator for a level label. + + This is like in fps games where you have a gps "nav" indicator + but your teammate is outside the range of view, except in 2D, on + the y-dimension. + + ''' + vr = chartview.state['viewRange'] + ymn, ymx = vr[1] + level = line.value() + + marker = line._marker + label = marker.label + + _, marker_right, _ = marker_right_points(line._chart) + + if level > ymx: # pin to top of view + marker.setPos( + QPointF( + marker_right, + marker._height/3, + ) + ) + + elif level < ymn: # pin to bottom of view + + marker.setPos( + QPointF( + marker_right, + chartview.height() - 4/3*marker._height, + ) + ) + + else: + # pp line is viewable so show marker normally + marker.update() + + # re-anchor label (i.e. trigger call of ``arrow_tr()`` from above + label.update() diff --git a/piker/ui/_label.py b/piker/ui/_label.py index e0a4543b..ea1fb4b6 100644 --- a/piker/ui/_label.py +++ b/piker/ui/_label.py @@ -223,61 +223,3 @@ class Label: def delete(self) -> None: self.vb.scene().removeItem(self.txt) - - -# anchoring helper funcs - -def vbr_left(label) -> Callable[..., float]: - """Return a closure which gives the scene x-coordinate for the - leftmost point of the containing view box. - - """ - return label.vbr().left - - -def right_axis( - - chart: 'ChartPlotWidget', # noqa - label: 'Label', # noqa - side: str = 'left', - offset: float = 10, - avoid_book: bool = True, - width: float = None, - -) -> Callable[..., float]: - """Return a position closure which gives the scene x-coordinate for - the x point on the right y-axis minus the width of the label given - it's contents. - - """ - ryaxis = chart.getAxis('right') - - if side == 'left': - - if avoid_book: - def right_axis_offset_by_w() -> float: - - # l1 spread graphics x-size - l1_len = chart._max_l1_line_len - - # sum of all distances "from" the y-axis - right_offset = l1_len + label.w + offset - - return ryaxis.pos().x() - right_offset - - else: - def right_axis_offset_by_w() -> float: - - return ryaxis.pos().x() - (label.w + offset) - - return right_axis_offset_by_w - - elif 'right': - - # axis_offset = ryaxis.style['tickTextOffset'][0] - - def on_axis() -> float: - - return ryaxis.pos().x() # + axis_offset - 2 - - return on_axis diff --git a/piker/ui/_lines.py b/piker/ui/_lines.py index df295b13..9e5fbd9c 100644 --- a/piker/ui/_lines.py +++ b/piker/ui/_lines.py @@ -18,6 +18,7 @@ Lines for orders, alerts, L2. """ +from functools import partial from math import floor from typing import Tuple, Optional, List @@ -27,8 +28,13 @@ from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import QPointF from ._annotate import mk_marker, qgo_draw_markers -from ._anchors import marker_right_points -from ._label import Label, vbr_left, right_axis +from ._anchors import ( + marker_right_points, + vbr_left, + right_axis, + update_pp_nav, +) +from ._label import Label from ._style import hcolor, _font @@ -785,46 +791,6 @@ def position_line( # sanity check line.update_labels({'level': level}) - def update_pp_nav(chartview): - '''Show a pp off-screen indicator when order mode is activated. - - This is like in fps games where you have a gps "nav" indicator - but your teammate is outside the range of view, except in 2D, on - the y-dimension. - ''' - vr = vb.state['viewRange'] - ymn, ymx = vr[1] - level = line.value() - - marker = line._marker - label = marker.label - - _, marker_right, _ = marker_right_points(line._chart) - - if level > ymx: # pin to top of view - marker.setPos( - QPointF( - marker_right, - marker._height/3, - ) - ) - - elif level < ymn: # pin to bottom of view - - marker.setPos( - QPointF( - marker_right, - vb.height() - 4/3*marker._height, - ) - ) - - else: - # pp line is viewable so show marker normally - marker.update() - - # re-anchor label (i.e. trigger call of ``arrow_tr()`` from above - label.update() - - vb.sigRangeChanged.connect(update_pp_nav) + vb.sigRangeChanged.connect(partial(update_pp_nav, chartview=vb, line=line)) return line