Improve styling and logging for UI font-size zoom

Refine zoom methods in `MainWindow` and font helpers
in `_style` to return `px_size` up the call chain and
log detailed zoom state on each change.

Deats,
- make `_set_qfont_px_size()` return `self.px_size`.
- make `configure_to_dpi()` and `_config_fonts_to_screen()`
  return the new `px_size` up through the call chain.
- add `font_size` to `log.info()` in `zoom_in()`,
  `zoom_out()`, and `reset_zoom()` alongside
  `zoom_step` and `zoom_level(%)`.
- reformat `has_ctrl`/`_has_shift` bitwise checks and
  key-match tuples to multiline style.
- comment out `Shift` modifier requirement for zoom
  hotkeys (now `Ctrl`-only).
- comment out unused `mn_dpi` and `dpi` locals.

Also,
- convert all single-line docstrings to `'''` multiline
  style across zoom and font methods.
- rewrap `configure_to_dpi()` docstring to 67 chars.
- move `from . import _style` to module-level import
  in `_window.py`.
- drop unused `screen` binding in `boundingRect()`.

(this commit msg was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
dpi-font-auto-calc_goodboy_test
Gud Boi 2026-03-11 19:07:38 -04:00
parent c5364c0440
commit a32ffb75f2
2 changed files with 120 additions and 39 deletions

View File

@ -79,9 +79,13 @@ class DpiAwareFont:
self._font_inches: float = None self._font_inches: float = None
self._screen = None self._screen = None
def _set_qfont_px_size(self, px_size: int) -> None: def _set_qfont_px_size(
self,
px_size: int,
) -> int:
self._qfont.setPixelSize(int(px_size)) self._qfont.setPixelSize(int(px_size))
self._qfm = QtGui.QFontMetrics(self._qfont) self._qfm = QtGui.QFontMetrics(self._qfont)
return self.px_size
@property @property
def screen(self) -> QtGui.QScreen: def screen(self) -> QtGui.QScreen:
@ -128,17 +132,18 @@ class DpiAwareFont:
self, self,
screen: QtGui.QScreen | None = None, screen: QtGui.QScreen | None = None,
zoom_level: float = 1.0, zoom_level: float = 1.0,
): ) -> int:
''' '''
Set an appropriately sized font size depending on the screen DPI. Set an appropriately sized font size depending on the screen DPI
or scale the size according to `zoom_level`.
If we end up needing to generalize this more here there are resources If we end up needing to generalize this more here there are
listed in the script in ``snippets/qt_screen_info.py``. resources listed in the script in
``snippets/qt_screen_info.py``.
''' '''
if self._font_size is not None: if self._font_size is not None:
self._set_qfont_px_size(self._font_size * zoom_level) return self._set_qfont_px_size(self._font_size * zoom_level)
return
# NOTE: if no font size set either in the [ui] section of the # NOTE: if no font size set either in the [ui] section of the
# config or not yet computed from our magic scaling calcs, # config or not yet computed from our magic scaling calcs,
@ -157,7 +162,7 @@ class DpiAwareFont:
ldpi = pdpi ldpi = pdpi
mx_dpi = max(pdpi, ldpi) mx_dpi = max(pdpi, ldpi)
mn_dpi = min(pdpi, ldpi) # mn_dpi = min(pdpi, ldpi)
scale = round(ldpi/pdpi, ndigits=2) scale = round(ldpi/pdpi, ndigits=2)
if mx_dpi <= 97: # for low dpi use larger font sizes if mx_dpi <= 97: # for low dpi use larger font sizes
@ -166,7 +171,7 @@ class DpiAwareFont:
else: # hidpi use smaller font sizes else: # hidpi use smaller font sizes
inches = _font_sizes['hi'][self._font_size_calc_key] inches = _font_sizes['hi'][self._font_size_calc_key]
dpi = mn_dpi # dpi = mn_dpi
mult = 1.0 mult = 1.0
@ -213,10 +218,10 @@ class DpiAwareFont:
f"\nOur best guess font size is {font_size}\n" f"\nOur best guess font size is {font_size}\n"
) )
# apply the size # apply the size
self._set_qfont_px_size(font_size) return self._set_qfont_px_size(font_size)
def boundingRect(self, value: str) -> QtCore.QRectF: def boundingRect(self, value: str) -> QtCore.QRectF:
if (screen := self.screen) is None: if self.screen is None:
raise RuntimeError("You must call .configure_to_dpi() first!") raise RuntimeError("You must call .configure_to_dpi() first!")
unscaled_br: QtCore.QRectF = self._qfm.boundingRect(value) unscaled_br: QtCore.QRectF = self._qfm.boundingRect(value)
@ -233,12 +238,22 @@ _font = DpiAwareFont()
_font_small = DpiAwareFont(_font_size_key='small') _font_small = DpiAwareFont(_font_size_key='small')
def _config_fonts_to_screen(zoom_level: float = 1.0) -> None: def _config_fonts_to_screen(
'configure global DPI aware font sizes' zoom_level: float = 1.0
) -> int:
'''
Configure global DPI aware font size(s).
If `zoom_level` is provided we apply it to auto-calculated
DPI-aware font.
Return the new `DpiAwareFont.px_size`.
'''
global _font, _font_small global _font, _font_small
_font.configure_to_dpi(zoom_level=zoom_level) _font.configure_to_dpi(zoom_level=zoom_level)
_font_small.configure_to_dpi(zoom_level=zoom_level) _font_small.configure_to_dpi(zoom_level=zoom_level)
return _font.px_size
def get_fonts() -> tuple[ def get_fonts() -> tuple[

View File

@ -43,7 +43,11 @@ from piker.ui.qt import (
QObject, QObject,
) )
from ..log import get_logger from ..log import get_logger
from ._style import _font_small, hcolor from . import _style
from ._style import (
_font_small,
hcolor,
)
from ._widget import GodWidget from ._widget import GodWidget
@ -73,6 +77,7 @@ class GlobalZoomEventFilter(QObject):
Filter keyboard events for global zoom shortcuts. Filter keyboard events for global zoom shortcuts.
Returns True to filter out (consume) the event, False to pass through. Returns True to filter out (consume) the event, False to pass through.
''' '''
if event.type() == QEvent.Type.KeyPress: if event.type() == QEvent.Type.KeyPress:
key = event.key() key = event.key()
@ -82,28 +87,49 @@ class GlobalZoomEventFilter(QObject):
mods = mods & ~Qt.KeyboardModifier.KeypadModifier mods = mods & ~Qt.KeyboardModifier.KeypadModifier
# Check if we have Ctrl+Shift (both required) # Check if we have Ctrl+Shift (both required)
has_ctrl = bool(mods & Qt.KeyboardModifier.ControlModifier) has_ctrl = bool(
has_shift = bool(mods & Qt.KeyboardModifier.ShiftModifier) mods
&
Qt.KeyboardModifier.ControlModifier
)
_has_shift = bool(
mods
&
Qt.KeyboardModifier.ShiftModifier
)
# Only handle UI zoom if BOTH Ctrl and Shift are pressed # Only handle UI zoom if BOTH Ctrl and Shift are pressed
# For Plus key: user presses Cmd+Shift+Equal (which makes Plus) # For Plus key: user presses Cmd+Shift+Equal (which makes Plus)
# For Minus key: user presses Cmd+Shift+Minus # For Minus key: user presses Cmd+Shift+Minus
if has_ctrl and has_shift: if (
has_ctrl
# and
# has_shift
):
# Zoom in: Ctrl+Shift+Plus # Zoom in: Ctrl+Shift+Plus
# Note: Plus key usually comes as Key_Equal with Shift modifier # Note: Plus key usually comes as Key_Equal with Shift modifier
if key in (Qt.Key.Key_Plus, Qt.Key.Key_Equal): if key in (
Qt.Key.Key_Plus,
Qt.Key.Key_Equal,
):
self.main_window.zoom_in() self.main_window.zoom_in()
return True # consume event return True # consume event
# Zoom out: Ctrl+Shift+Minus # Zoom out: Ctrl+Shift+Minus
# Note: On some keyboards Shift+Minus produces '_' (Underscore) # Note: On some keyboards Shift+Minus produces '_' (Underscore)
elif key in (Qt.Key.Key_Minus, Qt.Key.Key_Underscore): elif key in (
Qt.Key.Key_Minus,
Qt.Key.Key_Underscore,
):
self.main_window.zoom_out() self.main_window.zoom_out()
return True # consume event return True # consume event
# Reset zoom: Ctrl+Shift+0 # Reset zoom: Ctrl+Shift+0
# Note: On some keyboards Shift+0 produces ')' (ParenRight) # Note: On some keyboards Shift+0 produces ')' (ParenRight)
elif key in (Qt.Key.Key_0, Qt.Key.Key_ParenRight): elif key in (
Qt.Key.Key_0,
Qt.Key.Key_ParenRight,
):
self.main_window.reset_zoom() self.main_window.reset_zoom()
return True # consume event return True # consume event
@ -444,34 +470,69 @@ class MainWindow(QMainWindow):
event.accept() event.accept()
def zoom_in(self) -> None: def zoom_in(self) -> None:
'''Increase UI zoom level.''' '''
new_zoom = min(self._zoom_level + self._zoom_step, self._max_zoom) Increase overall UI-widgets zoom level by scaling it the
if new_zoom != self._zoom_level: global font sizes.
self._zoom_level = new_zoom
self._apply_zoom()
log.info(f'Zoomed in to {self._zoom_level:.1%}')
def zoom_out(self) -> None: '''
'''Decrease UI zoom level.''' new_zoom: float = min(
new_zoom = max(self._zoom_level - self._zoom_step, self._min_zoom) self._zoom_level + self._zoom_step,
self._max_zoom,
)
if new_zoom != self._zoom_level: if new_zoom != self._zoom_level:
self._zoom_level = new_zoom self._zoom_level = new_zoom
self._apply_zoom() font_size: int = self._apply_zoom()
log.info(f'Zoomed out to {self._zoom_level:.1%}') log.info(
f'Zoomed in UI\n'
f'zoom_step: {self._zoom_step!r}\n'
f'zoom_level(%): {self._zoom_level:.1%}\n'
f'font_size: {font_size!r}'
)
def zoom_out(self) -> float:
'''
Decrease UI zoom level.
'''
new_zoom: float = max(self._zoom_level - self._zoom_step, self._min_zoom)
if new_zoom != self._zoom_level:
self._zoom_level = new_zoom
font_size: int = self._apply_zoom()
log.info(
f'Zoomed out UI\n'
f'zoom_step: {self._zoom_step!r}\n'
f'zoom_level(%): {self._zoom_level:.1%}\n'
f'font_size: {font_size!r}'
)
return new_zoom
def reset_zoom(self) -> None: def reset_zoom(self) -> None:
'''Reset UI zoom to 100%.''' '''
Reset UI zoom to 100%.
'''
if self._zoom_level != 1.0: if self._zoom_level != 1.0:
self._zoom_level = 1.0 self._zoom_level = 1.0
self._apply_zoom() font_size: int = self._apply_zoom()
log.info('Reset zoom to 100%') log.info(
f'Reset zoom level\n'
f'zoom_step: {self._zoom_step!r}\n'
f'zoom_level(%): {self._zoom_level:.1%}\n'
f'font_size: {font_size!r}'
)
def _apply_zoom(self) -> None: return self._zoom_level
'''Apply current zoom level to all UI elements.'''
from . import _style
def _apply_zoom(self) -> int:
'''
Apply current zoom level to all UI elements.
'''
# reconfigure fonts with zoom multiplier # reconfigure fonts with zoom multiplier
_style._config_fonts_to_screen(zoom_level=self._zoom_level) font_size: int = _style._config_fonts_to_screen(
zoom_level=self._zoom_level
)
# update status bar styling with new font size # update status bar styling with new font size
if self._status_bar: if self._status_bar:
@ -500,8 +561,13 @@ class MainWindow(QMainWindow):
self._refresh_widget_fonts(self.godwidget) self._refresh_widget_fonts(self.godwidget)
self.godwidget.update() self.godwidget.update()
return font_size
def _update_chart_order_panes(self) -> None: def _update_chart_order_panes(self) -> None:
'''Update order entry panels in all charts.''' '''
Update order entry panels in all charts.
'''
if not self.godwidget: if not self.godwidget:
return return