ScrolledWindow problem
- From: "Andrew E. Makeev" <andrew solvo ru>
- To: gtkmm-list <gtkmm-list gnome org>
- Subject: ScrolledWindow problem
- Date: Wed, 20 Apr 2011 18:38:56 +0400
I found the error in Gtk::ScrolledWindow class.
The methods get_hscrollbar() and get_vscrollbar() always return 0,
because gtk_scrolled_window_get_hscrollbar() and
gtk_scrolled_window_get_vscrollbar() both return object of type
GtkScrolledBar that cannot be wrapped to Gtk::HScrollbar and
Gtk::VScrollbar.
There is simple test where I discover the problem.
Installed Component versions:
atk-2.0.0
atkmm-2.22.5
cairo-1.10.2
cairomm-1.9.8
fontconfig-2.8.0
gdk-pixbuf-2.22.1
glib-2.28.5
glibmm-2.28.0
gtk+-3.0.8
gtkmm-3.0.0
libsigc++-2.2.9
pango-1.28.4
pangomm-2.28.2
pixman-0.20.2
--
Andrew E. Makeev <andrew solvo ru>
Solvo Logistic
#include <gtk/gtk.h>
#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/label.h>
#include <gtkmm/entry.h>
#include <gtkmm/main.h>
#include <gtkmm/scrollbar.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/stock.h>
#include <gtkmm/window.h>
#include <iostream>
class ScrolledWindow : public Gtk::ScrolledWindow
{
public:
ScrolledWindow()
: Gtk::ScrolledWindow()
, htype_( Gtk::POLICY_AUTOMATIC )
, vtype_( Gtk::POLICY_AUTOMATIC ) {}
~ScrolledWindow()
{
}
void set_policy( Gtk::PolicyType htype, Gtk::PolicyType vtype )
{
htype_ = htype;
vtype_ = vtype;
Gtk::ScrolledWindow::set_policy( htype_, vtype_ );
}
protected:
int gtk_scrolled_window_get_scrollbar_spacing() const
{
GtkScrolledWindowClass* klass = GTK_SCROLLED_WINDOW_GET_CLASS( this->gobj() );
if( klass->scrollbar_spacing >= 0 )
return klass->scrollbar_spacing;
else
{
int scrollbar_spacing;
get_style_property( "scrollbar_spacing", scrollbar_spacing );
return scrollbar_spacing;
}
}
void get_preferred_width_vfunc( int& minWidth, int& natWidth ) const
{
get_preferred_size( Gtk::ORIENTATION_HORIZONTAL, minWidth, natWidth );
}
void get_preferred_height_vfunc( int& minHeight, int& natHeight ) const
{
get_preferred_size( Gtk::ORIENTATION_VERTICAL, minHeight, natHeight );
}
private:
void get_preferred_size( Gtk::Orientation orientation,
int& minSize,
int& natSize ) const
{
int extraWidth = 0;
int extraHeight = 0;
minSize = natSize = 0;
int scrollbarSpacing = gtk_scrolled_window_get_scrollbar_spacing();
Gtk::Requisition hscrollbarRequisition;
Gtk::Requisition vscrollbarRequisition;
Gtk::Requisition fakeReq;
//const Gtk::HScrollbar* hb = get_hscrollbar();
/* replaced ^^^^^^^^^^ to get my code working as I expected */
Gtk::Scrollbar* hb = 0;
GtkScrollbar* ghb = ( GtkScrollbar* )
gtk_scrolled_window_get_hscrollbar( const_cast< GtkScrolledWindow* >( gobj() ) );
if( ghb == NULL )
{
std::cout << "GTK scrollbar is NULL" << std::endl;
}
else if( GTK_IS_HSCROLLBAR( ghb ) )
{
std::cout << "GTK scrollbar is VALID" << std::endl;
}
else
{
std::cout << "GTK scrollbar is type: " << G_OBJECT_TYPE_NAME( ghb ) << std::endl;
GTypeInstance* ginst = (GTypeInstance*)ghb;
GTypeClass* gclass = (GTypeClass*)ginst->g_class;
GType gtype = gclass->g_type;
hb = Glib::wrap( ghb );
}
/* ^^^^^^^^^^^ recomment to get HScrollbar always NULL ^^^^^^^^^^^^^*/
const Gtk::VScrollbar* vb = get_vscrollbar();
if( hb )
hb->get_preferred_size( hscrollbarRequisition, fakeReq );
else
{
hscrollbarRequisition.width = 0;
hscrollbarRequisition.height = 0;
}
if( vb )
vb->get_preferred_size( vscrollbarRequisition, fakeReq );
else
{
vscrollbarRequisition.width = 0;
vscrollbarRequisition.height = 0;
}
const Gtk::Widget* child = get_child();
if( child && child->get_visible() )
{
int minChildSize, natChildSize;
if( orientation == Gtk::ORIENTATION_HORIZONTAL )
{
if( htype_ == Gtk::POLICY_NEVER )
{
child->get_preferred_width( minChildSize, natChildSize );
minSize += minChildSize;
natSize += natChildSize;
}
else
{
int minWidth = property_min_content_width().get_value();
if( vb && vb->get_visible() )
{
minWidth = MAX( minWidth, vscrollbarRequisition.width );
}
minSize += minWidth;
natSize += minWidth;
}
}
else
{
if( vtype_ == Gtk::POLICY_NEVER )
{
child->get_preferred_height( minChildSize, natChildSize );
minSize += minChildSize;
natSize += natChildSize;
}
else
{
int minHeight = property_min_content_height().get_value();
if( hb && hb->get_visible() )
{
minHeight = MAX( minHeight, hscrollbarRequisition.height );
}
minSize += minHeight;
natSize += minHeight;
}
}
}
if( htype_ != Gtk::POLICY_NEVER )
{
if( orientation == Gtk::ORIENTATION_HORIZONTAL )
{
minSize = MAX( minSize, hscrollbarRequisition.width );
natSize = MAX( natSize, hscrollbarRequisition.width );
}
}
if( vtype_ != Gtk::POLICY_NEVER )
{
if( orientation == Gtk::ORIENTATION_VERTICAL )
{
minSize = MAX( minSize, vscrollbarRequisition.height );
natSize = MAX( natSize, vscrollbarRequisition.height );
}
}
std::cout << "HB: " << hb << " vis: " << ( hb ? hb->get_visible() : false ) << std::endl;
if( hb && hb->get_visible() )
extraHeight = scrollbarSpacing + hscrollbarRequisition.height;
if( vb && vb->get_visible() )
extraWidth = scrollbarSpacing + vscrollbarRequisition.width;
if( orientation == Gtk::ORIENTATION_HORIZONTAL )
{
minSize += MAX( 0, extraWidth );
natSize += MAX( 0, extraWidth );
}
else
{
minSize += MAX( 0, extraHeight );
natSize += MAX( 0, extraHeight );
}
if( get_shadow_type() != Gtk::SHADOW_NONE )
{
Glib::RefPtr< Gtk::StyleContext > context = get_style_context();
Gtk::StateFlags state = get_state_flags();
context->context_save();
context->add_class( GTK_STYLE_CLASS_FRAME );
Gtk::Border padding = context->get_padding( state );
Gtk::Border border = context->get_border( state );
if( orientation == Gtk::ORIENTATION_HORIZONTAL )
{
minSize += ( padding.get_left() + padding.get_right() + border.get_left() + border.get_right() );
natSize += ( padding.get_left() + padding.get_right() + border.get_left() + border.get_right() );
}
else
{
minSize += ( padding.get_top() + padding.get_bottom() + border.get_top() + border.get_bottom() );
natSize += ( padding.get_top() + padding.get_bottom() + border.get_top() + border.get_bottom() );
}
context->context_restore();
}
}
Gtk::PolicyType htype_;
Gtk::PolicyType vtype_;
};
class App : public Gtk::Window
{
public:
App() : Gtk::Window( Gtk::WINDOW_TOPLEVEL )
{
Gtk::VBox* vbox = Gtk::manage( new Gtk::VBox( false, 5 ) );
add( *vbox );
ScrolledWindow* sw = Gtk::manage( new ScrolledWindow() );
sw->set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_NEVER );
vbox->pack_start( *sw, false, false );
Gtk::HBox* box = Gtk::manage( new Gtk::HBox( false, 5 ) );
sw->add( *box );
Gtk::Label* l = Gtk::manage( new Gtk::Label( "Entry:" ) );
box->pack_start( *l, false, false );
Gtk::Entry* e = Gtk::manage( new Gtk::Entry() );
box->pack_start( *e, false, false );
Gtk::Button* b = Gtk::manage( new Gtk::Button( Gtk::Stock::CLOSE ) );
b->signal_clicked().connect( sigc::ptr_fun( &Gtk::Main::quit ) );
box->pack_start( *b, false, false );
l = Gtk::manage( new Gtk::Label( "Spacer" ) );
vbox->pack_start( *l, true, false );
show_all_children();
}
};
int main( int argc, char* argv[] )
{
Gtk::Main kit( argc, argv );
App app;
kit.run( app );
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]