-
-
Notifications
You must be signed in to change notification settings - Fork 8.8k
frontend: Improve spin box UX #12337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
3bace4a to
478aeca
Compare
|
Moving this out of draft because DoubleSpinboxes are impacted by this weirdness far far more than normal spinboxes and I'd rather not hold up these improvements. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only thing I found unfortunate from a UX point of view was the truncation of digits when an input field is focused.
I'd find it more natural if a value like 540.0 stays 540.0 and is not converted into 540.0000 only to be magically truncated to 540.0 when selecting, because if I want to increase it to 540.0009 I have to add those zeros back in myself.
And I'd be thinking to myself "those decimal places were just there, why are they gone just because I focused that field?" and be annoyed.
PatTheMav
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it wouldn't be simpler to take the current value of the box, remove the expected unit suffix, and then opportunistically attempt to convert the value into the required number format.
If it succeeds, then the value was valid (-540.0, 10, 15.0001), if it fails (as an example --540.0 will throw an exception if used with stod) the string value was invalid and the original value is restored.
In some cases - and this depends on the conversion technique - the converter might try to be as successful as it could be and ignores superfluous characters, so 540--0 becomes 540.0 and likewise 540..0 becomes 540.0 (both tested with libc++'s stod).
After that step you got the most "valid" numerical representation of the string value, which you can then clamp to the valid range and round to the maximum amount of decimals, and use a single output formatting step to pad the value with decimals as needed and that formatter could assume that every number it gets is "valid".
Because as I understand Qt's process here, the validation allows you to intercept the value and update the box with the "correct" one before the next actual paint event.
478aeca to
df67684
Compare
Alright I did some more cleanup and managed to accomplish this despite originally thinking it was going to be impossible or annoyingly difficult (Spoiler: It was the second one). The spinbox will remember the number of decimals that have been input. If the widget has it's value updated programmatically, the displayed decimal precision will reset to what the widget was configured for. If the user pressed Up/Down or PageUp/PageDown to perform a step change to the value, it will adjust the displayed decimal precision to the smaller of: the current value precision or the step values precision. Ex.
I also made a number of adjustments to properly accommodate different locales that have a different decimal separator.
This is how Qt worked already, but unfortunately that process meant converting the text to a double and then putting that text into the box. This meant that after typing This PR effectively intercepts that behaviour and avoids actually updating the
This is how the PR works right now.
Qt more or less handles this already.
The core issue is that updating the |
df67684 to
c724019
Compare
c724019 to
e86a35b
Compare
|
I've been reviewing this today again and found a few bugs:
Also stupid question time: If the spinbox is configured to 2 decimal precision, why is it converted to 2.0000 first (as it would naturally be clamped/rounded to 2.00 per the spinbox configuration)? I did some test runs in other apps, and the common behaviour was that one can type as much wants at the beginning or end of the string (the input field doesn't interfere with the input itself). It is only when the value is submitted (either by pressing Enter or changing input focus) that the value is validated and either rejected (invalid characters, invalid value) or truncated/rounded to the configured value. Most transform boxes in other apps seem to only accept a single decimal place so entering "1920.06" converted back to "1920" and "1920.65" was converted to "1920.6". So the decimal precision of the input element was the ultimate arbiter of the actual value and presented value. How much does that align with your goals? |
Description
This PR introduces a number of changes to spinboxes and entering values into them to improve useability.
Note
These fixes are currently only applied to DoubleSpinBoxes. I still need to do the work for normal SpinBoxes as well. Either through moving most of this work onto a QAbstractSpinBox and inheriting from that, or by creating a SpinBox subclass. Still TBD which one makes more sense but I'd like this tested.
Motivation and Context
Currently typing in spin boxes is very headache inducing due to how Qt handles the restrictions on them. Typing after the decimal is blocked. Deleting a decimal digit automatically appends a 0 to the end of the string, thus still blocking a new value. Typing at the beginning is blocked, and much more. Effectively as soon as Qt is able to parse the text as a valid value, it will auto fill the box and screw up any further input.
Changes:
obs64_e36dRmUhOq.mp4
How Has This Been Tested?
Updated the spinboxes in the properties-views and transform dialog to use these new spinboxes. I have thoroughly tested entering values and deleting from various cursor positions in the Filters window as well as with spinboxes containing suffixes in the transform dialog.
Types of changes
Checklist: