Repository navigation
compound: optional step on a numeric binding - #28
Merged
Merged
Conversation
A binding maps an attribute to a property linearly - scale * x + offset - which is right for a continuous control and wrong for a segmented one. A meter drawn as discrete LED segments, a knob that should land on detents, a stepped bar: all of them need the *display* quantised while the attribute stays continuous, and that was not expressible. The alternative was quantising at the source, which changes the value everything else reads. `step` on CompoundBinding snaps the attribute value to the nearest multiple before the linear map, so one step is the same fraction of the range whatever the property it drives is measured in. 0 (the default) is smooth, so every existing binding is untouched. There is no bind-with-step entry point in the vtable and this needs none: the step travels through the existing float setter as "<prop>.step" (e.g. "width.step"), the same route stroke_dasharray takes to travel as a string. It is also kept in a per-layer bind_steps map, so setting it before the bind - or re-binding the prop afterwards - does not lose it, and setting it on an unbound prop cannot conjure a phantom binding that would read attribute "" as 0. The loader parses "step" inside a bind object and the serializer emits it when non-zero, so a component document round-trips. Tests cover the quantisation itself (rounding at the halfway point, reaching the full range, step 0 leaving the value alone), both setter orders plus the re-bind, and the document round-trip.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A binding maps an attribute to a property linearly -
scale * x + offset- whichis right for a continuous control and wrong for a segmented one. A meter drawn as
discrete LED segments, a knob that should land on detents, a stepped bar: all of
them need the display quantised while the attribute stays continuous, and that
was not expressible. The alternative was quantising at the source, which changes
the value everything else reads.
steponCompoundBindingsnaps the attribute value to the nearest multiplebefore the linear map, so one step is the same fraction of the range whatever the
property it drives is measured in.
0(the default) is smooth, so every existingbinding is untouched.
No ABI change
There is no bind-with-step entry point in the vtable and this needs none: the step
travels through the existing float setter as
"<prop>.step"(e.g."width.step"),the same route
stroke_dasharraytakes to travel as a string. It is also kept in aper-layer
bind_stepsmap, so setting it before the bind - or re-binding the propafterwards - does not lose it, and setting it on an unbound prop cannot conjure a
phantom binding that would read attribute
""as 0.The loader parses
"step"inside a bind object and the serializer emits it whennon-zero, so a component document round-trips.
Files
hosts/shared/compound.h- the field, the quantisation ineval_binding_float,the
"<prop>.step"setter, andapply_bindpreserving it.hosts/shared/component_loader.h- parse + emit.include/neui/d/compound.h- the prop and thebindsemantics documented.tests/- the quantisation itself (rounding at the halfway point, reaching thefull range,
step 0leaving the value alone), both setter orders plus there-bind, and the document round-trip.
Testing
neui_tests: 317 cases / 1863 checks pass, 4 of them new.