00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00079 }
00080
else
00081
if (((
KDockWidget*)child1)->forcedFixedWidth()!=-1)
00082 {
00083 setForcedFixedWidth(((
KDockWidget*)child1),((
KDockWidget*)child1)->forcedFixedWidth());
00084
00085 }
00086
00087
if (((
KDockWidget*)child0)->forcedFixedHeight()!=-1)
00088 {
00089 setForcedFixedHeight(((
KDockWidget*)child0),((
KDockWidget*)child0)->forcedFixedHeight());
00090
00091 }
00092
else
00093
if (((
KDockWidget*)child1)->forcedFixedHeight()!=-1)
00094 {
00095 setForcedFixedHeight(((
KDockWidget*)child1),((
KDockWidget*)child1)->forcedFixedHeight());
00096
00097 }
00098
00099
00100 }
00101
00102
00103
00104
00105
00106
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
00116 savedXPos=xpos;
00117 setSeparatorPos(w*factor/width(),
true);
00118
00119 }
00120
else
00121 {
00122 fixedWidth1=w;
00123 savedXPos=xpos;
00124 setSeparatorPos((width()-w)*factor/width(),
true);
00125
00126
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
00137 savedXPos=xpos;
00138 setSeparatorPos(h*factor/height(),
true);
00139
00140 }
00141
else
00142 {
00143 fixedHeight1=h;
00144 savedXPos=xpos;
00145 setSeparatorPos((height()-h)*factor/height(),
true);
00146
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
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
00224
00225
if (initialised){
00226
int factor = (mHighResolution)? 10000:100;
00227
00228
if (ev && mKeepSize && isVisible()) {
00229
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
00244
if ( isVisible()) {
00245
if (m_orientation == Horizontal) {
00246
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
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
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 {
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
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