1 /*
2 * LmmsStyle.cpp - the graphical style used by LMMS to create a consistent
3 * interface
4 *
5 * Copyright (c) 2007-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
6 *
7 * This file is part of LMMS - https://lmms.io
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program (see COPYING); if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301 USA.
23 *
24 */
25
26
27 #include <QFile>
28 #include <QApplication>
29 #include <QFrame>
30 #include <QPainter>
31 #include <QPainterPath>
32 #include <QStyleFactory>
33 #include <QStyleOption>
34
35 #include "LmmsStyle.h"
36
37 QPalette * LmmsStyle::s_palette = NULL;
38
getGradient(const QColor & _col,const QRectF & _rect)39 QLinearGradient getGradient( const QColor & _col, const QRectF & _rect )
40 {
41 QLinearGradient g( _rect.topLeft(), _rect.bottomLeft() );
42
43 qreal hue = _col.hueF();
44 qreal value = _col.valueF();
45 qreal saturation = _col.saturationF();
46
47 QColor c = _col;
48 c.setHsvF( hue, 0.42 * saturation, 0.98 * value ); // TODO: pattern: 1.08
49 g.setColorAt( 0, c );
50 c.setHsvF( hue, 0.58 * saturation, 0.95 * value ); // TODO: pattern: 1.05
51 g.setColorAt( 0.25, c );
52 c.setHsvF( hue, 0.70 * saturation, 0.93 * value ); // TODO: pattern: 1.03
53 g.setColorAt( 0.5, c );
54
55 c.setHsvF( hue, 0.95 * saturation, 0.9 * value );
56 g.setColorAt( 0.501, c );
57 c.setHsvF( hue * 0.95, 0.95 * saturation, 0.95 * value );
58 g.setColorAt( 0.75, c );
59 c.setHsvF( hue * 0.90, 0.95 * saturation, 1 * value );
60 g.setColorAt( 1.0, c );
61
62 return g;
63 }
64
65
66
darken(const QLinearGradient & _gradient)67 QLinearGradient darken( const QLinearGradient & _gradient )
68 {
69 QGradientStops stops = _gradient.stops();
70 for (int i = 0; i < stops.size(); ++i) {
71 QColor color = stops.at(i).second;
72 stops[i].second = color.lighter(133);
73 }
74
75 QLinearGradient g = _gradient;
76 g.setStops(stops);
77 return g;
78 }
79
80
81
drawPath(QPainter * p,const QPainterPath & path,const QColor & col,const QColor & borderCol,bool dark=false)82 void drawPath( QPainter *p, const QPainterPath &path,
83 const QColor &col, const QColor &borderCol,
84 bool dark = false )
85 {
86 const QRectF pathRect = path.boundingRect();
87
88 const QLinearGradient baseGradient = getGradient(col, pathRect);
89 const QLinearGradient darkGradient = darken(baseGradient);
90
91 p->setOpacity(0.25);
92
93 // glow
94 if (dark)
95 p->strokePath(path, QPen(darkGradient, 4));
96 else
97 p->strokePath(path, QPen(baseGradient, 4));
98
99 p->setOpacity(1.0);
100
101 // fill
102 if (dark)
103 p->fillPath(path, darkGradient);
104 else
105 p->fillPath(path, baseGradient);
106
107 // TODO: Remove??
108 /*
109 QLinearGradient g(pathRect.topLeft(), pathRect.topRight());
110 g.setCoordinateMode(QGradient::ObjectBoundingMode);
111
112 p->setOpacity(0.2);
113 p->fillPath(path, g);*/
114 // END: Remove??
115
116 p->setOpacity(0.5);
117
118 // highlight (bb)
119 if (dark)
120 p->strokePath(path, QPen(borderCol.lighter(133), 2));
121 else
122 p->strokePath(path, QPen(borderCol, 2));
123 }
124
125
126
LmmsStyle()127 LmmsStyle::LmmsStyle() :
128 QProxyStyle()
129 {
130 QFile file( "resources:style.css" );
131 file.open( QIODevice::ReadOnly );
132 qApp->setStyleSheet( file.readAll() );
133
134 if( s_palette != NULL ) { qApp->setPalette( *s_palette ); }
135
136 #if QT_VERSION >= 0x050000
137 setBaseStyle( QStyleFactory::create( "Fusion" ) );
138 #else
139 setBaseStyle( QStyleFactory::create( "Plastique" ) );
140 #endif
141 }
142
143
144
145
standardPalette(void) const146 QPalette LmmsStyle::standardPalette( void ) const
147 {
148 if( s_palette != NULL) { return * s_palette; }
149
150 QPalette pal = QProxyStyle::standardPalette();
151
152 return( pal );
153 }
154
155
drawComplexControl(ComplexControl control,const QStyleOptionComplex * option,QPainter * painter,const QWidget * widget) const156 void LmmsStyle::drawComplexControl( ComplexControl control,
157 const QStyleOptionComplex * option,
158 QPainter *painter,
159 const QWidget *widget ) const
160 {
161 // fix broken titlebar styling on win32
162 if( control == CC_TitleBar )
163 {
164 const QStyleOptionTitleBar * titleBar =
165 qstyleoption_cast<const QStyleOptionTitleBar *>(option );
166 if( titleBar )
167 {
168 QStyleOptionTitleBar so( *titleBar );
169 so.palette = standardPalette();
170 so.palette.setColor( QPalette::HighlightedText,
171 ( titleBar->titleBarState & State_Active ) ?
172 QColor( 255, 255, 255 ) :
173 QColor( 192, 192, 192 ) );
174 so.palette.setColor( QPalette::Text,
175 QColor( 64, 64, 64 ) );
176 QProxyStyle::drawComplexControl( control, &so,
177 painter, widget );
178 return;
179 }
180 }
181 else if (control == CC_MdiControls)
182 {
183 QStyleOptionComplex so(*option);
184 so.palette.setColor(QPalette::Button, QColor(223, 228, 236));
185 QProxyStyle::drawComplexControl(control, &so, painter, widget);
186 return;
187 }
188 /* else if( control == CC_ScrollBar )
189 {
190 painter->fillRect( option->rect, QApplication::palette().color( QPalette::Active,
191 QPalette::Background ) );
192
193 }*/
194 QProxyStyle::drawComplexControl( control, option, painter, widget );
195 }
196
197
198
199
drawPrimitive(PrimitiveElement element,const QStyleOption * option,QPainter * painter,const QWidget * widget) const200 void LmmsStyle::drawPrimitive( PrimitiveElement element,
201 const QStyleOption *option, QPainter *painter,
202 const QWidget *widget) const
203 {
204 if( element == QStyle::PE_Frame ||
205 element == QStyle::PE_FrameLineEdit ||
206 element == QStyle::PE_PanelLineEdit )
207 {
208 const QRect rect = option->rect;
209
210 QColor black = QColor( 0, 0, 0 );
211 QColor shadow = option->palette.shadow().color();
212 QColor highlight = option->palette.highlight().color();
213
214 int a100 = 165;
215 int a75 = static_cast<int>( a100 * .75 );
216 int a50 = static_cast<int>( a100 * .6 );
217 int a25 = static_cast<int>( a100 * .33 );
218
219 QLine lines[4];
220 QPoint points[4];
221
222 // black inside lines
223 // 50%
224 black.setAlpha(a100);
225 painter->setPen(QPen(black, 0));
226 lines[0] = QLine(rect.left() + 2, rect.top() + 1,
227 rect.right() - 2, rect.top() + 1);
228 lines[1] = QLine(rect.left() + 2, rect.bottom() - 1,
229 rect.right() - 2, rect.bottom() - 1);
230 lines[2] = QLine(rect.left() + 1, rect.top() + 2,
231 rect.left() + 1, rect.bottom() - 2);
232 lines[3] = QLine(rect.right() - 1, rect.top() + 2,
233 rect.right() - 1, rect.bottom() - 2);
234 painter->drawLines(lines, 4);
235
236 // black inside dots
237 black.setAlpha(a50);
238 painter->setPen(QPen(black, 0));
239 points[0] = QPoint(rect.left() + 2, rect.top() + 2);
240 points[1] = QPoint(rect.left() + 2, rect.bottom() - 2);
241 points[2] = QPoint(rect.right() - 2, rect.top() + 2);
242 points[3] = QPoint(rect.right() - 2, rect.bottom() - 2);
243 painter->drawPoints(points, 4);
244
245
246 // outside lines - shadow
247 // 100%
248 shadow.setAlpha(a75);
249 painter->setPen(QPen(shadow, 0));
250 lines[0] = QLine(rect.left() + 2, rect.top(),
251 rect.right() - 2, rect.top());
252 lines[1] = QLine(rect.left(), rect.top() + 2,
253 rect.left(), rect.bottom() - 2);
254 painter->drawLines(lines, 2);
255
256 // outside corner dots - shadow
257 // 75%
258 shadow.setAlpha(a50);
259 painter->setPen(QPen(shadow, 0));
260 points[0] = QPoint(rect.left() + 1, rect.top() + 1);
261 points[1] = QPoint(rect.right() - 1, rect.top() + 1);
262 painter->drawPoints(points, 2);
263
264 // outside end dots - shadow
265 // 50%
266 shadow.setAlpha(a25);
267 painter->setPen(QPen(shadow, 0));
268 points[0] = QPoint(rect.left() + 1, rect.top());
269 points[1] = QPoint(rect.left(), rect.top() + 1);
270 points[2] = QPoint(rect.right() - 1, rect.top());
271 points[3] = QPoint(rect.left(), rect.bottom() - 1);
272 painter->drawPoints(points, 4);
273
274
275 // outside lines - highlight
276 // 100%
277 highlight.setAlpha(a75);
278 painter->setPen(QPen(highlight, 0));
279 lines[0] = QLine(rect.left() + 2, rect.bottom(),
280 rect.right() - 2, rect.bottom());
281 lines[1] = QLine(rect.right(), rect.top() + 2,
282 rect.right(), rect.bottom() - 2);
283 painter->drawLines(lines, 2);
284
285 // outside corner dots - highlight
286 // 75%
287 highlight.setAlpha(a50);
288 painter->setPen(QPen(highlight, 0));
289 points[0] = QPoint(rect.left() + 1, rect.bottom() - 1);
290 points[1] = QPoint(rect.right() - 1, rect.bottom() - 1);
291 painter->drawPoints(points, 2);
292
293 // outside end dots - highlight
294 // 50%
295 highlight.setAlpha(a25);
296 painter->setPen(QPen(highlight, 0));
297 points[0] = QPoint(rect.right() - 1, rect.bottom());
298 points[1] = QPoint(rect.right(), rect.bottom() - 1);
299 points[2] = QPoint(rect.left() + 1, rect.bottom());
300 points[3] = QPoint(rect.right(), rect.top() + 1);
301 painter->drawPoints(points, 4);
302 }
303 else
304 {
305 QProxyStyle::drawPrimitive( element, option, painter, widget );
306 }
307
308 }
309
310
pixelMetric(PixelMetric _metric,const QStyleOption * _option,const QWidget * _widget) const311 int LmmsStyle::pixelMetric( PixelMetric _metric, const QStyleOption * _option,
312 const QWidget * _widget ) const
313 {
314 switch( _metric )
315 {
316 case QStyle::PM_ButtonMargin:
317 return 3;
318
319 case QStyle::PM_ButtonIconSize:
320 return 20;
321
322 case QStyle::PM_ToolBarItemMargin:
323 return 1;
324
325 case QStyle::PM_ToolBarItemSpacing:
326 return 2;
327
328 case QStyle::PM_TitleBarHeight:
329 return 24;
330
331 default:
332 return QProxyStyle::pixelMetric( _metric, _option, _widget );
333 }
334 }
335
336
colorizeXpm(const char * const * xpm,const QBrush & fill) const337 QImage LmmsStyle::colorizeXpm( const char * const * xpm, const QBrush& fill ) const
338 {
339 QImage arrowXpm( xpm );
340 QImage arrow( arrowXpm.size(), QImage::Format_ARGB32 );
341 QPainter arrowPainter( &arrow );
342 arrowPainter.fillRect( arrow.rect(), fill );
343 arrowPainter.end();
344 arrow.setAlphaChannel( arrowXpm );
345
346 return arrow;
347 }
348
349
hoverColors(bool sunken,bool hover,bool active,QColor & color,QColor & blend) const350 void LmmsStyle::hoverColors( bool sunken, bool hover, bool active, QColor& color, QColor& blend ) const
351 {
352 if( active )
353 {
354 if( sunken )
355 {
356 color = QColor( 75, 75, 75 );
357 blend = QColor( 65, 65, 65 );
358 }
359 else if( hover )
360 {
361 color = QColor( 100, 100, 100 );
362 blend = QColor( 75, 75, 75 );
363 }
364 else
365 {
366 color = QColor( 21, 21, 21 );
367 blend = QColor( 33, 33, 33 );
368 }
369 }
370 else
371 {
372 color = QColor( 21, 21, 21 );
373 blend = QColor( 33, 33, 33 );
374 }
375 }
376