Finalizing Theme API, input welcome

5 views
Skip to first unread message

Francisco Tolmasky

unread,
Mar 9, 2009, 5:54:49 PM3/9/09
to Cappuccino & Objective-J
I'm finally reaching a point in the merge where I'll be able to get
things pushed back into the master branch, but before I do that I'd
like to get your guys' input on the style/theme API so that we can
avoid as many API changes after the fact as possible. Currently, to
style a control, I've introduced the following methods:

- (void)setValue:(id)aValue forThemedAttributeName:(CPString)
anAttributeName inControlState:(CPControlState)aControlState
- (void)setValue:(id)aValue forThemedAttributeName:(CPString)
anAttributeName
- (id)valueForThemedAttributeName:(CPString)anAttributeName
inControlState:(CPControlState)aControlState
- (id)currentValueForThemedAttributeName:(CPString)anAttributeName

Basically, there is now the concept of a "themed attribute", which has
a few interesting properties. For starters, it is "stated", which
means its value changes according to the state of the control. For
example, if you wanted a button's text to turn from blue to red when
clicked on, you'd do the following:

[myButton setValue:[CPColor blueColor] forThemedAttributeName:"text-
color"]
[myButton setValue:[CPColor redColor] forThemedAttributeName:"text-
color" inControlState:CPControlStateHighlighted];

Notice that we leave out "inControlState:" in the first call, this is
a shorthand for replacing all state's text-color with blue. We then
say, specifically when the button is highlighted, make the text red.

The other thing you'll notice is that these properties are now key-
value pairs instead of direct accessors. In other words, instead of:

[mySlider setKnobColor:aKnobColor];

We have:

[mySlider setValue:knobColor forThemedAttributeName:"knob-color"]

This was to avoid the exponential code bloat that would have been
brought about by having each of these methods for *every* new property
that was introduced (we would need setKnobColor:,
setKnobColor:inControlState:, knobColorInControlState:, and
currentKnobColor). I've left the existing Cocoa methods for backwards
compatibility (setFont: just calls setValue:..., etc), but have
refrained from adding direct methods to the new properties we've
created.

All these properties are also now "themable", meaning that you can
take any styled control(s), and record their styles into a theme which
you can later reuse.

The main issue I see with this API currently is that it is a bit
verbose and it combines a number of different concepts together: Why
not support stated properties that aren't themable? Why do all
themable properties need to be stated? etc. I think these aren't too
bad tho, mainly because a lot of these are "opt-out". For example,
you can completely ignore the inControlState: stuff and treat a
property as if it was static and did not respond to state at all. I
chose "themabledAttributeName:" because "attributeName:" is used in
other parts of Cocoa for completely unrelated things and I didn't want
to confuse the API, but I'm open to suggestions.

I'd love any feedback and also any ideas for scenarios I may not be
taking into account.

Ross Boucher

unread,
Mar 9, 2009, 6:08:24 PM3/9/09
to objec...@googlegroups.com
A proposed way to reconcile the two desires (shorter method names/
existing API, and the limited code explosion) would be to use the
Objective-J equivalent of method_missing.

By capturing selectors we could intelligently forward

setKnobColor:aColor

to

setValue:aColor forThemedAttributedNamed:"knob-color"

The actual size of the code would not change, but the terse versions
of methods would be available. The rules for forwarding selector's
would be pretty trivial to implement. The only potential trade-off is
speed, but it's unlikely to be a big factor, especially since a) these
aren't usually super common operations and b) you can always fall back
on the longer, faster version.

-Ross

Nikso

unread,
Mar 10, 2009, 5:22:35 AM3/10/09
to Cappuccino & Objective-J
I partially agree with Ross idea. It uses one of the key feature of
obj-j but it can create confusion in the api and can be quite anoying
if it become common practice (aka keep compatibility with new
versions).

I haven't tried out the theme api yet but here is an idea to decrese
the verbosity and keep the themimg code together: like the dictionary:

[myButton setValuesForThemedAttributeNames:
"text-color", [CPColor blueColor],
"text-color:highlighted", [CPColor redColor],
nil];

the ":highlighted" part would like to be a shourtcut to specify the
control state but again, this could be confusing in the specification.
just an idea :P
> > taking into account.- Nascondi testo citato
>
> - Mostra testo citato -

cacaodev

unread,
Mar 10, 2009, 8:39:05 AM3/10/09
to objec...@googlegroups.com
I agree and I see another reason for using explicit setters and
getters: code completion. In editors I use (Xcode, coda, subethaEdit)
you can't auto-complete string arguments used with the key/value
mechanism.

Le 9 mars 09 à 23:08, Ross Boucher a écrit :

Reply all
Reply to author
Forward
0 new messages