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 switch (button)
00347 {
00348 case MidButton:
00349 maximize(maximizeMode() ^ MaximizeVertical);
00350 break;
00351
00352 case RightButton:
00353 maximize(maximizeMode() ^ MaximizeHorizontal);
00354 break;
00355
00356 case LeftButton:
00357 default:
00358 maximize(maximizeMode() == MaximizeFull ? MaximizeRestore : MaximizeFull);
00359 }
00360 }
00361
00362 WebButton *
00363 WebClient::_createButton(const QString & s, QWidget * parent)
00364 {
00365 WebButton * b = 0;
00366
00367 if (("Help" == s) && providesContextHelp())
00368 {
00369 b = new WebButtonHelp(parent, this);
00370 connect(b, SIGNAL(help()), this, SLOT(showContextHelp()));
00371 }
00372
00373 else if ("OnAllDesktops" == s)
00374 {
00375 b = new WebButtonSticky(isOnAllDesktops(), parent, this);
00376 connect(b, SIGNAL(toggleSticky()), this, SLOT(toggleOnAllDesktops()));
00377 connect(this, SIGNAL(oadChange(bool)), b, SLOT(slotOnAllDesktopsChange(bool)));
00378 }
00379
00380 else if ("Minimize" == s && isMinimizable())
00381 {
00382 b = new WebButtonIconify(parent, this);
00383 connect(b, SIGNAL(minimize()), this, SLOT(minimize()));
00384 }
00385
00386 else if ("Maximize" == s && isMaximizable())
00387 {
00388 b = new WebButtonMaximize((maximizeMode()==MaximizeFull), parent, this);
00389 connect(b, SIGNAL(maximize(int)), this, SLOT(slotMaximize(int)));
00390 connect(this, SIGNAL(maxChange(bool)), b, SLOT(slotMaximizeChange(bool)));
00391 }
00392
00393 else if ("Close" == s && isCloseable())
00394 {
00395 b = new WebButtonClose(parent, this);
00396 connect(b, SIGNAL(closeWindow()), this, SLOT(closeWindow()));
00397 }
00398
00399 else if ("Lower" == s)
00400 {
00401 b = new WebButtonLower(parent, this);
00402 connect(b, SIGNAL(lowerWindow()), this, SLOT(slotLowerWindow()));
00403 }
00404
00405 if (0 != b)
00406 {
00407 b->setShape(shape_);
00408 }
00409
00410 return b;
00411 }
00412
00413 void
00414 WebClient::_createButtons()
00415 {
00416 leftButtonList_ .clear();
00417 rightButtonList_ .clear();
00418
00419 QString buttons = options()->titleButtonsLeft() + "|" + options()->titleButtonsRight();
00420 QPtrList<WebButton> *buttonList = &leftButtonList_;
00421 for (unsigned int i = 0; i < buttons.length(); ++i)
00422 {
00423 WebButton * tb = 0;
00424 switch (buttons[i].latin1())
00425 {
00426 case 'S':
00427 tb = _createButton("OnAllDesktops", widget());
00428 break;
00429
00430 case 'H':
00431 tb = _createButton("Help", widget());
00432 break;
00433
00434 case 'I':
00435 tb = _createButton("Minimize", widget());
00436 break;
00437
00438 case 'A':
00439 tb = _createButton("Maximize", widget());
00440 break;
00441
00442 case 'X':
00443 tb = _createButton("Close", widget());
00444 break;
00445
00446 case '|':
00447 buttonList = &rightButtonList_;
00448 break;
00449 }
00450 if (0 != tb)
00451 buttonList->append(tb);
00452 }
00453
00454 if (!leftButtonList_.isEmpty())
00455 leftButtonList_.first()->setPosition(WebButton::Left);
00456
00457 if (!rightButtonList_.isEmpty())
00458 rightButtonList_.last()->setPosition(WebButton::Right);
00459 }
00460
00461 void
00462 WebClient::_resetLayout()
00463 {
00464 KConfig c("kwinwebrc");
00465 c.setGroup("General");
00466 shape_ = c.readBoolEntry("Shape", true);
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 const uint sideMargin = borderSize_;
00482 const uint bottomMargin = borderSize_;
00483
00484 if (0 != titleHeight_ % 2)
00485 titleHeight_ += 1;
00486
00487 delete mainLayout_;
00488
00489 mainLayout_ = new QVBoxLayout(widget(), 0, 0);
00490
00491 titleSpacer_ = new QSpacerItem ( 0, titleHeight_, QSizePolicy::Expanding,
00492 QSizePolicy::Fixed);
00493
00494 QBoxLayout * topLayout = new QBoxLayout(mainLayout_, QBoxLayout::LeftToRight, 0, 0);
00495
00496 _createButtons();
00497
00498
00499
00500 for (QPtrListIterator<WebButton> it(leftButtonList_); it.current(); ++it)
00501 {
00502 topLayout->addWidget(it.current(), Qt::AlignVCenter);
00503 topLayout->setStretchFactor(it.current(), 0);
00504 it.current()->setFixedSize(titleHeight_, titleHeight_);
00505 }
00506
00507 topLayout->addItem(titleSpacer_);
00508
00509
00510
00511 for (QPtrListIterator<WebButton> it(rightButtonList_); it.current(); ++it)
00512 {
00513 topLayout->addWidget(it.current(), Qt::AlignVCenter);
00514 it.current()->setFixedSize(titleHeight_, titleHeight_);
00515 }
00516
00517
00518
00519 QHBoxLayout * midLayout = new QHBoxLayout(mainLayout_, 0, 0);
00520
00521 midLayout->addSpacing(sideMargin);
00522 if( isPreview())
00523 midLayout->addWidget(new QLabel( i18n( "<center><b>Web</b></center>" ), widget()));
00524 else
00525 midLayout->addItem( new QSpacerItem( 0, 0 ));
00526 midLayout->addSpacing(sideMargin);
00527
00528
00529
00530 mainLayout_->addSpacing(bottomMargin);
00531
00532
00533
00534
00535 mainLayout_->setStretchFactor(topLayout, 0);
00536 mainLayout_->setStretchFactor(midLayout, 1);
00537 }
00538
00539 void WebClient::borders(int& left, int& right, int& top, int& bottom) const
00540 {
00541 left = borderSize_;
00542 right = borderSize_;
00543 top = titleHeight_;
00544 bottom = borderSize_;
00545 }
00546
00547 void WebClient::resize( const QSize& s )
00548 {
00549 widget()->resize( s );
00550 }
00551
00552 QSize WebClient::minimumSize() const
00553 {
00554 return QSize( 200, 50 );
00555 }
00556
00557 const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
00558 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
00559 | NET::UtilityMask | NET::SplashMask;
00560
00561 bool WebClient::isTool()
00562 {
00563 NET::WindowType type = windowType( SUPPORTED_WINDOW_TYPES_MASK );
00564 return ((type==NET::Toolbar)||(type==NET::NET::Utility)||(type==NET::Menu));
00565 }
00566
00567 bool WebClient::eventFilter( QObject* o, QEvent* e )
00568 {
00569 if( o != widget())
00570 return false;
00571 switch( e->type())
00572 {
00573 case QEvent::Resize:
00574 resizeEvent(static_cast< QResizeEvent* >( e ) );
00575 return true;
00576 case QEvent::Paint:
00577 paintEvent(static_cast< QPaintEvent* >( e ) );
00578 return true;
00579 case QEvent::MouseButtonDblClick:
00580 mouseDoubleClickEvent(static_cast< QMouseEvent* >( e ) );
00581 return true;
00582 case QEvent::MouseButtonPress:
00583 processMousePressEvent(static_cast< QMouseEvent* >( e ) );
00584 return true;
00585 default:
00586 break;
00587 }
00588 return false;
00589 }
00590
00591
00592 KDecoration* WebFactory::createDecoration( KDecorationBridge* b )
00593 {
00594 return(new WebClient(b, this));
00595 }
00596
00597 bool WebFactory::reset(unsigned long changed)
00598 {
00599
00600 bool needHardReset = true;
00601 if (changed & SettingColors || changed & SettingFont)
00602 {
00603 needHardReset = false;
00604 }
00605
00606 if (needHardReset) {
00607 return true;
00608 } else {
00609 resetDecorations(changed);
00610 return false;
00611 }
00612 }
00613
00614 QValueList< WebFactory::BorderSize > WebFactory::borderSizes() const
00615 {
00616 return QValueList< BorderSize >() << BorderNormal << BorderLarge <<
00617 BorderVeryLarge << BorderHuge << BorderVeryHuge << BorderOversized;
00618 }
00619
00620 }
00621
00622 #include "Web.moc"
00623