From 3bd87caf4b34c858157aabf0893332a37d562cf6 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Mon, 29 Mar 2021 16:01:05 -0400 Subject: [PATCH 1/6] Hip shot: try making low dpi font sizes "just work" --- piker/ui/_axes.py | 4 ++-- piker/ui/_graphics/_lines.py | 41 +++++++++++++++--------------------- piker/ui/_l1.py | 9 +++----- piker/ui/_label.py | 5 ++--- piker/ui/_style.py | 31 +++++++++++++++++---------- 5 files changed, 44 insertions(+), 46 deletions(-) diff --git a/piker/ui/_axes.py b/piker/ui/_axes.py index 72de9f48..18647e70 100644 --- a/piker/ui/_axes.py +++ b/piker/ui/_axes.py @@ -170,10 +170,10 @@ class AxisLabel(pg.GraphicsObject): parent: pg.GraphicsItem, digits: int = 2, - font_size_inches: Optional[float] = None, bg_color: str = 'bracket', fg_color: str = 'black', opacity: int = 1, # XXX: seriously don't set this to 0 + font_size: str = 'default', use_arrow: bool = True, @@ -195,7 +195,7 @@ class AxisLabel(pg.GraphicsObject): self._txt_br: QtCore.QRect = None - self._dpifont = DpiAwareFont(size_in_inches=font_size_inches) + self._dpifont = DpiAwareFont(font_size=font_size) self._dpifont.configure_to_dpi() self.bg_color = pg.mkColor(hcolor(bg_color)) diff --git a/piker/ui/_graphics/_lines.py b/piker/ui/_graphics/_lines.py index 63ca4f53..6277bc3b 100644 --- a/piker/ui/_graphics/_lines.py +++ b/piker/ui/_graphics/_lines.py @@ -27,10 +27,7 @@ from PyQt5.QtCore import QPointF from .._annotate import mk_marker, qgo_draw_markers from .._label import Label, vbr_left, right_axis -from .._style import ( - hcolor, - _down_2_font_inches_we_like, -) +from .._style import hcolor # TODO: probably worth investigating if we can @@ -157,7 +154,6 @@ class LevelLine(pg.InfiniteLine): side_of_axis: str = 'left', x_offset: float = 0, - font_size_inches: float = _down_2_font_inches_we_like, color: str = None, bg_color: str = None, avoid_book: bool = True, @@ -535,9 +531,6 @@ def level_line( level: float, color: str = 'default', - # size 4 font on 4k screen scaled down, so small-ish. - font_size_inches: float = _down_2_font_inches_we_like, - # whether or not the line placed in view should highlight # when moused over (aka "hovered") hl_on_hover: bool = True, @@ -682,21 +675,21 @@ def order_line( llabel.show() else: - # left side label - llabel = line.add_label( - side='left', - fmt_str=' {exec_type}-{order_type}:\n ${$value}', - ) - llabel.fields = { - 'order_type': order_type, - 'level': level, - '$value': lambda f: f['level'] * f['size'], - 'size': size, - 'exec_type': exec_type, - } - llabel.orient_v = orient_v - llabel.render() - llabel.show() + # # left side label + # llabel = line.add_label( + # side='left', + # fmt_str=' {exec_type}-{order_type}:\n ${$value}', + # ) + # llabel.fields = { + # 'order_type': order_type, + # 'level': level, + # '$value': lambda f: f['level'] * f['size'], + # 'size': size, + # 'exec_type': exec_type, + # } + # llabel.orient_v = orient_v + # llabel.render() + # llabel.show() # right before L1 label rlabel = line.add_label( @@ -770,7 +763,7 @@ def position_line( vb.sigYRangeChanged.connect(update_pp_nav) rlabel = line.add_label( - side='left', + side='right', fmt_str='{direction}: {size} -> ${$:.2f}', ) rlabel.fields = { diff --git a/piker/ui/_l1.py b/piker/ui/_l1.py index 02e3a49a..683f46b9 100644 --- a/piker/ui/_l1.py +++ b/piker/ui/_l1.py @@ -25,10 +25,7 @@ from PyQt5 import QtCore, QtGui from PyQt5.QtCore import QPointF from ._axes import YAxisLabel -from ._style import ( - hcolor, - _down_2_font_inches_we_like, -) +from ._style import hcolor class LevelLabel(YAxisLabel): @@ -248,7 +245,7 @@ class L1Labels: chart: 'ChartPlotWidget', # noqa digits: int = 2, size_digits: int = 3, - font_size_inches: float = _down_2_font_inches_we_like, + font_size: str = 'small', ) -> None: self.chart = chart @@ -259,7 +256,7 @@ class L1Labels: 'parent': raxis, 'opacity': 1, - 'font_size_inches': font_size_inches, + 'font_size': font_size, 'fg_color': chart.pen_color, 'bg_color': chart.view_color, } diff --git a/piker/ui/_label.py b/piker/ui/_label.py index fe629c23..8f776279 100644 --- a/piker/ui/_label.py +++ b/piker/ui/_label.py @@ -28,7 +28,6 @@ from PyQt5.QtCore import QPointF, QRectF from ._style import ( DpiAwareFont, hcolor, - _down_2_font_inches_we_like, ) @@ -108,7 +107,7 @@ class Label: fmt_str: str, color: str = 'bracket', x_offset: float = 0, - font_size_inches: float = _down_2_font_inches_we_like, + font_size: str = 'small', opacity: float = 0.666, fields: dict = {} @@ -125,7 +124,7 @@ class Label: # configure font size based on DPI dpi_font = DpiAwareFont( - size_in_inches=font_size_inches + font_size=font_size, ) dpi_font.configure_to_dpi() txt.setFont(dpi_font.font) diff --git a/piker/ui/_style.py b/piker/ui/_style.py index a0232a08..f8f77950 100644 --- a/piker/ui/_style.py +++ b/piker/ui/_style.py @@ -17,7 +17,7 @@ """ Qt UI styling. """ -from typing import Optional +from typing import Optional, Dict import math import pyqtgraph as pg @@ -30,11 +30,16 @@ from ._exec import current_screen log = get_logger(__name__) # chart-wide fonts specified in inches -_default_font_inches_we_like_low_dpi = 6 / 64 -_down_2_font_inches_we_like_low_dpi = 4 / 64 - -_default_font_inches_we_like = 0.0616 # 5 / 96 -_down_2_font_inches_we_like = 0.055 # 4 / 96 +_font_sizes: Dict[str, Dict[str, float]] = { + 'hi': { + 'default': 0.0616, + 'small': 0.055, + }, + 'lo': { + 'default': 6.5 / 64, + 'small': 6 / 64, + }, +} class DpiAwareFont: @@ -42,11 +47,13 @@ class DpiAwareFont: self, # TODO: move to config name: str = 'Hack', - size_in_inches: Optional[float] = None, + font_size: str = 'default', + # size_in_inches: Optional[float] = None, ) -> None: self.name = name self._qfont = QtGui.QFont(name) - self._iwl = size_in_inches or _default_font_inches_we_like + # self._iwl = size_in_inches or _default_font_inches_we_like + self._font_size: str = font_size self._qfm = QtGui.QFontMetrics(self._qfont) self._physical_dpi = None self._screen = None @@ -91,10 +98,12 @@ class DpiAwareFont: dpi = max(pdpi, ldpi) # for low dpi scale everything down - if dpi <= 96: - self._iwl = _default_font_inches_we_like_low_dpi + if dpi <= 97: + inches = _font_sizes['lo'][self._font_size] + else: + inches = _font_sizes['hi'][self._font_size] - font_size = math.floor(self._iwl * dpi) + font_size = math.floor(inches * dpi) log.info( f"\nscreen:{screen.name()} with DPI: {dpi}" f"\nbest font size is {font_size}\n" From 3f7d9c5c15136f1f4f8fc61ed8695cf1e40ed78b Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Wed, 31 Mar 2021 14:24:39 -0400 Subject: [PATCH 2/6] Base axis text offset on dpi-aware font size --- piker/ui/_axes.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/piker/ui/_axes.py b/piker/ui/_axes.py index 18647e70..d7f69742 100644 --- a/piker/ui/_axes.py +++ b/piker/ui/_axes.py @@ -18,8 +18,8 @@ Chart axes graphics and behavior. """ - from typing import List, Tuple, Optional +from math import floor import pandas as pd import pyqtgraph as pg @@ -51,13 +51,24 @@ class Axis(pg.AxisItem): self.linked_charts = linked_charts self._min_tick = min_tick + self._dpi_font = _font self.setTickFont(_font.font) + font_size = self._dpi_font.font.pixelSize() + + if self.orientation in ('bottom',): + text_offset = floor(0.25 * font_size) + + elif self.orientation in ('left', 'right'): + text_offset = floor(font_size / 2) + self.setStyle(**{ 'textFillLimits': [(0, 0.5)], - 'tickFont': _font.font, + 'tickFont': self._dpi_font.font, + # offset of text *away from* axis line in px - 'tickTextOffset': 6, + # use approx. half the font pixel size (height) + 'tickTextOffset': text_offset, }) self.setTickFont(_font.font) @@ -79,17 +90,6 @@ class Axis(pg.AxisItem): class PriceAxis(Axis): - def __init__( - self, - *args, - **kwargs, - ) -> None: - super().__init__(*args, **kwargs) - self.setStyle(**{ - # offset of text *away from* axis line in px - 'tickTextOffset': 9, - }) - def size_to_values(self) -> None: self.setWidth(self.typical_br.width()) @@ -457,7 +457,7 @@ class YAxisLabel(AxisLabel): path = QtGui.QPainterPath() h = self.rect.height() path.moveTo(0, 0) - path.lineTo(-x_offset - 4, h/2.) + path.lineTo(-x_offset - h/4, h/2.) path.lineTo(0, h) path.closeSubpath() self.path = path From 54d36f26f0954fc29f03cccdf33936365920032b Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Wed, 31 Mar 2021 14:25:17 -0400 Subject: [PATCH 3/6] Base anchor contents labels based on dpi-aware font bounding rect --- piker/ui/_graphics/_cursor.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/piker/ui/_graphics/_cursor.py b/piker/ui/_graphics/_cursor.py index 4144e3fd..e13ab20b 100644 --- a/piker/ui/_graphics/_cursor.py +++ b/piker/ui/_graphics/_cursor.py @@ -18,6 +18,7 @@ Mouse interaction graphics """ +import math from typing import Optional, Tuple, Set, Dict import inspect @@ -113,10 +114,6 @@ class LineDot(pg.CurvePoint): return False -# TODO: likely will need to tweak this based on dpi... -_y_margin = 5 - - # TODO: change this into our own ``Label`` class ContentsLabel(pg.LabelItem): """Label anchored to a ``ViewBox`` typically for displaying @@ -132,11 +129,11 @@ class ContentsLabel(pg.LabelItem): # XXX: fyi naming here is confusing / opposite to coords _corner_margins = { - ('top', 'left'): (-4, -_y_margin), - ('top', 'right'): (4, -_y_margin), + ('top', 'left'): (-2, lambda font_size: -font_size*0.25), + ('top', 'right'): (2, lambda font_size: -font_size*0.25), - ('bottom', 'left'): (-4, lambda font_size: font_size + 2*_y_margin), - ('bottom', 'right'): (4, lambda font_size: font_size + 2*_y_margin), + ('bottom', 'left'): (-2, lambda font_size: font_size), + ('bottom', 'right'): (2, lambda font_size: font_size), } def __init__( @@ -147,11 +144,21 @@ class ContentsLabel(pg.LabelItem): font_size: Optional[int] = None, ) -> None: font_size = font_size or _font.font.pixelSize() + super().__init__( justify=justify_text, size=f'{str(font_size)}px' ) + if _font._physical_dpi >= 97: + # ad-hoc scale it based on boundingRect + # TODO: need proper fix for this? + typical_br = _font._qfm.boundingRect('Qyp') + anchor_font_size = math.ceil(typical_br.height() * 1.25) + + else: + anchor_font_size = font_size + # anchor to viewbox self.setParentItem(chart._vb) chart.scene().addItem(self) @@ -163,7 +170,9 @@ class ContentsLabel(pg.LabelItem): ydim = margins[1] if inspect.isfunction(margins[1]): - margins = margins[0], ydim(font_size) + margins = margins[0], ydim(anchor_font_size) + + print(f'margins: {margins}') self.anchor(itemPos=index, parentPos=index, offset=margins) @@ -385,13 +394,12 @@ class Cursor(pg.GraphicsObject): if self._y_label_update: self.graphics[self.active_plot]['yl'].update_label( - abs_pos=plot.mapFromView(QPointF(ix, iy + line_offset)), + abs_pos=plot.mapFromView(QPointF(ix, iy)), value=iy ) # only update horizontal xhair line if label is enabled - self.graphics[plot]['hl'].setY(iy + line_offset) - + self.graphics[plot]['hl'].setY(iy) # update all trackers for item in self._trackers: From 0dfa92230d7ccdd29cc0cd5bb2253d545997ff9e Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Wed, 31 Mar 2021 14:25:51 -0400 Subject: [PATCH 4/6] Size level line markers to dpi aware font size --- piker/ui/_graphics/_lines.py | 39 ++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/piker/ui/_graphics/_lines.py b/piker/ui/_graphics/_lines.py index 6277bc3b..d2c5cf87 100644 --- a/piker/ui/_graphics/_lines.py +++ b/piker/ui/_graphics/_lines.py @@ -18,6 +18,7 @@ Lines for orders, alerts, L2. """ +from math import floor from typing import Tuple, Optional, List import pyqtgraph as pg @@ -27,7 +28,7 @@ from PyQt5.QtCore import QPointF from .._annotate import mk_marker, qgo_draw_markers from .._label import Label, vbr_left, right_axis -from .._style import hcolor +from .._style import hcolor, _font # TODO: probably worth investigating if we can @@ -628,11 +629,17 @@ def order_line( ) if show_markers: + font_size = _font.font.pixelSize() + + # scale marker size with dpi-aware font size + arrow_size = floor(1.375 * font_size) + alert_size = arrow_size * 0.666 + # add arrow marker on end of line nearest y-axis marker_style, marker_size = { - 'buy': ('|<', 20), - 'sell': ('>|', 20), - 'alert': ('v', 12), + 'buy': ('|<', arrow_size), + 'sell': ('>|', arrow_size), + 'alert': ('v', alert_size), }[action] # this fixes it the artifact issue! .. of course, bouding rect stuff @@ -695,7 +702,7 @@ def order_line( rlabel = line.add_label( side='right', side_of_axis='left', - x_offset=3*marker_size + 5, + x_offset=4*marker_size, fmt_str=( '{size:.{size_digits}f} ' ), @@ -739,14 +746,6 @@ def position_line( hide_xhair_on_hover=False, use_marker_margin=True, ) - if size > 0: - arrow_path = mk_marker('|<') - - elif size < 0: - arrow_path = mk_marker('>|') - - line.add_marker(arrow_path) - # hide position marker when out of view (for now) vb = line.getViewBox() @@ -775,6 +774,20 @@ def position_line( rlabel.render() rlabel.show() + # arrow marker + # scale marker size with dpi-aware font size + font_size = _font.font.pixelSize() + + # scale marker size with dpi-aware font size + arrow_size = floor(1.375 * font_size) + + if size > 0: + style = '|<' + elif size < 0: + style = '>|' + + arrow_path = mk_marker(style, size=arrow_size) + line.add_marker(arrow_path) line.set_level(level) # sanity check From f75b3108ceb1b0c6f9597b94abe3d25af6b86650 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Wed, 31 Mar 2021 14:26:13 -0400 Subject: [PATCH 5/6] Size execution arrows to dpi --- piker/ui/_interaction.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/piker/ui/_interaction.py b/piker/ui/_interaction.py index 1f4665f0..06258566 100644 --- a/piker/ui/_interaction.py +++ b/piker/ui/_interaction.py @@ -429,11 +429,14 @@ class ArrowEditor: None: 180, # pointing to right (as in an alert) }[pointing] + # scale arrow sizing to dpi-aware font + size = _font.font.pixelSize() * 0.8 + arrow = pg.ArrowItem( angle=angle, baseAngle=0, - headLen=5*3, - headWidth=2*3, + headLen=size, + headWidth=size/2, tailLen=None, pxMode=True, From d4395dbcbcc2b44aaa5b00e29447e9136cf361ca Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Wed, 31 Mar 2021 14:26:32 -0400 Subject: [PATCH 6/6] Make default view more zooomed in --- piker/ui/_style.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/piker/ui/_style.py b/piker/ui/_style.py index f8f77950..7284a9d1 100644 --- a/piker/ui/_style.py +++ b/piker/ui/_style.py @@ -142,8 +142,8 @@ _xaxis_at = 'bottom' # charting config CHART_MARGINS = (0, 0, 2, 2) _min_points_to_show = 6 -_bars_from_right_in_follow_mode = int(130) -_bars_to_left_in_follow_mode = int(616) +_bars_to_left_in_follow_mode = int(61*6) +_bars_from_right_in_follow_mode = round(0.16 * _bars_to_left_in_follow_mode) _tina_mode = False