A couple of thoughts:
a) Take a look at the serializer extension that was pulled out of
BXMLSerializer recently. If you intercept every call to a new instantiation of
an object in the BXML serializer, you can do everything you describe below and
satisfy many other use cases. It also a small change and it allows
experimentation with a few iterations before you decide on a specific
mechanism. Each project could then implement their own approach to apply styles
to an object based on class selection, or whatever criteria they choose as well
as however they want to specify the "class" styles...whether in BXML or json or
CSS. Its all quite easy and pluggable. It’s a minimum of mess and lets everyone
continue on their own path easily. Its BXML oriented but it allows easy
experimentation.
b) You can also do what you describe below (styles applied based on a class
selector and load) without changing anything in pivot today--zero
changes--which means you are not forced into an early decision that may present
blocks in the future. Doing it this way also retains parity between coding and
BXML. When I did it this way, I chose to specify "class" styles directly in
BXML (inline) and use the parent-child tree to find them because I was lazy
about any other integration and it satisfied my need at the time. You can
combine this method and (a) together.
c) Its my belief that it is critical to consider BXMLSerializer as not specific
to UI programs--to a large degree but not exclusively of course because its all
about pivot. I still encourage thinking about separating out the "how you
specify styles" to "how they are found and applied." If you build a mechanism
that handles each of these two things separately, you are in pretty good shape.
WPF, BXML's kissing cousin, could actually fairly easily have CSS styling as a
"specification" because it provides mechanisms to generally do find & apply. No
one bothers to do that of course for WPF.
d) You can also do WPF-like styling. To illustrate the point in (c), a small
WPF-like library says that setting styles in just one activity you want to do
on components, and actually, just a by-product of general "component actions."
Other people like CSS, which actually this library could also easily handle
since the library separates out "specifying" from "finding and applying." For
example, to enhance the font and set the style for all labels in the
parent-child tree, you can add the following BXML in the Window object and have
the parent-child tree control precedence for customizations by children (or
whatever). I also added a pluggable selectable interface so you can implement
your own selection approach (something WPF does not have):
<ComponentAction targetType="org.apache.pivot.wtk.Label">
<ApplyStyles styles="{backgroundColor:'#ff0000'}"/>
<FontEnhancer bold="true"/>
<SetProperty values="{foo:true}"/>
</ComponentAction>
which I was too lazy to specify the bold part in JSON so I just made them
properties on an action object to keep moving. FontEhancer has to read the
font, modify it, then stick it back into the styles dict. But the way that
worked for me may not for others. You can write your own ApplyCSSStyle to
handle specifications in CSS. This is very WPF'ish which some may not prefer. I
opted for a general capability to solve other common issues I wanted to
address. As Greg pointed out, its easy to specify things in CSS, but to me,
it's how the find&apply works that is really the key for pivot.
Michael, I just saw another email you just sent. I'll read that more closely.
Good thoughts. Still need to read up on CSS.
-----Original Message-----
From: Michael Allman [mailto:[email protected]]
Sent: Thursday, July 15, 2010 11:20 PM
To: [email protected]
Subject: Re: Typed styles, naming conventions
We could put it in a Component-specific subclass of BXMLSerializer, say,
WTKXSerializer, that assumes the classes are components. I'm not kidding.
Such a serializer could do a lot of UI-related stuff, too, while building
on the foundation of BXML.
Michael
On Thu, 15 Jul 2010, Greg Brown wrote:
> I think it is OK. We can't put this logic in BXMLSerializer since we
> can't assume that every class instance will be a Component. We just want
> to ensure that every instance of a particular type is assigned these
> styles, and setSkin() is the most centralized place to do that.
>
> On Jul 15, 2010, at 9:40 AM, Noel Grandin wrote:
>
>> I'm fine with the general concept, except for:
>>
>> Greg Brown wrote:
>>> The only issue I ran into involves naming conventions. My original logic in
>>> setSkin() looked for files on the classpath named <fully-qualified class
>>> name>.json. Unfortunately, this conflicts with resource bundles, which use
>>> the same naming convention.
>>>
>> Is it just me, or does it feel a little weird that Component#setSkin() is
>> digging around for files on the classpath?
>> I kind of liked that the loader classes were distinct from the runtime
>> classes - makes it obvious which files belongs to
>> which phase of the application, etc, etc.
>>
>> -- Noel
>