|
Boost : |
From: brock (brock.peabody_at_[hidden])
Date: 2003-08-02 10:33:23
----- Original Message -----
From: "E. Gladyshev" <egladysh_at_[hidden]>
To: "Boost mailing list" <boost_at_[hidden]>
Sent: Friday, August 01, 2003 7:49 PM
Subject: RE: [boost] GUI/GDI template library
>
> --- Brock Peabody <brock.peabody_at_[hidden]>
> wrote:
>
> > > Anyway I think I got the basic idea. The idea is
> > that
> > > the GUI elements are classes defined on top of a
> > > pImpl. Someone else creates the pImpl object and
> > > passes it to the GUI elements classes. The GUI
> > > elements then call pImpl methods do the real job.
> > > Did I get it right?
> >
> > Yes, and you're confused because I left part out.
> > Sorry!
> >
>
> I personally don't see any significant benefits in
> using pImpl here but there are lot of disadvantages.
>
> For example you would have to make sure that all pImpl
> functions use a set predefined data types. It means
> that the pImpl functions will have to convert the data
> between native format and pImpl.
> In the case of ImplTraits you can use native data
> types directly.
> Example:
>
> class win32
> {
> typedef WHND WinHnd;
> };
>
> template <typename ImplTraits>
> class window
> {
> public:
> ImplTraits::WinHnd m_hnd;
> ...
> };
>
> The bad list about pImpl goes on an on.
I think you missed the fact that the pImple itself was parameterized on the
traits class:
template <typename Traits> struct edit_imp {...};
The pImpl is necessary in this case because of the fact that there is no way
to easily deduce the result type of a complex template expression (short of
a typeof operator). In my library, for instance the result type of:
row(column(edit(), "text"), row(mapped_combo_box<job_code_map>(), .....)
Would be pages long typed out. If you want to store it somewhere you have
to use some sort of wrapper, which is going to depend on a pimpl. Check out
the rule<> template in Spirit.
>
>
> [...]
> > They would typically all be part of (or a sub part
> > of) the same gui
> > object.
>
> My personal preference is to have two kinds of
> groupings.
> 1. Visual/behaviour grouping
> 2. Data groping.
>
> Using the first the first option, you can group GUI
> elements into one presentation group. The visual
> grouping would be managed by gui managers.
>
> The second option is similar to the MFC document/view
> architecture. You could connect a data item in a list
> control to an edit box (even in different dialogs) on
> the data level. If one control changes the data, all
> connected controls get updated automatically. This
> kind of grouping will have to be independent from the
> gui managers.
You are certainly right in that there are relations that cannot be expressed
within the GUI manager as I've been talking about it. It's really difficult
to describe the relation between two controls this way when defining them
inline. One example of such a relationship is having a check box that
enables and disables a group of controls as it is checked and unchecked.
This seems fairly common to me. Here is how you express it in my library
(toy example):
struct employee {
bool has_a_name;
std::string name;
};
gui_manager<employee> has_a_name_box = check_box("Has a name?",
&employee::has_a_name);
gui_manager<employee> name_controls = row("Name:",
edit(&employee::name));
tie_to_enabler(has_a_name_box, name_controls);
gui_manager<employee> app = column(has_a_name_box, name_controls);
Now when the program is running the "Name:" static text control and the edit
box following it will only be enabled when the "Has a name?" check box is
checked. When the user un-checks it, they will become disabled.
Does that seem reasonable? I don't know if the code to do this is in the
part of the library that I posted, if you want to see it I can post it too.
Actually in my library it is data_manager<>, but someone earlier used the
term 'gui_manager', which seems better to me.
Brock
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk