kdeui Library API Documentation

kdockwidget_private.cpp

00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2000 Max Judin <novaprint@mtu-net.ru>
00003    Copyright (C) 2002,2003 Joseph Wenninger <jowenn@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License version 2 as published by the Free Software Foundation.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
00018 */
00019 #include "kdockwidget.h"
00020 #include "kdockwidget_p.h"
00021 #include "kdockwidget_private.h"
00022 
00023 #include <qpainter.h>
00024 #include <qcursor.h>
00025 #include <kdebug.h>
00026 #include <qtimer.h>
00027 
00028 KDockSplitter::KDockSplitter(QWidget *parent, const char *name, Orientation orient, int pos, bool highResolution)
00029 : QWidget(parent, name)
00030 {
00031   divider = 0L;
00032   child0 = 0L;
00033   child1 = 0L;
00034   fixedWidth0=-1;
00035   fixedWidth1=-1;
00036   fixedHeight0=-1;
00037   fixedHeight1=-1;
00038 
00039   m_orientation = orient;
00040   mOpaqueResize = false;
00041   mKeepSize = false;
00042   mHighResolution = highResolution;
00043   setSeparatorPos( pos, false );
00044   initialised = false;
00045 }
00046 
00047 void KDockSplitter::activate(QWidget *c0, QWidget *c1)
00048 {
00049   if ( c0 ) child0 = c0;
00050   if ( c1 ) child1 = c1;
00051 
00052   setupMinMaxSize();
00053 
00054   if (divider) delete divider;
00055   divider = new QFrame(this, "pannerdivider");
00056   divider->setFrameStyle(QFrame::Panel | QFrame::Raised);
00057   divider->setLineWidth(1);
00058   divider->raise();
00059 
00060   if (m_orientation == Horizontal)
00061     divider->setCursor(QCursor(sizeVerCursor));
00062   else
00063     divider->setCursor(QCursor(sizeHorCursor));
00064 
00065   divider->installEventFilter(this);
00066 
00067   initialised= true;
00068 
00069   updateName();
00070 
00071   divider->show();
00072   resizeEvent(0);
00073   if (fixedWidth0!=-1) restoreFromForcedFixedSize((KDockWidget*)child0);
00074   if (fixedWidth1!=-1) restoreFromForcedFixedSize((KDockWidget*)child1);
00075   if (((KDockWidget*)child0)->forcedFixedWidth()!=-1)
00076   {
00077     setForcedFixedWidth(((KDockWidget*)child0),((KDockWidget*)child0)->forcedFixedWidth());
00078     //QTimer::singleShot(100,this,SLOT(delayedResize()));
00079   }
00080   else
00081   if (((KDockWidget*)child1)->forcedFixedWidth()!=-1)
00082   {
00083     setForcedFixedWidth(((KDockWidget*)child1),((KDockWidget*)child1)->forcedFixedWidth());
00084     //QTimer::singleShot(100,this,SLOT(delayedResize()));
00085   }
00086 
00087   if (((KDockWidget*)child0)->forcedFixedHeight()!=-1)
00088   {
00089         setForcedFixedHeight(((KDockWidget*)child0),((KDockWidget*)child0)->forcedFixedHeight());
00090         //QTimer::singleShot(100,this,SLOT(delayedResize()));
00091   }
00092   else
00093   if (((KDockWidget*)child1)->forcedFixedHeight()!=-1)
00094   {
00095         setForcedFixedHeight(((KDockWidget*)child1),((KDockWidget*)child1)->forcedFixedHeight());
00096         //QTimer::singleShot(100,this,SLOT(delayedResize()));
00097   }
00098 
00099 
00100 }
00101 
00102 /*
00103 void KDockSplitter::delayedResize()
00104 {
00105     kdDebug()<<"*********************** DELAYED RESIZE !!!!!!!!!!!!!!!"<<endl;
00106     resizeEvent(0);
00107 }*/
00108 
00109 void KDockSplitter::setForcedFixedWidth(KDockWidget *dw,int w)
00110 {
00111     int factor = (mHighResolution)? 10000:100;
00112     if (dw==child0)
00113     {
00114                 fixedWidth0=w;
00115 //      setupMinMaxSize();
00116                 savedXPos=xpos;
00117         setSeparatorPos(w*factor/width(),true);
00118 //      kdDebug()<<"Set forced fixed width for widget 0 :"<<w<<endl;
00119     }
00120         else
00121     {
00122                 fixedWidth1=w;
00123                 savedXPos=xpos;
00124         setSeparatorPos((width()-w)*factor/width(),true);
00125 //      kdDebug()<<"Set forced fixed width for widget 1 :"<<w<<endl;
00126 //      kdDebug()<<"Width() :"<<width()<<endl;
00127     }
00128 }
00129 
00130 void KDockSplitter::setForcedFixedHeight(KDockWidget *dw,int h)
00131 {
00132     int factor = (mHighResolution)? 10000:100;
00133     if (dw==child0)
00134     {
00135                 fixedHeight0=h;
00136 //      setupMinMaxSize();
00137         savedXPos=xpos;
00138         setSeparatorPos(h*factor/height(),true);
00139 //      kdDebug()<<"Set forced fixed width for widget 0 :"<<h<<endl;
00140     }
00141         else
00142     {
00143                 fixedHeight1=h;
00144         savedXPos=xpos;
00145         setSeparatorPos((height()-h)*factor/height(),true);
00146 //      kdDebug()<<"Set forced fixed height for widget 1 :"<<h<<endl;
00147     }
00148 }
00149 
00150 void KDockSplitter::restoreFromForcedFixedSize(KDockWidget *dw)
00151 {
00152     if (dw==child0)
00153     {
00154         fixedWidth0=-1;
00155         fixedHeight0=-1;
00156         setSeparatorPos(savedXPos,true);
00157     }
00158     else
00159     {
00160         fixedWidth1=-1;
00161         fixedHeight1=-1;
00162         setSeparatorPos(savedXPos,true);
00163     }
00164 }
00165 
00166 
00167 void KDockSplitter::setupMinMaxSize()
00168 {
00169   // Set the minimum and maximum sizes
00170   int minx, maxx, miny, maxy;
00171   if (m_orientation == Horizontal) {
00172     miny = child0->minimumSize().height() + child1->minimumSize().height()+4;
00173     maxy = child0->maximumSize().height() + child1->maximumSize().height()+4;
00174     minx = (child0->minimumSize().width() > child1->minimumSize().width()) ? child0->minimumSize().width() : child1->minimumSize().width();
00175     maxx = (child0->maximumSize().width() > child1->maximumSize().width()) ? child0->maximumSize().width() : child1->maximumSize().width();
00176 
00177     miny = (miny > 4) ? miny : 4;
00178     maxy = (maxy < 32000) ? maxy : 32000;
00179     minx = (minx > 2) ? minx : 2;
00180     maxx = (maxx < 32000) ? maxx : 32000;
00181   } else {
00182     minx = child0->minimumSize().width() + child1->minimumSize().width()+4;
00183     maxx = child0->maximumSize().width() + child1->maximumSize().width()+4;
00184     miny = (child0->minimumSize().height() > child1->minimumSize().height()) ? child0->minimumSize().height() : child1->minimumSize().height();
00185     maxy = (child0->maximumSize().height() > child1->maximumSize().height()) ? child0->maximumSize().height() : child1->maximumSize().height();
00186 
00187     minx = (minx > 4) ? minx : 4;
00188     maxx = (maxx < 32000) ? maxx : 32000;
00189     miny = (miny > 2) ? miny : 2;
00190     maxy = (maxy < 32000) ? maxy : 32000;
00191   }
00192   setMinimumSize(minx, miny);
00193   setMaximumSize(maxx, maxy);
00194 }
00195 
00196 void KDockSplitter::deactivate()
00197 {
00198   delete divider;
00199   divider = 0L;
00200   initialised= false;
00201 }
00202 
00203 void KDockSplitter::setSeparatorPos(int pos, bool do_resize)
00204 {
00205   xpos = pos;
00206   if (do_resize)
00207     resizeEvent(0);
00208 }
00209 
00210 void KDockSplitter::setSeparatorPosX( int pos, bool do_resize )
00211 {
00212   savedXPos = pos;
00213   setSeparatorPos( pos, do_resize );
00214 }
00215 
00216 int KDockSplitter::separatorPos() const
00217 {
00218   return xpos;
00219 }
00220 
00221 void KDockSplitter::resizeEvent(QResizeEvent *ev)
00222 {
00223 //  kdDebug()<<"ResizeEvent :"<< ((initialised) ? "initialised":"not initialised")<<", "<< ((ev) ? "real event":"")<<
00224 //  ", "<<(isVisible() ?"visible":"")<<endl;
00225   if (initialised){
00226     int factor = (mHighResolution)? 10000:100;
00227     // real resize event, recalculate xpos
00228     if (ev && mKeepSize && isVisible()) {
00229 //  kdDebug()<<"mKeepSize : "<< ((m_orientation == Horizontal) ? "Horizontal":"Vertical") <<endl;
00230 
00231       if (ev->oldSize().width() != ev->size().width())
00232       {
00233           if (m_orientation == Horizontal) {
00234           xpos = factor * checkValue( child0->height()+1 ) / height();
00235           } else {
00236           xpos = factor * checkValue( child0->width()+1 ) / width();
00237       }
00238 
00239           }
00240       }
00241           else
00242           {
00243 //  kdDebug()<<"!mKeepSize : "<< ((m_orientation == Horizontal) ? "Horizontal":"Vertical") <<endl;
00244     if (/*ev &&*/ isVisible()) {
00245         if (m_orientation == Horizontal) {
00246         /*  if (ev->oldSize().height() != ev->size().height())*/
00247             {
00248               if (fixedHeight0!=-1)
00249                 xpos=fixedHeight0*factor/height();
00250               else
00251               if (fixedHeight1!=-1)
00252                 xpos=(height()-fixedHeight1)*factor/height();
00253             }
00254         }
00255         else
00256         {
00257 /*              if (ev->oldSize().width() != ev->size().width()) */
00258             {
00259               if (fixedWidth0!=-1)
00260                 xpos=fixedWidth0*factor/width();
00261               else
00262               if (fixedWidth1!=-1)
00263                 xpos=(width()-fixedWidth1)*factor/width();
00264             }
00265         }
00266     }
00267 //  else kdDebug()<<"Something else happened"<<endl;
00268    }
00269 
00270     KDockContainer *dc;
00271     KDockWidget *c0=(KDockWidget*)child0;
00272     KDockWidget *c1=(KDockWidget*)child1;
00273     bool stdHandling=false;
00274     if ((fixedWidth0==-1) && (fixedWidth1==-1)) {
00275         if ((c0->getWidget()) && (dc=dynamic_cast<KDockContainer*>(c0->getWidget()))
00276          && (dc->m_overlapMode)) {
00277             int position= (m_orientation == Vertical ? width() : height()) * xpos/factor;
00278             position=checkValueOverlapped(position,child0);
00279             child0->raise();
00280             divider->raise();
00281                       if (m_orientation == Horizontal){
00282                         child0->setGeometry(0, 0, width(), position);
00283                         child1->setGeometry(0, dc->m_nonOverlapSize+4, width(),
00284                         height()-dc->m_nonOverlapSize-4);
00285                         divider->setGeometry(0, position, width(), 4);
00286                       } else {
00287                         child0->setGeometry(0, 0, position, height());
00288                         child1->setGeometry(dc->m_nonOverlapSize+4, 0,
00289                         width()-dc->m_nonOverlapSize-4, height());
00290                         divider->setGeometry(position, 0, 4, height());
00291                       }
00292         } else {
00293          if ((c1->getWidget()) && (dc=dynamic_cast<KDockContainer*>(c1->getWidget()))
00294              && (dc->m_overlapMode)) {
00295                     int position= (m_orientation == Vertical ? width() : height()) * xpos/factor;
00296             position=checkValueOverlapped(position,child1);
00297                     child1->raise();
00298                     divider->raise();
00299                           if (m_orientation == Horizontal){
00300                             child0->setGeometry(0, 0, width(), height()-dc->m_nonOverlapSize-4);
00301                             child1->setGeometry(0, position+4, width(),
00302                                             height()-position-4);
00303                             divider->setGeometry(0, position, width(), 4);
00304                           } else {
00305                             child0->setGeometry(0, 0, width()-dc->m_nonOverlapSize-4, height());
00306                             child1->setGeometry(position+4, 0,
00307                                             width()-position-4, height());
00308                             divider->setGeometry(position, 0, 4, height());
00309                           }
00310         }
00311         else stdHandling=true;
00312           }
00313             }
00314      else stdHandling=true;
00315 
00316     if (stdHandling) {
00317               int position = checkValue( (m_orientation == Vertical ? width() : height()) * xpos/factor );
00318               if (m_orientation == Horizontal){
00319                 child0->setGeometry(0, 0, width(), position);
00320                 child1->setGeometry(0, position+4, width(), height()-position-4);
00321                 divider->setGeometry(0, position, width(), 4);
00322               } else {
00323                 child0->setGeometry(0, 0, position, height());
00324                 child1->setGeometry(position+4, 0, width()-position-4, height());
00325                 divider->setGeometry(position, 0, 4, height());
00326     }
00327 
00328     }
00329 
00330   }
00331 }
00332 
00333 int KDockSplitter::checkValueOverlapped(int position, QWidget *overlappingWidget) const {
00334     if (initialised) {
00335         if (m_orientation == Vertical) {
00336             if (child0==overlappingWidget) {
00337                 if (position<(child0->minimumSize().width()))
00338                     position=child0->minimumSize().width();
00339                 if (position>width()) position=width()-4;
00340             } else if (position>(width()-(child1->minimumSize().width())-4)){
00341                 position=width()-(child1->minimumSize().width())-4;
00342                 if (position<0) position=0;
00343             }
00344         } else {// orientation  == Horizontal
00345             if (child0==overlappingWidget) {
00346                 if (position<(child0->minimumSize().height()))
00347                     position=child0->minimumSize().height();
00348                 if (position>height()) position=height()-4;
00349             } else if (position>(height()-(child1->minimumSize().height())-4)){
00350                 position=height()-(child1->minimumSize().height())-4;
00351                 if (position<0) position=0;
00352 
00353             }
00354         }
00355 
00356     }
00357     return position;
00358 }
00359 
00360 int KDockSplitter::checkValue( int position ) const
00361 {
00362   if (initialised){
00363     if (m_orientation == Vertical){
00364       if (position < (child0->minimumSize().width()))
00365         position = child0->minimumSize().width();
00366       if ((width()-4-position) < (child1->minimumSize().width()))
00367         position = width() - (child1->minimumSize().width()) -4;
00368     } else {
00369       if (position < (child0->minimumSize().height()))
00370         position = (child0->minimumSize().height());
00371       if ((height()-4-position) < (child1->minimumSize().height()))
00372         position = height() - (child1->minimumSize().height()) -4;
00373     }
00374   }
00375 
00376   if (position < 0) position = 0;
00377 
00378   if ((m_orientation == Vertical) && (position > width()))
00379     position = width();
00380   if ((m_orientation == Horizontal) && (position > height()))
00381     position = height();
00382 
00383   return position;
00384 }
00385 
00386 bool KDockSplitter::eventFilter(QObject *o, QEvent *e)
00387 {
00388   QMouseEvent *mev;
00389   bool handled = false;
00390   int factor = (mHighResolution)? 10000:100;
00391 
00392   switch (e->type()) {
00393     case QEvent::MouseMove:
00394       mev= (QMouseEvent*)e;
00395       child0->setUpdatesEnabled(mOpaqueResize);
00396       child1->setUpdatesEnabled(mOpaqueResize);
00397       if (m_orientation == Horizontal) {
00398         if ((fixedHeight0!=-1) || (fixedHeight1!=-1))
00399         {
00400                 handled=true; break;
00401         }
00402 
00403     if (!mOpaqueResize) {
00404           int position = checkValue( mapFromGlobal(mev->globalPos()).y() );
00405           divider->move( 0, position );
00406         } else {
00407           xpos = factor * checkValue( mapFromGlobal(mev->globalPos()).y() ) / height();
00408           resizeEvent(0);
00409           divider->repaint(true);
00410         }
00411       } else {
00412         if ((fixedWidth0!=-1) || (fixedWidth1!=-1))
00413         {
00414                 handled=true; break;
00415         }
00416         if (!mOpaqueResize) {
00417           int position = checkValue( mapFromGlobal(QCursor::pos()).x() );
00418           divider->move( position, 0 );
00419         } else {
00420           xpos = factor * checkValue( mapFromGlobal( mev->globalPos()).x() ) / width();
00421           resizeEvent(0);
00422           divider->repaint(true);
00423         }
00424       }
00425       handled= true;
00426       break;
00427     case QEvent::MouseButtonRelease:
00428       child0->setUpdatesEnabled(true);
00429       child1->setUpdatesEnabled(true);
00430       mev= (QMouseEvent*)e;
00431       if (m_orientation == Horizontal){
00432         if ((fixedHeight0!=-1) || (fixedHeight1!=-1))
00433         {
00434                 handled=true; break;
00435         }
00436         xpos = factor* checkValue( mapFromGlobal(mev->globalPos()).y() ) / height();
00437         resizeEvent(0);
00438         divider->repaint(true);
00439       } else {
00440         if ((fixedWidth0!=-1) || (fixedWidth1!=-1))
00441         {
00442                 handled=true; break;
00443         }
00444         xpos = factor* checkValue( mapFromGlobal(mev->globalPos()).x() ) / width();
00445         resizeEvent(0);
00446         divider->repaint(true);
00447       }
00448       handled= true;
00449       break;
00450     default:
00451       break;
00452   }
00453   return (handled) ? true : QWidget::eventFilter( o, e );
00454 }
00455 
00456 bool KDockSplitter::event( QEvent* e )
00457 {
00458   if ( e->type() == QEvent::LayoutHint ){
00459     // change children min/max size
00460     setupMinMaxSize();
00461     setSeparatorPos(xpos);
00462   }
00463   return QWidget::event(e);
00464 }
00465 
00466 QWidget* KDockSplitter::getAnother( QWidget* w ) const
00467 {
00468   return ( w == child0 ) ? child1 : child0;
00469 }
00470 
00471 void KDockSplitter::updateName()
00472 {
00473   if ( !initialised ) return;
00474 
00475   QString new_name = QString( child0->name() ) + "," + child1->name();
00476   parentWidget()->setName( new_name.latin1() );
00477   parentWidget()->setCaption( child0->caption() + "," + child1->caption() );
00478   parentWidget()->repaint( false );
00479 
00480   ((KDockWidget*)parentWidget())->firstName = child0->name();
00481   ((KDockWidget*)parentWidget())->lastName = child1->name();
00482   ((KDockWidget*)parentWidget())->splitterOrientation = m_orientation;
00483 
00484   QWidget* p = parentWidget()->parentWidget();
00485   if ( p != 0L && p->inherits("KDockSplitter" ) )
00486     ((KDockSplitter*)p)->updateName();
00487 }
00488 
00489 void KDockSplitter::setOpaqueResize(bool b)
00490 {
00491   mOpaqueResize = b;
00492 }
00493 
00494 bool KDockSplitter::opaqueResize() const
00495 {
00496   return mOpaqueResize;
00497 }
00498 
00499 void KDockSplitter::setKeepSize(bool b)
00500 {
00501   mKeepSize = b;
00502 }
00503 
00504 bool KDockSplitter::keepSize() const
00505 {
00506   return mKeepSize;
00507 }
00508 
00509 void KDockSplitter::setHighResolution(bool b)
00510 {
00511   if (mHighResolution) {
00512     if (!b) xpos = xpos/100;
00513   } else {
00514     if (b) xpos = xpos*100;
00515   }
00516   mHighResolution = b;
00517 }
00518 
00519 bool KDockSplitter::highResolution() const
00520 {
00521   return mHighResolution;
00522 }
00523 
00524 
00525 /*************************************************************************/
00526 KDockButton_Private::KDockButton_Private( QWidget *parent, const char * name )
00527 :QPushButton( parent, name )
00528 {
00529   moveMouse = false;
00530   setFocusPolicy( NoFocus );
00531 }
00532 
00533 KDockButton_Private::~KDockButton_Private()
00534 {
00535 }
00536 
00537 void KDockButton_Private::drawButton( QPainter* p )
00538 {
00539   p->fillRect( 0,0, width(), height(), QBrush(colorGroup().brush(QColorGroup::Background)) );
00540   p->drawPixmap( (width() - pixmap()->width()) / 2, (height() - pixmap()->height()) / 2, *pixmap() );
00541   if ( moveMouse && !isDown() ){
00542     p->setPen( white );
00543     p->moveTo( 0, height() - 1 );
00544     p->lineTo( 0, 0 );
00545     p->lineTo( width() - 1, 0 );
00546 
00547     p->setPen( colorGroup().dark() );
00548     p->lineTo( width() - 1, height() - 1 );
00549     p->lineTo( 0, height() - 1 );
00550   }
00551   if ( isOn() || isDown() ){
00552     p->setPen( colorGroup().dark() );
00553     p->moveTo( 0, height() - 1 );
00554     p->lineTo( 0, 0 );
00555     p->lineTo( width() - 1, 0 );
00556 
00557     p->setPen( white );
00558     p->lineTo( width() - 1, height() - 1 );
00559     p->lineTo( 0, height() - 1 );
00560   }
00561 }
00562 
00563 void KDockButton_Private::enterEvent( QEvent * )
00564 {
00565   moveMouse = true;
00566   repaint();
00567 }
00568 
00569 void KDockButton_Private::leaveEvent( QEvent * )
00570 {
00571   moveMouse = false;
00572   repaint();
00573 }
00574 
00575 /*************************************************************************/
00576 KDockWidgetPrivate::KDockWidgetPrivate()
00577   : QObject()
00578   ,index(-1)
00579   ,splitPosInPercent(50)
00580   ,pendingFocusInEvent(false)
00581   ,blockHasUndockedSignal(false)
00582   ,pendingDtor(false)
00583   ,forcedWidth(-1)
00584   ,forcedHeight(-1)
00585   ,isContainer(false)
00586   ,container(0)
00587   ,resizePos(0,0)
00588   ,resizing(false)
00589 {
00590 #ifndef NO_KDE2
00591   windowType = NET::Normal;
00592 #endif
00593 
00594   _parent = 0L;
00595   transient = false;
00596 }
00597 
00598 KDockWidgetPrivate::~KDockWidgetPrivate()
00599 {
00600 }
00601 
00602 void KDockWidgetPrivate::slotFocusEmbeddedWidget(QWidget* w)
00603 {
00604    if (w) {
00605       QWidget* embeddedWdg = ((KDockWidget*)w)->getWidget();
00606       if (embeddedWdg && ((embeddedWdg->focusPolicy() == QWidget::ClickFocus) || (embeddedWdg->focusPolicy() == QWidget::StrongFocus))) {
00607          embeddedWdg->setFocus();
00608       }
00609    }
00610 }
00611 
00612 #ifndef NO_INCLUDE_MOCFILES // for Qt-only projects, because tmake doesn't take this name
00613 #include "kdockwidget_private.moc"
00614 #endif
KDE Logo
This file is part of the documentation for kdeui Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Jul 22 10:16:43 2005 by doxygen 1.3.6 written by Dimitri van Heesch, © 1997-2003