Add a dpi aware font wrapper type
parent
307c501763
commit
9e7aa3f9bf
|
@ -1,21 +1,23 @@
|
||||||
"""
|
"""
|
||||||
Chart axes graphics and behavior.
|
Chart axes graphics and behavior.
|
||||||
"""
|
"""
|
||||||
from typing import List, Tuple
|
from typing import List, Tuple, Optional
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
from PyQt5 import QtCore, QtGui
|
from PyQt5 import QtCore, QtGui
|
||||||
from PyQt5.QtCore import QPointF
|
from PyQt5.QtCore import QPointF
|
||||||
|
|
||||||
from ._style import _font, hcolor
|
from ._style import DpiAwareFont, hcolor, _font
|
||||||
from ..data._source import float_digits
|
from ..data._source import float_digits
|
||||||
|
|
||||||
_axis_pen = pg.mkPen(hcolor('bracket'))
|
_axis_pen = pg.mkPen(hcolor('bracket'))
|
||||||
|
|
||||||
|
|
||||||
class Axis(pg.AxisItem):
|
class Axis(pg.AxisItem):
|
||||||
|
"""A better axis that sizes to typical tick contents considering font size.
|
||||||
|
|
||||||
|
"""
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
linked_charts,
|
linked_charts,
|
||||||
|
@ -27,10 +29,10 @@ class Axis(pg.AxisItem):
|
||||||
|
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
self.setTickFont(_font)
|
self.setTickFont(_font.font)
|
||||||
self.setStyle(**{
|
self.setStyle(**{
|
||||||
'textFillLimits': [(0, 0.666)],
|
'textFillLimits': [(0, 0.666)],
|
||||||
'tickFont': _font,
|
'tickFont': _font.font,
|
||||||
# 'tickTextWidth': 100,
|
# 'tickTextWidth': 100,
|
||||||
# 'tickTextHeight': 20,
|
# 'tickTextHeight': 20,
|
||||||
# 'tickTextWidth': 40,
|
# 'tickTextWidth': 40,
|
||||||
|
@ -42,9 +44,9 @@ class Axis(pg.AxisItem):
|
||||||
})
|
})
|
||||||
# self.setLabel(**{'font-size': '10pt'})
|
# self.setLabel(**{'font-size': '10pt'})
|
||||||
|
|
||||||
self.setTickFont(_font)
|
self.setTickFont(_font.font)
|
||||||
self.setPen(_axis_pen)
|
self.setPen(_axis_pen)
|
||||||
self.typical_br = _font._fm.boundingRect(typical_max_str)
|
self.typical_br = _font._qfm.boundingRect(typical_max_str)
|
||||||
|
|
||||||
# size the pertinent axis dimension to a "typical value"
|
# size the pertinent axis dimension to a "typical value"
|
||||||
self.resize()
|
self.resize()
|
||||||
|
@ -92,17 +94,18 @@ class DynamicDateAxis(Axis):
|
||||||
self,
|
self,
|
||||||
indexes: List[int],
|
indexes: List[int],
|
||||||
) -> List[str]:
|
) -> List[str]:
|
||||||
|
|
||||||
bars = self.linked_charts.chart._array
|
bars = self.linked_charts.chart._array
|
||||||
times = bars['time']
|
|
||||||
bars_len = len(bars)
|
bars_len = len(bars)
|
||||||
# delay = times[-1] - times[times != times[-1]][-1]
|
times = bars['time']
|
||||||
delay = times[-1] - times[-2]
|
|
||||||
|
|
||||||
epochs = times[list(
|
epochs = times[list(
|
||||||
map(int, filter(lambda i: i < bars_len, indexes))
|
map(int, filter(lambda i: i < bars_len, indexes))
|
||||||
)]
|
)]
|
||||||
# TODO: **don't** have this hard coded shift to EST
|
# TODO: **don't** have this hard coded shift to EST
|
||||||
dts = pd.to_datetime(epochs, unit='s') # - 4*pd.offsets.Hour()
|
dts = pd.to_datetime(epochs, unit='s') # - 4*pd.offsets.Hour()
|
||||||
|
|
||||||
|
delay = times[-1] - times[-2]
|
||||||
return dts.strftime(self.tick_tpl[delay])
|
return dts.strftime(self.tick_tpl[delay])
|
||||||
|
|
||||||
def tickStrings(self, values: List[float], scale, spacing):
|
def tickStrings(self, values: List[float], scale, spacing):
|
||||||
|
@ -111,9 +114,8 @@ class DynamicDateAxis(Axis):
|
||||||
|
|
||||||
class AxisLabel(pg.GraphicsObject):
|
class AxisLabel(pg.GraphicsObject):
|
||||||
|
|
||||||
_font = _font
|
|
||||||
_w_margin = 0
|
_w_margin = 0
|
||||||
_h_margin = 3
|
_h_margin = 0
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
@ -122,46 +124,62 @@ class AxisLabel(pg.GraphicsObject):
|
||||||
bg_color: str = 'bracket',
|
bg_color: str = 'bracket',
|
||||||
fg_color: str = 'black',
|
fg_color: str = 'black',
|
||||||
opacity: int = 1,
|
opacity: int = 1,
|
||||||
|
font_size: Optional[int] = None,
|
||||||
):
|
):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.opacity = opacity
|
self.opacity = opacity
|
||||||
self.label_str = ''
|
self.label_str = ''
|
||||||
self.digits = digits
|
self.digits = digits
|
||||||
|
|
||||||
self._txt_br: QtCore.QRect = None
|
self._txt_br: QtCore.QRect = None
|
||||||
|
|
||||||
|
self._dpifont = DpiAwareFont()
|
||||||
|
self._dpifont.configure_to_dpi(_font._screen)
|
||||||
|
if font_size is not None:
|
||||||
|
self._dpifont._set_qfont_px_size(font_size)
|
||||||
|
|
||||||
|
# self._font._fm = QtGui.QFontMetrics(self._font)
|
||||||
|
|
||||||
self.bg_color = pg.mkColor(hcolor(bg_color))
|
self.bg_color = pg.mkColor(hcolor(bg_color))
|
||||||
self.fg_color = pg.mkColor(hcolor(fg_color))
|
self.fg_color = pg.mkColor(hcolor(fg_color))
|
||||||
|
|
||||||
self.pic = QtGui.QPicture()
|
# self.pic = QtGui.QPicture()
|
||||||
p = QtGui.QPainter(self.pic)
|
# p = QtGui.QPainter(self.pic)
|
||||||
|
|
||||||
self.rect = None
|
self.rect = None
|
||||||
|
|
||||||
p.setPen(self.fg_color)
|
# p.setPen(self.fg_color)
|
||||||
p.setOpacity(self.opacity)
|
|
||||||
|
|
||||||
self.setFlag(self.ItemIgnoresTransformations)
|
self.setFlag(self.ItemIgnoresTransformations)
|
||||||
|
|
||||||
def paint(self, p, option, widget):
|
def paint(self, p, option, widget):
|
||||||
p.drawPicture(0, 0, self.pic)
|
# p.drawPicture(0, 0, self.pic)
|
||||||
|
p.setCompositionMode(QtGui.QPainter.CompositionMode_SourceOver)
|
||||||
|
|
||||||
if self.label_str:
|
if self.label_str:
|
||||||
|
|
||||||
if not self.rect:
|
if not self.rect:
|
||||||
self._size_br_from_str(self.label_str)
|
self._size_br_from_str(self.label_str)
|
||||||
|
|
||||||
p.setFont(_font)
|
p.setFont(self._dpifont.font)
|
||||||
p.setPen(self.fg_color)
|
p.setPen(self.fg_color)
|
||||||
|
p.setOpacity(self.opacity)
|
||||||
p.fillRect(self.rect, self.bg_color)
|
p.fillRect(self.rect, self.bg_color)
|
||||||
|
|
||||||
# this adds a nice black outline around the label for some odd
|
# this adds a nice black outline around the label for some odd
|
||||||
# reason; ok by us
|
# reason; ok by us
|
||||||
p.drawRect(self.rect)
|
p.drawRect(self.rect)
|
||||||
|
|
||||||
p.drawText(option.rect, self.text_flags, self.label_str)
|
p.drawText(self.rect, self.text_flags, self.label_str)
|
||||||
|
|
||||||
def boundingRect(self): # noqa
|
def boundingRect(self): # noqa
|
||||||
|
# if self.label_str:
|
||||||
|
# self._size_br_from_str(self.label_str)
|
||||||
|
# return self.rect
|
||||||
|
|
||||||
|
# return QtCore.QRectF()
|
||||||
|
|
||||||
return self.rect or QtCore.QRectF()
|
return self.rect or QtCore.QRectF()
|
||||||
|
|
||||||
def _size_br_from_str(self, value: str) -> None:
|
def _size_br_from_str(self, value: str) -> None:
|
||||||
|
@ -169,9 +187,21 @@ class AxisLabel(pg.GraphicsObject):
|
||||||
around provided string contents.
|
around provided string contents.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
txt_br = self._font._fm.boundingRect(value)
|
# size the filled rect to text and/or parent axis
|
||||||
txt_h, txt_w = txt_br.height(), txt_br.width()
|
br = self._txt_br = self._dpifont.boundingRect(value)
|
||||||
|
|
||||||
|
# px_per_char = self._font._fm.averageCharWidth()
|
||||||
|
# br = br * 1.88
|
||||||
|
txt_h, txt_w = br.height(), br.width()
|
||||||
|
print(f'orig: {txt_h}')
|
||||||
|
# txt_h = (br.topLeft() - br.bottomRight()).y()
|
||||||
|
# txt_w = len(value) * px_per_char
|
||||||
|
# txt_w *= 1.88
|
||||||
|
# txt_h *= 1.88
|
||||||
|
# print(f'calced: {txt_h}')
|
||||||
|
|
||||||
h, w = self.size_hint()
|
h, w = self.size_hint()
|
||||||
|
|
||||||
self.rect = QtCore.QRectF(
|
self.rect = QtCore.QRectF(
|
||||||
0, 0,
|
0, 0,
|
||||||
(w or txt_w) + self._w_margin,
|
(w or txt_w) + self._w_margin,
|
||||||
|
@ -190,15 +220,12 @@ class AxisLabel(pg.GraphicsObject):
|
||||||
|
|
||||||
class XAxisLabel(AxisLabel):
|
class XAxisLabel(AxisLabel):
|
||||||
|
|
||||||
_w_margin = 8
|
_w_margin = 0
|
||||||
_h_margin = 0
|
_h_margin = 0
|
||||||
|
|
||||||
text_flags = (
|
text_flags = (
|
||||||
QtCore.Qt.TextDontClip
|
QtCore.Qt.TextDontClip
|
||||||
| QtCore.Qt.AlignCenter
|
| QtCore.Qt.AlignCenter
|
||||||
# | QtCore.Qt.AlignTop
|
|
||||||
# | QtCore.Qt.AlignVCenter
|
|
||||||
# | QtCore.Qt.AlignHCenter
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def size_hint(self) -> Tuple[float, float]:
|
def size_hint(self) -> Tuple[float, float]:
|
||||||
|
@ -211,43 +238,50 @@ class XAxisLabel(AxisLabel):
|
||||||
data: float, # data for text
|
data: float, # data for text
|
||||||
offset: int = 1 # if have margins, k?
|
offset: int = 1 # if have margins, k?
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
timestrs = self.parent._indexes_to_timestrs([int(data)])
|
timestrs = self.parent._indexes_to_timestrs([int(data)])
|
||||||
|
|
||||||
if not timestrs.any():
|
if not timestrs.any():
|
||||||
return
|
return
|
||||||
|
|
||||||
self.label_str = timestrs[0]
|
self.label_str = timestrs[0]
|
||||||
|
|
||||||
width = self.boundingRect().width()
|
width = self.boundingRect().width()
|
||||||
new_pos = QPointF(abs_pos.x() - width / 2 - offset, 0)
|
self.setPos(QPointF(
|
||||||
self.setPos(new_pos)
|
abs_pos.x() - width / 2, # - offset,
|
||||||
|
0
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
class YAxisLabel(AxisLabel):
|
class YAxisLabel(AxisLabel):
|
||||||
|
|
||||||
text_flags = (
|
text_flags = (
|
||||||
QtCore.Qt.AlignLeft
|
# QtCore.Qt.AlignLeft
|
||||||
|
QtCore.Qt.AlignVCenter
|
||||||
| QtCore.Qt.TextDontClip
|
| QtCore.Qt.TextDontClip
|
||||||
| QtCore.Qt.AlignVCenter
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def size_hint(self) -> Tuple[float, float]:
|
def size_hint(self) -> Tuple[float, float]:
|
||||||
# size to parent axis width
|
# size to parent axis width
|
||||||
return None, self.parent.width()
|
return None, self.parent.width()
|
||||||
|
|
||||||
def tick_to_string(self, tick_pos):
|
|
||||||
# WTF IS THIS FORMAT?
|
|
||||||
return ('{: ,.%df}' % self.digits).format(tick_pos).replace(',', ' ')
|
|
||||||
|
|
||||||
def update_label(
|
def update_label(
|
||||||
self,
|
self,
|
||||||
abs_pos: QPointF, # scene coords
|
abs_pos: QPointF, # scene coords
|
||||||
data: float, # data for text
|
data: float, # data for text
|
||||||
offset: int = 1 # if have margins, k?
|
offset: int = 1 # if have margins, k?
|
||||||
) -> None:
|
) -> None:
|
||||||
self.label_str = self.tick_to_string(data)
|
|
||||||
height = self.boundingRect().height()
|
# this is read inside ``.paint()``
|
||||||
new_pos = QPointF(0, abs_pos.y() - height / 2 - offset)
|
self.label_str = '{data: ,.{digits}f}'.format(
|
||||||
self.setPos(new_pos)
|
digits=self.digits, data=data).replace(',', ' ')
|
||||||
|
|
||||||
|
br = self.boundingRect()
|
||||||
|
h = br.height()
|
||||||
|
self.setPos(QPointF(
|
||||||
|
0,
|
||||||
|
abs_pos.y() - h / 2 #- offset
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
class YSticky(YAxisLabel):
|
class YSticky(YAxisLabel):
|
||||||
|
@ -264,29 +298,40 @@ class YSticky(YAxisLabel):
|
||||||
|
|
||||||
self._chart = chart
|
self._chart = chart
|
||||||
chart.sigRangeChanged.connect(self.update_on_resize)
|
chart.sigRangeChanged.connect(self.update_on_resize)
|
||||||
|
self._last_datum = (None, None)
|
||||||
|
|
||||||
def update_on_resize(self, vr, r):
|
def update_on_resize(self, vr, r):
|
||||||
# TODO: add an `.index` to the array data-buffer layer
|
# TODO: add an `.index` to the array data-buffer layer
|
||||||
# and make this way less shitty...
|
# and make this way less shitty...
|
||||||
chart = self._chart
|
index, last = self._last_datum
|
||||||
a = chart._array
|
if index is not None:
|
||||||
fields = a.dtype.fields
|
self.update_from_data(
|
||||||
if fields and 'close' in fields:
|
index,
|
||||||
index, last = a[-1][['index', 'close']]
|
last,
|
||||||
else:
|
)
|
||||||
# non-ohlc case
|
|
||||||
index = len(a) - 1
|
# chart = self._chart
|
||||||
last = a[chart.name][-1]
|
# a = chart._array
|
||||||
self.update_from_data(
|
# fields = a.dtype.fields
|
||||||
index,
|
|
||||||
last,
|
# 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(
|
def update_from_data(
|
||||||
self,
|
self,
|
||||||
index: int,
|
index: int,
|
||||||
value: float,
|
value: float,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
self._last_datum = (index, value)
|
||||||
self.update_label(
|
self.update_label(
|
||||||
self._chart.mapFromView(QPointF(index, value)),
|
self._chart.mapFromView(QPointF(index, value)),
|
||||||
value
|
value
|
||||||
|
|
|
@ -2,46 +2,129 @@
|
||||||
Qt UI styling.
|
Qt UI styling.
|
||||||
"""
|
"""
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
from PyQt5 import QtGui
|
from PyQt5 import QtCore, QtGui
|
||||||
from qdarkstyle.palette import DarkPalette
|
from qdarkstyle.palette import DarkPalette
|
||||||
|
|
||||||
from ..log import get_logger
|
from ..log import get_logger
|
||||||
|
|
||||||
log = get_logger(__name__)
|
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
|
# chart-wide font
|
||||||
# font size 6px / 53 dpi (3x scaled down on 4k hidpi)
|
# font size 6px / 53 dpi (3x scaled down on 4k hidpi)
|
||||||
_font_inches_we_like = 6 / 53
|
_font_inches_we_like = 6 / 53 # px / (px / inch) = inch
|
||||||
|
|
||||||
|
|
||||||
|
class DpiAwareFont:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
name: str = 'Hack',
|
||||||
|
) -> None:
|
||||||
|
self.name = name
|
||||||
|
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
|
||||||
|
|
||||||
|
def _set_qfont_px_size(self, px_size: int) -> None:
|
||||||
|
# self._qfont = QtGui.Qfont(self.name)
|
||||||
|
self._qfont.setPixelSize(px_size)
|
||||||
|
self._qfm = QtGui.QFontMetrics(self._qfont)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def font(self):
|
||||||
|
return self._qfont
|
||||||
|
|
||||||
|
@property
|
||||||
|
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.
|
||||||
|
|
||||||
|
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(self._iwl * dpi)
|
||||||
|
log.info(
|
||||||
|
f"\nscreen:{screen.name()} with DPI: {dpi}"
|
||||||
|
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:
|
||||||
|
screen = self._screen
|
||||||
|
if screen is None:
|
||||||
|
raise RuntimeError("You must call .configure_to_dpi() first!")
|
||||||
|
|
||||||
|
unscaled_br = self._qfm.boundingRect(value)
|
||||||
|
|
||||||
|
# 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}')
|
||||||
|
|
||||||
|
|
||||||
|
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(),
|
||||||
|
)
|
||||||
|
|
||||||
# use pixel size to be cross-resolution compatible?
|
# use pixel size to be cross-resolution compatible?
|
||||||
_font = QtGui.QFont("Hack")
|
_font = DpiAwareFont()
|
||||||
_font.setPixelSize(6) # default
|
|
||||||
|
|
||||||
# TODO: re-compute font size when main widget switches screens?
|
# TODO: re-compute font size when main widget switches screens?
|
||||||
# https://forum.qt.io/topic/54136/how-do-i-get-the-qscreen-my-widget-is-on-qapplication-desktop-screen-returns-a-qwidget-and-qobject_cast-qscreen-returns-null/3
|
# https://forum.qt.io/topic/54136/how-do-i-get-the-qscreen-my-widget-is-on-qapplication-desktop-screen-returns-a-qwidget-and-qobject_cast-qscreen-returns-null/3
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
# _i3_rgba = QtGui.QColor.fromRgbF(*[0.14]*3 + [1])
|
# _i3_rgba = QtGui.QColor.fromRgbF(*[0.14]*3 + [1])
|
||||||
|
|
||||||
# splitter widget config
|
# splitter widget config
|
||||||
|
@ -69,6 +152,7 @@ def hcolor(name: str) -> str:
|
||||||
"""Hex color codes by hipster speak.
|
"""Hex color codes by hipster speak.
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
|
|
||||||
# lives matter
|
# lives matter
|
||||||
'black': '#000000',
|
'black': '#000000',
|
||||||
'erie_black': '#1B1B1B',
|
'erie_black': '#1B1B1B',
|
||||||
|
@ -99,6 +183,9 @@ def hcolor(name: str) -> str:
|
||||||
'vwap_blue': '#0582fb',
|
'vwap_blue': '#0582fb',
|
||||||
'dodger_blue': '#1e90ff', # like the team?
|
'dodger_blue': '#1e90ff', # like the team?
|
||||||
'panasonic_blue': '#0040be', # from japan
|
'panasonic_blue': '#0040be', # from japan
|
||||||
|
# 'bid_blue': '#0077ea', # like the L1
|
||||||
|
'bid_blue': '#3094d9', # like the L1
|
||||||
|
'aquaman': '#39abd0',
|
||||||
|
|
||||||
# traditional
|
# traditional
|
||||||
'tina_green': '#00cc00',
|
'tina_green': '#00cc00',
|
||||||
|
|
Loading…
Reference in New Issue