Home | All Classes | Main Classes | Annotated | Grouped Classes | Functions |
This examples demonstrates how to write customized layout (geometry) managers like card layouts, border layout and flow layouts.
See also: Documentation of Geometry Management.
Header file of the flow layout:
/**************************************************************************** ** $Id: qt/flow.h 3.3.8 edited Jan 11 14:46 $ ** ** Definition of simple flow layout for custom layout example ** ** Created : 979899 ** ** Copyright (C) 1997-2007 Trolltech ASA. All rights reserved. ** ** This file is part of an example program for TQt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/ #ifndef FLOW_H #define FLOW_H #include <qlayout.h> #include <qptrlist.h> class SimpleFlow : public TQLayout { public: SimpleFlow( TQWidget *parent, int border=0, int space=-1, const char *name=0 ) : TQLayout( parent, border, space, name ), cached_width(0) {} SimpleFlow( TQLayout* parent, int space=-1, const char *name=0 ) : TQLayout( parent, space, name ), cached_width(0) {} SimpleFlow( int space=-1, const char *name=0 ) : TQLayout( space, name ), cached_width(0) {} ~SimpleFlow(); void addItem( TQLayoutItem *item); bool hasHeightForWidth() const; int heightForWidth( int ) const; TQSize sizeHint() const; TQSize minimumSize() const; TQLayoutIterator iterator(); TQSizePolicy::ExpandData expanding() const; protected: void setGeometry( const TQRect& ); private: int doLayout( const TQRect&, bool testonly = FALSE ); TQPtrList<TQLayoutItem> list; int cached_width; int cached_hfw; }; #endif
Implementation of the flow layout:
/**************************************************************************** ** $Id: qt/flow.cpp 3.3.8 edited Jan 11 14:46 $ ** ** Implementing your own layout: flow example ** ** Copyright (C) 1996-2007 Trolltech ASA. All rights reserved. ** ** This file is part of an example program for TQt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/ #include "flow.h" class SimpleFlowIterator :public TQGLayoutIterator { public: SimpleFlowIterator( TQPtrList<TQLayoutItem> *l ) :idx(0), list(l) {} uint count() const; TQLayoutItem *current(); TQLayoutItem *next(); TQLayoutItem *takeCurrent(); private: int idx; TQPtrList<TQLayoutItem> *list; }; uint SimpleFlowIterator::count() const { return list->count(); } TQLayoutItem *SimpleFlowIterator::current() { return idx < int(count()) ? list->at(idx) : 0; } TQLayoutItem *SimpleFlowIterator::next() { idx++; return current(); } TQLayoutItem *SimpleFlowIterator::takeCurrent() { return idx < int(count()) ? list->take( idx ) : 0; } SimpleFlow::~SimpleFlow() { deleteAllItems(); } int SimpleFlow::heightForWidth( int w ) const { if ( cached_width != w ) { //Not all C++ compilers support "mutable" yet: SimpleFlow * mthis = (SimpleFlow*)this; int h = mthis->doLayout( TQRect(0,0,w,0), TRUE ); mthis->cached_hfw = h; mthis->cached_width = w; return h; } return cached_hfw; } void SimpleFlow::addItem( TQLayoutItem *item) { list.append( item ); } bool SimpleFlow::hasHeightForWidth() const { return TRUE; } TQSize SimpleFlow::sizeHint() const { return minimumSize(); } TQSizePolicy::ExpandData SimpleFlow::expanding() const { return TQSizePolicy::NoDirection; } TQLayoutIterator SimpleFlow::iterator() { return TQLayoutIterator( new SimpleFlowIterator( &list ) ); } void SimpleFlow::setGeometry( const TQRect &r ) { TQLayout::setGeometry( r ); doLayout( r ); } int SimpleFlow::doLayout( const TQRect &r, bool testonly ) { int x = r.x(); int y = r.y(); int h = 0; //height of this line so far. TQPtrListIterator<TQLayoutItem> it(list); TQLayoutItem *o; while ( (o=it.current()) != 0 ) { ++it; int nextX = x + o->sizeHint().width() + spacing(); if ( nextX - spacing() > r.right() && h > 0 ) { x = r.x(); y = y + h + spacing(); nextX = x + o->sizeHint().width() + spacing(); h = 0; } if ( !testonly ) o->setGeometry( TQRect( TQPoint( x, y ), o->sizeHint() ) ); x = nextX; h = TQMAX( h, o->sizeHint().height() ); } return y + h - r.y(); } TQSize SimpleFlow::minimumSize() const { TQSize s(0,0); TQPtrListIterator<TQLayoutItem> it(list); TQLayoutItem *o; while ( (o=it.current()) != 0 ) { ++it; s = s.expandedTo( o->minimumSize() ); } return s; }
Header file of the border layout:
/**************************************************************************** ** $Id: qt/border.h 3.3.8 edited Jan 11 14:46 $ ** ** Definition of simple flow layout for custom layout example ** ** Created : 979899 ** ** Copyright (C) 1997-2007 Trolltech ASA. All rights reserved. ** ** This file is part of an example program for TQt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/ #ifndef BORDER_H #define BORDER_H #include <qlayout.h> #include <qptrlist.h> class BorderWidgetItem : public TQWidgetItem { public: BorderWidgetItem( TQWidget *w ) : TQWidgetItem( w ) {} void setGeometry( const TQRect &r ) { widget()->setGeometry( r ); } }; class BorderLayout : public TQLayout { public: enum Position { West = 0, North, South, East, Center }; struct BorderLayoutStruct { BorderLayoutStruct( TQLayoutItem *i, Position p ) { item = i; pos = p; } TQLayoutItem *item; Position pos; }; enum SizeType { Minimum = 0, SizeHint }; BorderLayout( TQWidget *parent, int border = 0, int autoBorder = -1, const char *name = 0 ) : TQLayout( parent, border, autoBorder, name ), cached( 0, 0 ), mcached( 0, 0 ), sizeDirty( TRUE ), msizeDirty( TRUE ) {} BorderLayout( TQLayout* parent, int autoBorder = -1, const char *name = 0 ) : TQLayout( parent, autoBorder, name ), cached( 0, 0 ), mcached( 0, 0 ), sizeDirty( TRUE ), msizeDirty( TRUE ) {} BorderLayout( int autoBorder = -1, const char *name = 0 ) : TQLayout( autoBorder, name ), cached( 0, 0 ), mcached( 0, 0 ), sizeDirty( TRUE ), msizeDirty( TRUE ) {} ~BorderLayout(); void addItem( TQLayoutItem *item ); void addWidget( TQWidget *widget, Position pos ); void add( TQLayoutItem *item, Position pos ); bool hasHeightForWidth() const; TQSize sizeHint() const; TQSize minimumSize() const; TQLayoutIterator iterator(); TQSizePolicy::ExpandData expanding() const; protected: void setGeometry( const TQRect &rect ); private: void doLayout( const TQRect &rect, bool testonly = FALSE ); void calcSize( SizeType st ); TQPtrList<BorderLayoutStruct> list; TQSize cached, mcached; bool sizeDirty, msizeDirty; }; #endif
Implementation of the border layout:
/**************************************************************************** ** $Id: qt/border.cpp 3.3.8 edited Jan 11 14:46 $ ** ** Implementing your own layout: flow example ** ** Copyright (C) 1996-2007 Trolltech ASA. All rights reserved. ** ** This file is part of an example program for TQt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/ #include "border.h" class BorderLayoutIterator : public TQGLayoutIterator { public: BorderLayoutIterator( const TQPtrList<BorderLayout::BorderLayoutStruct> *l ) : idx( 0 ) , list( (TQPtrList<BorderLayout::BorderLayoutStruct>*)l ) {} uint count() const; TQLayoutItem *current(); BorderLayout::BorderLayoutStruct *currentStruct(); void toFirst(); TQLayoutItem *next(); TQLayoutItem *takeCurrent(); BorderLayoutIterator &operator++(); private: int idx; TQPtrList<BorderLayout::BorderLayoutStruct> *list; }; uint BorderLayoutIterator::count() const { return list->count(); } TQLayoutItem *BorderLayoutIterator::current() { return idx < (int)count() ? list->at( idx )->item : 0; } BorderLayout::BorderLayoutStruct *BorderLayoutIterator::currentStruct() { return idx < (int)count() ? list->at( idx ) : 0; } void BorderLayoutIterator::toFirst() { idx = 0; } TQLayoutItem *BorderLayoutIterator::next() { idx++; return current(); } TQLayoutItem *BorderLayoutIterator::takeCurrent() { BorderLayout::BorderLayoutStruct *b = idx < int( list->count() ) ? list->take( idx ) : 0; TQLayoutItem *item = b ? b->item : 0; delete b; return item; } BorderLayoutIterator &BorderLayoutIterator::operator++() { next(); return *this; } BorderLayout::~BorderLayout() { deleteAllItems(); } void BorderLayout::addItem( TQLayoutItem *item ) { add( item, West ); } void BorderLayout::addWidget( TQWidget *widget, Position pos ) { add( new BorderWidgetItem( widget ), pos ); } void BorderLayout::add( TQLayoutItem *item, Position pos ) { list.append( new BorderLayoutStruct( item, pos ) ); sizeDirty = TRUE; msizeDirty = TRUE; calcSize( SizeHint ); calcSize( Minimum ); } bool BorderLayout::hasHeightForWidth() const { return FALSE; } TQSize BorderLayout::sizeHint() const { return cached; } TQSize BorderLayout::minimumSize() const { return cached; } TQSizePolicy::ExpandData BorderLayout::expanding() const { return TQSizePolicy::BothDirections; } TQLayoutIterator BorderLayout::iterator() { return TQLayoutIterator( new BorderLayoutIterator( &list ) ); } void BorderLayout::setGeometry( const TQRect &rct ) { TQLayout::setGeometry( rct ); doLayout( rct ); } void BorderLayout::doLayout( const TQRect &rct, bool /*testonly*/ ) { int ew = 0, ww = 0, nh = 0, sh = 0; int h = 0; BorderLayoutIterator it( &list ); BorderLayoutStruct *o; BorderLayoutStruct *center = 0; while ( ( o = it.currentStruct() ) != 0 ) { ++it; if ( o->pos == North ) { o->item->setGeometry( TQRect( rct.x(), nh, rct.width(), o->item->sizeHint().height() ) ); nh += o->item->geometry().height() + spacing(); } if ( o->pos == South ) { o->item->setGeometry( TQRect( o->item->geometry().x(), o->item->geometry().y(), rct.width(), o->item->sizeHint().height() ) ); sh += o->item->geometry().height() + spacing(); o->item->setGeometry( TQRect( rct.x(), rct.y() + rct.height() - sh + spacing(), o->item->geometry().width(), o->item->geometry().height() ) ); } if ( o->pos == Center ) center = o; } h = rct.height() - nh - sh; it.toFirst(); while ( ( o = it.currentStruct() ) != 0 ) { ++it; if ( o->pos == West ) { o->item->setGeometry( TQRect( rct.x() + ww, nh, o->item->sizeHint().width(), h ) ); ww += o->item->geometry().width() + spacing(); } if ( o->pos == East ) { o->item->setGeometry( TQRect( o->item->geometry().x(), o->item->geometry().y(), o->item->sizeHint().width(), h ) ); ew += o->item->geometry().width() + spacing(); o->item->setGeometry( TQRect( rct.x() + rct.width() - ew + spacing(), nh, o->item->geometry().width(), o->item->geometry().height() ) ); } } if ( center ) center->item->setGeometry( TQRect( ww, nh, rct.width() - ew - ww, h ) ); } void BorderLayout::calcSize( SizeType st ) { if ( ( st == Minimum && !msizeDirty ) || ( st == SizeHint && !sizeDirty ) ) return; int w = 0, h = 0; BorderLayoutIterator it( &list ); BorderLayoutStruct *o; while ( ( o = it.currentStruct() ) != 0 ) { ++it; if ( o->pos == North || o->pos == South ) { if ( st == Minimum ) h += o->item->minimumSize().height(); else h += o->item->sizeHint().height(); } else if ( o->pos == West || o->pos == East ) { if ( st == Minimum ) w += o->item->minimumSize().width(); else w += o->item->sizeHint().width(); } else { if ( st == Minimum ) { h += o->item->minimumSize().height(); w += o->item->minimumSize().width(); } else { h += o->item->sizeHint().height(); w += o->item->sizeHint().width(); } } } if ( st == Minimum ) { msizeDirty = FALSE; mcached = TQSize( w, h ); } else { sizeDirty = FALSE; cached = TQSize( w, h ); } return; }
Header file of the card layout:
/**************************************************************************** ** $Id: qt/card.h 3.3.8 edited Jan 11 14:46 $ ** ** Definition of simple flow layout for custom layout example ** ** Created : 979899 ** ** Copyright (C) 1997-2007 Trolltech ASA. All rights reserved. ** ** This file is part of an example program for TQt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/ #ifndef CARD_H #define CARD_H #include <qlayout.h> #include <qptrlist.h> class CardLayout : public TQLayout { public: CardLayout( TQWidget *parent, int dist ) : TQLayout( parent, 0, dist ) {} CardLayout( TQLayout* parent, int dist) : TQLayout( parent, dist ) {} CardLayout( int dist ) : TQLayout( dist ) {} ~CardLayout(); void addItem( TQLayoutItem *item ); TQSize sizeHint() const; TQSize minimumSize() const; TQLayoutIterator iterator(); void setGeometry( const TQRect &rect ); private: TQPtrList<TQLayoutItem> list; }; #endif
Implementation of the card layout:
/**************************************************************************** ** $Id: qt/card.cpp 3.3.8 edited Jan 11 14:46 $ ** ** Implementing your own layout: flow example ** ** Copyright (C) 1996-2007 Trolltech ASA. All rights reserved. ** ** This file is part of an example program for TQt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/ #include "card.h" class CardLayoutIterator :public TQGLayoutIterator { public: CardLayoutIterator( TQPtrList<TQLayoutItem> *l ) : idx( 0 ), list( l ) {} TQLayoutItem *current(); TQLayoutItem *next(); TQLayoutItem *takeCurrent(); private: int idx; TQPtrList<TQLayoutItem> *list; }; TQLayoutItem *CardLayoutIterator::current() { return idx < int( list->count() ) ? list->at( idx ) : 0; } TQLayoutItem *CardLayoutIterator::next() { idx++; return current(); } TQLayoutItem *CardLayoutIterator::takeCurrent() { return idx < int( list->count() ) ?list->take( idx ) : 0; } TQLayoutIterator CardLayout::iterator() { return TQLayoutIterator( new CardLayoutIterator( &list ) ); } CardLayout::~CardLayout() { deleteAllItems(); } void CardLayout::addItem( TQLayoutItem *item ) { list.append( item ); } void CardLayout::setGeometry( const TQRect &rct ) { TQLayout::setGeometry( rct ); TQPtrListIterator<TQLayoutItem> it( list ); if ( it.count() == 0 ) return; TQLayoutItem *o; int i = 0; int w = rct.width() - ( list.count() - 1 ) * spacing(); int h = rct.height() - ( list.count() - 1 ) * spacing(); while ( ( o=it.current() ) != 0 ) { ++it; TQRect geom( rct.x() + i * spacing(), rct.y() + i * spacing(), w, h ); o->setGeometry( geom ); ++i; } } TQSize CardLayout::sizeHint() const { TQSize s(0,0); int n = list.count(); if ( n > 0 ) s = TQSize(100,70); //start with a nice default size TQPtrListIterator<TQLayoutItem> it(list); TQLayoutItem *o; while ( (o=it.current()) != 0 ) { ++it; s = s.expandedTo( o->minimumSize() ); } return s + n*TQSize(spacing(),spacing()); } TQSize CardLayout::minimumSize() const { TQSize s(0,0); int n = list.count(); TQPtrListIterator<TQLayoutItem> it(list); TQLayoutItem *o; while ( (o=it.current()) != 0 ) { ++it; s = s.expandedTo( o->minimumSize() ); } return s + n*TQSize(spacing(),spacing()); }
Main:
/**************************************************************************** ** $Id: qt/main.cpp 3.3.8 edited Jan 11 14:46 $ ** ** Main for custom layout example ** ** Copyright (C) 1996-2007 Trolltech ASA. All rights reserved. ** ** This file is part of an example program for TQt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/ #include "flow.h" #include "border.h" #include "card.h" #include <qapplication.h> #include <qlabel.h> #include <qcolor.h> #include <qgroupbox.h> #include <qpushbutton.h> #include <qmultilineedit.h> #include <qcolor.h> int main( int argc, char **argv ) { TQApplication a( argc, argv ); TQWidget *f = new TQWidget; TQBoxLayout *gm = new TQVBoxLayout( f, 5 ); SimpleFlow *b1 = new SimpleFlow( gm ); b1->add( new TQPushButton( "Short", f ) ); b1->add( new TQPushButton( "Longer", f ) ); b1->add( new TQPushButton( "Different text", f ) ); b1->add( new TQPushButton( "More text", f ) ); b1->add( new TQPushButton( "Even longer button text", f ) ); TQPushButton* qb = new TQPushButton( "Quit", f ); a.connect( qb, SIGNAL( clicked() ), SLOT( tquit() ) ); b1->add( qb ); TQWidget *wid = new TQWidget( f ); BorderLayout *large = new BorderLayout( wid ); large->setSpacing( 5 ); large->addWidget( new TQPushButton( "North", wid ), BorderLayout::North ); large->addWidget( new TQPushButton( "West", wid ), BorderLayout::West ); TQMultiLineEdit* m = new TQMultiLineEdit( wid ); m->setText( "Central\nWidget" ); large->addWidget( m, BorderLayout::Center ); TQWidget *east1 = new TQPushButton( "East", wid ); large->addWidget( east1, BorderLayout::East ); TQWidget *east2 = new TQPushButton( "East 2", wid ); large->addWidget( east2 , BorderLayout::East ); large->addWidget( new TQPushButton( "South", wid ), BorderLayout::South ); //Left-to-right tab order looks better: TQWidget::setTabOrder( east2, east1 ); gm->addWidget( wid ); wid = new TQWidget( f ); CardLayout *card = new CardLayout( wid, 10 ); TQWidget *crd = new TQWidget( wid ); crd->setBackgroundColor( TQt::red ); card->add( crd ); crd = new TQWidget( wid ); crd->setBackgroundColor( TQt::green ); card->add( crd ); crd = new TQWidget( wid ); crd->setBackgroundColor( TQt::blue ); card->add( crd ); crd = new TQWidget( wid ); crd->setBackgroundColor( TQt::white ); card->add( crd ); crd = new TQWidget( wid ); crd->setBackgroundColor( TQt::black ); card->add( crd ); crd = new TQWidget( wid ); crd->setBackgroundColor( TQt::yellow ); card->add( crd ); gm->addWidget( wid ); TQLabel* s = new TQLabel( f ); s->setText( "outermost box" ); s->setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); s->setAlignment( TQt::AlignVCenter | TQt::AlignHCenter ); gm->addWidget( s ); a.setMainWidget( f ); f->setCaption("TQt Example - Custom Layout"); f->show(); int result = a.exec(); delete f; return result; }
See also Examples.
Copyright © 2007 Trolltech | Trademarks | TQt 3.3.8
|