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.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 20 09:48:44 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003