-
-
Notifications
You must be signed in to change notification settings - Fork 687
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
Style property redesign #3011
Comments
This is definitely true of the current Toga implementation - but I don't agree that it's fundamentally unresolvable. It strikes me as a gap of metadata, not a limitation of Toga's existing design. The manual solution is to annotate the "applicable" styles on each class. This doesn't strike me as an especially onerous task to add - certainly a lot less invasive than a full redesign of Toga's style implementation. However, my initial impression is that all this metadata could be largely (if not entirely) determined by inspection Applicator implementations - if a widget doesn't declare an implementation of the It's also worth nothing that CSS and HTML doesn't contain any runtime validation either - and that hasn't stopped GUI HTML/CSS builders from having widget-specific UIs in their design interface. Whether this is a strength or a weakness of the design of HTML and CSS is a debatable topic - but whatever the flaws, the HTML and CSS approach is undeniably successful, and I'd argue it's the single most prevalent UI API design in use today.
This is true - but I'm also not clear on why it's a problem. Can you provide an example of a style property that we would require extension in this form but couldn't be satisfied by a existing CSS3-compliant style property? The only examples I can think of relate to the styling of "complex" widgets like table, where you may want to (for example) set the text color of a particular column, or similar (see #1478) - but in that case, I'd argue the issue isn't that we need new style properties - it's that we don't have the ability to apply the existing style properties to "sub elements" of a large widget.
My fundamental objection here is that I'm not sure I agree styling properties should be extensible - or, at least, if we make them extensible, we need to be careful about that extension mechanism. The exiting It's also consistent with the long term goal of Toga to replace Pack with Colosseum - a true CSS implementation, with everything that entails. Ultimately, it should be possible to have a "mobile optimised app" in the same way that you have a "mobile optimised website" - the same widgets, but with a different stylesheet (or a single stylesheet with media specifiers) that accounts for the size and properties of the device where it is being used. The same could also be done for "dark mode" stylesheets. On top of that - CSS doesn't require arbitrary extension of style properties to render websites of almost arbitrary complexity... so why is it needed for Toga? What is the use case? It's also worth noting that with some a couple of very specific exceptions (mostly in the ImageView class - and I consider these exceptions to be bugs), a user could provide their own style class right now, with no impact on the operation of Toga. In practice, I don't consider that this is something most users will do - but the API separation is at the core of how a transition to Colosseum would work in future - replace any instance of
I feel like I'm missing something, because I see very little here that would be a net gain for Toga, and a lot that we would lose.
I agree that Toga (as currently implemented) has a metadata gap that would make it difficult to automatically generate GUI tooling. However, to me, the solution to this problem is to plug the metadata gap, not to completely redesign Toga. The only other benefit that I can see is that this design is (presumably) more closely aligned with Invent's API design, which might simplify writing a "Invent on Toga". However, if API adaptation is required, it's not clear to me why Toga's API should be changing to map to Invent's design, rather than the other way around - especially given the fact that (a) Toga's design mirrors explicitly the design of an established standard in HTML and CSS, and (b) Toga has (to the best of my knowledge) a bigger pre-existing user base, so the "principle of least harm" would dictate Toga's API is the one that is preserved. If there is some pedagogical reason why it's preferable for Invent to define |
My two cents are with Russel on this one, for what they're worth. However...
I somehow hadn't even noticed these, but yeah, it seems like it would be good to rename them to match. They can be aliased for backwards compatibility. |
Toga currently supports two kinds of property on a widget:
style
object, controlling its appearance, position and sizeThere are a few problems with this arrangement:
I'd like to discuss switching to the design used by Invent, which instead divides properties according to who's responsible for defining and implementing them:
layout
object, controlling its position and size – defined by the class of the widget's parentThis allows both sets of properties to be extensible, and even if the widgets and containers come from different developers, there's no risk of name clashes.
Implementation details
The first group of properties are implemented directly on the widget's class, or inherited from a base class. For example, this would include
background_color
andfont_family
. Mixin classes could be used to add multiple properties at once, such as all thefont
properties.The
layout
group is more complex because it depends on the widget's parent. Invent implements this as follows:Every container widget has a corresponding Layout class which defines the layout properties applicable to the container's children. So for the Toga
Box
, there would be aBoxLayout
class with propertieswidth
,height
,padding_...
andflex
. However,direction
andalignment
are set on the container itself, so they would be ordinary properties defined onBox
.Container classes are linked to their corresponding layout class by a
layout_class
attribute, i.e.Box.layout_class is BoxLayout
.Box.Layout
. The problem with this is that error messages only display the inner class name, so if you saw "Layout object has no attribute x", you wouldn't know what Layout class you were dealing with. Maybe we could get the best of both worlds by renaminglayout_class
toLayout
.Layout classes all have the constructor signature
(widget=None, **kwargs)
, where:widget
is the widget the layout properties will apply to, i.e. the child.kwargs
are initial values of properties.Layout classes can be instantiated directly, but for conciseness a
dict
is also accepted by the the widget constructor. So both of the following are equivalent:A widget's constructor doesn't know what its container will be, so the validation of the
layout
property is deferred until the widget has a parent. At that time, a new Layout object of the correct type is created and associated with the widget, and intialized from whatever was passed into the constructor:dict
, its keys are copied into the new object. Unknown properties will raise an error.If a widget is assigned to a different parent, or the
layout
property is itself assigned, the same validation takes place. This allows a widget to be moved to another container of the same class with its layout properties intact. Moving to a container of a different class currently requires an awkward dance, so in this case maybe the layout properties should be reset to the new container's defaults.Backward compatibility
The existing
style
syntax can be kept as a deprecated alternative. It maps onto the new system in a 1-1 manner, with eachstyle
property corresponding to either a direct widget property or alayout
property.However, the new syntax would be a good opportunity to rename the properties to more closely match CSS, e.g.
padding
tomargin
, andalignment
toalign_items
. This will help developers who are familiar with CSS, and even if they're not, it will allow them to search for the terms in general CSS documentation such as MDN.The text was updated successfully, but these errors were encountered: