00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <qlabel.h>
00023 #include <qlayout.h>
00024 #include <qpainter.h>
00025
00026 #include <kconfig.h>
00027
00028 #include "Web.h"
00029 #include "WebButton.h"
00030 #include "WebButtonHelp.h"
00031 #include "WebButtonIconify.h"
00032 #include "WebButtonClose.h"
00033 #include "WebButtonSticky.h"
00034 #include "WebButtonMaximize.h"
00035 #include "WebButtonLower.h"
00036
00037 extern "C"
00038 {
00039 KDecorationFactory *create_factory()
00040 {
00041 return new Web::WebFactory();
00042 }
00043 }
00044
00045 namespace Web {
00046
00047 WebClient::WebClient(KDecorationBridge* bridge, KDecorationFactory* factory)
00048 : KDecoration(bridge, factory),
00049 mainLayout_ (0),
00050 titleSpacer_ (0)
00051 {
00052
00053 }
00054
00055 WebClient::~WebClient()
00056 {
00057
00058 }
00059
00060 void
00061 WebClient::init()
00062 {
00063 createMainWidget(WNoAutoErase);
00064 widget()->installEventFilter( this );
00065 widget()->setBackgroundMode(NoBackground);
00066
00067
00068 const int textVMargin = 2;
00069 QFontMetrics fm(options()->font(isActive(), isTool()));
00070
00071
00072 switch(options()->preferredBorderSize( factory())) {
00073 case BorderLarge:
00074 borderSize_ = 8;
00075 break;
00076 case BorderVeryLarge:
00077 borderSize_ = 12;
00078 break;
00079 case BorderHuge:
00080 borderSize_ = 18;
00081 break;
00082 case BorderVeryHuge:
00083 borderSize_ = 27;
00084 break;
00085 case BorderOversized:
00086 borderSize_ = 40;
00087 break;
00088 case BorderNormal:
00089 default:
00090 borderSize_ = 4;
00091 }
00092 titleHeight_ = QMAX(QMAX(14, fm.height() + textVMargin * 2), borderSize_);
00093
00094 _resetLayout();
00095
00096 leftButtonList_ .setAutoDelete(true);
00097 rightButtonList_ .setAutoDelete(true);
00098 }
00099
00100 void
00101 WebClient::reset( unsigned long changed )
00102 {
00103 if (changed & SettingColors)
00104 {
00105
00106 widget()->repaint(false);
00107 } else if (changed & SettingFont) {
00108
00109
00110 const uint textVMargin = 2;
00111 QFontMetrics fm(options()->font(isActive(), isTool()));
00112 titleHeight_ = QMAX(14, fm.height() + textVMargin * 2);
00113
00114 for (QPtrListIterator<WebButton> it(leftButtonList_); it.current(); ++it)
00115 {
00116 it.current()->setFixedSize(titleHeight_, titleHeight_);
00117 }
00118 for (QPtrListIterator<WebButton> it(rightButtonList_); it.current(); ++it)
00119 {
00120 it.current()->setFixedSize(titleHeight_, titleHeight_);
00121 }
00122
00123
00124
00125
00126 titleSpacer_->changeSize(0, titleHeight_, QSizePolicy::Expanding,
00127 QSizePolicy::Fixed);
00128 widget()->repaint(false);
00129 }
00130 }
00131
00132 void
00133 WebClient::resizeEvent(QResizeEvent *)
00134 {
00135 doShape();
00136 widget()->repaint();
00137 }
00138
00139 void
00140 WebClient::captionChange()
00141 {
00142 widget()->repaint();
00143 }
00144
00145 void WebClient::iconChange()
00146 {
00147
00148 }
00149
00150 void
00151 WebClient::paintEvent(QPaintEvent * pe)
00152 {
00153 QRect titleRect(titleSpacer_->geometry());
00154 titleRect.setTop(1);
00155
00156 QPainter p(widget());
00157
00158 p.setPen(Qt::black);
00159 p.setBrush(options()->colorGroup(ColorFrame, isActive()).background());
00160
00161 p.setClipRegion(pe->region() - titleRect);
00162
00163 p.drawRect(widget()->rect());
00164
00165 p.setClipRegion(pe->region());
00166
00167 p.fillRect(titleRect, options()->color(ColorTitleBar, isActive()));
00168
00169 if (shape_)
00170 {
00171 int r(width());
00172 int b(height());
00173
00174
00175
00176 p.drawPoint(3, 1);
00177 p.drawPoint(4, 1);
00178 p.drawPoint(2, 2);
00179 p.drawPoint(1, 3);
00180 p.drawPoint(1, 4);
00181
00182
00183
00184 p.drawPoint(r - 5, 1);
00185 p.drawPoint(r - 4, 1);
00186 p.drawPoint(r - 3, 2);
00187 p.drawPoint(r - 2, 3);
00188 p.drawPoint(r - 2, 4);
00189
00190
00191
00192 p.drawPoint(1, b - 5);
00193 p.drawPoint(1, b - 4);
00194 p.drawPoint(2, b - 3);
00195 p.drawPoint(3, b - 2);
00196 p.drawPoint(4, b - 2);
00197
00198
00199
00200 p.drawPoint(r - 2, b - 5);
00201 p.drawPoint(r - 2, b - 4);
00202 p.drawPoint(r - 3, b - 3);
00203 p.drawPoint(r - 4, b - 2);
00204 p.drawPoint(r - 5, b - 2);
00205 }
00206
00207 p.setFont(options()->font(isActive(), isTool()));
00208
00209 p.setPen(options()->color(ColorFont, isActive()));
00210
00211 p.drawText(titleSpacer_->geometry(), AlignCenter, caption());
00212 }
00213
00214 void
00215 WebClient::doShape()
00216 {
00217 if (!shape_)
00218 return;
00219
00220 QRegion mask(0, 0, width(), height());
00221
00222 int r(width());
00223 int b(height());
00224
00225
00226
00227 mask -= QRegion(0, 0, 5, 1);
00228 mask -= QRegion(0, 1, 3, 1);
00229 mask -= QRegion(0, 2, 2, 1);
00230 mask -= QRegion(0, 3, 1, 2);
00231
00232
00233
00234 mask -= QRegion(r - 5, 0, 5, 1);
00235 mask -= QRegion(r - 3, 1, 3, 1);
00236 mask -= QRegion(r - 2, 2, 2, 1);
00237 mask -= QRegion(r - 1, 3, 1, 2);
00238
00239
00240
00241 mask -= QRegion(0, b - 5, 1, 3);
00242 mask -= QRegion(0, b - 3, 2, 1);
00243 mask -= QRegion(0, b - 2, 3, 1);
00244 mask -= QRegion(0, b - 1, 5, 1);
00245
00246
00247
00248 mask -= QRegion(r - 5, b - 1, 5, 1);
00249 mask -= QRegion(r - 3, b - 2, 3, 1);
00250 mask -= QRegion(r - 2, b - 3, 2, 1);
00251 mask -= QRegion(r - 1, b - 5, 1, 2);
00252
00253 setMask(mask);
00254 }
00255
00256 void
00257 WebClient::showEvent(QShowEvent *)
00258 {
00259 doShape();
00260 widget()->repaint();
00261 }
00262
00263 void
00264 WebClient::windowWrapperShowEvent(QShowEvent *)
00265 {
00266 doShape();
00267 widget()->repaint();
00268 }
00269
00270 void
00271 WebClient::mouseDoubleClickEvent(QMouseEvent * e)
00272 {
00273 if (titleSpacer_->geometry().contains(e->pos()))
00274 {
00275 titlebarDblClickOperation();
00276 }
00277 }
00278
00279 void
00280 WebClient::desktopChange()
00281 {
00282 emit(oadChange(isOnAllDesktops()));
00283 }
00284
00285 void
00286 WebClient::maximizeChange()
00287 {
00288 emit(maxChange(maximizeMode()==MaximizeFull));
00289 }
00290
00291 void
00292 WebClient::activeChange()
00293 {
00294 widget()->repaint();
00295 }
00296
00297 WebClient::Position
00298 WebClient::mousePosition(const QPoint & p) const
00299 {
00300 int x = p.x();
00301 int y = p.y();
00302 int corner = 14 + 3*borderSize_/2;
00303
00304 if (y < titleSpacer_->geometry().height())
00305 {
00306
00307
00308 #if 0
00309 if ((y < 4 && x < corner) || x < 4)
00310 return Client::TopLeft;
00311 else if ((y < 4 && x > width() - corner) || x > width() - 4)
00312 return Client::TopRight;
00313 else if (y < 4)
00314 return Client::Top;
00315 else
00316 #endif
00317 return KDecoration::PositionCenter;
00318 }
00319 else if (y < height() - borderSize_)
00320 {
00321 if (x < borderSize_)
00322 return KDecoration::PositionLeft;
00323 else
00324 if (x > width() - borderSize_)
00325 return KDecoration::PositionRight;
00326 else
00327 return KDecoration::PositionCenter;
00328 }
00329 else
00330 {
00331 if (x < 12 + corner)
00332 return KDecoration::PositionBottomLeft;
00333 else
00334 if (x > width() - corner)
00335 return KDecoration::PositionBottomRight;
00336 else
00337 return KDecoration::PositionBottom;
00338 }
00339
00340 return KDecoration::mousePosition(p);
00341 }
00342
00343 void
00344 WebClient::slotMaximize(int button)
00345 {
00346 maximize( static_cast<ButtonState>(button) );
00347 }
00348
00349 WebButton *
00350 WebClient::_createButton(const QString & s, QWidget * parent)
00351 {
00352 WebButton * b = 0;
00353
00354 if (("Help" == s) && providesContextHelp())
00355 {
00356 b = new WebButtonHelp(parent, this);
00357 connect(b, SIGNAL(help()), this, SLOT(showContextHelp()));
00358 }
00359
00360 else if ("OnAllDesktops" == s)
00361 {
00362 b = new WebButtonSticky(isOnAllDesktops(), parent, this);
00363 connect(b, SIGNAL(toggleSticky()), this, SLOT(toggleOnAllDesktops()));
00364 connect(this, SIGNAL(oadChange(bool)), b, SLOT(slotOnAllDesktopsChange(bool)));
00365 }
00366
00367 else if ("Minimize" == s && isMinimizable())
00368 {
00369 b = new WebButtonIconify(parent, this);
00370 connect(b, SIGNAL(minimize()), this, SLOT(minimize()));
00371 }
00372
00373 else if ("Maximize" == s && isMaximizable())
00374 {
00375 b = new WebButtonMaximize((maximizeMode()==MaximizeFull), parent, this);
00376 connect(b, SIGNAL(maximize(int)), this, SLOT(slotMaximize(int)));
00377 connect(this, SIGNAL(maxChange(bool)), b, SLOT(slotMaximizeChange(bool)));
00378 }
00379
00380 else if ("Close" == s && isCloseable())
00381 {
00382 b = new WebButtonClose(parent, this);
00383 connect(b, SIGNAL(closeWindow()), this, SLOT(closeWindow()));
00384 }
00385
00386 else if ("Lower" == s)
00387 {
00388 b = new WebButtonLower(parent, this);
00389 connect(b, SIGNAL(lowerWindow()), this, SLOT(slotLowerWindow()));
00390 }
00391
00392 if (0 != b)
00393 {
00394 b->setShape(shape_);
00395 }
00396
00397 return b;
00398 }
00399
00400 void
00401 WebClient::_createButtons()
00402 {
00403 leftButtonList_ .clear();
00404 rightButtonList_ .clear();
00405
00406 QString buttons = options()->titleButtonsLeft() + "|" + options()->titleButtonsRight();
00407 QPtrList<WebButton> *buttonList = &leftButtonList_;
00408 for (unsigned int i = 0; i < buttons.length(); ++i)
00409 {
00410 WebButton * tb = 0;
00411 switch (buttons[i].latin1())
00412 {
00413 case 'S':
00414 tb = _createButton("OnAllDesktops", widget());
00415 break;
00416
00417 case 'H':
00418 tb = _createButton("Help", widget());
00419 break;
00420
00421 case 'I':
00422 tb = _createButton("Minimize", widget());
00423 break;
00424
00425 case 'A':
00426 tb = _createButton("Maximize", widget());
00427 break;
00428
00429 case 'X':
00430 tb = _createButton("Close", widget());
00431 break;
00432
00433 case '|':
00434 buttonList = &rightButtonList_;
00435 break;
00436 }
00437 if (0 != tb)
00438 buttonList->append(tb);
00439 }
00440
00441 if (!leftButtonList_.isEmpty())
00442 leftButtonList_.first()->setPosition(WebButton::Left);
00443
00444 if (!rightButtonList_.isEmpty())
00445 rightButtonList_.last()->setPosition(WebButton::Right);
00446 }
00447
00448 void
00449 WebClient::_resetLayout()
00450 {
00451 KConfig c("kwinwebrc");
00452 c.setGroup("General");
00453 shape_ = c.readBoolEntry("Shape", true);
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468 const uint sideMargin = borderSize_;
00469 const uint bottomMargin = borderSize_;
00470
00471 if (0 != titleHeight_ % 2)
00472 titleHeight_ += 1;
00473
00474 delete mainLayout_;
00475
00476 mainLayout_ = new QVBoxLayout(widget(), 0, 0);
00477
00478 titleSpacer_ = new QSpacerItem ( 0, titleHeight_, QSizePolicy::Expanding,
00479 QSizePolicy::Fixed);
00480
00481 QBoxLayout * topLayout = new QBoxLayout(mainLayout_, QBoxLayout::LeftToRight, 0, 0);
00482
00483 _createButtons();
00484
00485
00486
00487 for (QPtrListIterator<WebButton> it(leftButtonList_); it.current(); ++it)
00488 {
00489 topLayout->addWidget(it.current(), Qt::AlignVCenter);
00490 topLayout->setStretchFactor(it.current(), 0);
00491 it.current()->setFixedSize(titleHeight_, titleHeight_);
00492 }
00493
00494 topLayout->addItem(titleSpacer_);
00495
00496
00497
00498 for (QPtrListIterator<WebButton> it(rightButtonList_); it.current(); ++it)
00499 {
00500 topLayout->addWidget(it.current(), Qt::AlignVCenter);
00501 it.current()->setFixedSize(titleHeight_, titleHeight_);
00502 }
00503
00504
00505
00506 QHBoxLayout * midLayout = new QHBoxLayout(mainLayout_, 0, 0);
00507
00508 midLayout->addSpacing(sideMargin);
00509 if( isPreview())
00510 midLayout->addWidget(new QLabel( i18n( "<center><b>Web</b></center>" ), widget()));
00511 else
00512 midLayout->addItem( new QSpacerItem( 0, 0 ));
00513 midLayout->addSpacing(sideMargin);
00514
00515
00516
00517 mainLayout_->addSpacing(bottomMargin);
00518
00519
00520
00521
00522 mainLayout_->setStretchFactor(topLayout, 0);
00523 mainLayout_->setStretchFactor(midLayout, 1);
00524 }
00525
00526 void WebClient::borders(int& left, int& right, int& top, int& bottom) const
00527 {
00528 left = borderSize_;
00529 right = borderSize_;
00530 top = titleHeight_;
00531 bottom = borderSize_;
00532 }
00533
00534 void WebClient::resize( const QSize& s )
00535 {
00536 widget()->resize( s );
00537 }
00538
00539 QSize WebClient::minimumSize() const
00540 {
00541 return QSize( 200, 50 );
00542 }
00543
00544 const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
00545 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
00546 | NET::UtilityMask | NET::SplashMask;
00547
00548 bool WebClient::isTool()
00549 {
00550 NET::WindowType type = windowType( SUPPORTED_WINDOW_TYPES_MASK );
00551 return ((type==NET::Toolbar)||(type==NET::Utility)||(type==NET::Menu));
00552 }
00553
00554 bool WebClient::eventFilter( QObject* o, QEvent* e )
00555 {
00556 if( o != widget())
00557 return false;
00558 switch( e->type())
00559 {
00560 case QEvent::Resize:
00561 resizeEvent(static_cast< QResizeEvent* >( e ) );
00562 return true;
00563 case QEvent::Paint:
00564 paintEvent(static_cast< QPaintEvent* >( e ) );
00565 return true;
00566 case QEvent::MouseButtonDblClick:
00567 mouseDoubleClickEvent(static_cast< QMouseEvent* >( e ) );
00568 return true;
00569 case QEvent::MouseButtonPress:
00570 processMousePressEvent(static_cast< QMouseEvent* >( e ) );
00571 return true;
00572 default:
00573 break;
00574 }
00575 return false;
00576 }
00577
00578
00579 KDecoration* WebFactory::createDecoration( KDecorationBridge* b )
00580 {
00581 return(new WebClient(b, this));
00582 }
00583
00584 bool WebFactory::reset(unsigned long changed)
00585 {
00586
00587 bool needHardReset = true;
00588 if (changed & SettingColors || changed & SettingFont)
00589 {
00590 needHardReset = false;
00591 }
00592
00593 if (needHardReset) {
00594 return true;
00595 } else {
00596 resetDecorations(changed);
00597 return false;
00598 }
00599 }
00600
00601 QValueList< WebFactory::BorderSize > WebFactory::borderSizes() const
00602 {
00603 return QValueList< BorderSize >() << BorderNormal << BorderLarge <<
00604 BorderVeryLarge << BorderHuge << BorderVeryHuge << BorderOversized;
00605 }
00606
00607 }
00608
00609 #include "Web.moc"
00610