| 1 | /****************************************************************************
|
|---|
| 2 | ** $Id: border.cpp 2 2005-11-16 15:49:26Z dmik $
|
|---|
| 3 | **
|
|---|
| 4 | ** Implementing your own layout: flow example
|
|---|
| 5 | **
|
|---|
| 6 | ** Copyright (C) 1996 by Trolltech AS. All rights reserved.
|
|---|
| 7 | **
|
|---|
| 8 | ** This file is part of an example program for Qt. This example
|
|---|
| 9 | ** program may be used, distributed and modified without limitation.
|
|---|
| 10 | **
|
|---|
| 11 | *****************************************************************************/
|
|---|
| 12 |
|
|---|
| 13 | #include "border.h"
|
|---|
| 14 |
|
|---|
| 15 | class BorderLayoutIterator : public QGLayoutIterator
|
|---|
| 16 | {
|
|---|
| 17 | public:
|
|---|
| 18 | BorderLayoutIterator( const QPtrList<BorderLayout::BorderLayoutStruct> *l )
|
|---|
| 19 | : idx( 0 ) , list( (QPtrList<BorderLayout::BorderLayoutStruct>*)l )
|
|---|
| 20 | {}
|
|---|
| 21 |
|
|---|
| 22 | uint count() const;
|
|---|
| 23 | QLayoutItem *current();
|
|---|
| 24 | BorderLayout::BorderLayoutStruct *currentStruct();
|
|---|
| 25 | void toFirst();
|
|---|
| 26 | QLayoutItem *next();
|
|---|
| 27 | QLayoutItem *takeCurrent();
|
|---|
| 28 | BorderLayoutIterator &operator++();
|
|---|
| 29 |
|
|---|
| 30 | private:
|
|---|
| 31 | int idx;
|
|---|
| 32 | QPtrList<BorderLayout::BorderLayoutStruct> *list;
|
|---|
| 33 |
|
|---|
| 34 | };
|
|---|
| 35 |
|
|---|
| 36 | uint BorderLayoutIterator::count() const
|
|---|
| 37 | {
|
|---|
| 38 | return list->count();
|
|---|
| 39 | }
|
|---|
| 40 |
|
|---|
| 41 | QLayoutItem *BorderLayoutIterator::current()
|
|---|
| 42 | {
|
|---|
| 43 | return idx < (int)count() ? list->at( idx )->item : 0;
|
|---|
| 44 | }
|
|---|
| 45 |
|
|---|
| 46 | BorderLayout::BorderLayoutStruct *BorderLayoutIterator::currentStruct()
|
|---|
| 47 | {
|
|---|
| 48 | return idx < (int)count() ? list->at( idx ) : 0;
|
|---|
| 49 | }
|
|---|
| 50 |
|
|---|
| 51 | void BorderLayoutIterator::toFirst()
|
|---|
| 52 | {
|
|---|
| 53 | idx = 0;
|
|---|
| 54 | }
|
|---|
| 55 |
|
|---|
| 56 | QLayoutItem *BorderLayoutIterator::next()
|
|---|
| 57 | {
|
|---|
| 58 | idx++;
|
|---|
| 59 | return current();
|
|---|
| 60 | }
|
|---|
| 61 |
|
|---|
| 62 | QLayoutItem *BorderLayoutIterator::takeCurrent()
|
|---|
| 63 | {
|
|---|
| 64 | BorderLayout::BorderLayoutStruct *b
|
|---|
| 65 | = idx < int( list->count() ) ? list->take( idx ) : 0;
|
|---|
| 66 | QLayoutItem *item = b ? b->item : 0;
|
|---|
| 67 | delete b;
|
|---|
| 68 | return item;
|
|---|
| 69 | }
|
|---|
| 70 |
|
|---|
| 71 | BorderLayoutIterator &BorderLayoutIterator::operator++()
|
|---|
| 72 | {
|
|---|
| 73 | next();
|
|---|
| 74 | return *this;
|
|---|
| 75 | }
|
|---|
| 76 |
|
|---|
| 77 | BorderLayout::~BorderLayout()
|
|---|
| 78 | {
|
|---|
| 79 | deleteAllItems();
|
|---|
| 80 | }
|
|---|
| 81 |
|
|---|
| 82 |
|
|---|
| 83 | void BorderLayout::addItem( QLayoutItem *item )
|
|---|
| 84 | {
|
|---|
| 85 | add( item, West );
|
|---|
| 86 | }
|
|---|
| 87 |
|
|---|
| 88 | void BorderLayout::addWidget( QWidget *widget, Position pos )
|
|---|
| 89 | {
|
|---|
| 90 | add( new BorderWidgetItem( widget ), pos );
|
|---|
| 91 | }
|
|---|
| 92 |
|
|---|
| 93 | void BorderLayout::add( QLayoutItem *item, Position pos )
|
|---|
| 94 | {
|
|---|
| 95 | list.append( new BorderLayoutStruct( item, pos ) );
|
|---|
| 96 | sizeDirty = TRUE; msizeDirty = TRUE;
|
|---|
| 97 | calcSize( SizeHint ); calcSize( Minimum );
|
|---|
| 98 | }
|
|---|
| 99 |
|
|---|
| 100 | bool BorderLayout::hasHeightForWidth() const
|
|---|
| 101 | {
|
|---|
| 102 | return FALSE;
|
|---|
| 103 | }
|
|---|
| 104 |
|
|---|
| 105 | QSize BorderLayout::sizeHint() const
|
|---|
| 106 | {
|
|---|
| 107 | return cached;
|
|---|
| 108 | }
|
|---|
| 109 |
|
|---|
| 110 | QSize BorderLayout::minimumSize() const
|
|---|
| 111 | {
|
|---|
| 112 | return cached;
|
|---|
| 113 | }
|
|---|
| 114 |
|
|---|
| 115 | QSizePolicy::ExpandData BorderLayout::expanding() const
|
|---|
| 116 |
|
|---|
| 117 | {
|
|---|
| 118 | return QSizePolicy::BothDirections;
|
|---|
| 119 | }
|
|---|
| 120 |
|
|---|
| 121 | QLayoutIterator BorderLayout::iterator()
|
|---|
| 122 | {
|
|---|
| 123 | return QLayoutIterator( new BorderLayoutIterator( &list ) );
|
|---|
| 124 | }
|
|---|
| 125 |
|
|---|
| 126 | void BorderLayout::setGeometry( const QRect &rct )
|
|---|
| 127 | {
|
|---|
| 128 | QLayout::setGeometry( rct );
|
|---|
| 129 | doLayout( rct );
|
|---|
| 130 | }
|
|---|
| 131 |
|
|---|
| 132 | void BorderLayout::doLayout( const QRect &rct, bool /*testonly*/ )
|
|---|
| 133 | {
|
|---|
| 134 | int ew = 0, ww = 0, nh = 0, sh = 0;
|
|---|
| 135 | int h = 0;
|
|---|
| 136 |
|
|---|
| 137 | BorderLayoutIterator it( &list );
|
|---|
| 138 | BorderLayoutStruct *o;
|
|---|
| 139 | BorderLayoutStruct *center = 0;
|
|---|
| 140 | while ( ( o = it.currentStruct() ) != 0 ) {
|
|---|
| 141 | ++it;
|
|---|
| 142 |
|
|---|
| 143 | if ( o->pos == North ) {
|
|---|
| 144 | o->item->setGeometry( QRect( rct.x(), nh, rct.width(), o->item->sizeHint().height() ) );
|
|---|
| 145 | nh += o->item->geometry().height() + spacing();
|
|---|
| 146 | }
|
|---|
| 147 | if ( o->pos == South ) {
|
|---|
| 148 | o->item->setGeometry( QRect( o->item->geometry().x(), o->item->geometry().y(),
|
|---|
| 149 | rct.width(), o->item->sizeHint().height() ) );
|
|---|
| 150 | sh += o->item->geometry().height() + spacing();
|
|---|
| 151 | o->item->setGeometry( QRect( rct.x(), rct.y() + rct.height() - sh + spacing(),
|
|---|
| 152 | o->item->geometry().width(), o->item->geometry().height() ) );
|
|---|
| 153 | }
|
|---|
| 154 | if ( o->pos == Center )
|
|---|
| 155 | center = o;
|
|---|
| 156 | }
|
|---|
| 157 |
|
|---|
| 158 | h = rct.height() - nh - sh;
|
|---|
| 159 |
|
|---|
| 160 | it.toFirst();
|
|---|
| 161 | while ( ( o = it.currentStruct() ) != 0 ) {
|
|---|
| 162 | ++it;
|
|---|
| 163 |
|
|---|
| 164 | if ( o->pos == West ) {
|
|---|
| 165 | o->item->setGeometry( QRect( rct.x() + ww, nh, o->item->sizeHint().width(), h ) );
|
|---|
| 166 | ww += o->item->geometry().width() + spacing();
|
|---|
| 167 | }
|
|---|
| 168 | if ( o->pos == East ) {
|
|---|
| 169 | o->item->setGeometry( QRect( o->item->geometry().x(), o->item->geometry().y(),
|
|---|
| 170 | o->item->sizeHint().width(), h ) );
|
|---|
| 171 | ew += o->item->geometry().width() + spacing();
|
|---|
| 172 | o->item->setGeometry( QRect( rct.x() + rct.width() - ew + spacing(), nh,
|
|---|
| 173 | o->item->geometry().width(), o->item->geometry().height() ) );
|
|---|
| 174 | }
|
|---|
| 175 | }
|
|---|
| 176 |
|
|---|
| 177 | if ( center )
|
|---|
| 178 | center->item->setGeometry( QRect( ww, nh, rct.width() - ew - ww, h ) );
|
|---|
| 179 | }
|
|---|
| 180 |
|
|---|
| 181 | void BorderLayout::calcSize( SizeType st )
|
|---|
| 182 | {
|
|---|
| 183 | if ( ( st == Minimum && !msizeDirty ) ||
|
|---|
| 184 | ( st == SizeHint && !sizeDirty ) )
|
|---|
| 185 | return;
|
|---|
| 186 |
|
|---|
| 187 | int w = 0, h = 0;
|
|---|
| 188 |
|
|---|
| 189 | BorderLayoutIterator it( &list );
|
|---|
| 190 | BorderLayoutStruct *o;
|
|---|
| 191 | while ( ( o = it.currentStruct() ) != 0 ) {
|
|---|
| 192 | ++it;
|
|---|
| 193 | if ( o->pos == North ||
|
|---|
| 194 | o->pos == South ) {
|
|---|
| 195 | if ( st == Minimum )
|
|---|
| 196 | h += o->item->minimumSize().height();
|
|---|
| 197 | else
|
|---|
| 198 | h += o->item->sizeHint().height();
|
|---|
| 199 | }
|
|---|
| 200 | else if ( o->pos == West ||
|
|---|
| 201 | o->pos == East ) {
|
|---|
| 202 | if ( st == Minimum )
|
|---|
| 203 | w += o->item->minimumSize().width();
|
|---|
| 204 | else
|
|---|
| 205 | w += o->item->sizeHint().width();
|
|---|
| 206 | } else {
|
|---|
| 207 | if ( st == Minimum ) {
|
|---|
| 208 | h += o->item->minimumSize().height();
|
|---|
| 209 | w += o->item->minimumSize().width();
|
|---|
| 210 | }
|
|---|
| 211 | else {
|
|---|
| 212 | h += o->item->sizeHint().height();
|
|---|
| 213 | w += o->item->sizeHint().width();
|
|---|
| 214 | }
|
|---|
| 215 | }
|
|---|
| 216 | }
|
|---|
| 217 |
|
|---|
| 218 | if ( st == Minimum ) {
|
|---|
| 219 | msizeDirty = FALSE;
|
|---|
| 220 | mcached = QSize( w, h );
|
|---|
| 221 | } else {
|
|---|
| 222 | sizeDirty = FALSE;
|
|---|
| 223 | cached = QSize( w, h );
|
|---|
| 224 | }
|
|---|
| 225 |
|
|---|
| 226 | return;
|
|---|
| 227 | }
|
|---|