Revamp/Reimplement the Kis[Int/Double]ParseSpinBox and Kis[Double]SliderSpinBox widgets
This MR reimplements the slider spin box widgets. Following some recent changes by @scottpetrovic to the slider I ended up taking a look at the code and realized that the widgets are created from scratch, inheriting from QWidget. The widgets conceptually are spin boxes, so part of the code was written just to mimic the appearance of a spin box.
In this patch I made a new implementation of the widgets that follows the same interface and that inherits from Kis[Int/Double]ParseSpinBox, which inherit from Q[Double]SpinBox. The benefits are that all the code related to the spin box painting and input handling hasn't to be implemented again.
The code focus in providing the same functionality as the old widgets while just implementing the slider and the change from edit mode to slider mode behaviors.
This is an overview of what the patch provides:
- The widget provides a spin box with a slider-like widget inside that can be dragged to change the value (same as before)
- All the slider related stuff is made by reusing the text edit widget already present in the spin box. In slider mode the events sent to it are intercepted, and in edit mode they don't, making it behave like a regular spin box text field. So no additional dummy widgets are used.
- The widget can enter edit mode in one of these ways:
- By right clicking on the slider area (old behavior)
- By pressing the enter key
- By pressing and holding the left mouse button in the same spot for a period of time determined by Qt. this is useful if you are using a pen with no buttons. If the mouse is moved a certain amount of pixels while pressing and the widget hasn't enter the edit mode yet, then the slider dragging is started and the widget will not enter the edit mode
- The widget can leave the edit mode by pressing enter (accepting the changes) or escape (rejecting the changes). This is the same as the old behavior
- When dragging the slider:
- One can move the pointer far from the widget to change how slow the value is changed. The farther, the slower. This is useful when using a tablet without physical keyboard. When the mouse is inside a certain vertical proximity to the slider this has no effect, and the values change the same when inside that area. When the pointer is far away, a vertical dotted line is drawn in the slider to mark where the user first pressed. The "scaling" of the change in value happens around that point
- The shift key can be used to make the value change slow down even when the pointer is over the widget. This is like the old behavior, but one can move the pointer far from the slider to make the slow down even more pronounced (as in the previous point)
- The control key can be used to snap the values to the multiples of a number set with setFastSliderStep
- When editing the value in the text field, one can use now the context menu of the spin box.
- Since the widget is in fact a spin box, all the style related stuff functions just like in a regular spin box out of the box (for example hovering/pressing/focus/etc. effects)
- By using the Kis[Int/Double]SliderSpinBox as a base, the widget has automatic validation and arithmetic parsing of expressions with no additional code.
- The functionality is extended with a new "soft range" feature. This allows setting a sub-range of the spin box range to be used by the slider. So one can set a range like [min_int, max_int] and a soft range like [-100, 100] and the slider will behave as if the range were [-100, 100] but entering the edit mode one can set any value of the real range. This is a similar feature as the sliders in blender have.
To test this feature I changed some screentone generator sliders to have a soft range (the ones in the transformations tab).
Some screenshots, the first in Breeze style with a light theme and the second in Fussion style with a dark theme:
Formalities Checklist
-
I confirmed this builds. -
I confirmed Krita ran and the relevant functions work. -
I tested the relevant unit tests and can confirm they are not broken. (If not possible, don't hesitate to ask for help!) -
I made sure my commits build individually and have good descriptions as per KDE guidelines. -
I made sure my code conforms to the standards set in the HACKING file. -
I can confirm the code is licensed and attributed appropriately, and that unattributed code is mine, as per KDE Licensing Policy.