Skip to content
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

Updated Pack property names to match CSS #3033

Merged
merged 17 commits into from
Dec 15, 2024

Conversation

HalfWhitt
Copy link
Contributor

@HalfWhitt HalfWhitt commented Dec 9, 2024

@mhsmith pointed out in #3011 that the padding (et al) and alignment Pack properties would be better named margin and align_items, to match their corresponding CSS properties. I've renamed them throughout the codebase, and set up an aliasing system for backwards compatibility (with tests). I've also taken the liberty of clarifying the name of text alignment whenever I encountered it in my searching-and-replacing.

PR Checklist:

  • All new features have been tested
  • All new features have been documented
  • I have read the CONTRIBUTING.md file
  • I will abide by the code of conduct

@HalfWhitt HalfWhitt marked this pull request as ready for review December 9, 2024 06:19
Copy link
Member

@freakboy3742 freakboy3742 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a whole lot of changes, but it's mostly a mechanical search and replace.

A couple of minor typos in docs flagged inline.

The only issue of substance is the set of allowed values for align-items. If we're going to the effort to ensure that we're using a "true" CSS subset, it seems like we should also be correcting the inconsistency in the allowed values. This would have the added benefit of removing the ambiguity around the interpretation with direction.

@@ -56,12 +60,12 @@
DISPLAY_CHOICES = Choices(PACK, NONE)
VISIBILITY_CHOICES = Choices(VISIBLE, HIDDEN)
DIRECTION_CHOICES = Choices(ROW, COLUMN)
ALIGNMENT_CHOICES = Choices(LEFT, RIGHT, TOP, BOTTOM, CENTER)
ALIGN_ITEMS_CHOICES = Choices(LEFT, RIGHT, TOP, BOTTOM, CENTER)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's worth noting that these aren't valid values for CSS3-flexbox align_items.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we implement this by simply making left and top aliases for start, and right and bottom aliases for end? This would be a change in the current documented behavior:

If a value is provided, but the value isn’t honored, the alignment reverts to the default for the direction.

But any code that's setting invalid alignment options is broken anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an edge case if the direction is RTL as well (left and start aren't analogs if direction=RTL) - but I think I could live with both of those inconsistencies as long as using the old names raises an appropriate warning on first use.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't had time to get to it yet, but for maximum compatibility, what I envisioned was only storing whichever version was set last — alignment with directions, or align_items with start/center/end. Then if the same one is requested, return that, but if the other is requested, compute it based on the set value and the current row/column direction and RTL/LTR direction.

Copy link
Member

@mhsmith mhsmith Dec 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's possible to make align_items the single source of truth, while keeping full compatibility with the current alignment behavior:

  • In the alignment setter, check the current direction and text_direction, and transform top, bottom, left or right to start or end according to the current behavior. In particular, this means that setting alignment="bottom" when direction="column" will result in align_items="start", which is "the default for the direction".

  • In the alignment getter, do the reverse transformation, which is simpler.

As discussed in #1194, there are some bugs in the layout algorithm. For example, the actual default alignment is sometimes start and sometimes what CSS calls stretch, and center doesn't always work. I'm working on fixing this in another branch which I'll stack on top of this one, so please don't make any structural changes to the layout algorithm beyond renaming the attributes.

Copy link
Member

@mhsmith mhsmith Dec 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the alignment setter, check the current direction and text_direction

I guess this also means that when setting multiple properties at once, either via the constructor or via update, we must make sure to set direction and text_direction before alignment. Code that sets the properties individually may experience a change in behavior, but I think that should be rare enough that we can accept it, especially since we're planning a version number bump to 0.5.0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But what if existing code sets alignment and then changes direction or text_direction? This is why I think it's safer to just preserve the existing behavior for the old name. And if align_items is requested while alignment is currently an invalid value for the current direction/text_direction, then align_items can read as not having been set.

As discussed in #1194, there are some bugs in the layout algorithm. For example, the actual default alignment is sometimes start and sometimes what CSS calls stretch, and center doesn't always work. I'm working on fixing this in another branch which I'll stack on top of this one, so please don't make any structural changes to the layout algorithm beyond renaming the attributes.

