Start to port kwin style
[kdeartwork.git] / kwin-styles / openlook / OpenLook.cpp
bloba854015b07fe3bcac85b7f85f813342203c15dc0
1 /*
2 'OpenLook' kwin client
4 Porting to kde3.2 API
5 Copyright 2003 Luciano Montanaro <mikelima@cirulla.net>
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to
9 deal in the Software without restriction, including without limitation the
10 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 sell copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 #include "config.h"
26 #include <unistd.h> // for usleep
27 #include <math.h>
29 #include <qlayout.h>
30 #include <qpainter.h>
31 #include <qdrawutil.h>
32 #include <qtoolbutton.h>
33 #include <qimage.h>
34 #include <qlabel.h>
35 #include <qpixmap.h>
36 //Added by qt3to4:
37 #include <QPaintEvent>
38 #include <Q3PointArray>
39 #include <QEvent>
40 #include <QBoxLayout>
41 #include <Q3ValueList>
42 #include <QShowEvent>
43 #include <QVBoxLayout>
44 #include <QResizeEvent>
45 #include <QMouseEvent>
47 #include <kapplication.h>
48 #include <klocale.h>
50 #include "OpenLook.h"
52 extern "C" KDE_EXPORT KDecorationFactory* create_factory()
54 return new OpenLook::DecorationFactory();
57 namespace OpenLook {
59 static uint openLookCornerSize = 11;
60 static uint openLookMargin = 5;
61 static const uint openLookTextVMargin = 1;
62 static uint titleHeight;
64 // ---------------------------------------
66 DecorationFactory::DecorationFactory()
70 DecorationFactory::~DecorationFactory()
74 KDecoration *DecorationFactory::createDecoration(KDecorationBridge *b)
76 return new OpenLook(b, this);
79 bool DecorationFactory::reset(unsigned long /*changed*/)
81 // TODO Do not recreate decorations if it is not needed. Look at
82 // ModernSystem for how to do that
83 // For now just return true.
84 return true;
87 bool DecorationFactory::supports( Ability ability )
89 switch( ability )
91 case AbilityAnnounceButtons:
92 case AbilityButtonMinimize:
93 return true;
94 default:
95 return false;
99 QList< DecorationFactory::BorderSize > DecorationFactory::borderSizes() const
101 // the list must be sorted
102 return QList< BorderSize >() << BorderNormal <<
103 BorderLarge << BorderVeryLarge << BorderHuge <<
104 BorderVeryHuge << BorderOversized;
107 // ---------------------------------------
109 static inline const KDecorationOptions* options()
111 return KDecoration::options();
114 // ---------------------------------------
116 OpenLook::OpenLook(KDecorationBridge *b, KDecorationFactory *f) :
117 KDecoration(b, f),
118 titleSpacer_ (0),
119 mousePressPoint_(0, 0), // Anywhere outside button rect.
120 buttonDown_ (false)
124 void OpenLook::init()
126 static const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask |
127 NET::DesktopMask | NET::DockMask | NET::ToolbarMask | NET::MenuMask |
128 NET::DialogMask | NET::OverrideMask | NET::TopMenuMask |
129 NET::UtilityMask | NET::SplashMask;
131 createMainWidget( Qt::WResizeNoErase);
132 widget()->setAttribute( Qt::WA_StaticContents);
133 widget()->setAttribute( Qt::WA_NoBackground );
134 widget()->installEventFilter(this);
135 widget()->setBackgroundMode(NoBackground);
136 NET::WindowType type = windowType(SUPPORTED_WINDOW_TYPES_MASK);
137 tool_ = (type == NET::Toolbar || type == NET::Utility || type == NET::Menu);
138 QFontMetrics fm(options()->font(isActive(), tool_));
140 titleHeight = fm.height() + openLookTextVMargin * 2;
142 switch(KDecoration::options()->preferredBorderSize(factory())) {
143 case KDecoration::BorderLarge:
144 openLookMargin = 9;
145 break;
146 case KDecoration::BorderVeryLarge:
147 openLookMargin = 13;
148 break;
149 case KDecoration::BorderHuge:
150 openLookMargin = 18;
151 break;
152 case KDecoration::BorderVeryHuge:
153 openLookMargin = 27;
154 break;
155 case KDecoration::BorderOversized:
156 openLookMargin = 40;
157 break;
158 case KDecoration::BorderNormal:
159 default:
160 openLookMargin = 5;
162 openLookCornerSize = 2*openLookMargin + 1;
163 if (titleHeight <= openLookMargin)
164 titleHeight = openLookMargin+1;
166 doLayout();
169 OpenLook::~OpenLook()
171 // Empty.
174 bool OpenLook::eventFilter(QObject *o, QEvent *e)
176 if (o != widget()) return false;
177 switch (e->type()) {
178 case QEvent::Resize:
179 resizeEvent(static_cast< QResizeEvent* >(e));
180 return true;
181 case QEvent::Paint:
182 paintEvent(static_cast< QPaintEvent* >(e));
183 return true;
184 case QEvent::MouseButtonDblClick:
185 mouseDoubleClickEvent(static_cast< QMouseEvent* >(e));
186 return true;
187 case QEvent::MouseButtonPress:
188 if (!isButtonPress(static_cast< QMouseEvent* >(e))) {
189 processMousePressEvent(static_cast< QMouseEvent* >(e));
191 return true;
192 case QEvent::MouseButtonRelease:
193 if (isButtonRelease(static_cast< QMouseEvent* >(e))) {
194 return true;
195 } else {
196 return false;
198 case QEvent::Show:
199 showEvent(static_cast< QShowEvent* >(e));
200 return true;
201 default:
202 break;
204 return false;
207 void
208 OpenLook::borders(int &left, int &right, int &top, int &bottom) const
210 // FRAME XXX Check
211 left = right = bottom = openLookMargin;
212 top = titleHeight + openLookMargin;
215 void
216 OpenLook::captionChange()
218 widget()->update(titleRect());
221 void
222 OpenLook::shadeChange()
226 QSize OpenLook::minimumSize() const
228 int left, right, top, bottom;
229 borders(left, right, top, bottom);
230 return QSize(left + right + 2 * titleHeight, top + bottom);
233 void
234 OpenLook::resize(const QSize& s)
236 widget()->resize(s);
237 widget()->repaint(); //there is some strange wrong repaint of the frame without
240 void
241 OpenLook::paintEvent(QPaintEvent * pe)
243 QRect tr(titleRect());
245 QPainter p(widget());
247 QRegion clipRegion(pe->region());
249 p.setClipRegion(clipRegion);
251 paintBorder(p);
253 paintTopLeftRect(p);
254 paintTopRightRect(p);
255 paintBottomLeftRect(p);
256 paintBottomRightRect(p);
258 p.setClipRegion(clipRegion + buttonRect());
260 QBrush titleBackground(options()->color(KDecoration::ColorTitleBar, true));
262 if (isActive())
263 qDrawShadePanel(&p, tr, widget()->colorGroup(), true, 1, &titleBackground);
264 else
265 p.fillRect(tr, widget()->colorGroup().brush(QColorGroup::Background));
267 p.setClipRegion(clipRegion);
269 paintButton(p);
271 p.setFont(options()->font(isActive(), tool_));
273 p.setPen(options()->color(KDecoration::ColorFont, isActive()));
275 tr.setLeft(openLookCornerSize + 3 + buttonRect().width() + 2);
277 p.drawText(tr, AlignCenter, caption());
280 void
281 OpenLook::showEvent(QShowEvent *)
283 widget()->repaint();
286 void
287 OpenLook::mouseDoubleClickEvent(QMouseEvent * e)
289 if (e->button() == Qt::LeftButton && titleRect().contains(e->pos()))
291 titlebarDblClickOperation();
295 void
296 OpenLook::resizeEvent(QResizeEvent* e)
298 widget()->update();
301 void
302 OpenLook::activeChange()
304 widget()->repaint();
307 KDecoration::Position
308 OpenLook::mousePosition(const QPoint & p) const
310 if (topLeftRect().contains(p))
311 return PositionTopLeft;
312 else if (topRightRect().contains(p))
313 return PositionTopRight;
314 else if (bottomLeftRect().contains(p))
315 return PositionBottomLeft;
316 else if (bottomRightRect().contains(p))
317 return PositionBottomRight;
318 else
319 return PositionCenter;
322 void
323 OpenLook::iconChange()
327 void
328 OpenLook::desktopChange()
332 void
333 OpenLook::maximizeChange()
335 widget()->repaint(false);
338 void
339 OpenLook::doLayout()
341 QVBoxLayout * layout = new QVBoxLayout(widget(), openLookMargin);
343 titleSpacer_ =
344 new QSpacerItem
347 titleHeight,
348 QSizePolicy::Expanding,
349 QSizePolicy::Fixed
352 layout->addItem(titleSpacer_);
354 layout->addSpacing(2);
356 QBoxLayout * midLayout =
357 new QBoxLayout(layout, QBoxLayout::LeftToRight, 0, 0);
359 if (isPreview()) {
360 midLayout->addWidget(new QLabel(
361 i18n("<center><b>OpenLook preview</b></center>"),
362 widget()),
364 } else {
365 midLayout->addItem( new QSpacerItem( 0, 0 ));
370 bool
371 OpenLook::animateMinimize(bool /*iconify*/)
373 #if 0
374 QRect icongeom(iconGeometry());
376 if (!icongeom.isValid())
377 return false;
379 QRect wingeom(geometry());
381 QPainter p(workspaceWidget());
383 p.setRasterOp(Qt::NotROP);
385 #if 0
386 if (iconify)
387 p.setClipRegion(
388 QRegion(workspace()->desktopWidget()->rect()) - wingeom
390 #endif
392 for (uint count = 0; count < 4; count++)
394 grabXServer();
396 p.drawLine(wingeom.bottomRight(), icongeom.bottomRight());
397 p.drawLine(wingeom.bottomLeft(), icongeom.bottomLeft());
398 p.drawLine(wingeom.topLeft(), icongeom.topLeft());
399 p.drawLine(wingeom.topRight(), icongeom.topRight());
401 p.flush();
403 kapp->syncX();
405 usleep(10000);
407 p.drawLine(wingeom.bottomRight(), icongeom.bottomRight());
408 p.drawLine(wingeom.bottomLeft(), icongeom.bottomLeft());
409 p.drawLine(wingeom.topLeft(), icongeom.topLeft());
410 p.drawLine(wingeom.topRight(), icongeom.topRight());
412 p.flush();
414 kapp->syncX();
416 usleep(10000);
418 ungrabXServer();
420 #endif
421 return true;
424 QRect
425 OpenLook::topLeftRect() const
427 return QRect
431 openLookCornerSize,
432 openLookCornerSize
436 QRect
437 OpenLook::topRightRect() const
439 return QRect
441 width() - openLookCornerSize,
443 openLookCornerSize,
444 openLookCornerSize
448 QRect
449 OpenLook::bottomLeftRect() const
451 return QRect
454 height() - openLookCornerSize,
455 openLookCornerSize,
456 openLookCornerSize
460 QRect
461 OpenLook::bottomRightRect() const
463 return QRect
465 width() - openLookCornerSize,
466 height() - openLookCornerSize,
467 openLookCornerSize,
468 openLookCornerSize
472 void
473 OpenLook::paintTopLeftRect(QPainter & p) const
475 QColor handleColour(options()->color(KDecoration::ColorHandle, isActive()));
477 QRect r(topLeftRect());
479 int x1(r.left());
480 int y1(r.top());
481 int x2(r.right());
482 int y2(r.bottom());
484 p.setPen(widget()->colorGroup().light());
486 p.drawLine(x1, y1, x2, y1);
487 p.drawLine(x1, y1 + 1, x1, y2);
489 p.fillRect(x1 + 1, y1 + 1, r.width()-2, openLookMargin-2, handleColour);
490 p.fillRect(x1 + 1, y1 + 1, openLookMargin-2, r.height()-2, handleColour);
492 p.setPen(widget()->colorGroup().dark());
494 p.drawLine(x2, y1 + 1, x2, y1 + openLookMargin-1);
496 p.drawLine(x1 + openLookMargin-1, y1 + openLookMargin-1, x2 - 1, y1 + openLookMargin-1);
498 p.drawLine(x1 + openLookMargin-1, y1 + openLookMargin, x1 + openLookMargin-1, y2 - 1);
500 p.drawLine(x1 + 1, y2, x1 + openLookMargin-1, y2);
503 void
504 OpenLook::paintTopRightRect(QPainter & p) const
506 QColor handleColour(options()->color(KDecoration::ColorHandle, isActive()));
508 QRect r(topRightRect());
510 int x1(r.left());
511 int y1(r.top());
512 int x2(r.right());
513 int y2(r.bottom());
515 p.setPen(widget()->colorGroup().light());
517 p.drawLine(x1, y1, x2, y1);
518 p.drawLine(x1, y1 + 1, x1, y1 + openLookMargin-1);
519 p.drawLine(x2 - openLookMargin+1, y1 + openLookMargin, x2 - openLookMargin+1, y2);
521 p.fillRect(x1 + 1, y1 + 1, r.width()-2, openLookMargin-2, handleColour);
522 p.fillRect(x2 - openLookMargin + 2, y1 + 1, openLookMargin-2, r.height()-2, handleColour);
524 p.setPen(widget()->colorGroup().dark());
526 p.drawLine(x1 + 1, y1 + openLookMargin-1, x2 - openLookMargin+1, y1 + openLookMargin-1);
527 p.drawLine(x2, y1 + 1, x2, y2);
528 p.drawLine(x2 - openLookMargin+1, y2, x2 - 1, y2);
531 void
532 OpenLook::paintBottomLeftRect(QPainter & p) const
534 QColor handleColour(options()->color(KDecoration::ColorHandle, isActive()));
536 QRect r(bottomLeftRect());
538 int x1(r.left());
539 int y1(r.top());
540 int x2(r.right());
541 int y2(r.bottom());
543 p.setPen(widget()->colorGroup().light());
545 p.drawLine(x1, y1, x1 + openLookMargin-1, y1);
546 p.drawLine(x1, y1 + 1, x1, y2);
547 p.drawLine(x1 + openLookMargin, y2 - openLookMargin+1, x2, y2 - openLookMargin+1);
549 p.fillRect(x1 + 1, y2 - openLookMargin + 2, r.width()-2, openLookMargin-2, handleColour);
550 p.fillRect(x1 + 1, y1 + 1, openLookMargin-2, r.height()-2, handleColour);
552 p.setPen(widget()->colorGroup().dark());
554 p.drawLine(x1 + openLookMargin-1, y1 + 1, x1 + openLookMargin-1, y2 - openLookMargin);
555 p.drawLine(x1 + 1, y2, x2, y2);
556 p.drawLine(x2, y2 - openLookMargin+2, x2, y2 - 1);
559 void
560 OpenLook::paintBottomRightRect(QPainter & p) const
562 QColor handleColour(options()->color(KDecoration::ColorHandle, isActive()));
564 QRect r(bottomRightRect());
566 int x1(r.left());
567 int y1(r.top());
568 int x2(r.right());
569 int y2(r.bottom());
571 p.setPen(widget()->colorGroup().light());
573 p.drawLine(x1, y2 - openLookMargin+1, x1, y2);
574 p.drawLine(x1 + 1, y2 - openLookMargin+1, x2 - openLookMargin+1, y2 - openLookMargin+1);
575 p.drawLine(x2 - openLookMargin+1, y1 + 1, x2 - openLookMargin+1, y2 - openLookMargin);
576 p.drawLine(x2 - openLookMargin+1, y1, x2, y1);
578 p.fillRect(x1 + 1, y2 - openLookMargin + 2, r.width()-2, openLookMargin-2, handleColour);
579 p.fillRect(x2 - openLookMargin + 2, y1 + 1, openLookMargin-2, r.height()-2, handleColour);
581 p.setPen(widget()->colorGroup().dark());
583 p.drawLine(x1 + 1, y2, x2, y2);
584 p.drawLine(x2, y1 + 1, x2, y2 - 1);
587 QRect
588 OpenLook::buttonRect() const
590 return QRect
592 openLookCornerSize + 3,
593 titleRect().top(),
594 titleRect().height(),
595 titleRect().height()
599 void
600 OpenLook::paintButton(QPainter & p) const
602 QRect r(buttonRect());
604 p.fillRect
606 r.left() + 1,
607 r.top() + 1,
608 r.width() - 2,
609 r.height() - 2,
610 buttonDown_
611 ? widget()->colorGroup().dark()
612 : options()->color(KDecoration::ColorButtonBg, isActive())
615 p.setPen(buttonDown_ ? widget()->colorGroup().dark() : widget()->colorGroup().light());
617 p.drawLine(r.left() + 1, r.top(), r.right() - 1, r.top());
618 p.drawLine(r.left(), r.top() + 1, r.left(), r.bottom() - 1);
620 p.setPen(buttonDown_ ? widget()->colorGroup().light() : widget()->colorGroup().dark());
622 p.drawLine(r.right(), r.top() + 1, r.right(), r.bottom() - 1);
623 p.drawLine(r.left() + 1, r.bottom(), r.right() - 1, r.bottom());
625 paintArrow(p);
628 void
629 OpenLook::paintArrow(QPainter & p) const
631 QRect br(buttonRect());
633 int x = br.left() + 5;
634 int y = br.top() + 5;
635 int w = br.width() - 10;
636 int h = br.height() - 10;
638 Q3PointArray poly(3);
640 p.setBrush(widget()->colorGroup().mid());
642 poly.setPoint(0, x, y);
643 poly.setPoint(1, x + w - 1, y);
644 poly.setPoint(2, x + (w / 2), y + h - 1);
646 p.drawPolygon(poly);
648 p.setPen(widget()->colorGroup().dark());
650 p.drawLine(x, y, x + w - 1, y);
652 p.drawLine(x, y, x + (w / 2), y + h - 1);
654 p.setPen(widget()->colorGroup().light());
656 p.drawLine(x + (w / 2), y + h - 1, x + w - 1, y);
659 void
660 OpenLook::paintBorder(QPainter & p) const
662 const uint cs(openLookCornerSize);
664 uint x = widget()->rect().left();
665 uint y = widget()->rect().top();
666 uint w = widget()->rect().width();
667 uint h = widget()->rect().height();
668 uint r = widget()->rect().right();
669 uint b = widget()->rect().bottom();
671 p.fillRect(x + cs, y, w - cs - cs, 2, widget()->colorGroup().shadow());
672 p.fillRect(x + cs, b - 1, w - cs - cs, 2, widget()->colorGroup().shadow());
673 p.fillRect(x, y + cs, 2, h - cs - cs, widget()->colorGroup().shadow());
674 p.fillRect(r - 1, y + cs, 2, h - cs - cs, widget()->colorGroup().shadow());
676 QColor frameColour(options()->color(KDecoration::ColorFrame, isActive()));
678 p.fillRect(x + cs, y + 2, w - cs - cs, openLookMargin-2, frameColour);
679 p.fillRect(x + cs, b - openLookMargin + 1, w - cs - cs, openLookMargin-2, frameColour);
680 p.fillRect(x + 2, y + cs, openLookMargin-2, h - cs - cs, frameColour);
681 p.fillRect(r - openLookMargin + 1, y + cs, openLookMargin-2, h - cs - cs, frameColour);
683 p.fillRect
685 openLookMargin,
686 titleRect().bottom() + 1,
687 width() - 2 * openLookMargin,
689 widget()->colorGroup().background()
693 QRect
694 OpenLook::titleRect() const
696 return titleSpacer_->geometry();
699 bool
700 OpenLook::isButtonPress(QMouseEvent * e)
702 mousePressPoint_ = e->pos();
704 buttonDown_ = buttonRect().contains(mousePressPoint_);
706 widget()->repaint(buttonRect());
707 return buttonDown_;
710 bool
711 OpenLook::isButtonRelease(QMouseEvent * e)
713 if (buttonDown_ && buttonRect().contains(e->pos()))
715 minimize();
716 return true;
718 buttonDown_ = false;
719 widget()->repaint(buttonRect());
721 return false;
726 #include "OpenLook.moc"
727 // vim:ts=2:sw=2:tw=78:set et: