
El 21/06/11 10:14, Artyom Beilis escribió:
----- Original Message ----
From: Mathias Gaunard<mathias.gaunard@ens-lyon.org> To: boost@lists.boost.org Sent: Mon, June 20, 2011 12:09:50 PM Subject: Re: [boost] [gui] Help with a little experiment.
On 18/06/2011 16:55, Artyom Beilis wrote:
Making a GUI library is not about providing nice syntactic sugar for building layout.
Syntactic sugar is the last thing that should interest you. Having a short and concise declarative definition of your GUI has several advantages. It's easier to validate it, it allows to avoid bugs, and you can really materialize the intent of what you want instead of coding its logic directly.
Moreover, writing GUIs is very tedious and uninteresting. It would be nice if it were possible to automate more things. Few points.
If you want an easy and fast declare GUI there are many RAD tools like QtCreator
or Glade that do this job well.
On the other hand. When I was programming some GUI tools the **easiest** part was to write a code that makes the layout and connects widgets...
The hard part was to write the actions that should be done behind the widgets.
Today when I write production code I think about users who are going to maintain it. And readability and clearness is very big concern.
See:
http://developer.qt.nokia.com/wiki/API_Design_Principles
There are 6 primary points:
* Be minimal * Be complete * Have clear and simple semantics * Be intuitive * Be easy to memorize * Lead to readable code
Especially this one:
An API is intuitive if a semi-experienced user gets away without reading the documentation, and if a programmer who doesn’t know the API can understand code written using it.
IMHO The proposed API does not helps with all this and makes things very obscure for a programmer that is not fully familiar with the toolkit.
If I show this code to average C++ programmer the vast majority of them would not know what happens there...
The fact that you and 1 percentile of C++ programmers (that write Boost Libraries) understand the proposed code does not mean it is understandable to other.
Consider:
This
auto gui_definition = Window(title="Hello, world!")<< VBox(expand=true)<< HBox(expand=true)<< Label(text="Name:")&& Entry[SLOT(onEntryChanged)]) << End(HBox); << Button(text="hello")[SLOT(onButtonClick)]; << End(VBox) << End(Window); Or this?
class MyWindow : public Window {
MyWindow { setTitle(tr("Hello, World!"));
base_layout = new VBoxLayout(); setLayout(base_layout); base_layout->sizePolicy(Expand);
top_layout = new HBoxLayout(); base_layout->addItem(top_layout);
top_layout->sizePolicy(Expand);
top_layout->addWdiget(new Label(tr("Name:")));
text = new TextEdit(); top_layour->addWidget(text);
button = new PushBotton(tr("Hello")); layout->addWidget(button);
connect(text,SIGNAL(valueChanged()),this,SLOT(onEntryChanged()); connect(button,SIGNAL(pressed()),this,SLOT(onButtonClick()); }
void onEntryChanged() { std::cout<<text->getText()<< std::endl; }
void onButtonClick() { std::cout<< "Button Pressed"<< std::endl; }
}
I'm trying to make my code readable as well. I changed my initial proposal a little, but I think that you didn't realize it. Look at it. And it's easy to follow once you understand the mini-language: auto gui_def = Window(title="Hello,world")[ VBox(expand=true)[ HBox[Label(text="Dollars:") | Entry(changed=BINDING(dollars))], HBox[Label(text="Euros:") | Entry(changed=BINDING(euros))] ] ]; I think that it's easy to follow. You just have to read once what operators do (| to separate in boxes). It's readable, very readable indeed. And it makes a lot of work in very few lines of code == less bugs. Of course I must think a lot about many problems I will find along the way before making a proposal, but being declarative and making code as short as possible while keeping readability are two choices I think are right. The average programmer just would have to learn a mini-language which, compared to the alternative (learning an imperative API) is much better. Of course, I must think a lot about bindings, signals, slots and all that stuff, but my starting point is a DSEL and after that I'll try some sort of runtime equivalent to make possible dynamic polymorphism.