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 int KDockSplitter::separatorPos() const
00211 {
00212   return xpos;
00213 }
00214 
00215 void KDockSplitter::resizeEvent(QResizeEvent *ev)
00216 {
00217 //  kdDebug()<<"ResizeEvent :"<< ((initialised) ? "initialised":"not initialised")<<", "<< ((ev) ? "real event":"")<<
00218 //  ", "<<(isVisible() ?"visible":"")<<endl;
00219   if (initialised){
00220     int factor = (mHighResolution)? 10000:100;
00221     // real resize event, recalculate xpos
00222     if (ev && mKeepSize && isVisible()) {
00223 //  kdDebug()<<"mKeepSize : "<< ((m_orientation == Horizontal) ? "Horizontal":"Vertical") <<endl;
00224 
00225       if (ev->oldSize().width() != ev->size().width())
00226       {
00227           if (m_orientation == Horizontal) {
00228           xpos = factor * checkValue( child0->height()+1 ) / height();
00229           } else {
00230           xpos = factor * checkValue( child0->width()+1 ) / width();
00231       }
00232       
00233           }
00234       }
00235           else
00236           {
00237 //  kdDebug()<<"!mKeepSize : "<< ((m_orientation == Horizontal) ? "Horizontal":"Vertical") <<endl;
00238     if (/*ev &&*/ isVisible()) {
00239         if (m_orientation == Horizontal) {
00240         /*  if (ev->oldSize().height() != ev->size().height())*/
00241             {
00242               if (fixedHeight0!=-1)
00243                 xpos=fixedHeight0*factor/height();
00244               else
00245               if (fixedHeight1!=-1)
00246                 xpos=(height()-fixedHeight1)*factor/height();
00247             }
00248         }
00249         else
00250         {
00251 /*              if (ev->oldSize().width() != ev->size().width()) */
00252             {
00253               if (fixedWidth0!=-1)
00254                 xpos=fixedWidth0*factor/width();
00255               else
00256               if (fixedWidth1!=-1)
00257                 xpos=(width()-fixedWidth1)*factor/width();
00258             }
00259         }
00260     }
00261 //  else kdDebug()<<"Something else happened"<<endl;
00262    }
00263 
00264     KDockContainer *dc;
00265     KDockWidget *c0=(KDockWidget*)child0;
00266     KDockWidget *c1=(KDockWidget*)child1;
00267     bool stdHandling=false;
00268     if ((fixedWidth0==-1) && (fixedWidth1==-1)) {
00269         if ((c0->getWidget()) && (dc=dynamic_cast<KDockContainer*>(c0->getWidget()))
00270          && (dc->m_overlapMode)) {
00271             int position= (m_orientation == Vertical ? width() : height()) * xpos/factor;
00272             position=checkValueOverlapped(position,child0);
00273             child0->raise();
00274             divider->raise();
00275                       if (m_orientation == Horizontal){
00276                         child0->setGeometry(0, 0, width(), position);
00277                         child1->setGeometry(0, dc->m_nonOverlapSize+4, width(), 
00278                         height()-dc->m_nonOverlapSize-4);
00279                         divider->setGeometry(0, position, width(), 4);
00280                       } else {
00281                         child0->setGeometry(0, 0, position, height());
00282                         child1->setGeometry(dc->m_nonOverlapSize+4, 0, 
00283                         width()-dc->m_nonOverlapSize-4, height());
00284                         divider->setGeometry(position, 0, 4, height());
00285                       }
00286         } else {
00287          if ((c1->getWidget()) && (dc=dynamic_cast<KDockContainer*>(c1->getWidget()))
00288              && (dc->m_overlapMode)) {
00289                     int position= (m_orientation == Vertical ? width() : height()) * xpos/factor;
00290             position=checkValueOverlapped(position,child1);
00291                     child1->raise();
00292                     divider->raise();
00293                           if (m_orientation == Horizontal){
00294                             child0->setGeometry(0, 0, width(), height()-dc->m_nonOverlapSize-4);
00295                             child1->setGeometry(0, position+4, width(),
00296                                             height()-position-4);
00297                             divider->setGeometry(0, position, width(), 4);
00298                           } else {
00299                             child0->setGeometry(0, 0, width()-dc->m_nonOverlapSize-4, height());
00300                             child1->setGeometry(position+4, 0,
00301                                             width()-position-4, height());
00302                             divider->setGeometry(position, 0, 4, height());
00303                           }
00304         }
00305         else stdHandling=true;
00306           }
00307             }
00308      else stdHandling=true;
00309 
00310     if (stdHandling) {
00311               int position = checkValue( (m_orientation == Vertical ? width() : height()) * xpos/factor );
00312               if (m_orientation == Horizontal){
00313                 child0->setGeometry(0, 0, width(), position);
00314                 child1->setGeometry(0, position+4, width(), height()-position-4);
00315                 divider->setGeometry(0, position, width(), 4);
00316               } else {
00317                 child0->setGeometry(0, 0, position, height());
00318                 child1->setGeometry(position+4, 0, width()-position-4, height());
00319                 divider->setGeometry(position, 0, 4, height());
00320     }
00321 
00322     }
00323     
00324   }
00325 }
00326 
00327 int KDockSplitter::checkValueOverlapped(int position, QWidget *overlappingWidget) const {
00328     if (initialised) {
00329         if (m_orientation == Vertical) {
00330             if (child0==overlappingWidget) {
00331                 if (position<(child0->minimumSize().width()))
00332                     position=child0->minimumSize().width();
00333                 if (position>width()) position=width()-4;
00334             } else if (position>(width()-(child1->minimumSize().width())-4)){
00335                 position=width()-(child1->minimumSize().width())-4;
00336                 if (position<0) position=0;
00337             }
00338         } else {// orientation  == Horizontal
00339             if (child0==overlappingWidget) {
00340                 if (position<(child0->minimumSize().height()))
00341                     position=child0->minimumSize().height();
00342                 if (position>height()) position=height()-4;
00343             } else if (position>(height()-(child1->minimumSize().height())-4)){
00344                 position=height()-(child1->minimumSize().height())-4;
00345                 if (position<0) position=0;
00346 
00347             }
00348         }
00349 
00350     }
00351     return position;
00352 }
00353 
00354 int KDockSplitter::checkValue( int position ) const
00355 {
00356   if (initialised){
00357     if (m_orientation == Vertical){
00358       if (position < (child0->minimumSize().width()))
00359         position = child0->minimumSize().width();
00360       if ((width()-4-position) < (child1->minimumSize().width()))
00361         position = width() - (child1->minimumSize().width()) -4;
00362     } else {
00363       if (position < (child0->minimumSize().height()))
00364         position = (child0->minimumSize().height());
00365       if ((height()-4-position) < (child1->minimumSize().height()))
00366         position = height() - (child1->minimumSize().height()) -4;
00367     }
00368   }
00369 
00370   if (position < 0) position = 0;
00371 
00372   if ((m_orientation == Vertical) && (position > width()))
00373     position = width();
00374   if ((m_orientation == Horizontal) && (position > height()))
00375     position = height();
00376 
00377   return position;
00378 }
00379 
00380 bool KDockSplitter::eventFilter(QObject *o, QEvent *e)
00381 {
00382   QMouseEvent *mev;
00383   bool handled = false;
00384   int factor = (mHighResolution)? 10000:100;
00385 
00386   switch (e->type()) {
00387     case QEvent::MouseMove:
00388       mev= (QMouseEvent*)e;
00389       child0->setUpdatesEnabled(mOpaqueResize);
00390       child1->setUpdatesEnabled(mOpaqueResize);
00391       if (m_orientation == Horizontal) {
00392         if ((fixedHeight0!=-1) || (fixedHeight1!=-1))
00393         {
00394                 handled=true; break;
00395         }
00396 
00397     if (!mOpaqueResize) {
00398           int position = checkValue( mapFromGlobal(mev->globalPos()).y() );
00399           divider->move( 0, position );
00400         } else {
00401           xpos = factor * checkValue( mapFromGlobal(mev->globalPos()).y() ) / height();
00402           resizeEvent(0);
00403           divider->repaint(true);
00404         }
00405       } else {
00406         if ((fixedWidth0!=-1) || (fixedWidth1!=-1))
00407         {
00408                 handled=true; break;
00409         }
00410         if (!mOpaqueResize) {
00411           int position = checkValue( mapFromGlobal(QCursor::pos()).x() );
00412           divider->move( position, 0 );
00413         } else {
00414           xpos = factor * checkValue( mapFromGlobal( mev->globalPos()).x() ) / width();
00415           resizeEvent(0);
00416           divider->repaint(true);
00417         }
00418       }
00419       handled= true;
00420       break;
00421     case QEvent::MouseButtonRelease:
00422       child0->setUpdatesEnabled(true);
00423       child1->setUpdatesEnabled(true);
00424       mev= (QMouseEvent*)e;
00425       if (m_orientation == Horizontal){
00426         if ((fixedHeight0!=-1) || (fixedHeight1!=-1))
00427         {
00428                 handled=true; break;
00429         }
00430         xpos = factor* checkValue( mapFromGlobal(mev->globalPos()).y() ) / height();
00431         resizeEvent(0);
00432         divider->repaint(true);
00433       } else {
00434         if ((fixedWidth0!=-1) || (fixedWidth1!=-1))
00435         {
00436                 handled=true; break;
00437         }
00438         xpos = factor* checkValue( mapFromGlobal(mev->globalPos()).x() ) / width();
00439         resizeEvent(0);
00440         divider->repaint(true);
00441       }
00442       handled= true;
00443       break;
00444     default:
00445       break;
00446   }
00447   return (handled) ? true : QWidget::eventFilter( o, e );
00448 }
00449 
00450 bool KDockSplitter::event( QEvent* e )
00451 {
00452   if ( e->type() == QEvent::LayoutHint ){
00453     // change children min/max size
00454     setupMinMaxSize();
00455     setSeparatorPos(xpos);
00456   }
00457   return QWidget::event(e);
00458 }
00459 
00460 QWidget* KDockSplitter::getAnother( QWidget* w ) const
00461 {
00462   return ( w == child0 ) ? child1 : child0;
00463 }
00464 
00465 void KDockSplitter::updateName()
00466 {
00467   if ( !initialised ) return;
00468 
00469   QString new_name = QString( child0->name() ) + "," + child1->name();
00470   parentWidget()->setName( new_name.latin1() );
00471   parentWidget()->setCaption( child0->caption() + "," + child1->caption() );
00472   parentWidget()->repaint( false );
00473 
00474   ((KDockWidget*)parentWidget())->firstName = child0->name();
00475   ((KDockWidget*)parentWidget())->lastName = child1->name();
00476   ((KDockWidget*)parentWidget())->splitterOrientation = m_orientation;
00477 
00478   QWidget* p = parentWidget()->parentWidget();
00479   if ( p != 0L && p->inherits("KDockSplitter" ) )
00480     ((KDockSplitter*)p)->updateName();
00481 }
00482 
00483 void KDockSplitter::setOpaqueResize(bool b)
00484 {
00485   mOpaqueResize = b;
00486 }
00487 
00488 bool KDockSplitter::opaqueResize() const
00489 {
00490   return mOpaqueResize;
00491 }
00492 
00493 void KDockSplitter::setKeepSize(bool b)
00494 {
00495   mKeepSize = b;
00496 }
00497 
00498 bool KDockSplitter::keepSize() const
00499 {
00500   return mKeepSize;
00501 }
00502 
00503 void KDockSplitter::setHighResolution(bool b)
00504 {
00505   if (mHighResolution) {
00506     if (!b) xpos = xpos/100;
00507   } else {
00508     if (b) xpos = xpos*100;
00509   }
00510   mHighResolution = b;
00511 }
00512 
00513 bool KDockSplitter::highResolution() const
00514 {
00515   return mHighResolution;
00516 }
00517 
00518 
00519 /*************************************************************************/
00520 KDockButton_Private::KDockButton_Private( QWidget *parent, const char * name )
00521 :QPushButton( parent, name )
00522 {
00523   moveMouse = false;
00524   setFocusPolicy( NoFocus );
00525 }
00526 
00527 KDockButton_Private::~KDockButton_Private()
00528 {
00529 }
00530 
00531 void KDockButton_Private::drawButton( QPainter* p )
00532 {
00533   p->fillRect( 0,0, width(), height(), QBrush(colorGroup().brush(QColorGroup::Background)) );
00534   p->drawPixmap( (width() - pixmap()->width()) / 2, (height() - pixmap()->height()) / 2, *pixmap() );
00535   if ( moveMouse && !isDown() ){
00536     p->setPen( white );
00537     p->moveTo( 0, height() - 1 );
00538     p->lineTo( 0, 0 );
00539     p->lineTo( width() - 1, 0 );
00540 
00541     p->setPen( colorGroup().dark() );
00542     p->lineTo( width() - 1, height() - 1 );
00543     p->lineTo( 0, height() - 1 );
00544   }
00545   if ( isOn() || isDown() ){
00546     p->setPen( colorGroup().dark() );
00547     p->moveTo( 0, height() - 1 );
00548     p->lineTo( 0, 0 );
00549     p->lineTo( width() - 1, 0 );
00550 
00551     p->setPen( white );
00552     p->lineTo( width() - 1, height() - 1 );
00553     p->lineTo( 0, height() - 1 );
00554   }
00555 }
00556 
00557 void KDockButton_Private::enterEvent( QEvent * )
00558 {
00559   moveMouse = true;
00560   repaint();
00561 }
00562 
00563 void KDockButton_Private::leaveEvent( QEvent * )
00564 {
00565   moveMouse = false;
00566   repaint();
00567 }
00568 
00569 /*************************************************************************/
00570 KDockWidgetPrivate::KDockWidgetPrivate()
00571   : QObject()
00572   ,index(-1)
00573   ,splitPosInPercent(50)
00574   ,pendingFocusInEvent(false)
00575   ,blockHasUndockedSignal(false)
00576   ,pendingDtor(false)
00577   ,forcedWidth(-1)
00578   ,forcedHeight(-1)
00579   ,isContainer(false)
00580   ,container(0)
00581   ,resizePos(0,0)
00582   ,resizing(false)
00583 {
00584 #ifndef NO_KDE2
00585   windowType = NET::Normal;
00586 #endif
00587 
00588   _parent = 0L;
00589   transient = false;
00590 }
00591 
00592 KDockWidgetPrivate::~KDockWidgetPrivate()
00593 {
00594 }
00595 
00596 void KDockWidgetPrivate::slotFocusEmbeddedWidget(QWidget* w)
00597 {
00598    if (w) {
00599       QWidget* embeddedWdg = ((KDockWidget*)w)->getWidget();
00600       if (embeddedWdg && ((embeddedWdg->focusPolicy() == QWidget::ClickFocus) || (embeddedWdg->focusPolicy() == QWidget::StrongFocus))) {
00601          embeddedWdg->setFocus();
00602       }
00603    }
00604 }
00605 
00606 #ifndef NO_INCLUDE_MOCFILES // for Qt-only projects, because tmake doesn't take this name
00607 #include "kdockwidget_private.moc"
00608 #endif
KDE Logo
This file is part of the documentation for kdeui Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Mar 3 19:23:10 2005 by doxygen 1.3.6 written by Dimitri van Heesch, © 1997-2003