[gtkmm] writing a custom cellrenderer
- From: Roel Vanhout <rvanhout riks nl>
- To: gtkmm-list gnome org
- Subject: [gtkmm] writing a custom cellrenderer
- Date: Wed, 30 Jun 2004 10:17:54 +0200
Hello all,
I spend the bigger part of yesterday evening trying to write a custom
cellrenderer for Gtk::TreeView but I didn't get it to work. I'm porting
an application from plain C Gtk to C++ with gtkmm. In the original
application I used the code from
http://scentric.net/tutorial/sec-custom-cell-renderers.html, which was
luckily exactly what I needed (in C). I thought that for a C++ version
all I'd have to is derive my own class from Gtk::CellRenderer, override
a few methods (that would have been declare pure virtual so that the
compiler would point me to them) and that would be it. Turns out I was
wrong.
I started by looking at
http://www.gtkmm.org/docs/gtkmm-2.4/docs/reference/html/classGtk_1_1CellRend
erer.html.
I didn't see anything there that indicated what functions I had to
override to make my own so I just write a small class, overriding
get_size(), _property_renderable() and render() and copied the code from
my original C renderer to the corresponding functions. I had to massage
it a bit to get it into C++ format and then it compiled. I used the
add_column() method that takes a custom renderer and when all of that
compiled I thought it'd work, but all I saw was a blank cell. So I
looked at the implementation of the CellRendererText and -Pixbut in the
gtkmm source and to my horror I found all the structs from the C version
in there - the init thing and a sort of virtual vtable and all the
things I hoped I would never have to bother with again when I switched
to gtkmm. I'm still hoping that this is only because they wrap the C
version and that it is possible to write one in pure C++.
Ok so sorry if this sounds frustrated (it's because I am), but here are
a few questions that I have:
- What functions do I have to override and what do I have to implement
to get a custom cellrenderer, a complete new one and not one that just
wraps a C version? I think I'm missing two things: first, registering a
custom property ('progress' in my case), and secondly registring the
cellrenderer itself somewhere.
- All properties (like property_xalign()) have comments like "You rarely
need to use properties because there are get_ and set_ methods for
almost all of them.". But are there really? Where are they declared? How
should I use those properties?
- What are the protected methods in CellRenderer (like get_size_vfunc()
) used for? Should I override them?
- Why are there two versions of get_size? Is there an easy way to
implement the one in terms of the other or should I write full
implementations for both?
I've attached the code that I have so far. Some of it is commented out,
that's what I was trying after I got everything to compile but when it
didn't work. It's mostly copied from CellRendererText, but that one
wraps the C version so it's not quite the same as what I try to do.
Thanks in advance.
cheers,
roel
#include <gtkmm.h>
#define FIXED_WIDTH 100
#define FIXED_HEIGHT 10
class CellRendererProgress : public Gtk::CellRenderer
{
/*class CellRendererProgress_Class
{
public:
const Glib::Class& init()
{
if (!gtype) {
class_init_func_ = &CellRendererProgress_Class::class_init_functions;
CppClassParent::CppObjectType::get_type();
}
return *this;
}
void class_init_function(void* g_class, void* class_data)
{
BaseClassType* const klass = static_cast<BaseClassType*>(g_class);
CppClassParent::class_init_function(klass, class_data);
klass->edited = &edited_callback;
}
};
typedef CellRendererProgress_Class CppClassType;
static CppClassType cellrendererprogress_class_;
GType GetType()
{
cellrendererprogress_class_.init().get_type();
}*/
void render(const Glib::RefPtr<Gdk::Window>& window
, Gtk::Widget& widget, const Gdk::Rectangle& background_area
, const Gdk::Rectangle& cell_area
, const Gdk::Rectangle& expose_area, Gtk::CellRendererState flags)
{
std::cout << "In render" << std::endl;
//CellRendererProgress* cellprogress = CUSTOM_CELL_RENDERER_PROGRESS (cell);
Gtk::StateType state;
gint width, height;
gint x_offset, y_offset;
Glib::RefPtr<Gtk::Style> style = Gtk::RC::get_style(widget);
get_size(widget, cell_area, x_offset, y_offset, width, height);
if (widget.has_focus()) {
state = Gtk::STATE_ACTIVE;
} else {
state = Gtk::STATE_NORMAL;
}
width -= this->property_xpad() * 2;
height -= this->property_ypad() * 2;
style->paint_box(window,
Gtk::STATE_NORMAL, Gtk::SHADOW_IN,
cell_area, widget, "trough",
cell_area.get_x() + x_offset + this->property_xpad(),
cell_area.get_y() + y_offset + this->property_ypad(),
width - 1, height - 1);
if ( (int)(width * this->property_progress() ) > 0) {
style->paint_box (window,
state, Gtk::SHADOW_OUT,
cell_area, widget, "bar",
cell_area.get_x() + x_offset + this->property_xpad(),
cell_area.get_y() + y_offset + this->property_ypad(),
width * this->property_progress(),
height - 1);
}
}
void get_size(Gtk::Widget& widget, int& x_offset, int& y_offset
, int& width, int& height) const
{
//get_size(widget, Gdk::Rec);
gint calc_width;
gint calc_height;
calc_width = (gint) const_cast<ProgressCellRenderer*>(this)->property_xpad() * 2 + FIXED_WIDTH;
calc_height = (gint) const_cast<ProgressCellRenderer*>(this)->property_ypad() * 2 + FIXED_HEIGHT;
if (width) {
width = calc_width;
}
if (height) {
height = calc_height;
}
}
void get_size(Gtk::Widget& widget, const Gdk::Rectangle& cell_area, int& x_offset, int& y_offset
, int& width, int& height) const
{
get_size(widget, x_offset, y_offset, width, height);
gint calc_width;
gint calc_height;
calc_width = (gint) const_cast<ProgressCellRenderer*>(this)->property_xpad() * 2 + FIXED_WIDTH;
calc_height = (gint) const_cast<ProgressCellRenderer*>(this)->property_ypad() * 2 + FIXED_HEIGHT;
if (x_offset) {
x_offset = (int)const_cast<ProgressCellRenderer*>(this)->property_xalign() * (cell_area.get_width() - calc_width);
x_offset = std::max(x_offset, 0);
}
if (y_offset) {
y_offset = const_cast<ProgressCellRenderer*>(this)->property_yalign() * (cell_area.get_height() - calc_height);
y_offset = std::max(y_offset, 0);
}
}
virtual Glib::PropertyProxy_Base _property_renderable()
{
return property_progress();
}
Glib::PropertyProxy<int> property_progress()
{
return Glib::PropertyProxy<int>(this, "progress");
}
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]