
On Sat, Jul 11, 2009 at 2:33 PM, Felipe Magno de Almeida<felipe.m.almeida@gmail.com> wrote:
Yep, decoupled. So for any layout system, widgets just need to describe their measurements. width, height, etc. A few things to learn from Eve and other experiences: - widgets (or static/free functions related to the widget) should be able to calculate their sizes based on inputs - ie a text label widget should be able to return its size for a given text string
Ok.I like the free functions idea. To use ADL and allow non-intrusive interoperability. But I didn't like the Eve approach. Creating the assemblage code for Eve is just too hard.
It is a bit to set up. But once set up, it becomes easy to do UI. Image a company like Adobe where 20 or even 200 developers (or maybe one day all Adobe dev) are all using the same GUI system. One where you write some eve-script code, and the UI just pops up. And think of how much UI there is in each Adobe app!! The cost of that one developer to get eve connected to the GUI/widget system is nothing compared to the savings. That doesn't necessarily help the 'little guy', and it would be nice if it was easier, but at least it helps see where it comes from. The other place it 'comes from' is that is that it is another form of an 'abstraction penalty'. Not a speed penalty, but a speed of coding and understanding penalty. Highly abstract code (which is all Sean Parent seems to write :-) often requires extra effort to bring it back down to earth. Often it requires a couple of levels of 'narrowing' to bring it back to concrete items.
If the widget uses overload to use some properties. Then using the parameters becomes a hell if/else code.
I've had a static lookup table/map { property -> boost::function } to help with this.
I think the only manageable way to create a assemblage code is using some static information as well. To allow some metaprogramming and overload to help.
I think static info is good. I think there will also be cases that need to be dynamic, but they can always uses switch or if/else to get to the static info. More about static vs dynamic later.
I don't understand why ':' position is required. Couldn't end of the widget be used instead?
Well, eve (and Adobe UI 'police', I mean UI designers) tend to be quite fussy, so eve aligns to the ':' (I think). But forget about that - alignment guides should be more generic and configurable. For the widget, it should just somehow expose what alignments it has and what type/category/tag each one is (and where they are, of course :-).
A few thoughts: - Start at the bottom - with known data types (int, float, string). - use a capabilities hierarchy. ie a generic string-editing-widget can be used as a number-editing-widget, just not the best one. Similarly it can be a date-editing-widget, etc.
I would think a I/O layer for edition would fit here. Where a string button would be a int button with a I/O controlling the string editing.
Adaption: ------------- Two different sides of the coin here. Or levels of the problem, maybe. eg: I need some data. So I write: get_data_input(data); // which calls present_ui_to_user(data); // which calls for each datum in data: show_widget(datum) Somewhere in there, show_widget might find exactly the right widget, or maybe it finds a more generic widget, and then uses an I/O layer to customize it. Or maybe it isn't so automatic, and the 'for each datum' isn't a loop but: create_custom_number_button(datum1) which calls create_button, then sets some 'adapter' points <snip>
Or the widget could be reused with a adapter. <snip> I think a adapter layer would be appropriate too. <snip> Yes, I think non-intrusiveness is important. <snip> I think that some adapter is necessary, so that we don't need to derive a huge amount of widgets to different types. <snip>
Yep. Overall, we make some widgets, describe (somehow) what they do, and then leave it at that. From there they can be adapted to more specific contexts (by the end coder, but with some common/useful adaptions living in boost). Overall, you want the client coder to be able to make adaptions that fit in seemlessly with the boost:: widgets. Sometimes the adaptions will be one-time cases (ie pass in a boost::function for input validation), other times the adaptions will be reused enough by the client that they decide to wrap them into separate widget classes. Static vs Dynamic... ---------------------------
- As a widget-author, all you need to do is to "publish" your widget's abilities. ie a single string that describes your widget.
string? I think we should do that by type_traits/concept_maps. As much static information as possible the better.
Consider an example:
struct Date // a poor date struct { int year; int month; string day; };
I think using fusion here would be great.
YES. I was thinking code from Boost.Python/LangBinding but I see that fusion has struct-to-fusion adaptor stuff, which would work great.
How about a tag?
....
Yes, but these should static information IMO.
Since the widgets are coded and compiled, then obviously their capabilities are static (until someone writes a widget that does nothing but load and execute Python code or something....) But the 'build_ui_for_data(data)' tends to be more dynamic. Or a combination of the 2. ie the data is statically typed, but some of the UI decisions are dynamic (ie from RC file or script file etc). Lots to think about here. I've written code where the data types and widgets are 'plug-ins' - ie from DLLs. Think of video effects plugins, or 3rd party Photoshop image filters - Photoshop knows very little about the data params required by the plugin, nor what widgets the plugin needs to use. (Or look at something like the OpenFX API for an example.) Traditionally the answer to this has been to see the data as a black-box and get the plugin to do all the UI itself. But if the plugin could describe the data (or at least some of it) and/or describe the widgets it could supply, then you could mix the custom plugin UI with the standard Photoshop (or whatever 'host' app) UI. This is particularly important for apps like AfterEffects, that want to animate each x/y/z datum separately. Anyhow, just saying there is a place for the dynamic side. but that doesn't mean we can't have both: lower layer: static info: <int_tag, etc> higher layer: dynamic info: "int type", etc the higher level then needs to do (ugly) if/else code to convert high level to static level (and add checks, assertions, etc).
I do like where this is going.
It might be going in many different directions - we need to be careful here. It is at least *coming from* many different directions. For me, I'm familiar with writing UI scripts, *which I can edit while the program is running* (ie as long as the dialog being edited isn't up) without changing my C++ code. Very dynamic! (I also want to let the end-user modify the UI) I suspect your cases are more static - possibly hard-coding all the UI in C++. I DSEL would definitely be useful here. Each direction has its uses. I've used both in a single interface actually. (Interestingly, the static (DSEL in fact) case, for me, was when I could create the entire section of UI (something like a 'tool palette' in my case) 'automatically'. ie given the data to be displayed, the widget selection and layout was automatically determined. My goal would be to have all the UI be created this way...) Either way, coming at it from different directions can be a great thing if we can make it work for each direction! It would be a good sign of something useful. Lastly, just because the 'ideal' is some large (impossible?) goal, it doesn't mean you can't write something useful now. Looking at the big goals just helps keep the small steps going in the right direction. Tony