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.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Sep 29 09:43:28 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003