add more spacing
[personal-kdebase.git] / workspace / kwin / clients / ozone / oxygenbutton.cpp
blobc0ccbfa1a7f5ab577907d4238049fbf80230dab2
1 //////////////////////////////////////////////////////////////////////////////
2 // oxygenbutton.cpp
3 // -------------------
4 // Ozone window decoration for KDE. Buttons.
5 // -------------------
6 // Copyright (c) 2006, 2007 Riccardo Iaconelli <riccardo@kde.org>
7 // Copyright (c) 2006, 2007 Casper Boemann <cbr@boemann.dk>
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to
11 // deal in the Software without restriction, including without limitation the
12 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
13 // sell copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 // IN THE SOFTWARE.
26 //////////////////////////////////////////////////////////////////////////////
28 #include "oxygenbutton.h"
29 #include <kcommondecoration.h>
31 #include <math.h>
32 #include <QPainterPath>
33 #include <QPainter>
34 #include <QPen>
35 #include <QBitmap>
37 #include <kdecoration.h>
38 #include <kglobal.h>
39 #include <KColorUtils>
40 #include <kdebug.h>
41 #include <KColorScheme>
43 #include "oxygenclient.h"
44 #include "oxygen.h"
46 namespace Ozone
48 namespace Oxygen
50 // class OxygenClient;
52 extern int BUTTONSIZE;
53 extern int DECOSIZE;*/
55 // static const int DECOSIZE = 8;
56 //////////////////////////////////////////////////////////////////////////////
57 // OxygenButton Class //
58 //////////////////////////////////////////////////////////////////////////////
60 //////////////////////////////////////////////////////////////////////////////
61 // OxygenButton()
62 // ---------------
63 // Constructor
65 OxygenButton::OxygenButton(OxygenClient &parent,
66 const QString& tip, ButtonType type)
67 : KCommonDecorationButton((::ButtonType)type, &parent)
68 , client_(parent)
69 , helper_(parent.helper_)
70 , type_(type)
71 , lastmouse_(0)
72 , colorCacheInvalid_(true)
74 setAutoFillBackground(false);
75 setAttribute(Qt::WA_OpaquePaintEvent, false);
76 setFixedSize(OXYGEN_BUTTONSIZE, OXYGEN_BUTTONSIZE);
77 setCursor(Qt::ArrowCursor);
78 setToolTip(tip);
81 OxygenButton::~OxygenButton()
85 //declare function from oxygenclient.cpp
86 QColor reduceContrast(const QColor &c0, const QColor &c1, double t);
89 QColor OxygenButton::buttonDetailColor(const QPalette &palette)
91 if (client_.isActive())
92 return palette.color(QPalette::Active, QPalette::ButtonText);
93 else {
94 if (colorCacheInvalid_) {
95 QColor ab = palette.color(QPalette::Active, QPalette::Button);
96 QColor af = palette.color(QPalette::Active, QPalette::ButtonText);
97 QColor nb = palette.color(QPalette::Inactive, QPalette::Button);
98 QColor nf = palette.color(QPalette::Inactive, QPalette::ButtonText);
100 colorCacheInvalid_ = false;
101 cachedButtonDetailColor_ = reduceContrast(nb, nf, qMax(qreal(2.5), KColorUtils::contrastRatio(ab, KColorUtils::mix(ab, af, 0.4))));
103 return cachedButtonDetailColor_;
107 //////////////////////////////////////////////////////////////////////////////
108 // sizeHint()
109 // ----------
110 // Return size hint
112 QSize OxygenButton::sizeHint() const
114 return QSize(OXYGEN_BUTTONSIZE, OXYGEN_BUTTONSIZE);
117 //////////////////////////////////////////////////////////////////////////////
118 // enterEvent()
119 // ------------
120 // Mouse has entered the button
122 void OxygenButton::enterEvent(QEvent *e)
124 KCommonDecorationButton::enterEvent(e);
125 if (status_ != Oxygen::Pressed) {
126 status_ = Oxygen::Hovered;
128 update();
131 //////////////////////////////////////////////////////////////////////////////
132 // leaveEvent()
133 // ------------
134 // Mouse has left the button
136 void OxygenButton::leaveEvent(QEvent *e)
138 KCommonDecorationButton::leaveEvent(e);
139 // if we wanted to do mouseovers, we would keep track of it here
140 status_ = Oxygen::Normal;
141 update();
144 //////////////////////////////////////////////////////////////////////////////
145 // mousePressEvent()
146 // ------------
147 // Mouse has pressed the button
149 void OxygenButton::mousePressEvent(QMouseEvent *e)
151 status_ = Oxygen::Pressed;
152 update();
154 KCommonDecorationButton::mousePressEvent(e);
157 //////////////////////////////////////////////////////////////////////////////
158 // mouseReleaseEvent()
159 // ------------
160 // Mouse has released the button
162 void OxygenButton::mouseReleaseEvent(QMouseEvent *e)
164 status_ = Oxygen::Normal;
165 update();
167 KCommonDecorationButton::mouseReleaseEvent(e);
170 //////////////////////////////////////////////////////////////////////////////
171 // drawButton()
172 // ------------
173 // Draw the button
175 void OxygenButton::paintEvent(QPaintEvent *)
177 QPainter painter(this);
178 QPalette pal = palette(); // de-const-ify
180 // Set palette to the right group.
181 // TODO - fix KWin to do this for us :-).
182 if (client_.isActive())
183 pal.setCurrentColorGroup(QPalette::Active);
184 else
185 pal.setCurrentColorGroup(QPalette::Inactive);
187 QPalette pal2( pal );
188 if( !OxygenFactory::blendTitlebarColors()) {
189 pal2.setColor( window()->backgroundRole(), client_.options()->color(
190 KDecorationDefines::ColorTitleBar, client_.isActive()));
192 // fill the grey square
193 helper_.renderWindowBackground(&painter, this->rect(), this, pal2, 0);
194 painter.setClipRect(this->rect());
196 // draw dividing line
197 painter.setRenderHints(QPainter::Antialiasing);
198 QRect frame = client_.widget()->rect();
199 int x = -this->geometry().x()+1;
200 int w = frame.width()-2;
202 const int titleHeight = client_.layoutMetric(KCommonDecoration::LM_TitleHeight);
204 QColor color = OxygenFactory::blendTitlebarColors()?pal.window().color()
205 :client_.options()->color( KDecorationDefines::ColorTitleBar, client_.isActive());
206 QColor light = helper_.calcLightColor( color );
207 QColor dark = helper_.calcDarkColor( color );
209 dark.setAlpha(120);
211 if(client_.isActive()) {
212 helper_.drawSeparator(&painter, QRect(x, titleHeight-1.5, w, 2), color, Qt::Horizontal);
215 if (type_ == ButtonMenu) {
216 // we paint the mini icon (which is 16 pixels high)
217 int dx = (width() - 16) / 2;
218 int dy = (height() - 16) / 2;
219 painter.drawPixmap(dx, dy, client_.icon().pixmap(16));
220 return;
224 if(client_.maximizeMode() == OxygenClient::MaximizeRestore)
225 painter.translate(0,-1);
227 QColor bg = helper_.backgroundTopColor(OxygenFactory::blendTitlebarColors()?pal.window().color()
228 :client_.options()->color(KDecorationDefines::ColorTitleBar,client_.isActive()));
230 color = buttonDetailColor(pal);
231 if(status_ == Oxygen::Hovered || status_ == Oxygen::Pressed) {
232 if(type_ == ButtonClose)
233 color = KColorScheme(pal.currentColorGroup()).foreground(KColorScheme::NegativeText).color();
234 else
235 color = KColorScheme(pal.currentColorGroup()).decoration(KColorScheme::HoverColor).color();
238 QLinearGradient lg = helper_.decoGradient(QRect(4,4,13,13), color);
239 QColor bt = OxygenFactory::blendTitlebarColors()?pal.window().color()
240 :client_.options()->color(KDecorationDefines::ColorButtonBg,client_.isActive());
241 painter.drawPixmap(0, 0, helper_.windecoButton(bt, status_ == Oxygen::Pressed));
243 if (client_.isActive()) {
244 painter.setRenderHints(QPainter::Antialiasing);
245 painter.setBrush(Qt::NoBrush);
246 painter.setPen(QPen(lg, 2.2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
247 drawIcon(&painter, pal, type_);
249 else {
250 // outlined mode
251 QPixmap pixmap(size());
252 pixmap.fill(Qt::transparent);
253 QPainter pp(&pixmap);
254 pp.setRenderHints(QPainter::Antialiasing);
255 pp.setBrush(Qt::NoBrush);
256 pp.setPen(QPen(color, 3.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
257 drawIcon(&pp, pal, type_);
259 pp.setCompositionMode(QPainter::CompositionMode_DestinationOut);
260 pp.setPen(QPen(color, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
261 drawIcon(&pp, pal, type_);
263 painter.drawPixmap(QPoint(0,0), pixmap);
267 void OxygenButton::drawIcon(QPainter *p, QPalette &pal, ButtonType &type)
269 switch(type)
271 case ButtonSticky:
272 if(isChecked()) {
273 QPen newPen = p->pen();
274 newPen.setColor(KColorScheme(pal.currentColorGroup()).decoration(KColorScheme::HoverColor).color());
275 p->setPen(newPen);
277 p->drawPoint(QPointF(10.5,10.5));
278 break;
279 case ButtonHelp:
280 p->translate(1.5, 1.5);
281 p->drawArc(7,5,4,4,135*16, -180*16);
282 p->drawArc(9,8,4,4,135*16,45*16);
283 p->drawPoint(9,12);
284 p->translate(-1.5, -1.5);
285 break;
286 case ButtonMin:
287 p->drawLine(QPointF( 7.5, 9.5), QPointF(10.5,12.5));
288 p->drawLine(QPointF(10.5,12.5), QPointF(13.5, 9.5));
289 break;
290 case ButtonMax:
291 switch(client_.maximizeMode())
293 case OxygenClient::MaximizeRestore:
294 case OxygenClient::MaximizeVertical:
295 case OxygenClient::MaximizeHorizontal:
296 p->drawLine(QPointF( 7.5,11.5), QPointF(10.5, 8.5));
297 p->drawLine(QPointF(10.5, 8.5), QPointF(13.5,11.5));
298 break;
299 case OxygenClient::MaximizeFull:
301 p->translate(1.5, 1.5);
302 //p->setBrush(lg);
303 QPoint points[4] = {QPoint(9, 6), QPoint(12, 9), QPoint(9, 12), QPoint(6, 9)};
304 //QPoint points[4] = {QPoint(9, 5), QPoint(13, 9), QPoint(9, 13), QPoint(5, 9)};
305 p->drawPolygon(points, 4);
306 p->translate(-1.5, -1.5);
307 break;
310 break;
311 case ButtonClose:
312 p->drawLine(QPointF( 7.5,7.5), QPointF(13.5,13.5));
313 p->drawLine(QPointF(13.5,7.5), QPointF( 7.5,13.5));
314 break;
315 case ButtonAbove:
316 if(isChecked()) {
317 QPen newPen = p->pen();
318 newPen.setColor(KColorScheme(pal.currentColorGroup()).decoration(KColorScheme::HoverColor).color());
319 p->setPen(newPen);
322 p->drawLine(QPointF( 7.5,14), QPointF(10.5,11));
323 p->drawLine(QPointF(10.5,11), QPointF(13.5,14));
324 p->drawLine(QPointF( 7.5,10), QPointF(10.5, 7));
325 p->drawLine(QPointF(10.5, 7), QPointF(13.5,10));
326 break;
327 case ButtonBelow:
328 if(isChecked()) {
329 QPen newPen = p->pen();
330 newPen.setColor(KColorScheme(pal.currentColorGroup()).decoration(KColorScheme::HoverColor).color());
331 p->setPen(newPen);
334 p->drawLine(QPointF( 7.5,11), QPointF(10.5,14));
335 p->drawLine(QPointF(10.5,14), QPointF(13.5,11));
336 p->drawLine(QPointF( 7.5, 7), QPointF(10.5,10));
337 p->drawLine(QPointF(10.5,10), QPointF(13.5, 7));
338 break;
339 case ButtonShade:
340 if (!isChecked()) // shade button
342 p->drawLine(QPointF( 7.5, 7.5), QPointF(10.5,10.5));
343 p->drawLine(QPointF(10.5,10.5), QPointF(13.5, 7.5));
344 p->drawLine(QPointF( 7.5,13.0), QPointF(13.5,13.0));
345 } else { // unshade button
346 p->drawLine(QPointF( 7.5,10.5), QPointF(10.5, 7.5));
347 p->drawLine(QPointF(10.5, 7.5), QPointF(13.5,10.5));
348 p->drawLine(QPointF( 7.5,13.0), QPointF(13.5,13.0));
350 break;
351 default:
352 break;
363 } //namespace Oxygen
364 } //namespace Ozone