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