diff options
Diffstat (limited to 'tqtinterface/qt4/src/widgets/tqsplitter.cpp')
-rw-r--r-- | tqtinterface/qt4/src/widgets/tqsplitter.cpp | 1366 |
1 files changed, 0 insertions, 1366 deletions
diff --git a/tqtinterface/qt4/src/widgets/tqsplitter.cpp b/tqtinterface/qt4/src/widgets/tqsplitter.cpp deleted file mode 100644 index 18cf11c..0000000 --- a/tqtinterface/qt4/src/widgets/tqsplitter.cpp +++ /dev/null @@ -1,1366 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQSplitter class -** -** Created : 980105 -** -** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. -** -** This file is part of the widgets module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#include "tqsplitter.h" -#ifndef TQT_NO_SPLITTER - -#include "tqlayout.h" -#include "../kernel/tqlayoutengine_p.h" -#include "tqapplication.h" -#include "tqbitmap.h" -#include "tqdrawutil.h" -#include "tqmemarray.h" -#include "tqobjectlist.h" -#include "tqpainter.h" -#include "tqptrlist.h" -#include "tqstyle.h" - -const uint Default = TQT_TQSPLITTER_DEFAULT; - -static int mouseOffset; -static int opaqueOldPos = -1; // this assumes that there's only one mouse - -static TQPoint toggle( TQWidget *w, TQPoint pos ) -{ - TQSize minS = tqSmartMinSize( w ); - return -pos - TQPoint( minS.width(), minS.height() ); -} - -static bool isCollapsed( TQWidget *w ) -{ - return w->x() < 0 || w->y() < 0; -} - -static TQPoint topLeft( TQWidget *w ) -{ - if ( isCollapsed(w) ) { - return toggle( w, w->pos() ); - } else { - return w->pos(); - } -} - -static TQPoint bottomRight( TQWidget *w ) -{ - if ( isCollapsed(w) ) { - return toggle( w, w->pos() ) - TQPoint( 1, 1 ); - } else { - return w->tqgeometry().bottomRight(); - } -} - -TQSplitterHandle::TQSplitterHandle( Qt::Orientation o, TQSplitter *parent, - const char * name ) - : TQWidget( parent, name ) -{ - s = parent; - setOrientation( o ); -} - -TQSize TQSplitterHandle::tqsizeHint() const -{ - int hw = s->handleWidth(); - return parentWidget()->tqstyle().tqsizeFromContents( TQStyle::CT_Splitter, s, - TQSize(hw, hw) ) - .expandedTo( TQApplication::globalStrut() ); -} - -void TQSplitterHandle::setOrientation( Qt::Orientation o ) -{ - orient = o; -#ifndef TQT_NO_CURSOR - setCursor( o == Qt::Horizontal ? Qt::SplitHCursor : Qt::SplitVCursor ); -#endif -} - -void TQSplitterHandle::mouseMoveEvent( TQMouseEvent *e ) -{ - if ( !(e->state()&Qt::LeftButton) ) - return; - TQCOORD pos = s->pick( parentWidget()->mapFromGlobal(e->globalPos()) ) - - mouseOffset; - if ( opaque() ) { - s->moveSplitter( pos, id() ); - } else { - s->setRubberband( s->adjustPos(pos, id()) ); - } -} - -void TQSplitterHandle::mousePressEvent( TQMouseEvent *e ) -{ - if ( e->button() == Qt::LeftButton ) - mouseOffset = s->pick( e->pos() ); -} - -void TQSplitterHandle::mouseReleaseEvent( TQMouseEvent *e ) -{ - if ( !opaque() && e->button() == Qt::LeftButton ) { - TQCOORD pos = s->pick( parentWidget()->mapFromGlobal(e->globalPos()) ) - - mouseOffset; - s->setRubberband( -1 ); - s->moveSplitter( pos, id() ); - } -} - -void TQSplitterHandle::paintEvent( TQPaintEvent * ) -{ - TQPainter p( this ); - parentWidget()->tqstyle().tqdrawPrimitive( TQStyle::PE_Splitter, &p, rect(), - tqcolorGroup(), - (TQStyle::SFlags)(orientation() == Qt::Horizontal ? - TQStyle::Style_Horizontal : 0) ); -} - -TQCOORD TQSplitterLayoutStruct::getSizer( Qt::Orientation orient ) -{ - if ( sizer == -1 ) { - TQSize s = wid->tqsizeHint(); - if ( !s.isValid() || wid->testWState(WState_Resized) ) - s = wid->size(); - sizer = ( orient == Qt::Horizontal ) ? s.width() : s.height(); - } - return sizer; -} - -/*! - \class TQSplitter - \brief The TQSplitter class implements a splitter widget. - - \ingroup organizers - \mainclass - - A splitter lets the user control the size of child widgets by - dragging the boundary between the tqchildren. Any number of widgets - may be controlled by a single splitter. - - To show a TQListBox, a TQListView and a TQTextEdit side by side: - \code - TQSplitter *split = new TQSplitter( parent ); - TQListBox *lb = new TQListBox( split ); - TQListView *lv = new TQListView( split ); - TQTextEdit *ed = new TQTextEdit( split ); - \endcode - - TQSplitter lays out its tqchildren horizontally (side by side); you - can use setOrientation(TQSplitter::Vertical) to lay out the - tqchildren vertically. - - By default, all widgets can be as large or as small as the user - wishes, between the \l tqminimumSizeHint() (or \l tqminimumSize()) - and \l tqmaximumSize() of the widgets. Use setResizeMode() to - specify that a widget should keep its size when the splitter is - resized, or set the stretch component of the \l sizePolicy. - - Although TQSplitter normally resizes the tqchildren only at the end - of a resize operation, if you call setOpaqueResize(TRUE) the - widgets are resized as often as possible. - - The initial distribution of size between the widgets is determined - by the initial size of each widget. You can also use setSizes() to - set the sizes of all the widgets. The function sizes() returns the - sizes set by the user. - - If you hide() a child its space will be distributed among the - other tqchildren. It will be reinstated when you show() it again. It - is also possible to reorder the widgets within the splitter using - moveToFirst() and moveToLast(). - - <img src=qsplitter-m.png> <img src=qsplitter-w.png> - - \sa TQTabBar -*/ - - -/*! - Constructs a horizontal splitter with the \a parent and \a name - arguments being passed on to the TQFrame constructor. -*/ - -TQSplitter::TQSplitter( TQWidget *parent, const char *name ) - : TQFrame( parent, name, TQt::WPaintUnclipped ) -{ - orient = Qt::Horizontal; - init(); -} - - -/*! - Constructs a splitter with orientation \a o with the \a parent and - \a name arguments being passed on to the TQFrame constructor. -*/ - -TQSplitter::TQSplitter( Qt::Orientation o, TQWidget *parent, const char *name ) - : TQFrame( parent, name, TQt::WPaintUnclipped ) -{ - orient = o; - init(); -} - - -/*! - Destroys the splitter and any tqchildren. -*/ - -TQSplitter::~TQSplitter() -{ - delete d; -} - - -void TQSplitter::init() -{ - d = new TQSplitterPrivate; - d->list.setAutoDelete( TRUE ); - TQSizePolicy sp( TQSizePolicy::Expanding, TQSizePolicy::Preferred ); - if ( orient == Qt::Vertical ) - sp.transpose(); - tqsetSizePolicy( sp ); - clearWState( TQt::WState_OwnSizePolicy ); -} - -/*! - \fn void TQSplitter::refresh() - - Updates the splitter's state. You should not need to call this - function. -*/ - - -/*! - \property TQSplitter::orientation - \brief the orientation of the splitter - - By default the orientation is horizontal (the widgets are side by - side). The possible orientations are \c Qt::Horizontal and - \c Qt::Vertical. -*/ - -void TQSplitter::setOrientation( Qt::Orientation o ) -{ - if ( orient == o ) - return; - - if ( !testWState( TQt::WState_OwnSizePolicy ) ) { - TQSizePolicy sp = tqsizePolicy(); - sp.transpose(); - tqsetSizePolicy( sp ); - clearWState( TQt::WState_OwnSizePolicy ); - } - - orient = o; - - TQSplitterLayoutStruct *s = d->list.first(); - while ( s ) { - if ( s->isHandle ) - ((TQSplitterHandle*)s->wid)->setOrientation( o ); - s = d->list.next(); - } - recalc( isVisible() ); -} - -/*! - \property TQSplitter::tqchildrenCollapsible - \brief whether child widgets can be resized down to size 0 by the user - - By default, tqchildren are collapsible. It is possible to enable - and disable the collapsing of individual tqchildren; see - setCollapsible(). -*/ - -void TQSplitter::setChildrenCollapsible( bool collapse ) -{ - d->tqchildrenCollapsible = collapse; -} - -bool TQSplitter::tqchildrenCollapsible() const -{ - return d->tqchildrenCollapsible; -} - -/*! - Sets whether the child widget \a w is collapsible to \a collapse. - - By default, tqchildren are collapsible, meaning that the user can - resize them down to size 0, even if they have a non-zero - tqminimumSize() or tqminimumSizeHint(). This behavior can be changed - on a per-widget basis by calling this function, or globally for - all the widgets in the splitter by setting the \l - tqchildrenCollapsible property. - - \sa tqchildrenCollapsible -*/ - -void TQSplitter::setCollapsible( TQWidget *w, bool collapse ) -{ - findWidget( w )->collapsible = collapse ? 1 : 0; -} - -/*! - \reimp -*/ -void TQSplitter::resizeEvent( TQResizeEvent * ) -{ - doResize(); -} - -TQSplitterLayoutStruct *TQSplitter::findWidget( TQWidget *w ) -{ - processChildEvents(); - TQSplitterLayoutStruct *s = d->list.first(); - while ( s ) { - if ( s->wid == w ) - return s; - s = d->list.next(); - } - return addWidget( w ); -} - -/* - Inserts the widget \a w at the end (or at the beginning if \a - prepend is TRUE) of the splitter's list of widgets. - - It is the responsibility of the caller to make sure that \a w is - not already in the splitter and to call recalcId() if needed. (If - \a prepend is TRUE, then recalcId() is very probably needed.) -*/ - -TQSplitterLayoutStruct *TQSplitter::addWidget( TQWidget *w, bool prepend ) -{ - TQSplitterLayoutStruct *s; - TQSplitterHandle *newHandle = 0; - if ( d->list.count() > 0 ) { - s = new TQSplitterLayoutStruct; - s->resizeMode = KeepSize; - TQString tmp = "qt_splithandle_"; - tmp += w->name(); - newHandle = new TQSplitterHandle( orientation(), this, tmp ); - s->wid = newHandle; - newHandle->setId( d->list.count() ); - s->isHandle = TRUE; - s->sizer = pick( newHandle->tqsizeHint() ); - if ( prepend ) - d->list.prepend( s ); - else - d->list.append( s ); - } - s = new TQSplitterLayoutStruct; - s->resizeMode = DefaultResizeMode; - s->wid = w; - s->isHandle = FALSE; - if ( prepend ) - d->list.prepend( s ); - else - d->list.append( s ); - if ( newHandle && isVisible() ) - newHandle->show(); // will trigger sending of post events - return s; -} - - -/*! - Tells the splitter that the child widget described by \a c has - been inserted or removed. -*/ - -void TQSplitter::childEvent( TQChildEvent *c ) -{ - if ( c->type() == TQEvent::ChildInserted ) { - if ( !c->child()->isWidgetType() ) - return; - - if ( ((TQWidget*)c->child())->testWFlags( TQt::WType_TopLevel ) ) - return; - - TQSplitterLayoutStruct *s = d->list.first(); - while ( s ) { - if ( s->wid == c->child() ) - return; - s = d->list.next(); - } - addWidget( (TQWidget*)c->child() ); - recalc( isVisible() ); - } else if ( c->type() == TQEvent::ChildRemoved ) { - TQSplitterLayoutStruct *prev = 0; - if ( d->list.count() > 1 ) - prev = d->list.at( 1 ); // yes, this is correct - TQSplitterLayoutStruct *curr = d->list.first(); - while ( curr ) { - if ( curr->wid == c->child() ) { - d->list.removeRef( curr ); - if ( prev && prev->isHandle ) { - TQWidget *w = prev->wid; - d->list.removeRef( prev ); - delete w; // will call childEvent() - } - recalcId(); - doResize(); - return; - } - prev = curr; - curr = d->list.next(); - } - } -} - - -/*! - Displays a rubber band at position \a p. If \a p is negative, the - rubber band is removed. -*/ - -void TQSplitter::setRubberband( int p ) -{ - TQPainter paint( this ); - paint.setPen( Qt::gray ); - paint.setBrush( Qt::gray ); - paint.setRasterOp( TQt::XorROP ); - TQRect r = contentsRect(); - const int rBord = 3; // customizable? - int hw = handleWidth(); - if ( orient == Qt::Horizontal ) { - if ( opaqueOldPos >= 0 ) - paint.drawRect( opaqueOldPos + hw / 2 - rBord, r.y(), - 2 * rBord, r.height() ); - if ( p >= 0 ) - paint.drawRect( p + hw / 2 - rBord, r.y(), 2 * rBord, r.height() ); - } else { - if ( opaqueOldPos >= 0 ) - paint.drawRect( r.x(), opaqueOldPos + hw / 2 - rBord, - r.width(), 2 * rBord ); - if ( p >= 0 ) - paint.drawRect( r.x(), p + hw / 2 - rBord, r.width(), 2 * rBord ); - } - opaqueOldPos = p; -} - - -/*! - \reimp -*/ - -bool TQSplitter::event( TQEvent *e ) -{ - switch ( e->type() ) { - case TQEvent::Show: - if ( !d->firstShow ) - break; - d->firstShow = FALSE; - // fall through - case TQEvent::LayoutHint: - recalc( isVisible() ); - break; - default: - ; - } - return TQWidget::event( e ); -} - - -/*! - \obsolete - - Draws the splitter handle in the rectangle described by \a x, \a y, - \a w, \a h using painter \a p. - \sa TQStyle::tqdrawPrimitive() -*/ - -// ### Remove this in 4.0 - -void TQSplitter::drawSplitter( TQPainter *p, - TQCOORD x, TQCOORD y, TQCOORD w, TQCOORD h ) -{ - tqstyle().tqdrawPrimitive(TQStyle::PE_Splitter, p, TQRect(x, y, w, h), tqcolorGroup(), - (TQStyle::SFlags)(orientation() == Qt::Horizontal ? - TQStyle::Style_Horizontal : 0)); -} - - -/*! - Returns the ID of the widget to the right of or below the widget - \a w, or 0 if there is no such widget (i.e. it is either not in - this TQSplitter or \a w is at the end). -*/ - -int TQSplitter::idAfter( TQWidget* w ) const -{ - TQSplitterLayoutStruct *s = d->list.first(); - bool seen_w = FALSE; - while ( s ) { - if ( s->isHandle && seen_w ) - return d->list.at(); - if ( !s->isHandle && s->wid == w ) - seen_w = TRUE; - s = d->list.next(); - } - return 0; -} - - -/*! - Moves the left/top edge of the splitter handle with ID \a id as - close as possible to position \a p, which is the distance from the - left (or top) edge of the widget. - - For Arabic, Hebrew and other right-to-left languages the tqlayout is - reversed. \a p is then the distance from the right (or top) edge - of the widget. - - \sa idAfter() -*/ -void TQSplitter::moveSplitter( TQCOORD p, int id ) -{ - TQSplitterLayoutStruct *s = d->list.at( id ); - int farMin; - int min; - int max; - int farMax; - - p = adjustPos( p, id, &farMin, &min, &max, &farMax ); - int oldP = pick( s->wid->pos() ); - - if ( TQApplication::reverseLayout() && orient == Qt::Horizontal ) { - int q = p + s->wid->width(); - doMove( FALSE, q, id - 1, -1, (q > oldP), (p > max) ); - doMove( TRUE, q, id, -1, (q > oldP), (p < min) ); - } else { - doMove( FALSE, p, id, +1, (p < oldP), (p > max) ); - doMove( TRUE, p, id - 1, +1, (p < oldP), (p < min) ); - } - storeSizes(); -} - - -void TQSplitter::setGeo( TQWidget *w, int p, int s, bool splitterMoved ) -{ - TQRect r; - if ( orient == Qt::Horizontal ) { - if ( TQApplication::reverseLayout() && orient == Qt::Horizontal - && !splitterMoved ) - p = contentsRect().width() - p - s; - r.setRect( p, contentsRect().y(), s, contentsRect().height() ); - } else { - r.setRect( contentsRect().x(), p, contentsRect().width(), s ); - } - - /* - Hide the child widget, but without calling hide() so that the - splitter handle is still shown. - */ - if ( !w->isHidden() && s <= 0 && pick(tqSmartMinSize(w)) > 0 ) - r.moveTopLeft( toggle(w, r.topLeft()) ); - w->setGeometry( r ); -} - - -void TQSplitter::doMove( bool backwards, int pos, int id, int delta, bool upLeft, - bool mayCollapse ) -{ - if ( id < 0 || id >= (int) d->list.count() ) - return; - - TQSplitterLayoutStruct *s = d->list.at( id ); - TQWidget *w = s->wid; - - int nextId = backwards ? id - delta : id + delta; - - if ( w->isHidden() ) { - doMove( backwards, pos, nextId, delta, upLeft, TRUE ); - } else { - if ( s->isHandle ) { - int dd = s->getSizer( orient ); - int nextPos = backwards ? pos - dd : pos + dd; - int left = backwards ? pos - dd : pos; - setGeo( w, left, dd, TRUE ); - doMove( backwards, nextPos, nextId, delta, upLeft, mayCollapse ); - } else { - int dd = backwards ? pos - pick( topLeft(w) ) - : pick( bottomRight(w) ) - pos + 1; - if ( dd > 0 || (!isCollapsed(w) && !mayCollapse) ) { - dd = TQMAX( pick(tqSmartMinSize(w)), - TQMIN(dd, pick(w->tqmaximumSize())) ); - } else { - dd = 0; - } - setGeo( w, backwards ? pos - dd : pos, dd, TRUE ); - doMove( backwards, backwards ? pos - dd : pos + dd, nextId, delta, - upLeft, TRUE ); - } - } -} - -int TQSplitter::findWidgetJustBeforeOrJustAfter( int id, int delta, int &collapsibleSize ) -{ - id += delta; - do { - TQWidget *w = d->list.at( id )->wid; - if ( !w->isHidden() ) { - if ( collapsible(d->list.at(id)) ) - collapsibleSize = pick( tqSmartMinSize(w) ); - return id; - } - id += 2 * delta; // go to previous (or next) widget, skip the handle - } while ( id >= 0 && id < (int)d->list.count() ); - - return -1; -} - -void TQSplitter::getRange( int id, int *farMin, int *min, int *max, int *farMax ) -{ - int n = d->list.count(); - if ( id <= 0 || id >= n - 1 ) - return; - - int collapsibleSizeBefore = 0; - int idJustBefore = findWidgetJustBeforeOrJustAfter( id, -1, collapsibleSizeBefore ); - - int collapsibleSizeAfter = 0; - int idJustAfter = findWidgetJustBeforeOrJustAfter( id, +1, collapsibleSizeAfter ); - - int minBefore = 0; - int minAfter = 0; - int maxBefore = 0; - int maxAfter = 0; - int i; - - for ( i = 0; i < id; i++ ) - addContribution( i, &minBefore, &maxBefore, i == idJustBefore ); - for ( i = id; i < n; i++ ) - addContribution( i, &minAfter, &maxAfter, i == idJustAfter ); - - TQRect r = contentsRect(); - int farMinVal; - int minVal; - int maxVal; - int farMaxVal; - - int smartMinBefore = TQMAX( minBefore, pick(r.size()) - maxAfter ); - int smartMaxBefore = TQMIN( maxBefore, pick(r.size()) - minAfter ); - - if ( orient == Qt::Vertical || !TQApplication::reverseLayout() ) { - minVal = pick( r.topLeft() ) + smartMinBefore; - maxVal = pick( r.topLeft() ) + smartMaxBefore; - - farMinVal = minVal; - if ( minBefore - collapsibleSizeBefore >= pick(r.size()) - maxAfter ) - farMinVal -= collapsibleSizeBefore; - farMaxVal = maxVal; - if ( pick(r.size()) - (minAfter - collapsibleSizeAfter) <= maxBefore ) - farMaxVal += collapsibleSizeAfter; - } else { - int hw = handleWidth(); - minVal = r.width() - smartMaxBefore - hw; - maxVal = r.width() - smartMinBefore - hw; - - farMinVal = minVal; - if ( pick(r.size()) - (minAfter - collapsibleSizeAfter) <= maxBefore ) - farMinVal -= collapsibleSizeAfter; - farMaxVal = maxVal; - if ( minBefore - collapsibleSizeBefore >= pick(r.size()) - maxAfter ) - farMaxVal += collapsibleSizeBefore; - } - - if ( farMin ) - *farMin = farMinVal; - if ( min ) - *min = minVal; - if ( max ) - *max = maxVal; - if ( farMax ) - *farMax = farMaxVal; -} - -/*! - Returns the valid range of the splitter with ID \a id in \a *min - and \a *max if \a min and \a max are not 0. - - \sa idAfter() -*/ - -void TQSplitter::getRange( int id, int *min, int *max ) -{ - getRange( id, min, 0, 0, max ); -} - - -/*! - Returns the closest legal position to \a pos of the widget with ID - \a id. - - \sa idAfter() -*/ - -int TQSplitter::adjustPos( int pos, int id ) -{ - int x, i, n, u; - return adjustPos( pos, id, &u, &n, &i, &x ); -} - -int TQSplitter::adjustPos( int pos, int id, int *farMin, int *min, int *max, - int *farMax ) -{ - const int Threshold = 40; - - getRange( id, farMin, min, max, farMax ); - - if ( pos >= *min ) { - if ( pos <= *max ) { - return pos; - } else { - int delta = pos - *max; - int width = *farMax - *max; - - if ( delta > width / 2 && delta >= TQMIN(Threshold, width) ) { - return *farMax; - } else { - return *max; - } - } - } else { - int delta = *min - pos; - int width = *min - *farMin; - - if ( delta > width / 2 && delta >= TQMIN(Threshold, width) ) { - return *farMin; - } else { - return *min; - } - } -} - -bool TQSplitter::collapsible( TQSplitterLayoutStruct *s ) -{ - if (pick(tqSmartMinSize(s->wid)) == 1) - return FALSE; - if ( s->collapsible != Default ) { - return (bool) s->collapsible; - } else { - return d->tqchildrenCollapsible; - } -} - -void TQSplitter::doResize() -{ - TQRect r = contentsRect(); - int n = d->list.count(); - TQMemArray<TQLayoutStruct> a( n ); - - for ( int pass = 0; pass < 2; pass++ ) { - int numAutoWithStretch = 0; - int numAutoWithoutStretch = 0; - - for ( int i = 0; i < n; i++ ) { - a[i].init(); - TQSplitterLayoutStruct *s = d->list.at( i ); - if ( s->wid->isHidden() || isCollapsed(s->wid) ) { - a[i].tqmaximumSize = 0; - } else if ( s->isHandle ) { - a[i].tqsizeHint = a[i].tqminimumSize = a[i].tqmaximumSize = s->sizer; - a[i].empty = FALSE; - } else { - int mode = s->resizeMode; - int stretch = 1; - - if ( mode == DefaultResizeMode ) { - TQSizePolicy p = s->wid->tqsizePolicy(); - int sizePolicyStretch = - pick( TQSize(p.horStretch(), p.verStretch()) ); - if ( sizePolicyStretch > 0 ) { - mode = Stretch; - stretch = sizePolicyStretch; - numAutoWithStretch++; - } else { - /* - Do things differently on the second pass, - if there's one. A second pass is necessary - if it was found out during the first pass - that all DefaultResizeMode items are - KeepSize items. In that case, we make them - all Stretch items instead, for a more TQt - 3.0-compatible behavior. - */ - mode = ( pass == 0 ) ? KeepSize : Stretch; - numAutoWithoutStretch++; - } - } - - a[i].tqminimumSize = pick( tqSmartMinSize(s->wid) ); - a[i].tqmaximumSize = pick( s->wid->tqmaximumSize() ); - a[i].empty = FALSE; - - if ( mode == Stretch ) { - if ( s->getSizer(orient) > 1 ) - stretch *= s->getSizer( orient ); - // TQMIN(): ad hoc work-around for tqlayout engine limitation - a[i].stretch = TQMIN( stretch, 8192 ); - a[i].tqsizeHint = a[i].tqminimumSize; - } else if ( mode == KeepSize ) { - a[i].tqsizeHint = s->getSizer( orient ); - } else { // mode == FollowSizeHint - a[i].tqsizeHint = pick( s->wid->tqsizeHint() ); - } - } - } - - // a second pass would yield the same results - if ( numAutoWithStretch > 0 || numAutoWithoutStretch == 0 ) - break; - } - - qGeomCalc( a, 0, n, pick( r.topLeft() ), pick( r.size() ), 0 ); - - for ( int i = 0; i < n; i++ ) { - TQSplitterLayoutStruct *s = d->list.at(i); - setGeo( s->wid, a[i].pos, a[i].size, FALSE ); - } -} - -void TQSplitter::recalc( bool update ) -{ - int fi = 2 * frameWidth(); - int maxl = fi; - int minl = fi; - int maxt = TQWIDGETSIZE_MAX; - int mint = fi; - int n = d->list.count(); - bool first = TRUE; - - /* - Splitter handles before the first visible widget or right - before a hidden widget must be hidden. - */ - for ( int i = 0; i < n; i++ ) { - TQSplitterLayoutStruct *s = d->list.at( i ); - if ( !s->isHandle ) { - TQSplitterLayoutStruct *p = 0; - if ( i > 0 ) - p = d->list.at( i - 1 ); - - // may trigger new recalc - if ( p && p->isHandle ) - p->wid->setHidden( first || s->wid->isHidden() ); - - if ( !s->wid->isHidden() ) - first = FALSE; - } - } - - bool empty = TRUE; - for ( int j = 0; j < n; j++ ) { - TQSplitterLayoutStruct *s = d->list.at( j ); - if ( !s->wid->isHidden() ) { - empty = FALSE; - if ( s->isHandle ) { - minl += s->getSizer( orient ); - maxl += s->getSizer( orient ); - } else { - TQSize minS = tqSmartMinSize( s->wid ); - minl += pick( minS ); - maxl += pick( s->wid->tqmaximumSize() ); - mint = TQMAX( mint, trans(minS) ); - int tm = trans( s->wid->tqmaximumSize() ); - if ( tm > 0 ) - maxt = TQMIN( maxt, tm ); - } - } - } - if ( empty ) { - if ( ::tqqt_cast<TQSplitter*>(parentWidget()) ) { - // nested splitters; be nice - maxl = maxt = 0; - } else { - // TQSplitter with no tqchildren yet - maxl = TQWIDGETSIZE_MAX; - } - } else { - maxl = TQMIN( maxl, TQWIDGETSIZE_MAX ); - } - if ( maxt < mint ) - maxt = mint; - - if ( orient == Qt::Horizontal ) { - setMaximumSize( maxl, maxt ); - setMinimumSize( minl, mint ); - } else { - setMaximumSize( maxt, maxl ); - setMinimumSize( mint, minl ); - } - if ( update ) - doResize(); - else - d->firstShow = TRUE; -} - -/*! - \enum TQSplitter::ResizeMode - - This enum type describes how TQSplitter will resize each of its - child widgets. - - \value Auto The widget will be resized according to the stretch - factors set in its sizePolicy(). - - \value Stretch The widget will be resized when the splitter - itself is resized. - - \value KeepSize TQSplitter will try to keep the widget's size - unchanged. - - \value FollowSizeHint TQSplitter will resize the widget when the - widget's size hint changes. -*/ - -/*! - Sets resize mode of widget \a w to \a mode. (The default is \c - Auto.) -*/ - -void TQSplitter::setResizeMode( TQWidget *w, ResizeMode mode ) -{ - findWidget( w )->resizeMode = mode; -} - - -/*! - \property TQSplitter::opaqueResize - \brief whether resizing is opaque - - Opaque resizing is off by default. -*/ - -bool TQSplitter::opaqueResize() const -{ - return d->opaque; -} - - -void TQSplitter::setOpaqueResize( bool on ) -{ - d->opaque = on; -} - - -/*! - Moves widget \a w to the leftmost/top position. -*/ - -void TQSplitter::moveToFirst( TQWidget *w ) -{ - processChildEvents(); - bool found = FALSE; - TQSplitterLayoutStruct *s = d->list.first(); - while ( s ) { - if ( s->wid == w ) { - found = TRUE; - TQSplitterLayoutStruct *p = d->list.prev(); - if ( p ) { // not already at first place - d->list.take(); // take p - d->list.take(); // take s - d->list.prepend( p ); - d->list.prepend( s ); - } - break; - } - s = d->list.next(); - } - if ( !found ) - addWidget( w, TRUE ); - recalcId(); -} - - -/*! - Moves widget \a w to the rightmost/bottom position. -*/ - -void TQSplitter::moveToLast( TQWidget *w ) -{ - processChildEvents(); - bool found = FALSE; - TQSplitterLayoutStruct *s = d->list.first(); - while ( s ) { - if ( s->wid == w ) { - found = TRUE; - d->list.take(); // take s - TQSplitterLayoutStruct *p = d->list.current(); - if ( p ) { // the splitter handle after s - d->list.take(); // take p - d->list.append( p ); - } - d->list.append( s ); - break; - } - s = d->list.next(); - } - if ( !found ) - addWidget( w ); - recalcId(); -} - - -void TQSplitter::recalcId() -{ - int n = d->list.count(); - for ( int i = 0; i < n; i++ ) { - TQSplitterLayoutStruct *s = d->list.at( i ); - if ( s->isHandle ) - ((TQSplitterHandle*)s->wid)->setId( i ); - } -} - - -/*! - \reimp -*/ -TQSize TQSplitter::tqsizeHint() const -{ - constPolish(); - int l = 0; - int t = 0; - if ( !childrenListObject().isEmpty() ) { - TQObjectListIt it( childrenListObject() ); - TQObject * o; - - while( (o = it.current()) != 0 ) { - ++it; - if ( o->isWidgetType() && !((TQWidget*)o)->isHidden() ) { - TQSize s = ((TQWidget*)o)->tqsizeHint(); - if ( s.isValid() ) { - l += pick( s ); - t = TQMAX( t, trans( s ) ); - } - } - } - } - return orientation() == Qt::Horizontal ? TQSize( l, t ) : TQSize( t, l ); -} - - -/*! - \reimp -*/ - -TQSize TQSplitter::tqminimumSizeHint() const -{ - constPolish(); - int l = 0; - int t = 0; - if ( !childrenListObject().isEmpty() ) { - TQObjectListIt it( childrenListObject() ); - TQObject * o; - - while ( (o = it.current()) != 0 ) { - ++it; - if ( o->isWidgetType() && !((TQWidget*)o)->isHidden() ) { - TQSize s = tqSmartMinSize( (TQWidget*)o ); - if ( s.isValid() ) { - l += pick( s ); - t = TQMAX( t, trans( s ) ); - } - } - } - } - return orientation() == Qt::Horizontal ? TQSize( l, t ) : TQSize( t, l ); -} - - -void TQSplitter::storeSizes() -{ - TQSplitterLayoutStruct *s = d->list.first(); - while ( s ) { - if ( !s->isHandle ) - s->sizer = pick( s->wid->size() ); - s = d->list.next(); - } -} - - -void TQSplitter::addContribution( int id, int *min, int *max, - bool mayCollapse ) -{ - TQSplitterLayoutStruct *s = d->list.at( id ); - if ( !s->wid->isHidden() ) { - if ( s->isHandle ) { - *min += s->getSizer( orient ); - *max += s->getSizer( orient ); - } else { - if ( mayCollapse || !isCollapsed(s->wid) ) - *min += pick( tqSmartMinSize(s->wid) ); - *max += pick( s->wid->tqmaximumSize() ); - } - } -} - - -/*! - Returns a list of the size parameters of all the widgets in this - splitter. - - If the splitter's orientation is horizontal, the list is a list of - widget widths; if the orientation is vertical, the list is a list - of widget heights. - - Giving the values to another splitter's setSizes() function will - produce a splitter with the same tqlayout as this one. - - Note that if you want to iterate over the list, you should iterate - over a copy, e.g. - \code - TQValueList<int> list = mySplitter.sizes(); - TQValueList<int>::Iterator it = list.begin(); - while( it != list.end() ) { - myProcessing( *it ); - ++it; - } - \endcode - - \sa setSizes() -*/ - -TQValueList<int> TQSplitter::sizes() const -{ - if ( !testWState(TQt::WState_Polished) ) - constPolish(); - - TQValueList<int> list; - TQSplitterLayoutStruct *s = d->list.first(); - while ( s ) { - if ( !s->isHandle ) - list.append( isCollapsed(s->wid) ? 0 : pick(s->wid->size())); - s = d->list.next(); - } - return list; -} - -/*! - Sets the size parameters to the values given in the \a list. If - the splitter is horizontal, the values set the widths of each - widget going from left to right. If the splitter is vertical, the - values set the heights of each widget going from top to bottom. - Extra values in the \a list are ignored. - - If \a list contains too few values, the result is undefined but - the program will still be well-behaved. - - Note that the values in \a list should be the height/width that - the widgets should be resized to. - - \sa sizes() -*/ - -void TQSplitter::setSizes( TQValueList<int> list ) -{ - processChildEvents(); - TQValueList<int>::Iterator it = list.begin(); - TQSplitterLayoutStruct *s = d->list.first(); - while ( s && it != list.end() ) { - if ( !s->isHandle ) { - s->sizer = TQMAX( *it, 0 ); - int smartMinSize = pick( tqSmartMinSize(s->wid) ); - // Make sure that we reset the collapsed state. - if ( s->sizer == 0 ) { - if ( collapsible(s) && smartMinSize > 0 ) { - s->wid->move( -1, -1 ); - } else { - s->sizer = smartMinSize; - s->wid->move( 0, 0 ); - } - } else { - if ( s->sizer < smartMinSize ) - s->sizer = smartMinSize; - s->wid->move( 0, 0 ); - } - ++it; - } - s = d->list.next(); - } - doResize(); -} - -/*! - \property TQSplitter::handleWidth - \brief the width of the splitter handle -*/ - -int TQSplitter::handleWidth() const -{ - if ( d->handleWidth > 0 ) { - return d->handleWidth; - } else { - return tqstyle().tqpixelMetric( TQStyle::PM_SplitterWidth, this ); - } -} - -void TQSplitter::setHandleWidth( int width ) -{ - d->handleWidth = width; - updateHandles(); -} - -/*! - Processes all posted child events, ensuring that the internal state of - the splitter is kept consistent. -*/ - -void TQSplitter::processChildEvents() -{ - TQApplication::sendPostedEvents( this, TQEvent::ChildInserted ); -} - -/*! - \reimp -*/ - -void TQSplitter::styleChange( TQStyle& old ) -{ - updateHandles(); - TQFrame::styleChange( old ); -} - -void TQSplitter::updateHandles() -{ - int hw = handleWidth(); - TQSplitterLayoutStruct *s = d->list.first(); - while ( s ) { - if ( s->isHandle ) - s->sizer = hw; - s = d->list.next(); - } - recalc( isVisible() ); -} - -#ifndef TQT_NO_TEXTSTREAM -/*! - \relates TQSplitter - - Writes the sizes and the hidden state of the widgets in the - splitter \a splitter to the text stream \a ts. - - \sa operator>>(), sizes(), TQWidget::isHidden() -*/ - -TQTextStream& operator<<( TQTextStream& ts, const TQSplitter& splitter ) -{ - TQSplitterLayoutStruct *s = splitter.d->list.first(); - bool first = TRUE; - ts << "["; - - while ( s != 0 ) { - if ( !s->isHandle ) { - if ( !first ) - ts << ","; - - if ( s->wid->isHidden() ) { - ts << "H"; - } else if ( isCollapsed(s->wid) ) { - ts << 0; - } else { - ts << s->getSizer( splitter.orientation() ); - } - first = FALSE; - } - s = splitter.d->list.next(); - } - ts << "]" << endl; - return ts; -} - -/*! - \relates TQSplitter - - Reads the sizes and the hidden state of the widgets in the - splitter \a splitter from the text stream \a ts. The sizes must - have been previously written by the operator<<() function. - - \sa operator<<(), setSizes(), TQWidget::hide() -*/ - -TQTextStream& operator>>( TQTextStream& ts, TQSplitter& splitter ) -{ -#undef SKIP_SPACES -#define SKIP_SPACES() \ - while ( line[i].isSpace() ) \ - i++ - - splitter.processChildEvents(); - TQSplitterLayoutStruct *s = splitter.d->list.first(); - TQString line = ts.readLine(); - int i = 0; - - SKIP_SPACES(); - if ( line[i] == '[' ) { - i++; - SKIP_SPACES(); - while ( line[i] != ']' ) { - while ( s != 0 && s->isHandle ) - s = splitter.d->list.next(); - if ( s == 0 ) - break; - - if ( line[i].upper() == 'H' ) { - s->wid->hide(); - i++; - } else { - s->wid->show(); - int dim = 0; - while ( line[i].digitValue() >= 0 ) { - dim *= 10; - dim += line[i].digitValue(); - i++; - } - s->sizer = dim; - if ( dim == 0 ) - splitter.setGeo( s->wid, 0, 0, FALSE ); - } - SKIP_SPACES(); - if ( line[i] == ',' ) { - i++; - } else { - break; - } - SKIP_SPACES(); - s = splitter.d->list.next(); - } - } - splitter.doResize(); - return ts; -} -#endif - -#endif |