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.
26 #include <unistd.h> // for usleep
31 #include <qdrawutil.h>
32 #include <qtoolbutton.h>
37 #include <QPaintEvent>
38 #include <Q3PointArray>
41 #include <Q3ValueList>
43 #include <QVBoxLayout>
44 #include <QResizeEvent>
45 #include <QMouseEvent>
47 #include <kapplication.h>
52 extern "C" KDE_EXPORT KDecorationFactory
* create_factory()
54 return new OpenLook::DecorationFactory();
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.
87 bool DecorationFactory::supports( Ability ability
)
91 case AbilityAnnounceButtons
:
92 case AbilityButtonMinimize
:
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
) :
119 mousePressPoint_(0, 0), // Anywhere outside button rect.
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
:
146 case KDecoration::BorderVeryLarge
:
149 case KDecoration::BorderHuge
:
152 case KDecoration::BorderVeryHuge
:
155 case KDecoration::BorderOversized
:
158 case KDecoration::BorderNormal
:
162 openLookCornerSize
= 2*openLookMargin
+ 1;
163 if (titleHeight
<= openLookMargin
)
164 titleHeight
= openLookMargin
+1;
169 OpenLook::~OpenLook()
174 bool OpenLook::eventFilter(QObject
*o
, QEvent
*e
)
176 if (o
!= widget()) return false;
179 resizeEvent(static_cast< QResizeEvent
* >(e
));
182 paintEvent(static_cast< QPaintEvent
* >(e
));
184 case QEvent::MouseButtonDblClick
:
185 mouseDoubleClickEvent(static_cast< QMouseEvent
* >(e
));
187 case QEvent::MouseButtonPress
:
188 if (!isButtonPress(static_cast< QMouseEvent
* >(e
))) {
189 processMousePressEvent(static_cast< QMouseEvent
* >(e
));
192 case QEvent::MouseButtonRelease
:
193 if (isButtonRelease(static_cast< QMouseEvent
* >(e
))) {
199 showEvent(static_cast< QShowEvent
* >(e
));
208 OpenLook::borders(int &left
, int &right
, int &top
, int &bottom
) const
211 left
= right
= bottom
= openLookMargin
;
212 top
= titleHeight
+ openLookMargin
;
216 OpenLook::captionChange()
218 widget()->update(titleRect());
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
);
234 OpenLook::resize(const QSize
& s
)
237 widget()->repaint(); //there is some strange wrong repaint of the frame without
241 OpenLook::paintEvent(QPaintEvent
* pe
)
243 QRect
tr(titleRect());
245 QPainter
p(widget());
247 QRegion
clipRegion(pe
->region());
249 p
.setClipRegion(clipRegion
);
254 paintTopRightRect(p
);
255 paintBottomLeftRect(p
);
256 paintBottomRightRect(p
);
258 p
.setClipRegion(clipRegion
+ buttonRect());
260 QBrush
titleBackground(options()->color(KDecoration::ColorTitleBar
, true));
263 qDrawShadePanel(&p
, tr
, widget()->colorGroup(), true, 1, &titleBackground
);
265 p
.fillRect(tr
, widget()->colorGroup().brush(QColorGroup::Background
));
267 p
.setClipRegion(clipRegion
);
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());
281 OpenLook::showEvent(QShowEvent
*)
287 OpenLook::mouseDoubleClickEvent(QMouseEvent
* e
)
289 if (e
->button() == Qt::LeftButton
&& titleRect().contains(e
->pos()))
291 titlebarDblClickOperation();
296 OpenLook::resizeEvent(QResizeEvent
* e
)
302 OpenLook::activeChange()
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
;
319 return PositionCenter
;
323 OpenLook::iconChange()
328 OpenLook::desktopChange()
333 OpenLook::maximizeChange()
335 widget()->repaint(false);
341 QVBoxLayout
* layout
= new QVBoxLayout(widget(), openLookMargin
);
348 QSizePolicy::Expanding
,
352 layout
->addItem(titleSpacer_
);
354 layout
->addSpacing(2);
356 QBoxLayout
* midLayout
=
357 new QBoxLayout(layout
, QBoxLayout::LeftToRight
, 0, 0);
360 midLayout
->addWidget(new QLabel(
361 i18n("<center><b>OpenLook preview</b></center>"),
365 midLayout
->addItem( new QSpacerItem( 0, 0 ));
371 OpenLook::animateMinimize(bool /*iconify*/)
374 QRect
icongeom(iconGeometry());
376 if (!icongeom
.isValid())
379 QRect
wingeom(geometry());
381 QPainter
p(workspaceWidget());
383 p
.setRasterOp(Qt::NotROP
);
388 QRegion(workspace()->desktopWidget()->rect()) - wingeom
392 for (uint count
= 0; count
< 4; count
++)
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());
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());
425 OpenLook::topLeftRect() const
437 OpenLook::topRightRect() const
441 width() - openLookCornerSize
,
449 OpenLook::bottomLeftRect() const
454 height() - openLookCornerSize
,
461 OpenLook::bottomRightRect() const
465 width() - openLookCornerSize
,
466 height() - openLookCornerSize
,
473 OpenLook::paintTopLeftRect(QPainter
& p
) const
475 QColor
handleColour(options()->color(KDecoration::ColorHandle
, isActive()));
477 QRect
r(topLeftRect());
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
);
504 OpenLook::paintTopRightRect(QPainter
& p
) const
506 QColor
handleColour(options()->color(KDecoration::ColorHandle
, isActive()));
508 QRect
r(topRightRect());
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
);
532 OpenLook::paintBottomLeftRect(QPainter
& p
) const
534 QColor
handleColour(options()->color(KDecoration::ColorHandle
, isActive()));
536 QRect
r(bottomLeftRect());
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);
560 OpenLook::paintBottomRightRect(QPainter
& p
) const
562 QColor
handleColour(options()->color(KDecoration::ColorHandle
, isActive()));
564 QRect
r(bottomRightRect());
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);
588 OpenLook::buttonRect() const
592 openLookCornerSize
+ 3,
594 titleRect().height(),
600 OpenLook::paintButton(QPainter
& p
) const
602 QRect
r(buttonRect());
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());
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);
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
);
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
);
686 titleRect().bottom() + 1,
687 width() - 2 * openLookMargin
,
689 widget()->colorGroup().background()
694 OpenLook::titleRect() const
696 return titleSpacer_
->geometry();
700 OpenLook::isButtonPress(QMouseEvent
* e
)
702 mousePressPoint_
= e
->pos();
704 buttonDown_
= buttonRect().contains(mousePressPoint_
);
706 widget()->repaint(buttonRect());
711 OpenLook::isButtonRelease(QMouseEvent
* e
)
713 if (buttonDown_
&& buttonRect().contains(e
->pos()))
719 widget()->repaint(buttonRect());
726 #include "OpenLook.moc"
727 // vim:ts=2:sw=2:tw=78:set et: