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
int KDockSplitter::separatorPos()
const
00211
{
00212
return xpos;
00213 }
00214
00215
void KDockSplitter::resizeEvent(
QResizeEvent *ev)
00216 {
00217
00218
00219
if (initialised){
00220
int factor = (mHighResolution)? 10000:100;
00221
00222
if (ev && mKeepSize &&
isVisible()) {
00223
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
00238
if (
isVisible()) {
00239
if (m_orientation == Horizontal) {
00240
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
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
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 {
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
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