1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <qapplication.h>
43 #include <qwidget.h>
44 #include <qpainter.h>
45 #include <qdrawutil.h>
46 #include "qdecorationwindows_qws.h"
47
48 QT_BEGIN_NAMESPACE
49
50 #if !defined(QT_NO_QWS_DECORATION_WINDOWS) || defined(QT_PLUGIN)
51
52 #ifndef QT_NO_IMAGEFORMAT_XPM
53
54 /* XPM */
55 static const char * const win_close_xpm[] = {
56 "16 16 4 1",
57 " s None c None",
58 ". c #000000",
59 "X c #FFFFFF",
60 "Y c #707070",
61 " ",
62 " ",
63 " ",
64 " Y. .Y ",
65 " .. .. ",
66 " .. .. ",
67 " .YY. ",
68 " Y..Y ",
69 " .YY. ",
70 " .. .. ",
71 " .. .. ",
72 " Y. .Y ",
73 " ",
74 " ",
75 " ",
76 " "};
77
78 static const char * const win_help_xpm[] = {
79 "16 16 3 1",
80 " s None c None",
81 ". c #ffffff",
82 "X c #000000",
83 " ",
84 " ",
85 " ",
86 " XXXXXX ",
87 " XX XX ",
88 " XX XX ",
89 " XX ",
90 " XX ",
91 " XX ",
92 " XX ",
93 " ",
94 " XX ",
95 " XX ",
96 " ",
97 " ",
98 " "};
99
100 static const char * const win_maximize_xpm[] = {
101 "16 16 4 1",
102 " s None c None",
103 ". c #000000",
104 "X c #FFFFFF",
105 "Y c #707070",
106 " ",
107 " ",
108 " ",
109 " .......... ",
110 " .......... ",
111 " . . ",
112 " . . ",
113 " . . ",
114 " . . ",
115 " . . ",
116 " . . ",
117 " .......... ",
118 " ",
119 " ",
120 " ",
121 " "};
122
123 static const char * const win_minimize_xpm[] = {
124 "16 16 4 1",
125 " s None c None",
126 ". c #000000",
127 "X c #FFFFFF",
128 "Y c #707070",
129 " ",
130 " ",
131 " ",
132 " ",
133 " ",
134 " ",
135 " ",
136 " ",
137 " ",
138 " ",
139 " ........ ",
140 " ........ ",
141 " ",
142 " ",
143 " ",
144 " "};
145
146 static const char * const win_normalize_xpm[] = {
147 "16 16 4 1",
148 " s None c None",
149 ". c #000000",
150 "X c #FFFFFF",
151 "Y c #707070",
152 " ",
153 " ",
154 " ......... ",
155 " ......... ",
156 " . . ",
157 " . . ",
158 " ......... . ",
159 " ......... . ",
160 " . . . ",
161 " . .... ",
162 " . . ",
163 " . . ",
164 " ......... ",
165 " ",
166 " ",
167 " "};
168
169 #endif // QT_NO_IMAGEFORMAT_XPM
170
171
QDecorationWindows()172 QDecorationWindows::QDecorationWindows()
173 : QDecorationDefault()
174 {
175 menu_width = 16;
176 help_width = 18;
177 minimize_width = 18;
178 maximize_width = 18;
179 close_width = 18;
180 }
181
~QDecorationWindows()182 QDecorationWindows::~QDecorationWindows()
183 {
184 }
185
xpmForRegion(int reg)186 const char **QDecorationWindows::xpmForRegion(int reg)
187 {
188 #ifdef QT_NO_IMAGEFORMAT_XPM
189 Q_UNUSED(reg);
190 #else
191 switch(reg)
192 {
193 case Close:
194 return (const char **)win_close_xpm;
195 case Help:
196 return (const char **)win_help_xpm;
197 case Minimize:
198 return (const char **)win_minimize_xpm;
199 case Maximize:
200 return (const char **)win_maximize_xpm;
201 case Normalize:
202 return (const char **)win_normalize_xpm;
203 default:
204 return QDecorationDefault::xpmForRegion(reg);
205 }
206 #endif
207 return 0;
208 }
209
region(const QWidget * widget,const QRect & rect,int type)210 QRegion QDecorationWindows::region(const QWidget *widget, const QRect &rect, int type)
211 {
212 Qt::WindowFlags flags = widget->windowFlags();
213 bool hasTitle = flags & Qt::WindowTitleHint;
214 bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
215 bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
216 bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
217 bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;
218 const QFontMetrics fontMetrics = QApplication::fontMetrics();
219 int titleHeight = hasTitle ? qMax(20, fontMetrics.height()) : 0;
220 int state = widget->windowState();
221 bool isMinimized = state & Qt::WindowMinimized;
222 bool isMaximized = state & Qt::WindowMaximized;
223
224 QRegion region;
225 switch (type) {
226 case Menu: {
227 if (hasSysMenu) {
228 region = QRect(rect.left() + 2, rect.top() - titleHeight,
229 menu_width, titleHeight);
230 }
231 }
232 break;
233
234 case Title: {
235 QRect r(rect.left()
236 + (hasSysMenu ? menu_width + 4: 0),
237 rect.top() - titleHeight,
238 rect.width()
239 - (hasSysMenu ? menu_width : 0)
240 - close_width
241 - (hasMaximize ? maximize_width : 0)
242 - (hasMinimize ? minimize_width : 0)
243 - (hasContextHelp ? help_width : 0)
244 - 3,
245 titleHeight);
246 if (r.width() > 0)
247 region = r;
248 }
249 break;
250 case Help: {
251 if (hasContextHelp) {
252 QRect r(rect.right()
253 - close_width
254 - (hasMaximize ? maximize_width : 0)
255 - (hasMinimize ? minimize_width : 0)
256 - help_width - 3, rect.top() - titleHeight,
257 help_width, titleHeight);
258 if (r.left() > rect.left() + titleHeight)
259 region = r;
260 }
261 }
262 break;
263
264 case Minimize: {
265 if (hasMinimize && !isMinimized) {
266 QRect r(rect.right() - close_width
267 - (hasMaximize ? maximize_width : 0)
268 - minimize_width - 3, rect.top() - titleHeight,
269 minimize_width, titleHeight);
270 if (r.left() > rect.left() + titleHeight)
271 region = r;
272 }
273 }
274 break;
275
276 case Maximize: {
277 if (hasMaximize && !isMaximized) {
278 QRect r(rect.right() - close_width - maximize_width - 3,
279 rect.top() - titleHeight, maximize_width, titleHeight);
280 if (r.left() > rect.left() + titleHeight)
281 region = r;
282 }
283 }
284 break;
285
286 case Normalize: {
287 if (hasMinimize && isMinimized) {
288 QRect r(rect.right() - close_width
289 - (hasMaximize ? maximize_width : 0)
290 - minimize_width - 3, rect.top() - titleHeight,
291 minimize_width, titleHeight);
292 if (r.left() > rect.left() + titleHeight)
293 region = r;
294 } else if (hasMaximize && isMaximized) {
295 QRect r(rect.right() - close_width - maximize_width - 3,
296 rect.top() - titleHeight, maximize_width, titleHeight);
297 if (r.left() > rect.left() + titleHeight)
298 region = r;
299 }
300 }
301 break;
302
303 case Close: {
304 QRect r(rect.right() - close_width - 1, rect.top() - titleHeight,
305 close_width, titleHeight);
306 if (r.left() > rect.left() + titleHeight)
307 region = r;
308 }
309 break;
310
311 default:
312 region = QDecorationDefault::region(widget, rect, type);
313 break;
314 }
315
316 return region;
317 }
318
paint(QPainter * painter,const QWidget * widget,int decorationRegion,DecorationState state)319 bool QDecorationWindows::paint(QPainter *painter, const QWidget *widget, int decorationRegion,
320 DecorationState state)
321 {
322 if (decorationRegion == None)
323 return false;
324
325 const QRect titleRect = QDecoration::region(widget, Title).boundingRect();
326 const QPalette pal = QApplication::palette();
327 QRegion oldClipRegion = painter->clipRegion();
328
329 bool paintAll = (decorationRegion == int(All));
330 if ((paintAll || decorationRegion & Title && titleRect.width() > 0) && state == Normal
331 && (widget->windowFlags() & Qt::WindowTitleHint) ) {
332 painter->setClipRegion(oldClipRegion);
333 QColor fromBrush, toBrush;
334 QPen titlePen;
335
336 if (widget == qApp->activeWindow() || qApp->activeWindow() == qApp->activePopupWidget()) {
337 fromBrush = pal.color(QPalette::Highlight);
338 titlePen = pal.color(QPalette::HighlightedText);
339 } else {
340 fromBrush = pal.color(QPalette::Window);
341 titlePen = pal.color(QPalette::Text);
342 }
343 toBrush = fromBrush.lighter(300);
344
345 painter->setPen(Qt::NoPen);
346 QPoint p1(titleRect.x(), titleRect.y() + titleRect.height()/2);
347 QPoint p2(titleRect.right(), titleRect.y() + titleRect.height()/2);
348 QLinearGradient lg(p1, p2);
349 lg.setColorAt(0, fromBrush);
350 lg.setColorAt(1, toBrush);
351 painter->fillRect(titleRect, lg);
352
353 painter->setPen(titlePen);
354 painter->drawText(titleRect, Qt::AlignVCenter, windowTitleFor(widget));
355 decorationRegion ^= Title;
356 }
357
358 return QDecorationDefault::paint(painter, widget, decorationRegion, state);
359 }
360
paintButton(QPainter * painter,const QWidget * widget,int buttonRegion,DecorationState state,const QPalette & pal)361 void QDecorationWindows::paintButton(QPainter *painter, const QWidget *widget, int buttonRegion,
362 DecorationState state, const QPalette &pal)
363 {
364 QBrush fromBrush, toBrush;
365 QPen titlePen;
366
367 if (widget == qApp->activeWindow() || qApp->activeWindow() == qApp->activePopupWidget()) {
368 fromBrush = pal.brush(QPalette::Highlight);
369 titlePen = pal.color(QPalette::HighlightedText);
370 } else {
371 fromBrush = pal.brush(QPalette::Window);
372 titlePen = pal.color(QPalette::Text);
373 }
374 toBrush = fromBrush.color().lighter(300);
375
376 QRect brect(QDecoration::region(widget, buttonRegion).boundingRect());
377 if (buttonRegion != Close && buttonRegion != Menu)
378 painter->fillRect(brect, toBrush);
379 else
380 painter->fillRect(brect.x() - 2, brect.y(), brect.width() + 4, brect.height(),
381 buttonRegion == Menu ? fromBrush : toBrush);
382
383 int xoff = 1;
384 int yoff = 2;
385 const QPixmap pm = pixmapFor(widget, buttonRegion, xoff, yoff);
386 if (buttonRegion != Menu) {
387 if (state & Normal) {
388 qDrawWinPanel(painter, brect.x(), brect.y() + 2, brect.width(),
389 brect.height() - 4, pal, false, &pal.brush(QPalette::Window));
390 } else if (state & Pressed) {
391 qDrawWinPanel(painter, brect.x(), brect.y() + 2, brect.width(),
392 brect.height() - 4, pal, true, &pal.brush(QPalette::Window));
393 ++xoff;
394 ++yoff;
395 }
396 } else {
397 xoff = 0;
398 yoff = 2;
399 }
400
401 if (!pm.isNull())
402 painter->drawPixmap(brect.x() + xoff, brect.y() + yoff, pm);
403 }
404
405 #endif // QT_NO_QWS_DECORATION_WINDOWS || QT_PLUGIN
406
407 QT_END_NAMESPACE
408