65 lines
2.1 KiB
Python
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))
|