Design discussion: options and styling
Opened this issue · 0 comments
This issue is to discuss how to store options (meaning orientation of the widget, whether some things should be displayed etc.). and how to style / customize existing widgets.
Regarding the options discussion, overall I have the impression that the design originally proposed by @shashi in #16 works very well in the new framework, as using a Dict
of Observable
objects would be a simple way to allow modifying options from other widgets.
Options
I've realized that having some observables play a role in the layout function is a very good solution. For example, let's say that we have two children :a
and :b
and a third children :vertical
(Observable
of Bool
), then one can simply do:
@layout! wdg $(:vertical) ? vbox(:a, :b) : hbox(:a, :b)
However I wonder whether :vertical
and similar keyword arguments should be stored among the children or if it is better to have a separate options
field. That would remove name conflicts and ambiguities and organize things a bit better but would require a different syntax (meaning in all these macros I should somehow distinguish whether a symbol refers to a child
or an option
). My personal preference is to have one unique OrderedDict
with all the relevant information (either subwidgets, options, data that should be stored). Then @layout!
can be used to only display some of them. The only thing to change is that I should maybe rename the fieldname as children
is no longer very appropriate. I'm not sure what a better options would be though. Maybe wdg.arguments
as it is where I'm storing all the widget's arguments?
Styling
Concerning styling and changing Node
properties, my take is that the user should normally style in place the children of the widget that are nodes. To simplify this process, we should decide what is the "primary node" of a widget.
One option is that each widget would define which of its children is "primary" and styling the widget would by default style that node (it makes sense in a lot of widgets, for example in a slider widget it'd be the input node). In this case props(wdg)
could maybe refer to props(node(wdg))
.
Another option is that the node
of a widget would basically be what is rendered, meaning wdg.layout(wdg)
. In this case the user would work with layout
pretty much like with dom
in a Scope
, and one could consider forwarding all Node like functions to it, meaning:
style(wdg::Widget, dict) = (wdg.layout = x -> style(wdg.layout(x), dict); wdg)
If one node is very important, it would simply be given an important name and be accessed by that name.