Boost logo

Boost :

From: Brock Peabody (brock.peabody_at_[hidden])
Date: 2003-08-01 18:35:18


> -----Original Message-----
> From: boost-bounces_at_[hidden]
[mailto:boost-bounces_at_[hidden]]
> On Behalf Of E. Gladyshev
> Sent: Friday, August 01, 2003 4:57 PM
> To: Boost mailing list
> Subject: RE: [boost] GUI/GDI template library
>
> > Here is a very simplified version of how this can
> > happen.
> >
> > template <typename Traits> struct edit_imp {...};
> >
> > struct edit {
> >
> > template <typename Traits> edit_imp<Traits>
> > make_gui() {...}
> > };
> >
> > template <typename Traits> struct
> > gui_wrapper_base {
> >
> > //some pure virtual functions
> > };
> >
> > template <typename Traits, typename Control>
> > struct gui_wrapper :
> > gui_wrapper_base<Traits> {
> >
> > gui_wrapper(const Control& imp);
> >
> > //implements virtual functions by forwarding
> > to Control
> >
> > private:
> >
> > Control imp;
> > };
> >
> > template <typename Traits> struct gui_application
> > {
> >
> > template <typename Control>
> > gui_application(const Control&
> > control)
> > : pimpl(new
> > gui_wrapper<Traits,Control>(control) {

oops this line should be

    gui_wrapper<traits,Control>(control

> > }
> >
> > //also assignment operator, etc...
> >
> > //forward operations to pimpl
> >
> > private:
> >
> > boost::shared_ptr<gui_wrapper_base<Traits> >
> > pimpl;
> > };
>
>
> Something is confusing here. How does make_gui() get
> used?
> 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!

Add in the function:

   template <typename Traits, typename Control>
      boost::shared_ptr<gui_wrapper_base<Traits> >
      make_gui_wrapper(const Control& control) {

         return boost::shared_ptr<gui_wrapper_base<Traits> >(
                  new gui_wrapper<Traits,Control>(control));
   }

Then change the constructor for gui_application to:

   template <typename Control> gui_application(const Control& c)
      : pimpl(make_gui_wrapper<Traits>(c.make_gui<Traits>())) {
   }

This part calls the make gui function, the type edit_gui<Traits> is
deduced in the call to make_gui_wraper<>().

[...]
 
> >
> > you could connect two controls
> > with my code like:
> >
> > set_manager( row( edit(&employee::name),
> > edit(&employee::name)));
>

OK. The code where you set up your application might look like:

   gui_application<employee> app = row( edit(&employee::name),
                                        edit(&employee::name));

Then to initialize your application with an employee object you would
do:

   employee e = load_employee();

   app.load_controls(e); //all controls get set here

Both controls get set at the same time to the same thing. I guess this
isn't quite exactly the same as what you have.

>
> I don't think that it is exactly the same. If some
> control changes the data, how do other connected
> controls get updated in your code?

They would typically all be part of (or a sub part of) the same gui
object. It's pretty easy to decompose parts of the gui into other
windows and string them together too.

   struct health_insurance {...};

   struct employee {

      std::string name;
      health_insurance insurance;
   };

   struct health_insurance_window : managed_window<health_insurance> {

      //.. do health insurance stuff
   };

   //inside the main employee window:

   gui_app<employee> app = column(
   
      row( "name: ", edit(&employee::name)),

      control<health_insurance_window>(&employee::insurance));

   app.set_data(load_employee()); //sets name and the insurance window

Brock


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk