venerdì 31 ottobre 2008

Inheriting from Gtk::CellRendererCombo

On ggredit the user can change properties of the selected object using a properties browser, implemented using the Gtk::TreeView object. On my previous post "Different CellRenderers on the same Column" I explain the way I use for renderer each property with a different cell-renderer. Later I see that the deceased crow designer use the same method.
For select enumeration values (i.e. alignment can be left, right or center) I would like to use a Gtk::CellRendererCombo, but my derived class never start editing. In effect a simple Gtk::CellRendererCombo inherited class like this:

#include <gtkmm.h>

class CellRendererComboDerived : public Gtk::CellRendererCombo

{
public:
CellRendererComboDerived() :
Glib::ObjectBase (typeid(CellRendererComboDerived)),
Gtk::CellRendererCombo()

{
}

virtual ~CellRendererComboDerived()
{

}
};

never start edit. On the gtkmm mailing list someone ask for this "subclassing Gtk::CellRendererCombo" issue but no one answer.
I start to write my own combo as a custom cell renderer, following the gtkmm example. At the end the custom cell renderer result a poor combo.
So I come back to the Gtk::CellRendererCombo, first I look at the gtkmm source. This is the constructor of the CellRendererCombo:

CellRendererCombo::CellRendererCombo()
:

// Mark this class as non-derived to allow C++ vfuncs to be skipped.
Glib::ObjectBase(0),
Gtk::CellRendererText(Glib::ConstructParams(cellrenderercombo_class_.init()))

{


}

The CellRendererCombo call the Glib::ObjectBase constructor passing zero instead of the typeid of the class.
I try to revrite the CellRendererComboDerived class in this way:

#include <gtkmm.h>

class CellRendererComboDerived : public Gtk::CellRendererCombo

{
public:
CellRendererComboDerived() :
Glib::ObjectBase (0),
Gtk::CellRendererCombo()

{
}

virtual ~CellRendererComboDerived()
{

}
};

and the cell renderer start work as expected, when the user click on the cell the edit start.

The editing_started signal


For modify the combo used as editable from the CellRendererCombo we must catch the signal_editing_started signal.
The gtkmm documentation says that this signal does not work yet (Bug 301597).

Note that this signal does not work yet in gtkmm. See http://bugzilla.gnome.org/show_bug.cgi?id=301597

I try to use it:

#include <gtkmm.h>

#include <iostream>

class CellRendererComboDerived : public Gtk::CellRendererCombo

{
public:
CellRendererComboDerived() :
Glib::ObjectBase (0),
Gtk::CellRendererCombo()

{
this->signal_editing_started().connect(
sigc::mem_fun(*this, &CellRendererComboDerived::on_editing_started));

}

virtual ~CellRendererComboDerived()
{
}

virtual void on_editing_started(Gtk::CellEditable* editable, const Glib::ustring& path)

{
std::cout << "Editing started editable: " << editable << std::endl;

}
};

the signal is emitted but the editable pointer is always null.
Murray Cumming on Bugzilla tell us to use the C API (g_signal_connect()). I never use the C API, so I first have a look at how to use g_signal_connect(), we have to give a callback to this function, and the callback must be a static function. So we can not pass a class member function, but we can pass a raw gpointer parameter and use this for invoke a class member function. The code may be more clear, this is the header:
#ifndef CELLRENDERERCOMBODERIVED_H_
#define CELLRENDERERCOMBODERIVED_H_

#include <gtkmm.h>

class CellRendererComboDerived : public Gtk::CellRendererCombo
{
public:
CellRendererComboDerived();
virtual ~CellRendererComboDerived();

virtual void on_editing_started(Gtk::ComboBox* combo_ptr, const Glib::ustring& path);
};

#endif /* CELLRENDERERCOMBODERIVED_H_ */

and this is the implementation:
#include "CellRendererComboDerived.h"

#include <iostream>

void cb_editing_started(GtkCellRenderer* cell,
GtkCellEditable* editable,
const gchar* path,
gpointer data)
{
reinterpret_cast< CellRendererComboDerived* >(data)->on_editing_started (
Glib::wrap(reinterpret_cast< GtkComboBox* >(editable), true), path);
};

CellRendererComboDerived::CellRendererComboDerived() :
Glib::ObjectBase (0),
Gtk::CellRendererCombo()
{
g_signal_connect (this->gobj(), "editing-started", G_CALLBACK(cb_editing_started), (gpointer)this);
}

CellRendererComboDerived::~CellRendererComboDerived()
{
}

void CellRendererComboDerived::on_editing_started(Gtk::ComboBox* combo_ptr, const Glib::ustring& path)
{
std::cout << "Editing started columns: " << combo_ptr->get_model()->get_n_columns() << std::endl;
}


On the constructor we use g_signal_connect() for connect the function cb_editing_started to the signal editing-started, and we give also the this pointer.
Whe the signal was emitted the function cb_editing_started was called, the function receive on the data parameter the pointer we give on the contructor. So the function cast the pointer to the CellRendererComboDerived class. For create a gtkmm Gtk::ComboBox class from the GtkCellEditable we can use the Glib::wrap() function.
Now I need to implement this on ggredit...

2 commenti:

  1. Davidson garment is a quintessential Harley abercrombie Outlet davidson item, especially if you feature ones Harley decked abercrombie and fitch over. Featuring the whole distinctive line of leather abercrombie sale jackets, t-shirts, buckles, hats, belts, boots abercrombie & fitch and helmets, feeling of guilt reason this is abercrombie not to accessorize to max.A decent buy Harley enthusiast will abercrombie uk go in closet and grab a Harley t-shirt, leather jacket and boots. But, abercrombie london does your closet contain present accessory considering all abercrombie and Fitch Polo of? The Harley helmet. With out them your road abercrombie Polos trip could end in disaster.

    RispondiElimina