-
Notifications
You must be signed in to change notification settings - Fork 8.4k
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
Unify padding parsers, make SUI operate on struct Thickness
#18300
base: main
Are you sure you want to change the base?
Conversation
The code in #17909 was not completely right for padding values with fewer than four components, and it was doing some fragile string math (that is: if you wanted to change the third element in the padding it would parse out the whole thing, edit the third value, and then format it again). This pull request moves the control's padding parser into cppwinrt_utils (for lack of a better place) and makes the settings UI use it to parse the padding out into a `Thickness` as early as possible. Then, the controls operate directly on the Thickness' members rather than parsing the padding string again. To handle two-way serialization properly, we also required a function that converts a thickness back into a reduced string representation (i.e. when all four values are N, it will return "N"). As a bonus, this pull request also: - removes another use of `std::getline` - fixes an issue where resetting the padding would change it (infinitesimally) and cause it to be set again - adds a readout of the current padding value in the expander itself
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.
open Q 2: why would we push Padding down to the Control as a string and force the control to parse it? Why couldn't we just use the Thickness
on the settings model, where it could be serialized with a JsonSerializationHelper and we could generate useful error messages if it was wrong?
const hstring& padding = _GetNewPadding(PaddingDirection::Left, value); | ||
|
||
Padding(padding); | ||
if (std::abs(_parsedPadding.Left - value) >= .0001) |
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.
@lhecker I was so horribly indoctrinated at a young age - this can't STILL be right, can it?
} | ||
// fall through | ||
} | ||
return ::winrt::hstring{ fmt::format(FMT_COMPILE(L"{},{},{},{}"), t.Left, t.Top, t.Right, t.Bottom) }; |
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.
open Q: does this need a width specifier?
padding
parsers, make SUI operate on Thickness
structsThickness
wchar_t buf[17]; | ||
for (const auto& token : til::split_iterator{ padding, L',' }) | ||
{ | ||
const auto l{ std::min(token.size(), std::extent_v<decltype(buf)> - 1) }; |
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.
You can use std::size(buf)
here. But I think we can also just use a std::wstring
. The primary cost of a std::wstring
if any is the heap allocation and we can just reuse the object instance.
std::copy_n(token.data(), l, &buf[0]); // the length of buf is controlled for above | ||
til::at(buf, l) = L'\0'; | ||
til::at(t, count++) = std::wcstod(&buf[0], nullptr); |
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 believe this would need to do error checking to filter invalid inputs. Converters::MaxValueFromPaddingString
above does it. Now that I think about it, you could even merge both functions by creating one that returns a std::array<double, 4>
. 🤔
#pragma warning(push) | ||
#pragma warning(disable : 26446) // Prefer to use gsl::at() instead of unchecked subscript operator (bounds.4). |
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.
Meh warning. I wish it would just check and see if the subscript index is constant...
The code in #17909 was not completely right for padding values with fewer than four components, and it was doing some fragile string math (that is: if you wanted to change the third element in the padding it would parse out the whole thing, edit the third value, and then format it again).
This pull request moves the control's padding parser into cppwinrt_utils (for lack of a better place) and makes the settings UI use it to parse the padding out into a
Thickness
as early as possible. Then, the controls operate directly on the Thickness' members rather than parsing the padding string again.To handle two-way serialization properly, we also required a function that converts a thickness back into a reduced string representation (i.e. when all four values are N, it will return "N").
As a bonus, this pull request also:
std::getline