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
#include <qapplication.h>
00028
00029 KDockSplitter::KDockSplitter(
QWidget *parent,
const char *name, Orientation orient,
int pos,
bool highResolution)
00030 :
QWidget(parent,
name)
00031 {
00032 m_dontRecalc=
false;
00033 divider = 0L;
00034 child0 = 0L;
00035 child1 = 0L;
00036 fixedWidth0=-1;
00037 fixedWidth1=-1;
00038 fixedHeight0=-1;
00039 fixedHeight1=-1;
00040
00041 m_orientation = orient;
00042 mOpaqueResize =
false;
00043 mKeepSize =
false;
00044 mHighResolution = highResolution;
00045 setSeparatorPos( pos,
false );
00046 initialised =
false;
00047 }
00048
00049
void KDockSplitter::activate(
QWidget *c0,
QWidget *c1)
00050 {
00051
if ( c0 ) child0 = c0;
00052
if ( c1 ) child1 = c1;
00053
00054 setupMinMaxSize();
00055
00056
if (divider)
delete divider;
00057 divider =
new QFrame(
this,
"pannerdivider");
00058 divider->
setFrameStyle(QFrame::Panel | QFrame::Raised);
00059 divider->
setLineWidth(1);
00060 divider->raise();
00061
00062
if (m_orientation == Horizontal)
00063 divider->setCursor(
QCursor(sizeVerCursor));
00064
else
00065 divider->setCursor(
QCursor(sizeHorCursor));
00066
00067 divider->installEventFilter(
this);
00068
00069 initialised=
true;
00070
00071 updateName();
00072 divider->show();
00073 resizeEvent(0);
00074
if (fixedWidth0!=-1 || fixedHeight0!=-1) restoreFromForcedFixedSize((
KDockWidget*)child0);
00075
if (fixedWidth1!=-1 || fixedHeight1!=-1) restoreFromForcedFixedSize((
KDockWidget*)child1);
00076
if (((
KDockWidget*)child0)->forcedFixedWidth()!=-1)
00077 {
00078 setForcedFixedWidth(((
KDockWidget*)child0),((
KDockWidget*)child0)->forcedFixedWidth());
00079
00080 }
00081
else
00082
if (((
KDockWidget*)child1)->forcedFixedWidth()!=-1)
00083 {
00084 setForcedFixedWidth(((
KDockWidget*)child1),((
KDockWidget*)child1)->forcedFixedWidth());
00085
00086 }
00087
00088
if (((
KDockWidget*)child0)->forcedFixedHeight()!=-1)
00089 {
00090 setForcedFixedHeight(((
KDockWidget*)child0),((
KDockWidget*)child0)->forcedFixedHeight());
00091
00092 }
00093
else
00094
if (((
KDockWidget*)child1)->forcedFixedHeight()!=-1)
00095 {
00096 setForcedFixedHeight(((
KDockWidget*)child1),((
KDockWidget*)child1)->forcedFixedHeight());
00097
00098 }
00099
00100
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
void KDockSplitter::setForcedFixedWidth(
KDockWidget *dw,
int w)
00111 {
00112
int factor = (mHighResolution)? 10000:100;
00113
if (dw==child0)
00114 {
00115
if (fixedWidth0==-1) savedXPos=xpos;
00116
if (w==fixedWidth0)
return;
00117 fixedWidth0=w;
00118 setSeparatorPos(w*factor/
width(),
true);
00119
00120
00121
00122 }
00123
else
00124 {
00125
if (fixedWidth1==-1) savedXPos=xpos;
00126
if (w==fixedWidth1)
return;
00127 fixedWidth1=w;
00128 setSeparatorPos((
width()-w)*factor/
width(),
true);
00129
00130
00131 }
00132 divider->hide();
00133 setupMinMaxSize();
00134 }
00135
00136
void KDockSplitter::setForcedFixedHeight(
KDockWidget *dw,
int h)
00137 {
00138
int factor = (mHighResolution)? 10000:100;
00139
if (dw==child0)
00140 {
00141
if (fixedHeight0==-1) savedXPos=xpos;
00142
if (h==fixedHeight0)
return;
00143 fixedHeight0=h;
00144
00145 setSeparatorPos(h*factor/
height(),
true);
00146
00147 }
00148
else
00149 {
00150
if (fixedHeight1==-1) savedXPos=xpos;
00151
if (h==fixedHeight1)
return;
00152 fixedHeight1=h;
00153 setSeparatorPos((
height()-h)*factor/
height(),
true);
00154
00155 }
00156 divider->hide();
00157 setupMinMaxSize();
00158 }
00159
00160
void KDockSplitter::restoreFromForcedFixedSize(
KDockWidget *dw)
00161 {
00162
if (dw==child0)
00163 {
00164 fixedWidth0=-1;
00165 fixedHeight0=-1;
00166 setSeparatorPos(savedXPos,
true);
00167 }
00168
else
00169 {
00170 fixedWidth1=-1;
00171 fixedHeight1=-1;
00172 setSeparatorPos(savedXPos,
true);
00173 }
00174 divider->show();
00175 }
00176
00177
00178
void KDockSplitter::setupMinMaxSize()
00179 {
00180
00181
int minx, maxx, miny, maxy;
00182
if (m_orientation == Horizontal) {
00183 miny = child0->
minimumSize().height() + child1->
minimumSize().height()+4;
00184 maxy = child0->
maximumSize().height() + child1->
maximumSize().height()+4;
00185 minx = (child0->
minimumSize().width() > child1->
minimumSize().width()) ? child0->
minimumSize().width() : child1->
minimumSize().
width();
00186 maxx = (child0->
maximumSize().width() > child1->
maximumSize().width()) ? child0->
maximumSize().width() : child1->
maximumSize().
width();
00187
00188 miny = (miny > 4) ? miny : 4;
00189 maxy = (maxy < 32000) ? maxy : 32000;
00190 minx = (minx > 2) ? minx : 2;
00191 maxx = (maxx < 32000) ? maxx : 32000;
00192 }
else {
00193 minx = child0->
minimumSize().width() + child1->
minimumSize().width()+4;
00194 maxx = child0->
maximumSize().width() + child1->
maximumSize().width()+4;
00195 miny = (child0->
minimumSize().height() > child1->
minimumSize().height()) ? child0->
minimumSize().height() : child1->
minimumSize().
height();
00196 maxy = (child0->
maximumSize().height() > child1->
maximumSize().height()) ? child0->
maximumSize().height() : child1->
maximumSize().
height();
00197
00198 minx = (minx > 4) ? minx : 4;
00199 maxx = (maxx < 32000) ? maxx : 32000;
00200 miny = (miny > 2) ? miny : 2;
00201 maxy = (maxy < 32000) ? maxy : 32000;
00202
00203 }
00204
setMinimumSize(minx, miny);
00205
setMaximumSize(maxx, maxy);
00206 }
00207
00208
void KDockSplitter::deactivate()
00209 {
00210
delete divider;
00211 divider = 0L;
00212 initialised=
false;
00213 }
00214
00215
void KDockSplitter::setSeparatorPos(
int pos,
bool do_resize)
00216 {
00217 xpos = pos;
00218
if (do_resize)
00219 resizeEvent(0);
00220 }
00221
00222 void KDockSplitter::setSeparatorPosX(
int pos,
bool do_resize )
00223 {
00224 savedXPos = pos;
00225 setSeparatorPos( pos, do_resize );
00226 }
00227
00228
int KDockSplitter::separatorPos()
const
00229
{
00230
return xpos;
00231 }
00232
00233
void KDockSplitter::resizeEvent(
QResizeEvent *ev)
00234 {
00235
00236
00237
if (initialised){
00238
double factor = (mHighResolution)? 10000.0:100.0;
00239
00240
if (ev && mKeepSize &&
isVisible()) {
00241
00242
00243
if (ev->
oldSize().width() != ev->
size().width())
00244 {
00245
if (m_orientation == Horizontal) {
00246 xpos = qRound(factor * checkValue( child0->
height()+1 ) /
height());
00247 }
else {
00248 xpos = qRound(factor * checkValue( child0->
width()+1 ) /
width());
00249 }
00250
00251 }
00252 }
00253
else
00254 {
00255
00256
if (
isVisible()) {
00257
if (m_orientation == Horizontal) {
00258
00259 {
00260
if (fixedHeight0!=-1)
00261
00262 xpos=qRound(fixedHeight0*factor/
height());
00263
else
00264
if (fixedHeight1!=-1)
00265
00266 xpos=qRound((
height()-fixedHeight1)*factor/
height());
00267 }
00268 }
00269
else
00270 {
00271
00272 {
00273
if (fixedWidth0!=-1)
00274
00275 xpos=qRound(fixedWidth0*factor/
width());
00276
else
00277
if (fixedWidth1!=-1)
00278
00279 xpos=qRound((
width()-fixedWidth1)*factor/
width());
00280 }
00281 }
00282 }
00283
00284 }
00285
00286 KDockContainer *dc;
00287
KDockWidget *c0=(
KDockWidget*)child0;
00288
KDockWidget *c1=(
KDockWidget*)child1;
00289
bool stdHandling=
false;
00290
if ( ( (m_orientation==Vertical) &&((fixedWidth0==-1) && (fixedWidth1==-1)) ) ||
00291 ( (m_orientation==Horizontal) &&((fixedHeight0==-1) && (fixedHeight1==-1)) ) ) {
00292
if ((c0->
getWidget()) && (dc=dynamic_cast<KDockContainer*>(c0->
getWidget()))
00293 && (dc->m_overlapMode)) {
00294
int position= qRound((m_orientation == Vertical ?
width() :
height()) * xpos/factor);
00295 position=checkValueOverlapped(position,child0);
00296 child0->
raise();
00297 divider->raise();
00298
if (m_orientation == Horizontal){
00299 child0->
setGeometry(0, 0,
width(), position);
00300 child1->
setGeometry(0, dc->m_nonOverlapSize+4,
width(),
00301
height()-dc->m_nonOverlapSize-4);
00302 divider->setGeometry(0, position,
width(), 4);
00303 }
else {
00304 child0->
setGeometry(0, 0, position,
height());
00305 child1->
setGeometry(dc->m_nonOverlapSize+4, 0,
00306
width()-dc->m_nonOverlapSize-4,
height());
00307 divider->setGeometry(position, 0, 4,
height());
00308 }
00309 }
else {
00310
if ((c1->
getWidget()) && (dc=dynamic_cast<KDockContainer*>(c1->
getWidget()))
00311 && (dc->m_overlapMode)) {
00312
int position= qRound((m_orientation == Vertical ?
width() :
height()) * xpos/factor);
00313 position=checkValueOverlapped(position,child1);
00314 child1->
raise();
00315 divider->raise();
00316
if (m_orientation == Horizontal){
00317 child0->
setGeometry(0, 0,
width(),
height()-dc->m_nonOverlapSize-4);
00318 child1->
setGeometry(0, position+4,
width(),
00319
height()-position-4);
00320 divider->setGeometry(0, position,
width(), 4);
00321 }
else {
00322 child0->
setGeometry(0, 0,
width()-dc->m_nonOverlapSize-4,
height());
00323 child1->
setGeometry(position+4, 0,
00324
width()-position-4,
height());
00325 divider->setGeometry(position, 0, 4,
height());
00326 }
00327 }
00328
else stdHandling=
true;
00329 }
00330 }
00331
else stdHandling=
true;
00332
00333
if (stdHandling) {
00334
int position = checkValue( qRound((m_orientation == Vertical ?
width() :
height()) * xpos/factor) );
00335
if (m_orientation == Horizontal){
00336 child0->
setGeometry(0, 0,
width(), position);
00337 child1->
setGeometry(0, position+4,
width(),
height()-position-4);
00338 divider->setGeometry(0, position,
width(), 4);
00339 }
else {
00340 child0->
setGeometry(0, 0, position,
height());
00341 child1->
setGeometry(position+4, 0,
width()-position-4,
height());
00342 divider->setGeometry(position, 0, 4,
height());
00343 }
00344
00345 }
00346
00347 }
00348 }
00349
00350
int KDockSplitter::checkValueOverlapped(
int position,
QWidget *overlappingWidget)
const {
00351
if (initialised) {
00352
if (m_orientation == Vertical) {
00353
if (child0==overlappingWidget) {
00354
if (position<(child0->
minimumSize().width()))
00355 position=child0->
minimumSize().width();
00356
if (position>
width()) position=
width()-4;
00357 }
else if (position>(
width()-(child1->
minimumSize().width())-4)){
00358 position=
width()-(child1->
minimumSize().width())-4;
00359
if (position<0) position=0;
00360 }
00361 }
else {
00362
if (child0==overlappingWidget) {
00363
if (position<(child0->
minimumSize().height()))
00364 position=child0->
minimumSize().height();
00365
if (position>
height()) position=
height()-4;
00366 }
else if (position>(
height()-(child1->
minimumSize().height())-4)){
00367 position=
height()-(child1->
minimumSize().height())-4;
00368
if (position<0) position=0;
00369
00370 }
00371 }
00372
00373 }
00374
return position;
00375 }
00376
00377
int KDockSplitter::checkValue(
int position )
const
00378
{
00379
if (initialised){
00380
if (m_orientation == Vertical){
00381
if (position < (child0->
minimumSize().width()))
00382 position = child0->
minimumSize().width();
00383
if ((
width()-4-position) < (child1->
minimumSize().width()))
00384 position =
width() - (child1->
minimumSize().width()) -4;
00385 }
else {
00386
if (position < (child0->
minimumSize().height()))
00387 position = (child0->
minimumSize().height());
00388
if ((
height()-4-position) < (child1->
minimumSize().height()))
00389 position =
height() - (child1->
minimumSize().height()) -4;
00390 }
00391 }
00392
00393
if (position < 0) position = 0;
00394
00395
if ((m_orientation == Vertical) && (position >
width()))
00396 position =
width();
00397
if ((m_orientation == Horizontal) && (position >
height()))
00398 position =
height();
00399
00400
return position;
00401 }
00402
00403
bool KDockSplitter::eventFilter(
QObject *o,
QEvent *e)
00404 {
00405
QMouseEvent *mev;
00406
bool handled =
false;
00407
int factor = (mHighResolution)? 10000:100;
00408
00409
switch (e->
type()) {
00410
case QEvent::MouseMove:
00411 mev= (
QMouseEvent*)e;
00412 child0->
setUpdatesEnabled(mOpaqueResize);
00413 child1->
setUpdatesEnabled(mOpaqueResize);
00414
if (m_orientation == Horizontal) {
00415
if ((fixedHeight0!=-1) || (fixedHeight1!=-1))
00416 {
00417 handled=
true;
break;
00418 }
00419
00420
if (!mOpaqueResize) {
00421
int position = checkValue(
mapFromGlobal(mev->
globalPos()).y() );
00422 divider->move( 0, position );
00423 }
else {
00424 xpos = factor * checkValue(
mapFromGlobal(mev->
globalPos()).y() ) /
height();
00425 resizeEvent(0);
00426 divider->repaint(
true);
00427 }
00428 }
else {
00429
if ((fixedWidth0!=-1) || (fixedWidth1!=-1))
00430 {
00431 handled=
true;
break;
00432 }
00433
if (!mOpaqueResize) {
00434
int position = checkValue(
mapFromGlobal(QCursor::pos()).
x() );
00435 divider->move( position, 0 );
00436 }
else {
00437 xpos = factor * checkValue(
mapFromGlobal( mev->
globalPos()).x() ) /
width();
00438 resizeEvent(0);
00439 divider->repaint(
true);
00440 }
00441 }
00442 handled=
true;
00443
break;
00444
case QEvent::MouseButtonRelease:
00445 child0->
setUpdatesEnabled(
true);
00446 child1->
setUpdatesEnabled(
true);
00447 mev= (
QMouseEvent*)e;
00448
if (m_orientation == Horizontal){
00449
if ((fixedHeight0!=-1) || (fixedHeight1!=-1))
00450 {
00451 handled=
true;
break;
00452 }
00453 xpos = factor* checkValue(
mapFromGlobal(mev->
globalPos()).y() ) /
height();
00454 resizeEvent(0);
00455 divider->repaint(
true);
00456 }
else {
00457
if ((fixedWidth0!=-1) || (fixedWidth1!=-1))
00458 {
00459 handled=
true;
break;
00460 }
00461 xpos = factor* checkValue(
mapFromGlobal(mev->
globalPos()).x() ) /
width();
00462 resizeEvent(0);
00463 divider->repaint(
true);
00464 }
00465 handled=
true;
00466
break;
00467
default:
00468
break;
00469 }
00470
return (handled) ?
true : QWidget::eventFilter( o, e );
00471 }
00472
00473
bool KDockSplitter::event(
QEvent* e )
00474 {
00475
if ( e->
type() == QEvent::LayoutHint ){
00476
00477 setupMinMaxSize();
00478 setSeparatorPos(xpos);
00479 }
00480
return QWidget::event(e);
00481 }
00482
00483
QWidget* KDockSplitter::getAnother(
QWidget* w )
const
00484
{
00485
return ( w == child0 ) ? child1 : child0;
00486 }
00487
00488
void KDockSplitter::updateName()
00489 {
00490
if ( !initialised )
return;
00491
00492
QString new_name =
QString( child0->name() ) +
"," + child1->name();
00493
parentWidget()->setName( new_name.
latin1() );
00494
parentWidget()->setCaption( child0->
caption() +
"," + child1->
caption() );
00495
parentWidget()->repaint(
false );
00496
00497 ((
KDockWidget*)
parentWidget())->firstName = child0->name();
00498 ((
KDockWidget*)
parentWidget())->lastName = child1->name();
00499 ((
KDockWidget*)
parentWidget())->splitterOrientation = m_orientation;
00500
00501
QWidget* p =
parentWidget()->parentWidget();
00502
if ( p && p->inherits(
"KDockSplitter" ) )
00503 ((
KDockSplitter*)p)->updateName();
00504 }
00505
00506
void KDockSplitter::setOpaqueResize(
bool b)
00507 {
00508 mOpaqueResize = b;
00509 }
00510
00511
bool KDockSplitter::opaqueResize()
const
00512
{
00513
return mOpaqueResize;
00514 }
00515
00516
void KDockSplitter::setKeepSize(
bool b)
00517 {
00518 mKeepSize = b;
00519 }
00520
00521
bool KDockSplitter::keepSize()
const
00522
{
00523
return mKeepSize;
00524 }
00525
00526
void KDockSplitter::setHighResolution(
bool b)
00527 {
00528
if (mHighResolution) {
00529
if (!b) xpos = xpos/100;
00530 }
else {
00531
if (b) xpos = xpos*100;
00532 }
00533 mHighResolution = b;
00534 }
00535
00536
bool KDockSplitter::highResolution()
const
00537
{
00538
return mHighResolution;
00539 }
00540
00541
00542
00543 KDockButton_Private::KDockButton_Private(
QWidget *parent,
const char * name )
00544 :
QPushButton( parent,
name )
00545 {
00546 moveMouse =
false;
00547
setFocusPolicy( NoFocus );
00548 }
00549
00550 KDockButton_Private::~KDockButton_Private()
00551 {
00552 }
00553
00554
void KDockButton_Private::drawButton(
QPainter* p )
00555 {
00556 p->
fillRect( 0,0, width(), height(),
QBrush(colorGroup().brush(QColorGroup::Background)) );
00557 p->
drawPixmap( (width() -
pixmap()->width()) / 2, (height() -
pixmap()->height()) / 2, *
pixmap() );
00558
if ( moveMouse && !
isDown() ){
00559 p->
setPen( white );
00560 p->moveTo( 0, height() - 1 );
00561 p->lineTo( 0, 0 );
00562 p->lineTo( width() - 1, 0 );
00563
00564 p->
setPen( colorGroup().dark() );
00565 p->lineTo( width() - 1, height() - 1 );
00566 p->lineTo( 0, height() - 1 );
00567 }
00568
if (
isOn() ||
isDown() ){
00569 p->
setPen( colorGroup().dark() );
00570 p->moveTo( 0, height() - 1 );
00571 p->lineTo( 0, 0 );
00572 p->lineTo( width() - 1, 0 );
00573
00574 p->
setPen( white );
00575 p->lineTo( width() - 1, height() - 1 );
00576 p->lineTo( 0, height() - 1 );
00577 }
00578 }
00579
00580
void KDockButton_Private::enterEvent(
QEvent * )
00581 {
00582 moveMouse =
true;
00583 repaint();
00584 }
00585
00586
void KDockButton_Private::leaveEvent(
QEvent * )
00587 {
00588 moveMouse =
false;
00589 repaint();
00590 }
00591
00592
00593 KDockWidgetPrivate::KDockWidgetPrivate()
00594 :
QObject()
00595 ,index(-1)
00596 ,splitPosInPercent(50)
00597 ,pendingFocusInEvent(false)
00598 ,blockHasUndockedSignal(false)
00599 ,pendingDtor(false)
00600 ,forcedWidth(-1)
00601 ,forcedHeight(-1)
00602 ,isContainer(false)
00603 ,container(0)
00604 ,resizePos(0,0)
00605 ,resizing(false)
00606 {
00607
#ifndef NO_KDE2
00608
windowType = NET::Normal;
00609
#endif
00610
00611 _parent = 0L;
00612
transient =
false;
00613 }
00614
00615 KDockWidgetPrivate::~KDockWidgetPrivate()
00616 {
00617 }
00618
00619 void KDockWidgetPrivate::slotFocusEmbeddedWidget(
QWidget* w)
00620 {
00621
if (w) {
00622
QWidget* embeddedWdg = ((
KDockWidget*)w)->getWidget();
00623
if (embeddedWdg && ((embeddedWdg->
focusPolicy() == QWidget::ClickFocus) || (embeddedWdg->
focusPolicy() == QWidget::StrongFocus))) {
00624 embeddedWdg->
setFocus();
00625 }
00626 }
00627 }
00628
00629
#ifndef NO_INCLUDE_MOCFILES // for Qt-only projects, because tmake doesn't take this name
00630
#include "kdockwidget_private.moc"
00631
#endif