Thanks for the heads up! I was looking at potentially merging the nearly-identical row and column layout methods, either here or in a second PR, but will avoid mucking about with any of that for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for maximum compatibility, what I envisioned was only storing whichever version was set last. [...] Then if the same one is requested, return that, but if the other is requested, compute it

It would be more complex that way, but I guess it's the only way to achieve 100% backward compatibility. Either approach is OK with me.

docs/reference/api/containers/box.rst Outdated Show resolved Hide resolved
docs/tutorial/tutorial-0.rst Outdated Show resolved Hide resolved
@mhsmith
Copy link
Member

mhsmith commented Dec 10, 2024

I've also taken the liberty of clarifying the name of text alignment whenever I encountered it in my searching-and-replacing.

If we're going to all this trouble, we might as well match the CSS name of text_align rather than text_alignment.

@HalfWhitt
Copy link
Contributor Author

HalfWhitt commented Dec 10, 2024

If we're going to all this trouble, we might as well match the CSS name of text_align rather than text_alignment.

The Pack property is already named text_align... My thinking for using "alignment" in a number of other places was that it's a noun, and a thing we control, test, and verify, regardless of what the property that controls it is named. Also "align" can be misleading in a function name; toga_align sounds like it actually aligns something, whereas toga_alignment is more grokkable (to me, at least) as what it is: a converter that returns a Toga-compatible alignment value.

That said, I do realize that's an inconsistency, and I'm not against switching it.

@mhsmith
Copy link
Member

mhsmith commented Dec 11, 2024

I agree the grammar is questionable, but I think that's outweighed by the advantage of using the CSS name everywhere. It would be one less thing we need to remember, and it might be useful for some form of automation in the future.

@mhsmith mhsmith mentioned this pull request Dec 11, 2024
4 tasks
Copy link
Contributor Author

@HalfWhitt HalfWhitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

align_items now coexists with alignment. It's a pretty convoluted backwards-compatibility section, but it does seem to work as expected.

I've also made the requested tweaks to the docs, rewritten the part about align_items, and applied a consistent text_align name everywhere.

core/src/toga/style/pack.py Show resolved Hide resolved
android/tests_backend/widgets/properties.py Outdated Show resolved Hide resolved
Copy link
Member

@freakboy3742 freakboy3742 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've given this a quick review, and it definitely looks on the right track to me. I'm about to sign off for end-of-year leave, so I'll be on reduced availability until the new year; @mhsmith is currently elbow deep in this code because of #3036 (and some related work to land soon), so I'll leave it to him to do a deep final review.

core/src/toga/style/pack.py Show resolved Hide resolved
core/src/toga/style/pack.py Outdated Show resolved Hide resolved
@HalfWhitt
Copy link
Contributor Author

Thanks for giving it a look, and have a good holiday, @freakboy3742!

Copy link
Member

@mhsmith mhsmith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done a few minor cleanups, but overall this is very thorough. Thanks!

@mhsmith mhsmith merged commit eec2395 into beeware:main Dec 15, 2024
41 checks passed
# Travertino 0.3.0 doesn't support accessing a directional property via bracket
# notation.
# ("padding", "margin", (5, 5, 5, 5), (0, 0, 0, 0)),
("padding", "margin", (5, 5, 5, 5), (0, 0, 0, 0)),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, it hadn't even occurred to me that I'd made this work. Nice catch! 🤣

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually wait, my attempt to deduplicate logic (by having __getitem__ call __getattribute__) had the happy accident of letting bracket notation access padding, but only because it entirely bypasses BaseStyle.__getitem__, which verifies valid property names. Now you can set style['bogus-name'] and it won't complain.

This mechanism is currently enforced in Travertino's tests, but not Toga's, so I missed it. I'll make a fix and add a test.

@HalfWhitt HalfWhitt deleted the align_properties_with_css branch December 17, 2024 03:35
@HalfWhitt HalfWhitt mentioned this pull request Dec 18, 2024
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants