From 119196f2ff9834b2960c61882e2f6a9c690f4a39 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Mon, 2 Nov 2020 15:27:48 -0500 Subject: [PATCH] Scale level label correctly to small(er) fonts Not sure what fixed it exactly, and I guess we didn't need any relative DPI scaling factor after all. Using the 3px margin on the level label seems to make it look nice for any font size (i think) as well. Gonna need some cleanup after this one. --- piker/ui/_axes.py | 44 ++++++++---------------- piker/ui/_chart.py | 10 +++--- piker/ui/_graphics.py | 26 +++++++------- piker/ui/_style.py | 79 ++++++++++++++++--------------------------- 4 files changed, 60 insertions(+), 99 deletions(-) diff --git a/piker/ui/_axes.py b/piker/ui/_axes.py index b4b910ce..4e4bcb16 100644 --- a/piker/ui/_axes.py +++ b/piker/ui/_axes.py @@ -136,7 +136,9 @@ class AxisLabel(pg.GraphicsObject): self._dpifont = DpiAwareFont() self._dpifont.configure_to_dpi(_font._screen) + if font_size is not None: + # print(f"SETTING FONT TO: {font_size}") self._dpifont._set_qfont_px_size(font_size) # self._font._fm = QtGui.QFontMetrics(self._font) @@ -155,7 +157,7 @@ class AxisLabel(pg.GraphicsObject): def paint(self, p, option, widget): # p.drawPicture(0, 0, self.pic) - p.setCompositionMode(QtGui.QPainter.CompositionMode_SourceOver) + # p.setCompositionMode(QtGui.QPainter.CompositionMode_SourceOver) if self.label_str: @@ -174,13 +176,13 @@ class AxisLabel(pg.GraphicsObject): p.drawText(self.rect, self.text_flags, self.label_str) def boundingRect(self): # noqa - # if self.label_str: - # self._size_br_from_str(self.label_str) - # return self.rect + if self.label_str: + self._size_br_from_str(self.label_str) + return self.rect - # return QtCore.QRectF() + return QtCore.QRectF() - return self.rect or QtCore.QRectF() + # return self.rect or QtCore.QRectF() def _size_br_from_str(self, value: str) -> None: """Do our best to render the bounding rect to a set margin @@ -193,7 +195,7 @@ class AxisLabel(pg.GraphicsObject): # px_per_char = self._font._fm.averageCharWidth() # br = br * 1.88 txt_h, txt_w = br.height(), br.width() - print(f'orig: {txt_h}') + # print(f'orig: {txt_h}') # txt_h = (br.topLeft() - br.bottomRight()).y() # txt_w = len(value) * px_per_char # txt_w *= 1.88 @@ -220,9 +222,6 @@ class AxisLabel(pg.GraphicsObject): class XAxisLabel(AxisLabel): - _w_margin = 0 - _h_margin = 0 - text_flags = ( QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter @@ -246,14 +245,15 @@ class XAxisLabel(AxisLabel): self.label_str = timestrs[0] - width = self.boundingRect().width() + w = self.boundingRect().width() self.setPos(QPointF( - abs_pos.x() - width / 2, # - offset, - 0 + abs_pos.x() - w / 2 - offset, + 0, )) class YAxisLabel(AxisLabel): + _h_margin = 3 text_flags = ( # QtCore.Qt.AlignLeft @@ -280,7 +280,7 @@ class YAxisLabel(AxisLabel): h = br.height() self.setPos(QPointF( 0, - abs_pos.y() - h / 2 #- offset + abs_pos.y() - h / 2 - offset )) @@ -310,22 +310,6 @@ class YSticky(YAxisLabel): last, ) - # chart = self._chart - # a = chart._array - # fields = a.dtype.fields - - # if fields and 'close' in fields: - # index, last = a[-1][['index', 'close']] - - # else: # non-ohlc case - # index = len(a) - 1 - # last = a[chart.name][-1] - - # self.update_from_data( - # index, - # last, - # ) - def update_from_data( self, index: int, diff --git a/piker/ui/_chart.py b/piker/ui/_chart.py index 80c9b369..268c8332 100644 --- a/piker/ui/_chart.py +++ b/piker/ui/_chart.py @@ -18,11 +18,11 @@ from ._graphics import ( CrossHair, ContentsLabel, BarItems, - h_line, + level_line, ) from ._axes import YSticky from ._style import ( - configure_font_to_dpi, + _font, hcolor, CHART_MARGINS, _xaxis_at, @@ -660,7 +660,7 @@ async def _async_main( chart_app = widgets['main'] # attempt to configure DPI aware font size - configure_font_to_dpi(current_screen()) + _font.configure_to_dpi(current_screen()) # from ._exec import get_screen # screen = get_screen(chart_app.geometry().bottomRight()) @@ -898,8 +898,8 @@ async def chart_from_fsp( # graphics.curve.setFillLevel(50) # add moveable over-[sold/bought] lines - chart.plotItem.addItem(h_line(30)) - chart.plotItem.addItem(h_line(70)) + level_line(chart, 30) + level_line(chart, 70) chart._shm = shm chart._set_yrange() diff --git a/piker/ui/_graphics.py b/piker/ui/_graphics.py index 5dafc81b..5281b1a6 100644 --- a/piker/ui/_graphics.py +++ b/piker/ui/_graphics.py @@ -644,6 +644,9 @@ class BarItems(pg.GraphicsObject): class LevelLabel(YSticky): + _w_margin = 3 + _h_margin = 3 + def update_label( self, abs_pos: QPointF, # scene coords @@ -653,17 +656,18 @@ class LevelLabel(YSticky): # this is read inside ``.paint()`` self.label_str = '{data: ,.{digits}f}'.format( - digits=self.digits, data=data).replace(',', ' ') + digits=self.digits, + data=data + ).replace(',', ' ') self._size_br_from_str(self.label_str) br = self.boundingRect() - w, h = br.height(), br.width() + h, w = br.height(), br.width() self.setPos(QPointF( - # *2 why? wat..? - 0 - w*2, - abs_pos.y(), # - h / 2 - offset + -w, + abs_pos.y() - offset )) def size_hint(self) -> Tuple[None, None]: @@ -683,16 +687,12 @@ class LevelLine(pg.InfiniteLine): def set_value(self, value: float) -> None: self.label.update_from_data(0, self.value()) - # def valueChanged(self) -> None: - # print('yooo') - # self.label.update_from_data(0, self.value()) - def level_line( chart: 'ChartPlogWidget', # noqa level: float, - digits: int = 3, - # label_precision: int = 0, + digits: int = 1, + font_size: int = 4, ) -> LevelLine: """Convenience routine to add a styled horizontal line to a plot. @@ -703,11 +703,10 @@ def level_line( # TODO: pass this from symbol data digits=digits, opacity=1, - font_size=4, + font_size=font_size, bg_color='default', ) label.update_from_data(0, level) - # label._size_br_from_str( line = LevelLine( label, @@ -719,7 +718,6 @@ def level_line( # activate/draw label line.setValue(level) - # line.show() chart.plotItem.addItem(line) return line diff --git a/piker/ui/_style.py b/piker/ui/_style.py index 8f1e9425..dba601d0 100644 --- a/piker/ui/_style.py +++ b/piker/ui/_style.py @@ -9,28 +9,6 @@ from ..log import get_logger log = get_logger(__name__) - -# def configure_font_to_dpi(screen: QtGui.QScreen): -# """Set an appropriately sized font size depending on the screen DPI. - -# If we end up needing to generalize this more here there are resources -# listed in the script in ``snippets/qt_screen_info.py``. - -# """ -# dpi = screen.physicalDotsPerInch() -# font_size = round(_font_inches_we_like * dpi) -# log.info( -# f"\nscreen:{screen.name()} with DPI: {dpi}" -# f"\nbest font size is {font_size}\n" -# ) - -# global _font -# _font.setPixelSize(font_size) -# _font._fm = QtGui.QFontMetrics(_font) - -# return _font - - # chart-wide font # font size 6px / 53 dpi (3x scaled down on 4k hidpi) _font_inches_we_like = 6 / 53 # px / (px / inch) = inch @@ -45,9 +23,9 @@ class DpiAwareFont: self._qfont = QtGui.QFont(name) self._iwl = _font_inches_we_like self._qfm = QtGui.QFontMetrics(self._qfont) - self._font_size = None self._physical_dpi = None self._screen = None + self._dpi_scalar = 1. def _set_qfont_px_size(self, px_size: int) -> None: # self._qfont = QtGui.Qfont(self.name) @@ -62,9 +40,6 @@ class DpiAwareFont: def px_size(self): return self._qfont.pixelSize() - # def set_px_size(self, size: int) -> None: - # pass - def configure_to_dpi(self, screen: QtGui.QScreen): """Set an appropriately sized font size depending on the screen DPI. @@ -79,11 +54,12 @@ class DpiAwareFont: f"\nbest font size is {font_size}\n" ) self._set_qfont_px_size(font_size) - self._font_size = font_size self._physical_dpi = dpi self._screen = screen def boundingRect(self, value: str) -> QtCore.QRectF: + # print(f'boundingRect STRING: {value}') + screen = self._screen if screen is None: raise RuntimeError("You must call .configure_to_dpi() first!") @@ -93,31 +69,34 @@ class DpiAwareFont: # XXX: for wtv absolutely fucked reason, the scaling only applies # to everything when the current font size **is not** the size # needed to get the original desired text height... :mindblow: - if self._font_size != 6: - # scalar = self._qfm.fontDpi() / self._physical_dpi - scalar = screen.logicalDotsPerInch() / screen.physicalDotsPerInch() - # scalar = 100 / screen.physicalDotsPerInch() - # assert 0 - print(f'SCALAR {scalar}') + + # if self.px_size != 6: + # # scalar = self._qfm.fontDpi() / self._physical_dpi + # # self._dpi_scalar = scalar = screen.logicalDotsPerInch() / screen.physicalDotsPerInch() + # # self._dpi_scalar = scalar = 96 / screen.physicalDotsPerInch() + # # # assert 0 + # # print(f'SCALAR {scalar}') + # # w = min(self._qfm.averageCharWidth() * len(value), unscaled_br.width()) - return QtCore.QRectF( - # unscaled_br.x(), - # unscaled_br.y(), - 0, - 0, - unscaled_br.width() * scalar, - unscaled_br.height() * scalar, - ) - else: - return QtCore.QRectF( - # unscaled_br.x(), - # unscaled_br.y(), - 0, - 0, - unscaled_br.width(), - unscaled_br.height(), - ) + # return QtCore.QRectF( + # # unscaled_br.x(), + # # unscaled_br.y(), + # 0, + # 0, + # # w * scalar, + # unscaled_br.width(), # * scalar, + # unscaled_br.height(),# * scalar, + # ) + # else: + return QtCore.QRectF( + # unscaled_br.x(), + # unscaled_br.y(), + 0, + 0, + unscaled_br.width(), + unscaled_br.height(), + ) # use pixel size to be cross-resolution compatible? _font = DpiAwareFont()