| 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 <ntqlayout.h>
#include <ntqptrlist.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 <ntqlayout.h>
#include <ntqptrlist.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 <ntqlayout.h>
#include <ntqptrlist.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 <ntqapplication.h>
#include <ntqlabel.h>
#include <ntqcolor.h>
#include <ntqgroupbox.h>
#include <ntqpushbutton.h>
#include <ntqmultilineedit.h>
#include <ntqcolor.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, TQ_SIGNAL( clicked() ), TQ_SLOT( quit() ) );
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
|