auto-sd-paint-ext/frontends/krita/krita_diff/widgets/spin_box.py

65 lines
2.1 KiB
Python

from functools import partial
from math import isclose
from typing import Union
from krita import QDoubleSpinBox, QHBoxLayout, QSpinBox
from ..config import Config
from .misc import QLabel
class QSpinBoxLayout(QHBoxLayout):
def __init__(
self,
cfg: Config,
field_cfg: str,
label: str = None,
min: Union[int, float] = 0.0,
max: Union[int, float] = 1.0,
step: Union[int, float] = 0.1,
*args,
**kwargs
):
"""Layout for labelled QSpinBox/QDoubleSpinBox.
Will infer which to use based on type of min, max and step.
Args:
cfg (Config): Config to connect to.
field_cfg (str): Config key to read/write value to.
label (str, optional): Label, uses `field_cfg` if None. Defaults to None.
min (Union[int, float], optional): Min value. Defaults to 0.0.
max (Union[int, float], optional): Max value. Defaults to 1.0.
step (Union[int, float], optional): Value step. Defaults to 0.1.
"""
super(QSpinBoxLayout, self).__init__(*args, **kwargs)
self.cfg = cfg
self.field_cfg = field_cfg
self.qlabel = QLabel(field_cfg if label is None else label)
is_integer = (
float(step).is_integer()
and float(min).is_integer()
and float(max).is_integer()
)
self.cast = int if is_integer else float
self.qspin = QSpinBox() if is_integer else QDoubleSpinBox()
self.qspin.setMinimum(self.cast(min))
self.qspin.setMaximum(self.cast(max))
self.qspin.setSingleStep(self.cast(step))
self.addWidget(self.qlabel)
self.addWidget(self.qspin)
def cfg_init(self):
val = self.cfg(self.field_cfg, self.cast)
cur = self.qspin.value()
# prevent cursor from jumping when cfg_init is called by update
if not isclose(val, cur):
self.qspin.setValue(self.cfg(self.field_cfg, self.cast))
def cfg_connect(self):
self.qspin.valueChanged.connect(partial(self.cfg.set, self.field_cfg))