[Ekiga-devel-list] Parenting the forms
- From: Julien Puydt <jpuydt free fr>
- To: Ekiga development mailing list <ekiga-devel-list gnome org>
- Subject: [Ekiga-devel-list] Parenting the forms
- Date: Sun, 16 Dec 2007 07:19:42 +0100
Hi,
the problem with the current organization to display forms in ekiga is
that they appear as separate windows, ie: they don't depend on another
window.
(I) A solution: wide scale
The obvious solution is to make the forms find their way to the ui not
directly like this : Some::Component -> Ekiga::UI, but more like :
Some::Component -> Some::Hub -> Ekiga::WhateverCore -> Ekiga::WhateverView.
What I propose is the following scheme, which hopefully will do what we
want : use a "chain of responsibility". It is a sort of signal where
callbacks are run each in turn, and return a boolean, until one of them
returns true, in which case the others isn't called.
This means that only one callback will really do something, and hence we
won't get hit by the "I have several views and all of them have proposed
the form to the user, (s)he is pretty unhappy!!" problem.
This also means we get rid of the Ekiga::UI class for now (but of course
the rest of the ui code will still run happily!).
(II) A solution: details
When the dialog for the forms will be created by the code responsible
for a window, correct parenting will require :
- adding a set_parent_window method to the Gtk::FormDialog class ;
- use said method like this :
Gtk::FormDialog dialog(request);
dialog.set_parent_window (window);
dialog.run ();
Using the code from a chain of responsibility should look something like:
* declaring a chain of responsibility dealing with form requests :
Ekiga::ChainOfResponsibility<Ekiga::FormRequest> my_chain;
* sample debug handler for this chain :
static bool
debug_handler (Ekiga::FormRequest &request)
{
Ekiga::FormDumper printer(std::cout);
#ifdef __GNUC__
std::cout << __PRETTY_FUNCTION__ << std::endl;
#endif
printer.dump (request);
return false; // means we only peeked and decided not to really handle
}
* using the debug handler :
In the class which declares the chain, do the following in the
constructor, so it's the first handler to be run :
my_chain.add_handler (sigc::ptr_fun (debug_handler));
* gtk+ handler for the form :
This is more a reminder, I quoted the possible code above :
bool
addressbook_window_run_form_request (Ekiga::FormRequest &request,
AddressBookWindow *window)
{
Gtk::FormDialog dialog(request);
dialog.set_parent_window (window);
dialog.run ();
}
* sending a form to the user :
my_chain.handle_request (request);
* code for the chain of responsibility :
This is simply a one-parameter bool-returning signal with a special
return value accumulator, and some method-renaming to make it look
better ; notice that the fact it returns a bool allows doing 'if' tests
on the handle_request call, and if it's false, dump an error message on
the console to notify us about the problem!
struct responsibility_accumulator
{
typedef bool result_type;
template <typename T_slot_iterator>
bool operator() (T_slot_iterator begin, T_slot_iterator end)
{
bool result = false;
for (T_slot_iterator iter = begin ;
iter != end && !result;
iter++)
result = *iter;
return result;
}
};
template<typename T_request>
struct ChainOfResponsibility:
public sigc::signal1<bool,
T_request,
responsibility_accumulator>
{
typedef typename sigc::signal1<bool,
T_request,
responsibility_accumulator>::iterator iterator;
typedef typename sigc::signal1<bool,
T_request,
responsibility_accumulator>::slot_type slot_type;
iterator add_handler (const slot_type& slot_)
{ return connect (slot_); }
bool handle_request (typename sigc::type_trait<T_request>::take request)
{ return emit (request); }
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]