-
-
Notifications
You must be signed in to change notification settings - Fork 122
Proposal: Theming #74
Comments
👍 Like your thoughts I also wonder what approach tui will take. There are some ideas for theming: bottom-up, or fully-custom. I hope tui takes the bottom-up approach likes html, where a set of base elements is defined. Each base element has stylable defined. The users, who dont care about how exactly to draw yellow bold text or red border, will composite those base elements. In this approach, theming is a lot easier if the composite tree is traversable explicitly (we are not there yet?). A style applier can then apply style to any widget, before passing it to tui.UI. I don't have a concrete thought on dsl yet, but the idea is close to css. |
@cceckman First off, awesome work with the proposal! I'm intrigued by the idea of the StylePolicy but I think I at least would need to see some more examples from the perspective of a user. Meanwhile, I definitely think style inheritance is the solution to #60 at least. I think we can do some work here while discussing the StylePolicy idea. @taylorchu The HTML/CSS approach was my initial idea, due to it being a tried and tested approach to separating structure from presentation. I'd like to see other approaches to this problem though. And no, the widget tree is not traversable yet but I think it might be time to implement it for theming purposes. Also, it would be useful for tabbing through widgets (which is a bit basic right now). |
Yeah, I'd originally brainstormed towards I've got a few things to say against getting approaching CSS as a model:
I definitely think there's lessons to be learned from it- in particular, I'm a fan of having I like the idea of embedding as a way to define a base style + derivative styles for a Here's a Gist to that effect. I'm not sure how to get the dynamic-dispatch behavior in Go without making things significantly harder. New proposal:
|
Considering this done by now |
Splitting off of #60, also trying to address #45 :
Styling / theming support in
tui
is pretty limited at the moment. There's lots of elements where it would be useful to apply custom coloring / styles to. But as is usually the case, API design is hard: getting the right balance of knobs and low-friction.Brainstorming (copied from here):
Terms:
Requirements:
Wants:
I don't like the proposal in CSS-like selectors for theming #36 - making a CSS-like DSL for associating Widgets with styles after the fact. The programmer already creates the Widget hierarchy when instantiating the view. Why not require style specification at that time? (Answer: because “style” and “style policy” are coupled; see below.)
Proposal:
StylePolicy
Separate “style” and “style policy”. The Style in use changes over the lifetime of a widget, e.g. on select / deselect; but the StylePolicy shouldn’t. So: apply a StylePolicy at Widget initialization time, rather than a Style, and let the Style be selected at draw time.
A style policy could say “use the style with this name in my Theme” - which may change over time, e.g. on a SetTheme.
What does that look like, mechanically?
type StylePolicy func(t Theme, parent Style) Style
IsSelected
)WidgetBase
getsSetStylePolicy(s StylePolicy)
(New comments from here.)
Drawbacks of
StylePolicy
StylePolicy
because they're styling sub-widget items, and based on sub-widget or draw state.Box
has separate border and non-border styles.List
applies styles to its items, and predicates them on whether the item is selected / deselected.StylePolicy
functions?Proposal: Embedding
To address (1) above: Each class of Widget has a fixed number of styles it may apply.
Box
has border as well.List
has selected / unselected.These are the styles used in its
Draw
method;Draw
effectively callsp.WithStyle(style, drawElement)
.Different instances of that widget may want to have different styles. e.g.: #45 / #46 request different
Box
es to have different styles.Rather than a separate
StylePolicy
type, have individual methods which return style selectors:and, in some cases, multiple methods:
which
Draw
calls as appropriate. A non-default style can be applied by embedding thetui
widget in another struct, overriding the Style methods. (I think I've got Go's dispatch right in my head, that that would work?)The (default) behavior of returning "" could be used to indicate "no special style", i.e. inherit the parent style.
Proposal: Cascading styles
One coda: I think it would make code easier to reason about if the default
Style
was defined as "inherit the parent style"; only by explicitly setting a field would it be reconfigured. This would allow a style specification to say "the same as before, only underlined" without explicitly reading the currently-active style. (I don't think this is the case today the boolean fields:Reverse
,Bold
,Underline
.)The text was updated successfully, but these errors were encountered: