Re: inserting ColorButton in CellRenderer ....
- From: "Andrew E. Makeev" <andrew solvo ru>
- To: Roberto Alejandro Espí Muñoz <teratux gmail com>
- Cc: gtkmm-list <gtkmm-list gnome org>
- Subject: Re: inserting ColorButton in CellRenderer ....
- Date: Fri, 14 Mar 2008 10:50:37 +0300
В Чтв, 13/03/2008 в 15:14 -0400, Roberto Alejandro Espí Muñoz пишет:
> Thanks for your help. I'm trying to follow your directions. I still
> have some doubts about how to define the two functions you wish me to
> override. In get_size_vfunc I receive a &Widget, a Gdk::Rectangle*
> cell_area, an offset to x and y and a width and height parameters.
> How can I use them? Do I set those parameters onto the oncoming widget
> or do I set them from the Widget's parameters?? For the second
> function render_vfunc I didn't clearly understand what you wanted me
> to do.
The best way to understand those functions behavior is to look at source
code:
gtkcellrenderertext.c
gtkcellrenderertoggle.c
get_size_vfunc - should set width and height for cell you are going to
poaint button on.
render_vfunc - should paint the button itself.
I will attach source of my ButtonRenderer (Button with text) to give you
some hints. But don't copy it to your code, just get some clue how to
implement your renderer.
-andrew
#include "slib/dbglog.h"
#include "Utils.h"
#include "CellRendererButton.h"
#include "CellData.h"
#include "Profiler.h"
namespace Mgr
{
CellRendererButton::CellRendererButton() :
Glib::ObjectBase ( typeid( CellRendererButton ) ),
Gtk::CellRenderer (),
property_data_ ( *this, "data", ( void* )0 ),
property_row_color_ ( *this, "row_color", "" ),
property_activatable_( *this, "activatable", false ),
property_separator_ ( *this, "separator", true ),
property_format_ ( *this, "format", "" )
{
property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
property_xpad() = 2;
property_ypad() = 2;
}
Glib::PropertyProxy< void* > CellRendererButton::property_data()
{
return property_data_.get_proxy();
}
Glib::PropertyProxy< Glib::ustring > CellRendererButton::property_row_color()
{
return property_row_color_.get_proxy();
}
Glib::PropertyProxy< bool > CellRendererButton::property_activatable()
{
return property_activatable_.get_proxy();
}
Glib::PropertyProxy< bool > CellRendererButton::property_separator()
{
return property_separator_.get_proxy();
}
Glib::PropertyProxy< Glib::ustring > CellRendererButton::property_format()
{
return property_format_.get_proxy();
}
void CellRendererButton::get_size_vfunc
( Gtk::Widget& widget,
const Gdk::Rectangle* cell_area,
int* x_offset,
int* y_offset,
int* width,
int* height )
#if ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 4 )
const
#endif
{
Glib::ustring text;
#if ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 4 )
CellRendererButton* self = const_cast< CellRendererButton* >( this );
#else
CellRendererButton* self = this;
#endif
void* ptr = self->property_data().get_value();
if( ptr )
{
CellData* data = reinterpret_cast< CellData* >( ptr );
text = data->get_string();
}
Glib::RefPtr<Pango::Layout> ptrLayout = widget.create_pango_layout( text );
Pango::Rectangle rect = ptrLayout->get_pixel_logical_extents();
enum
{
TOGGLE_WIDTH = 12
};
const int calc_width = property_xpad() * 4 + std::max( (int)TOGGLE_WIDTH, rect.get_width() );
const int calc_height = property_ypad() * 4 + std::max( (int)TOGGLE_WIDTH, rect.get_height() );
if( width )
*width = calc_width;
if( height )
*height = calc_height;
if( self->property_format() == "invisible" )
return;
if( cell_area )
{
if( x_offset )
{
*x_offset = int( property_xalign() *
( cell_area->get_width() - calc_width ) );
*x_offset = std::max( 0, *x_offset );
}
if( y_offset )
{
*y_offset = int( property_yalign() *
( cell_area->get_height() - calc_height ) );
*y_offset = std::max( 0, *y_offset );
}
}
}
void CellRendererButton::render_vfunc
#if ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 4 )
( const Glib::RefPtr<Gdk::Drawable>& window,
#else
( const Glib::RefPtr<Gdk::Window>& window,
#endif
Gtk::Widget& widget,
const Gdk::Rectangle& background_area,
const Gdk::Rectangle& cell_area,
const Gdk::Rectangle& /*expose_area*/,
Gtk::CellRendererState flags )
{
Glib::ustring rowBG;
Glib::ustring text;
void* ptr = property_data().get_value();
if( ptr )
{
CellData* data = reinterpret_cast< CellData* >( ptr );
parse_attributes( data->get_attr() );
text = data->get_string();
}
Glib::RefPtr<Pango::Layout> ptrLayout = widget.create_pango_layout( text );
const unsigned int cell_xpad = property_xpad();
const unsigned int cell_ypad = property_ypad();
int x_offset = 0, y_offset = 0, width = 0, height = 0;
get_size( widget, cell_area, x_offset, y_offset, width, height );
width -= cell_xpad * 2;
height -= cell_ypad * 2;
if( width <= 0 || height <= 0 )
return;
Gtk::StateType state;
Gtk::StateType textState;
if( ( flags & Gtk::CELL_RENDERER_SELECTED ) != 0 )
{
state = Gtk::STATE_SELECTED;
textState = ( widget.has_focus() ) ? Gtk::STATE_SELECTED : Gtk::STATE_ACTIVE;
}
else
{
if( property_activatable_ )
state = Gtk::STATE_NORMAL;
else
state = Gtk::STATE_NORMAL;
textState = ( widget.is_sensitive() ) ? Gtk::STATE_NORMAL : Gtk::STATE_INSENSITIVE;
}
Glib::ustring row_attribute = property_row_color().get_value();
if( m_colColorSet )
{
if( state != Gtk::STATE_SELECTED )
{
Glib::RefPtr< Gdk::GC > gc = Gdk::GC::create( window );
gc->set_rgb_fg_color( m_colBgColor );
window->draw_rectangle( gc,
true,
background_area.get_x(),
background_area.get_y(),
background_area.get_width(),
background_area.get_height() );
}
}
else if( !row_attribute.empty() )
{
rowBG = Profiler::instance()->get_attr_bg( row_attribute );
if( state != Gtk::STATE_SELECTED )
{
Gdk::Color color;
if( color.parse( rowBG ) )
{
Glib::RefPtr<Gdk::GC> gc = Gdk::GC::create( window );
gc->set_rgb_fg_color( color );
window->draw_rectangle( gc,
true,
background_area.get_x(),
background_area.get_y(),
background_area.get_width(),
background_area.get_height() );
}
else
{
rowBG.clear();
}
}
}
if( property_format() == "invisible" )
{
if( state == Gtk::STATE_SELECTED )
{
Glib::RefPtr< Pango::Layout > ptrLayout = widget.create_pango_layout( "" );
#if ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 4 )
Glib::RefPtr<Gdk::Window> win = Glib::RefPtr<Gdk::Window>::cast_dynamic( window );
widget.get_style()->paint_layout
( win,
state,
true,
cell_area,
widget,
"cellrenderertext",
cell_area.get_x() + x_offset + cell_xpad,
cell_area.get_y() + y_offset + cell_ypad,
ptrLayout );
#else
widget.get_style()->paint_layout
( window,
state,
true,
cell_area,
widget,
"cellrenderertext",
cell_area.get_x() + x_offset + cell_xpad,
cell_area.get_y() + y_offset + cell_ypad,
ptrLayout );
#endif
}
}
else
{
#if ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 4 )
Glib::RefPtr<Gdk::Window> win =
Glib::RefPtr<Gdk::Window>::cast_dynamic( window );
widget.get_style()->paint_box
( win, state, Gtk::SHADOW_OUT,
cell_area, widget, "button",
cell_area.get_x() + x_offset + cell_xpad,
cell_area.get_y() + y_offset + cell_ypad,
width, height );
widget.get_style()->paint_layout
( win,
textState,
true,
cell_area,
widget,
"cellrenderertext",
cell_area.get_x() + x_offset + 2 * cell_xpad,
cell_area.get_y() + y_offset + 2 * cell_ypad,
ptrLayout );
#else
widget.get_style()->paint_box
( window, state, Gtk::SHADOW_OUT,
cell_area, widget, "button",
cell_area.get_x() + x_offset + cell_xpad,
cell_area.get_y() + y_offset + cell_ypad,
width, height );
widget.get_style()->paint_layout
( window,
textState,
true,
cell_area,
widget,
"cellrenderertext",
cell_area.get_x() + x_offset + cell_xpad,
cell_area.get_y() + y_offset + cell_ypad,
ptrLayout );
#endif
}
if( m_colColorSet && state == Gtk::STATE_SELECTED )
{
Glib::RefPtr< Gdk::GC > gc = Gdk::GC::create( window );
gc->set_rgb_fg_color( m_colBgColor );
window->draw_rectangle( gc,
true,
background_area.get_x(),
background_area.get_y() + 1,
background_area.get_width(),
3 );
window->draw_rectangle( gc,
true,
background_area.get_x(),
background_area.get_y() + background_area.get_height() - 4,
background_area.get_width(),
3 );
}
else if( !rowBG.empty() && state == Gtk::STATE_SELECTED )
{
Gdk::Color color;
if( color.parse( rowBG ) )
{
Glib::RefPtr< Gdk::GC > gc = Gdk::GC::create( window );
gc->set_rgb_fg_color( color );
window->draw_rectangle( gc,
true,
background_area.get_x(),
background_area.get_y() + 1,
background_area.get_width(),
3 );
window->draw_rectangle( gc,
true,
background_area.get_x(),
background_area.get_y() + background_area.get_height() - 4,
background_area.get_width(),
3 );
}
}
}
bool CellRendererButton::activate_vfunc( GdkEvent*,
Gtk::Widget&,
const Glib::ustring& path,
const Gdk::Rectangle&,
const Gdk::Rectangle&,
Gtk::CellRendererState )
{
if( property_activatable_ )
{
Glib::ustring local_path = path;
signal_toggled_( local_path );
return true;
}
return false;
}
void CellRendererButton::parse_attributes( const Glib::ustring& attr_str )
{
m_colColorSet = false;
if( attr_str == "" )
return;
if( Profiler::instance() == 0 )
return;
Glib::ustring val = Profiler::instance()->get_attr_bg( attr_str );
if( m_colBgColor.parse( val ) )
m_colColorSet = true;
}
} // namespace Mgr
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]