|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the QtGui of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "qs60style_p.h" |
|
43 |
|
44 #include "qapplication.h" |
|
45 #include "qpainter.h" |
|
46 #include "qstyleoption.h" |
|
47 #include "qevent.h" |
|
48 #include "qpixmapcache.h" |
|
49 |
|
50 #include "qcalendarwidget.h" |
|
51 #include "qdial.h" |
|
52 #include "qdialog.h" |
|
53 #include "qgroupbox.h" |
|
54 #include "qheaderview.h" |
|
55 #include "qlist.h" |
|
56 #include "qlistwidget.h" |
|
57 #include "qlistview.h" |
|
58 #include "qmenu.h" |
|
59 #include "qmenubar.h" |
|
60 #include "qpushbutton.h" |
|
61 #include "qscrollarea.h" |
|
62 #include "qscrollbar.h" |
|
63 #include "qtabbar.h" |
|
64 #include "qtablewidget.h" |
|
65 #include "qtableview.h" |
|
66 #include "qtextedit.h" |
|
67 #include "qtoolbar.h" |
|
68 #include "qtoolbutton.h" |
|
69 #include "qtreeview.h" |
|
70 #include "qfocusframe.h" |
|
71 |
|
72 #include "private/qtoolbarextension_p.h" |
|
73 #include "private/qcombobox_p.h" |
|
74 #include "private/qwidget_p.h" |
|
75 #include "private/qapplication_p.h" |
|
76 |
|
77 #if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN) |
|
78 |
|
79 QT_BEGIN_NAMESPACE |
|
80 |
|
81 // from text/qfont.cpp |
|
82 extern Q_GUI_EXPORT int qt_defaultDpiY(); |
|
83 |
|
84 const QS60StylePrivate::SkinElementFlags QS60StylePrivate::KDefaultSkinElementFlags = |
|
85 SkinElementFlags(SF_PointNorth | SF_StateEnabled); |
|
86 |
|
87 static const QByteArray propertyKeyLayouts = "layouts"; |
|
88 static const QByteArray propertyKeyCurrentlayout = "currentlayout"; |
|
89 |
|
90 static const qreal goldenRatio = 1.618; |
|
91 |
|
92 const layoutHeader QS60StylePrivate::m_layoutHeaders[] = { |
|
93 // *** generated layout data *** |
|
94 {240,320,1,14,true,"QVGA Landscape Mirrored"}, |
|
95 {240,320,1,14,false,"QVGA Landscape"}, |
|
96 {320,240,1,14,true,"QVGA Portrait Mirrored"}, |
|
97 {320,240,1,14,false,"QVGA Portrait"}, |
|
98 {360,640,1,14,true,"NHD Landscape Mirrored"}, |
|
99 {360,640,1,14,false,"NHD Landscape"}, |
|
100 {640,360,1,14,true,"NHD Portrait Mirrored"}, |
|
101 {640,360,1,14,false,"NHD Portrait"}, |
|
102 {352,800,1,12,true,"E90 Landscape Mirrored"}, |
|
103 {352,800,1,12,false,"E90 Landscape"} |
|
104 // *** End of generated data *** |
|
105 }; |
|
106 const int QS60StylePrivate::m_numberOfLayouts = |
|
107 (int)sizeof(QS60StylePrivate::m_layoutHeaders)/sizeof(QS60StylePrivate::m_layoutHeaders[0]); |
|
108 |
|
109 const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = { |
|
110 // *** generated pixel metrics *** |
|
111 {5,0,-909,0,0,1,0,0,-1,8,15,22,15,15,7,198,-909,-909,-909,19,15,2,0,0,21,-909,21,-909,4,4,1,-909,-909,0,2,0,0,13,23,17,17,21,21,2,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,51,27,51,4,4,5,10,15,-909,5,58,12,5,0,7,4,4,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1}, |
|
112 {5,0,-909,0,0,1,0,0,-1,8,15,22,15,15,7,198,-909,-909,-909,19,15,2,0,0,21,-909,21,-909,4,4,1,-909,-909,0,2,0,0,13,23,17,17,21,21,2,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,51,27,51,4,4,5,10,15,-909,5,58,12,5,0,4,4,7,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1}, |
|
113 {5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,-909,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,7,4,4,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1}, |
|
114 {5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,-909,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1}, |
|
115 {7,0,-909,0,0,2,0,0,-1,20,53,28,19,19,9,258,-909,-909,-909,29,19,26,0,0,32,-909,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,8,5,5,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1}, |
|
116 {7,0,-909,0,0,2,0,0,-1,20,53,28,19,19,9,258,-909,-909,-909,29,19,26,0,0,32,-909,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1}, |
|
117 {7,0,-909,0,0,2,0,0,-1,20,52,28,19,19,9,258,-909,-909,-909,29,19,6,0,0,32,-909,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,98,35,98,5,5,6,8,19,-909,7,74,22,7,0,8,5,5,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1}, |
|
118 {7,0,-909,0,0,2,0,0,-1,20,52,28,19,19,9,258,-909,-909,-909,29,19,6,0,0,32,-909,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,98,35,98,5,5,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1}, |
|
119 {7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,-909,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,5,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,8,6,5,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1}, |
|
120 {7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,-909,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1} |
|
121 // *** End of generated data *** |
|
122 }; |
|
123 |
|
124 const short *QS60StylePrivate::m_pmPointer = QS60StylePrivate::data[0]; |
|
125 |
|
126 // theme background texture |
|
127 QPixmap *QS60StylePrivate::m_background = 0; |
|
128 |
|
129 // theme palette |
|
130 QPalette *QS60StylePrivate::m_themePalette = 0; |
|
131 |
|
132 const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameElementsData[] = { |
|
133 {SE_ButtonNormal, QS60StyleEnums::SP_QsnFrButtonTbCenter}, |
|
134 {SE_ButtonPressed, QS60StyleEnums::SP_QsnFrButtonTbCenterPressed}, |
|
135 {SE_FrameLineEdit, QS60StyleEnums::SP_QsnFrInputCenter}, |
|
136 {SE_ListHighlight, QS60StyleEnums::SP_QsnFrListCenter}, |
|
137 {SE_OptionsMenu, QS60StyleEnums::SP_QsnFrPopupCenter}, |
|
138 {SE_SettingsList, QS60StyleEnums::SP_QsnFrSetOptCenter}, |
|
139 {SE_TableItem, QS60StyleEnums::SP_QsnFrCaleCenter}, |
|
140 {SE_TableHeaderItem, QS60StyleEnums::SP_QsnFrCaleHeadingCenter}, |
|
141 {SE_ToolTip, QS60StyleEnums::SP_QsnFrPopupPreviewCenter}, |
|
142 {SE_ToolBar, QS60StyleEnums::SP_QsnFrPopupSubCenter}, |
|
143 {SE_ToolBarButton, QS60StyleEnums::SP_QsnFrSctrlButtonCenter}, |
|
144 {SE_ToolBarButtonPressed, QS60StyleEnums::SP_QsnFrSctrlButtonCenterPressed}, |
|
145 {SE_PanelBackground, QS60StyleEnums::SP_QsnFrSetOptCenter}, |
|
146 {SE_ButtonInactive, QS60StyleEnums::SP_QsnFrButtonCenterInactive}, |
|
147 {SE_Editor, QS60StyleEnums::SP_QsnFrNotepadCenter}, |
|
148 }; |
|
149 |
|
150 static const int frameElementsCount = |
|
151 int(sizeof(QS60StylePrivate::m_frameElementsData)/sizeof(QS60StylePrivate::m_frameElementsData[0])); |
|
152 |
|
153 const int KNotFound = -909; |
|
154 const double KTabFontMul = 0.72; |
|
155 |
|
156 QS60StylePrivate::~QS60StylePrivate() |
|
157 { |
|
158 clearCaches(); //deletes also background image |
|
159 deleteThemePalette(); |
|
160 } |
|
161 |
|
162 void QS60StylePrivate::drawSkinElement(SkinElements element, QPainter *painter, |
|
163 const QRect &rect, SkinElementFlags flags) |
|
164 { |
|
165 switch (element) { |
|
166 case SE_ButtonNormal: |
|
167 drawFrame(SF_ButtonNormal, painter, rect, flags | SF_PointNorth); |
|
168 break; |
|
169 case SE_ButtonPressed: |
|
170 drawFrame(SF_ButtonPressed, painter, rect, flags | SF_PointNorth); |
|
171 break; |
|
172 case SE_FrameLineEdit: |
|
173 drawFrame(SF_FrameLineEdit, painter, rect, flags | SF_PointNorth); |
|
174 break; |
|
175 case SE_ProgressBarGrooveHorizontal: |
|
176 drawRow(QS60StyleEnums::SP_QgnGrafBarFrameSideL, QS60StyleEnums::SP_QgnGrafBarFrameCenter, |
|
177 QS60StyleEnums::SP_QgnGrafBarFrameSideR, Qt::Horizontal, painter, rect, flags | SF_PointNorth); |
|
178 break; |
|
179 case SE_ProgressBarGrooveVertical: |
|
180 drawRow(QS60StyleEnums::SP_QgnGrafBarFrameSideL, QS60StyleEnums::SP_QgnGrafBarFrameCenter, |
|
181 QS60StyleEnums::SP_QgnGrafBarFrameSideR, Qt::Vertical, painter, rect, flags | SF_PointEast); |
|
182 break; |
|
183 case SE_ProgressBarIndicatorHorizontal: |
|
184 drawPart(QS60StyleEnums::SP_QgnGrafBarProgress, painter, rect, flags | SF_PointNorth); |
|
185 break; |
|
186 case SE_ProgressBarIndicatorVertical: |
|
187 drawPart(QS60StyleEnums::SP_QgnGrafBarProgress, painter, rect, flags | SF_PointWest); |
|
188 break; |
|
189 case SE_ScrollBarGrooveHorizontal: |
|
190 drawRow(QS60StyleEnums::SP_QsnCpScrollBgBottom, QS60StyleEnums::SP_QsnCpScrollBgMiddle, |
|
191 QS60StyleEnums::SP_QsnCpScrollBgTop, Qt::Horizontal, painter, rect, flags | SF_PointEast); |
|
192 break; |
|
193 case SE_ScrollBarGrooveVertical: |
|
194 drawRow(QS60StyleEnums::SP_QsnCpScrollBgTop, QS60StyleEnums::SP_QsnCpScrollBgMiddle, |
|
195 QS60StyleEnums::SP_QsnCpScrollBgBottom, Qt::Vertical, painter, rect, flags | SF_PointNorth); |
|
196 break; |
|
197 case SE_ScrollBarHandleHorizontal: |
|
198 drawRow(QS60StyleEnums::SP_QsnCpScrollHandleBottom, QS60StyleEnums::SP_QsnCpScrollHandleMiddle, |
|
199 QS60StyleEnums::SP_QsnCpScrollHandleTop, Qt::Horizontal, painter, rect, flags | SF_PointEast); |
|
200 break; |
|
201 case SE_ScrollBarHandleVertical: |
|
202 drawRow(QS60StyleEnums::SP_QsnCpScrollHandleTop, QS60StyleEnums::SP_QsnCpScrollHandleMiddle, |
|
203 QS60StyleEnums::SP_QsnCpScrollHandleBottom, Qt::Vertical, painter, rect, flags | SF_PointNorth); |
|
204 break; |
|
205 case SE_SliderHandleHorizontal: |
|
206 drawPart(QS60StyleEnums::SP_QgnIndiSliderEdit, painter, rect, flags | SF_PointNorth); |
|
207 break; |
|
208 case SE_SliderHandleVertical: |
|
209 drawPart(QS60StyleEnums::SP_QgnIndiSliderEdit, painter, rect, flags | SF_PointEast); |
|
210 break; |
|
211 case SE_TabBarTabEastActive: |
|
212 drawRow(QS60StyleEnums::SP_QgnGrafTabActiveL, QS60StyleEnums::SP_QgnGrafTabActiveM, |
|
213 QS60StyleEnums::SP_QgnGrafTabActiveR, Qt::Vertical, painter, rect, flags | SF_PointEast); |
|
214 break; |
|
215 case SE_TabBarTabEastInactive: |
|
216 drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveL, QS60StyleEnums::SP_QgnGrafTabPassiveM, |
|
217 QS60StyleEnums::SP_QgnGrafTabPassiveR, Qt::Vertical, painter, rect, flags | SF_PointEast); |
|
218 break; |
|
219 case SE_TabBarTabNorthActive: |
|
220 drawRow(QS60StyleEnums::SP_QgnGrafTabActiveL, QS60StyleEnums::SP_QgnGrafTabActiveM, |
|
221 QS60StyleEnums::SP_QgnGrafTabActiveR, Qt::Horizontal, painter, rect, flags | SF_PointNorth); |
|
222 break; |
|
223 case SE_TabBarTabNorthInactive: |
|
224 drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveL, QS60StyleEnums::SP_QgnGrafTabPassiveM, |
|
225 QS60StyleEnums::SP_QgnGrafTabPassiveR, Qt::Horizontal, painter, rect, flags | SF_PointNorth); |
|
226 break; |
|
227 case SE_TabBarTabSouthActive: |
|
228 drawRow(QS60StyleEnums::SP_QgnGrafTabActiveR, QS60StyleEnums::SP_QgnGrafTabActiveM, |
|
229 QS60StyleEnums::SP_QgnGrafTabActiveL, Qt::Horizontal, painter, rect, flags | SF_PointSouth); |
|
230 break; |
|
231 case SE_TabBarTabSouthInactive: |
|
232 drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveR, QS60StyleEnums::SP_QgnGrafTabPassiveM, |
|
233 QS60StyleEnums::SP_QgnGrafTabPassiveL, Qt::Horizontal, painter, rect, flags | SF_PointSouth); |
|
234 break; |
|
235 case SE_TabBarTabWestActive: |
|
236 drawRow(QS60StyleEnums::SP_QgnGrafTabActiveR, QS60StyleEnums::SP_QgnGrafTabActiveM, |
|
237 QS60StyleEnums::SP_QgnGrafTabActiveL, Qt::Vertical, painter, rect, flags | SF_PointWest); |
|
238 break; |
|
239 case SE_TabBarTabWestInactive: |
|
240 drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveR, QS60StyleEnums::SP_QgnGrafTabPassiveM, |
|
241 QS60StyleEnums::SP_QgnGrafTabPassiveL, Qt::Vertical, painter, rect, flags | SF_PointWest); |
|
242 break; |
|
243 case SE_ListHighlight: |
|
244 drawFrame(SF_ListHighlight, painter, rect, flags | SF_PointNorth); |
|
245 break; |
|
246 case SE_OptionsMenu: |
|
247 drawFrame(SF_OptionsMenu, painter, rect, flags | SF_PointNorth); |
|
248 break; |
|
249 case SE_SettingsList: |
|
250 drawFrame(SF_SettingsList, painter, rect, flags | SF_PointNorth); |
|
251 break; |
|
252 case SE_TableItem: |
|
253 drawFrame(SF_TableItem, painter, rect, flags | SF_PointNorth); |
|
254 break; |
|
255 case SE_TableHeaderItem: |
|
256 drawFrame(SF_TableHeaderItem, painter, rect, flags | SF_PointNorth); |
|
257 break; |
|
258 case SE_ToolTip: |
|
259 drawFrame(SF_ToolTip, painter, rect, flags | SF_PointNorth); |
|
260 break; |
|
261 case SE_ToolBar: |
|
262 drawFrame(SF_ToolBar, painter, rect, flags | SF_PointNorth); |
|
263 break; |
|
264 case SE_ToolBarButton: |
|
265 drawFrame(SF_ToolBarButton, painter, rect, flags | SF_PointNorth); |
|
266 break; |
|
267 case SE_ToolBarButtonPressed: |
|
268 drawFrame(SF_ToolBarButtonPressed, painter, rect, flags | SF_PointNorth); |
|
269 break; |
|
270 case SE_PanelBackground: |
|
271 drawFrame(SF_PanelBackground, painter, rect, flags | SF_PointNorth); |
|
272 break; |
|
273 case SE_ScrollBarHandlePressedHorizontal: |
|
274 drawRow(QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed, QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed, |
|
275 QS60StyleEnums::SP_QsnCpScrollHandleTopPressed, Qt::Horizontal, painter, rect, flags | SF_PointEast); |
|
276 break; |
|
277 case SE_ScrollBarHandlePressedVertical: |
|
278 drawRow(QS60StyleEnums::SP_QsnCpScrollHandleTopPressed, QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed, |
|
279 QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed, Qt::Vertical, painter, rect, flags | SF_PointNorth); |
|
280 break; |
|
281 case SE_ButtonInactive: |
|
282 drawFrame(SF_ButtonInactive, painter, rect, flags | SF_PointNorth); |
|
283 break; |
|
284 case SE_Editor: |
|
285 drawFrame(SF_Editor, painter, rect, flags | SF_PointNorth); |
|
286 break; |
|
287 default: |
|
288 break; |
|
289 } |
|
290 } |
|
291 |
|
292 void QS60StylePrivate::drawSkinPart(QS60StyleEnums::SkinParts part, |
|
293 QPainter *painter, const QRect &rect, SkinElementFlags flags) |
|
294 { |
|
295 drawPart(part, painter, rect, flags); |
|
296 } |
|
297 |
|
298 short QS60StylePrivate::pixelMetric(int metric) |
|
299 { |
|
300 Q_ASSERT(metric < MAX_PIXELMETRICS); |
|
301 const short returnValue = m_pmPointer[metric]; |
|
302 return returnValue; |
|
303 } |
|
304 |
|
305 void QS60StylePrivate::setStyleProperty(const char *name, const QVariant &value) |
|
306 { |
|
307 if (name == propertyKeyCurrentlayout) { |
|
308 static const QStringList layouts = styleProperty(propertyKeyLayouts).toStringList(); |
|
309 const QString layout = value.toString(); |
|
310 Q_ASSERT(layouts.contains(layout)); |
|
311 const int layoutIndex = layouts.indexOf(layout); |
|
312 setCurrentLayout(layoutIndex); |
|
313 QApplication::setLayoutDirection(m_layoutHeaders[layoutIndex].mirroring ? Qt::RightToLeft : Qt::LeftToRight); |
|
314 clearCaches(); |
|
315 refreshUI(); |
|
316 } |
|
317 } |
|
318 |
|
319 QVariant QS60StylePrivate::styleProperty(const char *name) const |
|
320 { |
|
321 if (name == propertyKeyLayouts) { |
|
322 static QStringList layouts; |
|
323 if (layouts.isEmpty()) |
|
324 for (int i = 0; i < m_numberOfLayouts; i++) |
|
325 layouts.append(QLatin1String(m_layoutHeaders[i].layoutName)); |
|
326 return layouts; |
|
327 } |
|
328 return QVariant(); |
|
329 } |
|
330 |
|
331 QColor QS60StylePrivate::stateColor(const QColor &color, const QStyleOption *option) |
|
332 { |
|
333 QColor retColor (color); |
|
334 if (option && !(option->state & QStyle::State_Enabled)) { |
|
335 QColor hsvColor = retColor.toHsv(); |
|
336 int colorSat = hsvColor.saturation(); |
|
337 int colorVal = hsvColor.value(); |
|
338 colorSat = (colorSat!=0) ? (colorSat>>1) : 128; |
|
339 colorVal = (colorVal!=0) ? (colorVal>>1) : 128; |
|
340 hsvColor.setHsv(hsvColor.hue(), colorSat, colorVal); |
|
341 retColor = hsvColor.toRgb(); |
|
342 } |
|
343 return retColor; |
|
344 } |
|
345 |
|
346 QColor QS60StylePrivate::lighterColor(const QColor &baseColor) |
|
347 { |
|
348 QColor result(baseColor); |
|
349 bool modifyColor = false; |
|
350 if (result.saturation() == 0) { |
|
351 result.setHsv(result.hue(), 128, result.value()); |
|
352 modifyColor = true; |
|
353 } |
|
354 if (result.value() == 0) { |
|
355 result.setHsv(result.hue(), result.saturation(), 128); |
|
356 modifyColor = true; |
|
357 } |
|
358 if (modifyColor) |
|
359 result = result.lighter(175); |
|
360 else |
|
361 result = result.lighter(225); |
|
362 return result; |
|
363 } |
|
364 |
|
365 bool QS60StylePrivate::drawsOwnThemeBackground(const QWidget *widget) |
|
366 { |
|
367 return qobject_cast<const QDialog *> (widget); |
|
368 } |
|
369 |
|
370 QFont QS60StylePrivate::s60Font( |
|
371 QS60StyleEnums::FontCategories fontCategory, int pointSize) const |
|
372 { |
|
373 QFont result; |
|
374 int actualPointSize = pointSize; |
|
375 if (actualPointSize <= 0) { |
|
376 const QFont appFont = QApplication::font(); |
|
377 actualPointSize = appFont.pointSize(); |
|
378 if (actualPointSize <= 0) |
|
379 actualPointSize = appFont.pixelSize() * 72 / qt_defaultDpiY(); |
|
380 } |
|
381 Q_ASSERT(actualPointSize > 0); |
|
382 const QPair<QS60StyleEnums::FontCategories, int> key(fontCategory, actualPointSize); |
|
383 if (!m_mappedFontsCache.contains(key)) { |
|
384 result = s60Font_specific(fontCategory, actualPointSize); |
|
385 m_mappedFontsCache.insert(key, result); |
|
386 } else { |
|
387 result = m_mappedFontsCache.value(key); |
|
388 if (result.pointSize() != actualPointSize) |
|
389 result.setPointSize(actualPointSize); |
|
390 } |
|
391 return result; |
|
392 } |
|
393 |
|
394 void QS60StylePrivate::clearCaches(CacheClearReason reason) |
|
395 { |
|
396 switch(reason){ |
|
397 case CC_LayoutChange: |
|
398 // when layout changes, the colors remain in cache, but graphics and fonts can change |
|
399 m_mappedFontsCache.clear(); |
|
400 deleteBackground(); |
|
401 QPixmapCache::clear(); |
|
402 break; |
|
403 case CC_ThemeChange: |
|
404 m_colorCache.clear(); |
|
405 QPixmapCache::clear(); |
|
406 deleteBackground(); |
|
407 break; |
|
408 case CC_UndefinedChange: |
|
409 default: |
|
410 m_colorCache.clear(); |
|
411 m_mappedFontsCache.clear(); |
|
412 QPixmapCache::clear(); |
|
413 deleteBackground(); |
|
414 break; |
|
415 } |
|
416 } |
|
417 |
|
418 // Since S60Style has 'button' and 'tooltip' as a graphic, we don't have any native color which to use |
|
419 // for QPalette::Button and QPalette::ToolTipBase. Therefore S60Style needs to guesstimate |
|
420 // palette colors by calculating average rgb values for button pixels. |
|
421 // Returns Qt::black if there is an issue with the graphics (image is NULL, or no bits() found). |
|
422 QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const |
|
423 { |
|
424 const bool cachedColorExists = m_colorCache.contains(frame); |
|
425 if (!cachedColorExists) { |
|
426 const int frameCornerWidth = pixelMetric(PM_Custom_FrameCornerWidth); |
|
427 const int frameCornerHeight = pixelMetric(PM_Custom_FrameCornerHeight); |
|
428 Q_ASSERT(2*frameCornerWidth<32); |
|
429 Q_ASSERT(2*frameCornerHeight<32); |
|
430 |
|
431 const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32,32)).toImage(); |
|
432 Q_ASSERT(frameImage.bytesPerLine() > 0); |
|
433 if (frameImage.isNull()) |
|
434 return Qt::black; |
|
435 |
|
436 const QRgb *pixelRgb = (const QRgb*)frameImage.bits(); |
|
437 const int pixels = frameImage.numBytes()/sizeof(QRgb); |
|
438 |
|
439 int estimatedRed = 0; |
|
440 int estimatedGreen = 0; |
|
441 int estimatedBlue = 0; |
|
442 |
|
443 int skips = 0; |
|
444 int estimations = 0; |
|
445 |
|
446 const int topBorderLastPixel = frameCornerHeight*frameImage.width()-1; |
|
447 const int bottomBorderFirstPixel = frameImage.width()*frameImage.height()-frameCornerHeight*frameImage.width()-1; |
|
448 const int rightBorderFirstPixel = frameImage.width()-frameCornerWidth; |
|
449 const int leftBorderLastPixel = frameCornerWidth; |
|
450 |
|
451 while ((skips + estimations) < pixels) { |
|
452 if ((skips+estimations) > topBorderLastPixel && |
|
453 (skips+estimations) < bottomBorderFirstPixel) { |
|
454 for (int rowIndex = 0; rowIndex < frameImage.width(); rowIndex++) { |
|
455 if (rowIndex > leftBorderLastPixel && |
|
456 rowIndex < rightBorderFirstPixel) { |
|
457 estimatedRed += qRed(*pixelRgb); |
|
458 estimatedGreen += qGreen(*pixelRgb); |
|
459 estimatedBlue += qBlue(*pixelRgb); |
|
460 } |
|
461 pixelRgb++; |
|
462 estimations++; |
|
463 } |
|
464 } else { |
|
465 pixelRgb++; |
|
466 skips++; |
|
467 } |
|
468 } |
|
469 QColor frameColor(estimatedRed/estimations, estimatedGreen/estimations, estimatedBlue/estimations); |
|
470 m_colorCache.insert(frame, frameColor); |
|
471 return !estimations ? Qt::black : frameColor; |
|
472 } else { |
|
473 return m_colorCache.value(frame); |
|
474 } |
|
475 |
|
476 } |
|
477 |
|
478 void QS60StylePrivate::setThemePalette(QApplication *app) const |
|
479 { |
|
480 Q_UNUSED(app) |
|
481 QPalette widgetPalette = QPalette(Qt::white); |
|
482 setThemePalette(&widgetPalette); |
|
483 QApplication::setPalette(widgetPalette); //calling QApplication::setPalette clears palette hash |
|
484 setThemePaletteHash(&widgetPalette); |
|
485 storeThemePalette(&widgetPalette); |
|
486 } |
|
487 |
|
488 void QS60StylePrivate::setThemePalette(QStyleOption *option) const |
|
489 { |
|
490 setThemePalette(&option->palette); |
|
491 } |
|
492 |
|
493 QPalette* QS60StylePrivate::themePalette() |
|
494 { |
|
495 return m_themePalette; |
|
496 } |
|
497 |
|
498 void QS60StylePrivate::setBackgroundTexture(QApplication *app) const |
|
499 { |
|
500 Q_UNUSED(app) |
|
501 QPalette applicationPalette = QApplication::palette(); |
|
502 applicationPalette.setBrush(QPalette::Window, backgroundTexture()); |
|
503 QApplication::setPalette(applicationPalette); |
|
504 } |
|
505 |
|
506 void QS60StylePrivate::deleteBackground() |
|
507 { |
|
508 if (m_background) { |
|
509 delete m_background; |
|
510 m_background = 0; |
|
511 } |
|
512 } |
|
513 |
|
514 void QS60StylePrivate::setCurrentLayout(int index) |
|
515 { |
|
516 m_pmPointer = data[index]; |
|
517 } |
|
518 |
|
519 void QS60StylePrivate::drawPart(QS60StyleEnums::SkinParts skinPart, |
|
520 QPainter *painter, const QRect &rect, SkinElementFlags flags) |
|
521 { |
|
522 static const bool doCache = |
|
523 #if defined(Q_WS_S60) |
|
524 // Freezes on 3.1. Anyways, caching is only really needed on touch UI |
|
525 !(QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2); |
|
526 #else |
|
527 true; |
|
528 #endif |
|
529 const QPixmap skinPartPixMap((doCache ? cachedPart : part)(skinPart, rect.size(), flags)); |
|
530 if (!skinPartPixMap.isNull()) |
|
531 painter->drawPixmap(rect.topLeft(), skinPartPixMap); |
|
532 } |
|
533 |
|
534 void QS60StylePrivate::drawFrame(SkinFrameElements frameElement, QPainter *painter, const QRect &rect, SkinElementFlags flags) |
|
535 { |
|
536 static const bool doCache = |
|
537 #if defined(Q_WS_S60) |
|
538 // Freezes on 3.1. Anyways, caching is only really needed on touch UI |
|
539 !(QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2); |
|
540 #else |
|
541 true; |
|
542 #endif |
|
543 const QPixmap frameElementPixMap((doCache ? cachedFrame : frame)(frameElement, rect.size(), flags)); |
|
544 if (!frameElementPixMap.isNull()) |
|
545 painter->drawPixmap(rect.topLeft(), frameElementPixMap); |
|
546 } |
|
547 |
|
548 void QS60StylePrivate::drawRow(QS60StyleEnums::SkinParts start, |
|
549 QS60StyleEnums::SkinParts middle, QS60StyleEnums::SkinParts end, |
|
550 Qt::Orientation orientation, QPainter *painter, const QRect &rect, |
|
551 SkinElementFlags flags) |
|
552 { |
|
553 QSize startEndSize(partSize(start, flags)); |
|
554 startEndSize.scale(rect.size(), Qt::KeepAspectRatio); |
|
555 |
|
556 QRect startRect = QRect(rect.topLeft(), startEndSize); |
|
557 QRect middleRect = rect; |
|
558 QRect endRect; |
|
559 |
|
560 if (orientation == Qt::Horizontal) { |
|
561 startRect.setWidth(qMin((rect.width() >> 1) - 1, startRect.width())); |
|
562 endRect = startRect.translated(rect.width() - startRect.width(), 0); |
|
563 middleRect.adjust(startRect.width(), 0, -startRect.width(), 0); |
|
564 if (startRect.bottomRight().x() > endRect.topLeft().x()) { |
|
565 const int overlap = (startRect.bottomRight().x() - endRect.topLeft().x())>>1; |
|
566 startRect.setWidth(startRect.width()-overlap); |
|
567 endRect.adjust(overlap,0,0,0); |
|
568 } |
|
569 } else { |
|
570 startRect.setHeight(qMin((rect.height() >> 1) - 1, startRect.height())); |
|
571 endRect = startRect.translated(0, rect.height() - startRect.height()); |
|
572 middleRect.adjust(0, startRect.height(), 0, -startRect.height()); |
|
573 if (startRect.topRight().y() > endRect.bottomLeft().y()) { |
|
574 const int overlap = (startRect.topRight().y() - endRect.bottomLeft().y())>>1; |
|
575 startRect.setHeight(startRect.height()-overlap); |
|
576 endRect.adjust(0,overlap,0,0); |
|
577 } |
|
578 } |
|
579 |
|
580 #if 0 |
|
581 painter->save(); |
|
582 painter->setOpacity(.3); |
|
583 painter->fillRect(startRect, Qt::red); |
|
584 painter->fillRect(middleRect, Qt::green); |
|
585 painter->fillRect(endRect, Qt::blue); |
|
586 painter->restore(); |
|
587 #else |
|
588 drawPart(start, painter, startRect, flags); |
|
589 if (middleRect.isValid()) |
|
590 drawPart(middle, painter, middleRect, flags); |
|
591 drawPart(end, painter, endRect, flags); |
|
592 #endif |
|
593 } |
|
594 |
|
595 QPixmap QS60StylePrivate::cachedPart(QS60StyleEnums::SkinParts part, |
|
596 const QSize &size, SkinElementFlags flags) |
|
597 { |
|
598 QPixmap result; |
|
599 const QString cacheKey = |
|
600 QString::fromLatin1("S60Style: SkinParts=%1 QSize=%2|%3 SkinPartFlags=%4") |
|
601 .arg((int)part).arg(size.width()).arg(size.height()).arg((int)flags); |
|
602 if (!QPixmapCache::find(cacheKey, result)) { |
|
603 result = QS60StylePrivate::part(part, size, flags); |
|
604 QPixmapCache::insert(cacheKey, result); |
|
605 } |
|
606 return result; |
|
607 } |
|
608 |
|
609 QPixmap QS60StylePrivate::cachedFrame(SkinFrameElements frame, const QSize &size, SkinElementFlags flags) |
|
610 { |
|
611 QPixmap result; |
|
612 const QString cacheKey = |
|
613 QString::fromLatin1("S60Style: SkinFrameElements=%1 QSize=%2|%3 SkinElementFlags=%4") |
|
614 .arg((int)frame).arg(size.width()).arg(size.height()).arg((int)flags); |
|
615 if (!QPixmapCache::find(cacheKey, result)) { |
|
616 result = QS60StylePrivate::frame(frame, size, flags); |
|
617 QPixmapCache::insert(cacheKey, result); |
|
618 } |
|
619 return result; |
|
620 } |
|
621 |
|
622 void QS60StylePrivate::refreshUI() |
|
623 { |
|
624 QList<QWidget *> widgets = QApplication::allWidgets(); |
|
625 |
|
626 for (int i = 0; i < widgets.size(); ++i) { |
|
627 QWidget *widget = widgets.at(i); |
|
628 if (widget == 0) |
|
629 continue; |
|
630 |
|
631 if (widget->style()) { |
|
632 widget->style()->polish(widget); |
|
633 QEvent event(QEvent::StyleChange); |
|
634 qApp->sendEvent(widget, &event); |
|
635 } |
|
636 widget->update(); |
|
637 widget->updateGeometry(); |
|
638 } |
|
639 } |
|
640 |
|
641 void QS60StylePrivate::setFont(QWidget *widget) const |
|
642 { |
|
643 QS60StyleEnums::FontCategories fontCategory = QS60StyleEnums::FC_Undefined; |
|
644 if (!widget) |
|
645 return; |
|
646 if (qobject_cast<QPushButton *>(widget)){ |
|
647 fontCategory = QS60StyleEnums::FC_Primary; |
|
648 } else if (qobject_cast<QToolButton *>(widget)){ |
|
649 fontCategory = QS60StyleEnums::FC_Primary; |
|
650 } else if (qobject_cast<QHeaderView *>(widget)){ |
|
651 fontCategory = QS60StyleEnums::FC_Secondary; |
|
652 } else if (qobject_cast<QGroupBox *>(widget)){ |
|
653 fontCategory = QS60StyleEnums::FC_Title; |
|
654 } |
|
655 if (fontCategory != QS60StyleEnums::FC_Undefined) { |
|
656 const QFont suggestedFont = |
|
657 s60Font(fontCategory, widget->font().pointSizeF()); |
|
658 widget->setFont(suggestedFont); |
|
659 } |
|
660 } |
|
661 |
|
662 void QS60StylePrivate::setThemePalette(QWidget *widget) const |
|
663 { |
|
664 if(!widget) |
|
665 return; |
|
666 QPalette widgetPalette = QApplication::palette(widget); |
|
667 |
|
668 //header view and its viewport need to be set 100% transparent button color, since drawing code will |
|
669 //draw transparent theme graphics to table column and row headers. |
|
670 if (qobject_cast<QHeaderView *>(widget)){ |
|
671 widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, |
|
672 s60Color(QS60StyleEnums::CL_QsnTextColors, 23, 0)); |
|
673 QHeaderView* header = qobject_cast<QHeaderView *>(widget); |
|
674 widgetPalette.setColor(QPalette::Button, Qt::transparent ); |
|
675 if ( header->viewport() ) |
|
676 header->viewport()->setPalette(widgetPalette); |
|
677 QApplication::setPalette(widgetPalette, "QHeaderView"); |
|
678 } |
|
679 } |
|
680 |
|
681 void QS60StylePrivate::setThemePalette(QPalette *palette) const |
|
682 { |
|
683 if (!palette) |
|
684 return; |
|
685 |
|
686 // basic colors |
|
687 palette->setColor(QPalette::WindowText, |
|
688 s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); |
|
689 palette->setColor(QPalette::ButtonText, |
|
690 s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); |
|
691 palette->setColor(QPalette::Text, |
|
692 s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); |
|
693 palette->setColor(QPalette::ToolTipText, |
|
694 s60Color(QS60StyleEnums::CL_QsnTextColors, 55, 0)); |
|
695 palette->setColor(QPalette::BrightText, palette->color(QPalette::WindowText).lighter()); |
|
696 palette->setColor(QPalette::HighlightedText, |
|
697 s60Color(QS60StyleEnums::CL_QsnTextColors, 10, 0)); |
|
698 palette->setColor(QPalette::Link, |
|
699 s60Color(QS60StyleEnums::CL_QsnHighlightColors, 3, 0)); |
|
700 palette->setColor(QPalette::LinkVisited, palette->color(QPalette::Link).darker()); |
|
701 palette->setColor(QPalette::Highlight, |
|
702 s60Color(QS60StyleEnums::CL_QsnHighlightColors, 2, 0)); |
|
703 // set background image as a texture brush |
|
704 palette->setBrush(QPalette::Window, backgroundTexture()); |
|
705 // set these as transparent so that styled full screen theme background is visible |
|
706 palette->setColor(QPalette::AlternateBase, Qt::transparent); |
|
707 palette->setBrush(QPalette::Base, Qt::transparent); |
|
708 // set button and tooltipbase based on pixel colors |
|
709 const QColor buttonColor = colorFromFrameGraphics(SF_ButtonNormal); |
|
710 palette->setColor(QPalette::Button, buttonColor); |
|
711 const QColor toolTipColor = colorFromFrameGraphics(SF_ToolTip); |
|
712 palette->setColor(QPalette::ToolTipBase, toolTipColor); |
|
713 palette->setColor(QPalette::Light, palette->color(QPalette::Button).lighter()); |
|
714 palette->setColor(QPalette::Dark, palette->color(QPalette::Button).darker()); |
|
715 palette->setColor(QPalette::Midlight, palette->color(QPalette::Button).lighter(125)); |
|
716 palette->setColor(QPalette::Mid, palette->color(QPalette::Button).darker(150)); |
|
717 palette->setColor(QPalette::Shadow, Qt::black); |
|
718 } |
|
719 |
|
720 void QS60StylePrivate::deleteThemePalette() |
|
721 { |
|
722 if (m_themePalette) { |
|
723 delete m_themePalette; |
|
724 m_themePalette = 0; |
|
725 } |
|
726 } |
|
727 |
|
728 void QS60StylePrivate::storeThemePalette(QPalette *palette) |
|
729 { |
|
730 deleteThemePalette(); |
|
731 //store specified palette for latter use. |
|
732 m_themePalette = new QPalette(*palette); |
|
733 } |
|
734 |
|
735 // set widget specific palettes |
|
736 void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const |
|
737 { |
|
738 if (!palette) |
|
739 return; |
|
740 |
|
741 //store the original palette |
|
742 QPalette widgetPalette = *palette; |
|
743 const QColor mainAreaTextColor = |
|
744 s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0); |
|
745 |
|
746 widgetPalette.setColor(QPalette::All, QPalette::WindowText, |
|
747 s60Color(QS60StyleEnums::CL_QsnLineColors, 8, 0)); |
|
748 QApplication::setPalette(widgetPalette, "QSlider"); |
|
749 // return to original palette after each widget |
|
750 widgetPalette = *palette; |
|
751 |
|
752 widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, mainAreaTextColor); |
|
753 widgetPalette.setColor(QPalette::Inactive, QPalette::ButtonText, mainAreaTextColor); |
|
754 const QStyleOption opt; |
|
755 widgetPalette.setColor(QPalette::Disabled, QPalette::ButtonText, |
|
756 s60Color(QS60StyleEnums::CL_QsnTextColors, 6, &opt)); |
|
757 QApplication::setPalette(widgetPalette, "QPushButton"); |
|
758 widgetPalette = *palette; |
|
759 |
|
760 widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, mainAreaTextColor); |
|
761 widgetPalette.setColor(QPalette::Inactive, QPalette::ButtonText, mainAreaTextColor); |
|
762 QApplication::setPalette(widgetPalette, "QToolButton"); |
|
763 widgetPalette = *palette; |
|
764 |
|
765 widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, |
|
766 s60Color(QS60StyleEnums::CL_QsnTextColors, 23, 0)); |
|
767 QApplication::setPalette(widgetPalette, "QHeaderView"); |
|
768 widgetPalette = *palette; |
|
769 |
|
770 widgetPalette.setColor(QPalette::All, QPalette::ButtonText, |
|
771 s60Color(QS60StyleEnums::CL_QsnTextColors, 8, 0)); |
|
772 QApplication::setPalette(widgetPalette, "QMenuBar"); |
|
773 widgetPalette = *palette; |
|
774 |
|
775 widgetPalette.setColor(QPalette::Active, QPalette::WindowText, |
|
776 s60Color(QS60StyleEnums::CL_QsnTextColors, 4, 0)); |
|
777 QApplication::setPalette(widgetPalette, "QTabBar"); |
|
778 widgetPalette = *palette; |
|
779 |
|
780 widgetPalette.setColor(QPalette::All, QPalette::Text, |
|
781 s60Color(QS60StyleEnums::CL_QsnTextColors, 22, 0)); |
|
782 QApplication::setPalette(widgetPalette, "QTableView"); |
|
783 widgetPalette = *palette; |
|
784 |
|
785 widgetPalette.setColor(QPalette::All, QPalette::HighlightedText, |
|
786 s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0)); |
|
787 QApplication::setPalette(widgetPalette, "QLineEdit"); |
|
788 widgetPalette = *palette; |
|
789 |
|
790 widgetPalette.setColor(QPalette::All, QPalette::Text, |
|
791 s60Color(QS60StyleEnums::CL_QsnTextColors, 34, 0)); |
|
792 widgetPalette.setColor(QPalette::All, QPalette::HighlightedText, |
|
793 s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0)); |
|
794 QApplication::setPalette(widgetPalette, "QTextEdit"); |
|
795 widgetPalette = *palette; |
|
796 |
|
797 widgetPalette.setColor(QPalette::All, QPalette::HighlightedText, |
|
798 s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0)); |
|
799 QApplication::setPalette(widgetPalette, "QComboBox"); |
|
800 widgetPalette = *palette; |
|
801 |
|
802 widgetPalette.setColor(QPalette::WindowText, mainAreaTextColor); |
|
803 widgetPalette.setColor(QPalette::Button, QApplication::palette().color(QPalette::Button)); |
|
804 widgetPalette.setColor(QPalette::Dark, mainAreaTextColor.darker()); |
|
805 widgetPalette.setColor(QPalette::Light, mainAreaTextColor.lighter()); |
|
806 QApplication::setPalette(widgetPalette, "QDial"); |
|
807 widgetPalette = *palette; |
|
808 |
|
809 widgetPalette.setBrush(QPalette::Window, QBrush()); |
|
810 QApplication::setPalette(widgetPalette, "QScrollArea"); |
|
811 widgetPalette = *palette; |
|
812 } |
|
813 |
|
814 QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlags flags) |
|
815 { |
|
816 QSize result(20, 20); |
|
817 switch (part) |
|
818 { |
|
819 case QS60StyleEnums::SP_QgnGrafBarProgress: |
|
820 result.setWidth(pixelMetric(QStyle::PM_ProgressBarChunkWidth)); |
|
821 break; |
|
822 case QS60StyleEnums::SP_QgnGrafTabActiveM: |
|
823 case QS60StyleEnums::SP_QgnGrafTabPassiveM: |
|
824 case QS60StyleEnums::SP_QgnGrafTabActiveR: |
|
825 case QS60StyleEnums::SP_QgnGrafTabPassiveR: |
|
826 case QS60StyleEnums::SP_QgnGrafTabPassiveL: |
|
827 case QS60StyleEnums::SP_QgnGrafTabActiveL: |
|
828 break; |
|
829 case QS60StyleEnums::SP_QgnIndiSliderEdit: |
|
830 result.scale(pixelMetric(QStyle::PM_SliderLength), |
|
831 pixelMetric(QStyle::PM_SliderControlThickness), Qt::IgnoreAspectRatio); |
|
832 break; |
|
833 |
|
834 case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed: |
|
835 case QS60StyleEnums::SP_QsnCpScrollHandleTopPressed: |
|
836 case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed: |
|
837 case QS60StyleEnums::SP_QsnCpScrollBgBottom: |
|
838 case QS60StyleEnums::SP_QsnCpScrollBgMiddle: |
|
839 case QS60StyleEnums::SP_QsnCpScrollBgTop: |
|
840 case QS60StyleEnums::SP_QsnCpScrollHandleBottom: |
|
841 case QS60StyleEnums::SP_QsnCpScrollHandleMiddle: |
|
842 case QS60StyleEnums::SP_QsnCpScrollHandleTop: |
|
843 result.setHeight(pixelMetric(QStyle::PM_ScrollBarExtent)); |
|
844 result.setWidth(pixelMetric(QStyle::PM_ScrollBarSliderMin)); |
|
845 break; |
|
846 default: |
|
847 // Generic frame part size gathering. |
|
848 for (int i = 0; i < frameElementsCount; ++i) |
|
849 { |
|
850 switch (m_frameElementsData[i].center - part) { |
|
851 case 8: /* CornerTl */ |
|
852 case 7: /* CornerTr */ |
|
853 case 6: /* CornerBl */ |
|
854 case 5: /* CornerBr */ |
|
855 result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth)); |
|
856 // Falltrough intended... |
|
857 case 4: /* SideT */ |
|
858 case 3: /* SideB */ |
|
859 result.setHeight(pixelMetric(PM_Custom_FrameCornerHeight)); |
|
860 break; |
|
861 case 2: /* SideL */ |
|
862 case 1: /* SideR */ |
|
863 result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth)); |
|
864 break; |
|
865 case 0: /* center */ |
|
866 default: |
|
867 break; |
|
868 } |
|
869 } |
|
870 break; |
|
871 } |
|
872 if (flags & (SF_PointEast | SF_PointWest)) { |
|
873 const int temp = result.width(); |
|
874 result.setWidth(result.height()); |
|
875 result.setHeight(temp); |
|
876 } |
|
877 return result; |
|
878 } |
|
879 |
|
880 /*! |
|
881 \class QS60Style |
|
882 \brief The QS60Style class provides a look and feel suitable for applications on S60. |
|
883 \since 4.6 |
|
884 \ingroup appearance |
|
885 |
|
886 \sa QMacStyle, QWindowsStyle, QWindowsXPStyle, QWindowsVistaStyle, QPlastiqueStyle, QCleanlooksStyle, QMotifStyle |
|
887 */ |
|
888 |
|
889 |
|
890 /*! |
|
891 Destroys the style. |
|
892 */ |
|
893 QS60Style::~QS60Style() |
|
894 { |
|
895 } |
|
896 |
|
897 /*! |
|
898 \reimp |
|
899 */ |
|
900 void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const |
|
901 { |
|
902 const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled; |
|
903 SubControls sub = option->subControls; |
|
904 |
|
905 switch (control) { |
|
906 #ifndef QT_NO_SCROLLBAR |
|
907 case CC_ScrollBar: |
|
908 if (const QStyleOptionSlider *optionSlider = qstyleoption_cast<const QStyleOptionSlider *>(option)) { |
|
909 const bool horizontal = optionSlider->orientation == Qt::Horizontal; |
|
910 |
|
911 const QRect scrollBarSlider = subControlRect(control, optionSlider, SC_ScrollBarSlider, widget); |
|
912 const QRect grooveRect = subControlRect(control, optionSlider, SC_ScrollBarGroove, widget); |
|
913 |
|
914 const QS60StylePrivate::SkinElements grooveElement = |
|
915 horizontal ? QS60StylePrivate::SE_ScrollBarGrooveHorizontal : QS60StylePrivate::SE_ScrollBarGrooveVertical; |
|
916 QS60StylePrivate::drawSkinElement(grooveElement, painter, grooveRect, flags); |
|
917 |
|
918 const QStyle::SubControls subControls = optionSlider->subControls; |
|
919 |
|
920 // select correct slider (horizontal/vertical/pressed) |
|
921 const bool sliderPressed = ((optionSlider->state & QStyle::State_Sunken) && (subControls & SC_ScrollBarSlider)); |
|
922 const QS60StylePrivate::SkinElements handleElement = |
|
923 horizontal ? |
|
924 ( sliderPressed ? |
|
925 QS60StylePrivate::SE_ScrollBarHandlePressedHorizontal : |
|
926 QS60StylePrivate::SE_ScrollBarHandleHorizontal ) : |
|
927 ( sliderPressed ? |
|
928 QS60StylePrivate::SE_ScrollBarHandlePressedVertical : |
|
929 QS60StylePrivate::SE_ScrollBarHandleVertical); |
|
930 QS60StylePrivate::drawSkinElement(handleElement, painter, scrollBarSlider, flags); |
|
931 } |
|
932 break; |
|
933 #endif // QT_NO_SCROLLBAR |
|
934 #ifndef QT_NO_SLIDER |
|
935 case CC_Slider: |
|
936 if (const QStyleOptionSlider *optionSlider = qstyleoption_cast<const QStyleOptionSlider *>(option)) { |
|
937 |
|
938 // The groove is just a centered line. Maybe a qgn_graf_line_* at some point |
|
939 const QRect sliderGroove = subControlRect(control, optionSlider, SC_SliderGroove, widget); |
|
940 const QPoint sliderGrooveCenter = sliderGroove.center(); |
|
941 const bool horizontal = optionSlider->orientation == Qt::Horizontal; |
|
942 painter->save(); |
|
943 if (widget) |
|
944 painter->setPen(widget->palette().windowText().color()); |
|
945 if (horizontal) |
|
946 painter->drawLine(0, sliderGrooveCenter.y(), sliderGroove.right(), sliderGrooveCenter.y()); |
|
947 else |
|
948 painter->drawLine(sliderGrooveCenter.x(), 0, sliderGrooveCenter.x(), sliderGroove.bottom()); |
|
949 painter->restore(); |
|
950 |
|
951 const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget); |
|
952 const QS60StylePrivate::SkinElements handleElement = |
|
953 horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical; |
|
954 QS60StylePrivate::drawSkinElement(handleElement, painter, sliderHandle, flags); |
|
955 } |
|
956 break; |
|
957 #endif // QT_NO_SLIDER |
|
958 #ifndef QT_NO_COMBOBOX |
|
959 case CC_ComboBox: |
|
960 if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { |
|
961 const QRect cmbxEditField = subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget); |
|
962 const QRect cmbxFrame = subControlRect(CC_ComboBox, option, SC_ComboBoxFrame, widget); |
|
963 const bool direction = cmb->direction == Qt::LeftToRight; |
|
964 |
|
965 // Button frame |
|
966 QStyleOptionFrame buttonOption; |
|
967 buttonOption.QStyleOption::operator=(*cmb); |
|
968 const int maxHeight = cmbxFrame.height(); |
|
969 const int maxWidth = cmbxFrame.width() - cmbxEditField.width(); |
|
970 const int topLeftPoint = direction ? cmbxEditField.right()+1 : cmbxEditField.left()+1-maxWidth; |
|
971 const QRect buttonRect(topLeftPoint, cmbxEditField.top(), maxWidth, maxHeight); |
|
972 buttonOption.rect = buttonRect; |
|
973 buttonOption.state = cmb->state & (State_Enabled | State_MouseOver); |
|
974 drawPrimitive(PE_PanelButtonCommand, &buttonOption, painter, widget); |
|
975 |
|
976 // draw label background - label itself is drawn separately |
|
977 const QS60StylePrivate::SkinElements skinElement = QS60StylePrivate::SE_FrameLineEdit; |
|
978 QS60StylePrivate::drawSkinElement(skinElement, painter, cmbxEditField, flags); |
|
979 |
|
980 // Draw the combobox arrow |
|
981 if (sub & SC_ComboBoxArrow) { |
|
982 // Make rect slightly smaller |
|
983 buttonOption.rect.adjust(1, 1, -1, -1); |
|
984 painter->save(); |
|
985 painter->setPen(option->palette.buttonText().color()); |
|
986 drawPrimitive(PE_IndicatorSpinDown, &buttonOption, painter, widget); |
|
987 painter->restore(); |
|
988 } |
|
989 } |
|
990 break; |
|
991 #endif // QT_NO_COMBOBOX |
|
992 #ifndef QT_NO_TOOLBUTTON |
|
993 case CC_ToolButton: |
|
994 if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) { |
|
995 const State bflags = toolBtn->state; |
|
996 const QRect button(subControlRect(control, toolBtn, SC_ToolButton, widget)); |
|
997 QStyleOptionToolButton toolButton = *toolBtn; |
|
998 |
|
999 if (sub&SC_ToolButton) { |
|
1000 QStyleOption tool(0); |
|
1001 tool.palette = toolBtn->palette; |
|
1002 |
|
1003 // Check if toolbutton is in toolbar. |
|
1004 QToolBar *toolBar = 0; |
|
1005 if (widget) |
|
1006 toolBar = qobject_cast<QToolBar *>(widget->parentWidget()); |
|
1007 |
|
1008 if (bflags & (State_Sunken | State_On | State_Raised)) { |
|
1009 tool.rect = button; |
|
1010 tool.state = bflags; |
|
1011 |
|
1012 // todo: I'd like to move extension button next to where last button is |
|
1013 // however, the painter seems to want to clip the button rect even if I turn of the clipping. |
|
1014 if (toolBar && (qobject_cast<const QToolBarExtension *>(widget))){ |
|
1015 /*QList<QAction *> actionList = toolBar->actions(); |
|
1016 const int actionCount = actionList.count(); |
|
1017 const int toolbarWidth = toolBar->width(); |
|
1018 const int extButtonWidth = pixelMetric(PM_ToolBarExtensionExtent, option, widget); |
|
1019 const int toolBarButtonWidth = pixelMetric(PM_ToolBarIconSize, option, widget); |
|
1020 const int frame = pixelMetric(PM_ToolBarFrameWidth, option, widget); |
|
1021 const int margin = pixelMetric(PM_ToolBarItemMargin, option, widget); |
|
1022 const int border = frame + margin; |
|
1023 const int spacing = pixelMetric(PM_ToolBarItemSpacing, option, widget); |
|
1024 const int toolBarButtonArea = toolbarWidth - extButtonWidth - spacing - 2*border; |
|
1025 const int numberOfVisibleButtons = toolBarButtonArea / toolBarButtonWidth; |
|
1026 // new extension button place is after border and all the other visible buttons (with spacings) |
|
1027 const int newXForExtensionButton = numberOfVisibleButtons * toolBarButtonWidth + (numberOfVisibleButtons-1)*spacing + border; |
|
1028 painter->save(); |
|
1029 painter->setClipping(false); |
|
1030 tool.rect.translate(-newXForExtensionButton,0); |
|
1031 painter->restore();*/ |
|
1032 } |
|
1033 |
|
1034 if (toolBar){ |
|
1035 /*if (toolBar->orientation() == Qt::Vertical){ |
|
1036 // todo: I'd like to make all vertical buttons the same size, but again the painter |
|
1037 // prefers to use clipping for button rects, even though clipping has been set off. |
|
1038 painter->save(); |
|
1039 painter->setClipping(false); |
|
1040 |
|
1041 const int origWidth = tool.rect.width(); |
|
1042 const int newWidth = toolBar->width()-2*pixelMetric(PM_ToolBarFrameWidth, option, widget); |
|
1043 painter->translate(origWidth-newWidth,0); |
|
1044 tool.rect.translate(origWidth-tool.rect.width(),0); |
|
1045 tool.rect.setWidth(newWidth); |
|
1046 |
|
1047 if (option->state & QStyle::State_Sunken) |
|
1048 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButtonPressed, painter, tool.rect, flags); |
|
1049 else |
|
1050 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButton, painter, tool.rect, flags); |
|
1051 |
|
1052 }*/ |
|
1053 if (option->state & QStyle::State_Sunken) |
|
1054 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButtonPressed, painter, tool.rect, flags); |
|
1055 else |
|
1056 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButton, painter, tool.rect, flags); |
|
1057 /* |
|
1058 if (toolBar->orientation() == Qt::Vertical) |
|
1059 painter->restore(); |
|
1060 */ |
|
1061 } else { |
|
1062 drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); |
|
1063 } |
|
1064 } |
|
1065 } |
|
1066 |
|
1067 if (toolBtn->features & QStyleOptionToolButton::Arrow) { |
|
1068 QStyle::PrimitiveElement pe; |
|
1069 switch (toolBtn->arrowType) { |
|
1070 case Qt::LeftArrow: |
|
1071 pe = QStyle::PE_IndicatorArrowLeft; |
|
1072 break; |
|
1073 case Qt::RightArrow: |
|
1074 pe = QStyle::PE_IndicatorArrowRight; |
|
1075 break; |
|
1076 case Qt::UpArrow: |
|
1077 pe = QStyle::PE_IndicatorArrowUp; |
|
1078 break; |
|
1079 case Qt::DownArrow: |
|
1080 pe = QStyle::PE_IndicatorArrowDown; |
|
1081 break; |
|
1082 default: |
|
1083 break; } |
|
1084 toolButton.rect = button; |
|
1085 drawPrimitive(pe, &toolButton, painter, widget); |
|
1086 } |
|
1087 |
|
1088 if (toolBtn->text.length()>0 || |
|
1089 !toolBtn->icon.isNull()) { |
|
1090 const int frameWidth = pixelMetric(PM_DefaultFrameWidth, option, widget); |
|
1091 toolButton.rect = button.adjusted(frameWidth, frameWidth, -frameWidth, -frameWidth); |
|
1092 drawControl(CE_ToolButtonLabel, &toolButton, painter, widget); |
|
1093 } |
|
1094 } |
|
1095 break; |
|
1096 #endif //QT_NO_TOOLBUTTON |
|
1097 #ifndef QT_NO_SPINBOX |
|
1098 case CC_SpinBox: |
|
1099 if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { |
|
1100 QStyleOptionSpinBox copy = *spinBox; |
|
1101 PrimitiveElement pe; |
|
1102 |
|
1103 if (spinBox->subControls & SC_SpinBoxUp) { |
|
1104 copy.subControls = SC_SpinBoxUp; |
|
1105 QPalette spinBoxPal = spinBox->palette; |
|
1106 if (!(spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled)) { |
|
1107 spinBoxPal.setCurrentColorGroup(QPalette::Disabled); |
|
1108 copy.state &= ~State_Enabled; |
|
1109 copy.palette = spinBoxPal; |
|
1110 } |
|
1111 |
|
1112 if (spinBox->activeSubControls == SC_SpinBoxUp && (spinBox->state & State_Sunken)) { |
|
1113 copy.state |= State_On; |
|
1114 copy.state |= State_Sunken; |
|
1115 } else { |
|
1116 copy.state |= State_Raised; |
|
1117 copy.state &= ~State_Sunken; |
|
1118 } |
|
1119 pe = (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) ? |
|
1120 PE_IndicatorSpinPlus : |
|
1121 PE_IndicatorSpinUp; |
|
1122 |
|
1123 copy.rect = subControlRect(CC_SpinBox, spinBox, SC_SpinBoxUp, widget); |
|
1124 drawPrimitive(PE_PanelButtonBevel, ©, painter, widget); |
|
1125 copy.rect.adjust(1, 1, -1, -1); |
|
1126 drawPrimitive(pe, ©, painter, widget); |
|
1127 } |
|
1128 |
|
1129 if (spinBox->subControls & SC_SpinBoxDown) { |
|
1130 copy.subControls = SC_SpinBoxDown; |
|
1131 copy.state = spinBox->state; |
|
1132 QPalette spinBoxPal = spinBox->palette; |
|
1133 if (!(spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled)) { |
|
1134 spinBoxPal.setCurrentColorGroup(QPalette::Disabled); |
|
1135 copy.state &= ~State_Enabled; |
|
1136 copy.palette = spinBoxPal; |
|
1137 } |
|
1138 |
|
1139 if (spinBox->activeSubControls == SC_SpinBoxDown && (spinBox->state & State_Sunken)) { |
|
1140 copy.state |= State_On; |
|
1141 copy.state |= State_Sunken; |
|
1142 } else { |
|
1143 copy.state |= State_Raised; |
|
1144 copy.state &= ~State_Sunken; |
|
1145 } |
|
1146 pe = (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) ? |
|
1147 PE_IndicatorSpinMinus : |
|
1148 PE_IndicatorSpinDown; |
|
1149 |
|
1150 copy.rect = subControlRect(CC_SpinBox, spinBox, SC_SpinBoxDown, widget); |
|
1151 drawPrimitive(PE_PanelButtonBevel, ©, painter, widget); |
|
1152 copy.rect.adjust(1, 1, -1, -1); |
|
1153 drawPrimitive(pe, ©, painter, widget); |
|
1154 } |
|
1155 } |
|
1156 break; |
|
1157 #endif //QT_NO_SPINBOX |
|
1158 #ifndef QT_NO_GROUPBOX |
|
1159 case CC_GroupBox: |
|
1160 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) { |
|
1161 // Draw frame |
|
1162 const QRect textRect = subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget); |
|
1163 const QRect checkBoxRect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget); |
|
1164 if (groupBox->subControls & QStyle::SC_GroupBoxFrame) { |
|
1165 QStyleOptionFrameV2 frame; |
|
1166 frame.QStyleOption::operator=(*groupBox); |
|
1167 frame.features = groupBox->features; |
|
1168 frame.lineWidth = groupBox->lineWidth; |
|
1169 frame.midLineWidth = groupBox->midLineWidth; |
|
1170 frame.rect = subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget); |
|
1171 drawPrimitive(PE_FrameGroupBox, &frame, painter, widget); |
|
1172 } |
|
1173 |
|
1174 // Draw title |
|
1175 if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) { |
|
1176 const QColor textColor = groupBox->textColor; |
|
1177 painter->save(); |
|
1178 |
|
1179 if (textColor.isValid()) |
|
1180 painter->setPen(textColor); |
|
1181 int alignment = int(groupBox->textAlignment); |
|
1182 if (!styleHint(QStyle::SH_UnderlineShortcut, option, widget)) |
|
1183 alignment |= Qt::TextHideMnemonic; |
|
1184 |
|
1185 drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | Qt::AlignVCenter | alignment, |
|
1186 groupBox->palette, groupBox->state & State_Enabled, groupBox->text, |
|
1187 textColor.isValid() ? QPalette::NoRole : QPalette::WindowText); |
|
1188 painter->restore(); |
|
1189 } |
|
1190 |
|
1191 // Draw checkbox |
|
1192 if (groupBox->subControls & SC_GroupBoxCheckBox) { |
|
1193 QStyleOptionButton box; |
|
1194 box.QStyleOption::operator=(*groupBox); |
|
1195 box.rect = checkBoxRect; |
|
1196 drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget); |
|
1197 } |
|
1198 } |
|
1199 break; |
|
1200 #endif //QT_NO_GROUPBOX |
|
1201 default: |
|
1202 QCommonStyle::drawComplexControl(control, option, painter, widget); |
|
1203 } |
|
1204 } |
|
1205 |
|
1206 /*! |
|
1207 \reimp |
|
1208 */ |
|
1209 void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const |
|
1210 { |
|
1211 Q_D(const QS60Style); |
|
1212 const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled; |
|
1213 switch (element) { |
|
1214 case CE_PushButton: |
|
1215 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { |
|
1216 |
|
1217 drawControl(CE_PushButtonBevel, btn, painter, widget); |
|
1218 QStyleOptionButton subopt = *btn; |
|
1219 subopt.rect = subElementRect(SE_PushButtonContents, btn, widget); |
|
1220 |
|
1221 drawControl(CE_PushButtonLabel, &subopt, painter, widget); |
|
1222 } |
|
1223 break; |
|
1224 case CE_PushButtonBevel: |
|
1225 if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) { |
|
1226 const bool isDisabled = !(option->state & QStyle::State_Enabled); |
|
1227 const bool isFlat = button->features & QStyleOptionButton::Flat; |
|
1228 QS60StyleEnums::SkinParts skinPart; |
|
1229 QS60StylePrivate::SkinElements skinElement; |
|
1230 if (!isDisabled) { |
|
1231 const bool isPressed = (option->state & QStyle::State_Sunken) || |
|
1232 (option->state & QStyle::State_On); |
|
1233 if (isFlat) { |
|
1234 skinPart = |
|
1235 isPressed ? QS60StyleEnums::SP_QsnFrButtonTbCenterPressed : QS60StyleEnums::SP_QsnFrButtonTbCenter; |
|
1236 } else { |
|
1237 skinElement = |
|
1238 isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal; |
|
1239 } |
|
1240 } else { |
|
1241 if (isFlat) |
|
1242 skinPart =QS60StyleEnums::SP_QsnFrButtonCenterInactive; |
|
1243 else |
|
1244 skinElement = QS60StylePrivate::SE_ButtonInactive; |
|
1245 } |
|
1246 if (isFlat) |
|
1247 QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags); |
|
1248 else |
|
1249 QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); |
|
1250 } |
|
1251 break; |
|
1252 #ifndef QT_NO_TOOLBUTTON |
|
1253 case CE_ToolButtonLabel: |
|
1254 if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) { |
|
1255 QStyleOptionToolButton optionToolButton = *toolBtn; |
|
1256 |
|
1257 if (!optionToolButton.icon.isNull() && (optionToolButton.state & QStyle::State_Sunken) |
|
1258 && (optionToolButton.state & State_Enabled)) { |
|
1259 |
|
1260 const QIcon::State state = optionToolButton.state & State_On ? QIcon::On : QIcon::Off; |
|
1261 const QPixmap pm(optionToolButton.icon.pixmap(optionToolButton.rect.size().boundedTo(optionToolButton.iconSize), |
|
1262 QIcon::Normal, state)); |
|
1263 optionToolButton.icon = generatedIconPixmap(QIcon::Selected, pm, &optionToolButton); |
|
1264 } |
|
1265 |
|
1266 QCommonStyle::drawControl(element, &optionToolButton, painter, widget); |
|
1267 } |
|
1268 break; |
|
1269 #endif //QT_NO_TOOLBUTTON |
|
1270 #ifndef QT_NO_COMBOBOX |
|
1271 case CE_ComboBoxLabel: |
|
1272 if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { |
|
1273 QStyleOption optionComboBox = *comboBox; |
|
1274 optionComboBox.palette.setColor(QPalette::Active, QPalette::WindowText, |
|
1275 optionComboBox.palette.text().color() ); |
|
1276 optionComboBox.palette.setColor(QPalette::Inactive, QPalette::WindowText, |
|
1277 optionComboBox.palette.text().color() ); |
|
1278 QRect editRect = subControlRect(CC_ComboBox, comboBox, SC_ComboBoxEditField, widget); |
|
1279 painter->save(); |
|
1280 painter->setClipRect(editRect); |
|
1281 |
|
1282 if (!comboBox->currentIcon.isNull()) { |
|
1283 QIcon::Mode mode = comboBox->state & State_Enabled ? QIcon::Normal : QIcon::Disabled; |
|
1284 QPixmap pixmap = comboBox->currentIcon.pixmap(comboBox->iconSize, mode); |
|
1285 QRect iconRect(editRect); |
|
1286 iconRect.setWidth(comboBox->iconSize.width() + 4); |
|
1287 iconRect = alignedRect(comboBox->direction, |
|
1288 Qt::AlignLeft | Qt::AlignVCenter, |
|
1289 iconRect.size(), editRect); |
|
1290 if (comboBox->editable) |
|
1291 painter->fillRect(iconRect, optionComboBox.palette.brush(QPalette::Base)); |
|
1292 drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap); |
|
1293 |
|
1294 if (comboBox->direction == Qt::RightToLeft) |
|
1295 editRect.translate(-4 - comboBox->iconSize.width(), 0); |
|
1296 else |
|
1297 editRect.translate(comboBox->iconSize.width() + 4, 0); |
|
1298 } |
|
1299 if (!comboBox->currentText.isEmpty() && !comboBox->editable) { |
|
1300 QCommonStyle::drawItemText(painter, |
|
1301 editRect.adjusted(QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth), 0, -1, 0), |
|
1302 visualAlignment(comboBox->direction, Qt::AlignLeft | Qt::AlignVCenter), |
|
1303 comboBox->palette, comboBox->state & State_Enabled, comboBox->currentText); |
|
1304 } |
|
1305 painter->restore(); |
|
1306 } |
|
1307 break; |
|
1308 #endif //QT_NO_COMBOBOX |
|
1309 #ifndef QT_NO_ITEMVIEWS |
|
1310 case CE_ItemViewItem: |
|
1311 if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) { |
|
1312 QStyleOptionViewItemV4 voptAdj = *vopt; |
|
1313 painter->save(); |
|
1314 |
|
1315 painter->setClipRect(voptAdj.rect); |
|
1316 const bool isSelected = (vopt->state & QStyle::State_Selected); |
|
1317 |
|
1318 bool isVisible = false; |
|
1319 int scrollBarWidth = 0; |
|
1320 QList<QScrollBar *> scrollBars = qFindChildren<QScrollBar *>(widget); |
|
1321 for (int i = 0; i < scrollBars.size(); ++i) { |
|
1322 QScrollBar *scrollBar = scrollBars.at(i); |
|
1323 if (scrollBar && scrollBar->orientation() == Qt::Vertical) { |
|
1324 isVisible = scrollBar->isVisible(); |
|
1325 scrollBarWidth = scrollBar->size().width(); |
|
1326 break; |
|
1327 } |
|
1328 } |
|
1329 |
|
1330 int rightValue = widget ? widget->contentsRect().right() : 0; |
|
1331 |
|
1332 if (isVisible) |
|
1333 rightValue -= scrollBarWidth; |
|
1334 |
|
1335 if (voptAdj.rect.right() > rightValue) |
|
1336 voptAdj.rect.setRight(rightValue); |
|
1337 |
|
1338 const QRect iconRect = subElementRect(SE_ItemViewItemDecoration, &voptAdj, widget); |
|
1339 QRect textRect = subElementRect(SE_ItemViewItemText, &voptAdj, widget); |
|
1340 |
|
1341 // draw themed background for table unless background brush has been defined. |
|
1342 if (vopt->backgroundBrush == Qt::NoBrush) { |
|
1343 const QStyleOptionViewItemV4 *tableOption = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option); |
|
1344 const QTableView *table = qobject_cast<const QTableView *>(widget); |
|
1345 if (table && tableOption) { |
|
1346 const QModelIndex index = tableOption->index; |
|
1347 //todo: Draw cell background only once - for the first cell. |
|
1348 QStyleOptionViewItemV4 voptAdj2 = voptAdj; |
|
1349 const QModelIndex indexFirst = table->model()->index(0,0); |
|
1350 const QModelIndex indexLast = table->model()->index( |
|
1351 table->model()->rowCount()-1,table->model()->columnCount()-1); |
|
1352 if (table->viewport()) |
|
1353 voptAdj2.rect = QRect( table->visualRect(indexFirst).topLeft(), |
|
1354 table->visualRect(indexLast).bottomRight()).intersect(table->viewport()->rect()); |
|
1355 drawPrimitive(PE_PanelItemViewItem, &voptAdj2, painter, widget); |
|
1356 } |
|
1357 } else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget);} |
|
1358 |
|
1359 // draw the focus rect |
|
1360 if (isSelected) { |
|
1361 QRect highlightRect = option->rect.adjusted(1,1,-1,-1); |
|
1362 const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget); |
|
1363 if (view && view->selectionBehavior() != QAbstractItemView::SelectItems) { |
|
1364 // set highlight rect so that it is continuous from cell to cell, yet sligthly |
|
1365 // smaller than cell rect |
|
1366 int xBeginning = 0, yBeginning = 0, xEnd = 0, yEnd = 0; |
|
1367 if (view->selectionBehavior() == QAbstractItemView::SelectRows) { |
|
1368 yBeginning = 1; yEnd = -1; |
|
1369 if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning) |
|
1370 xBeginning = 1; |
|
1371 else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End) |
|
1372 xEnd = -1; |
|
1373 } else if (view->selectionBehavior() == QAbstractItemView::SelectColumns) { |
|
1374 xBeginning = 1; xEnd = -1; |
|
1375 if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning) |
|
1376 yBeginning = 1; |
|
1377 else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End) |
|
1378 yEnd = -1; |
|
1379 } |
|
1380 highlightRect = option->rect.adjusted(xBeginning, yBeginning, xEnd, xBeginning); |
|
1381 } |
|
1382 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, highlightRect, flags); |
|
1383 } |
|
1384 |
|
1385 // draw the icon |
|
1386 const QIcon::Mode mode = (voptAdj.state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled; |
|
1387 const QIcon::State state = voptAdj.state & QStyle::State_Open ? QIcon::On : QIcon::Off; |
|
1388 voptAdj.icon.paint(painter, iconRect, voptAdj.decorationAlignment, mode, state); |
|
1389 |
|
1390 // Draw selection check mark. Show check mark only in multi selection modes. |
|
1391 if (const QListView *listView = (qobject_cast<const QListView *>(widget))) { |
|
1392 const bool singleSelection = |
|
1393 listView && |
|
1394 (listView->selectionMode() == QAbstractItemView::SingleSelection || |
|
1395 listView->selectionMode() == QAbstractItemView::NoSelection); |
|
1396 const QRect selectionRect = subElementRect(SE_ItemViewItemCheckIndicator, &voptAdj, widget); |
|
1397 if (voptAdj.state & QStyle::State_Selected && !singleSelection) { |
|
1398 QStyleOptionViewItemV4 option(voptAdj); |
|
1399 option.rect = selectionRect; |
|
1400 // Draw selection mark. |
|
1401 drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, painter, widget); |
|
1402 if ( textRect.right() > selectionRect.left() ) |
|
1403 textRect.setRight(selectionRect.left()); |
|
1404 } else if (singleSelection && |
|
1405 voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator) { |
|
1406 // draw the check mark |
|
1407 if (selectionRect.isValid()) { |
|
1408 QStyleOptionViewItemV4 option(*vopt); |
|
1409 option.rect = selectionRect; |
|
1410 option.state = option.state & ~QStyle::State_HasFocus; |
|
1411 |
|
1412 switch (vopt->checkState) { |
|
1413 case Qt::Unchecked: |
|
1414 option.state |= QStyle::State_Off; |
|
1415 break; |
|
1416 case Qt::PartiallyChecked: |
|
1417 option.state |= QStyle::State_NoChange; |
|
1418 break; |
|
1419 case Qt::Checked: |
|
1420 option.state |= QStyle::State_On; |
|
1421 break; |
|
1422 } |
|
1423 drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, painter, widget); |
|
1424 } |
|
1425 } |
|
1426 } |
|
1427 |
|
1428 // draw the text |
|
1429 if (!voptAdj.text.isEmpty()) { |
|
1430 const QStyleOptionViewItemV4 *tableOption = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option); |
|
1431 if (isSelected) { |
|
1432 if (qobject_cast<const QTableView *>(widget) && tableOption) |
|
1433 voptAdj.palette.setColor( |
|
1434 QPalette::Text, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0)); |
|
1435 else |
|
1436 voptAdj.palette.setColor( |
|
1437 QPalette::Text, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 10, 0)); |
|
1438 } |
|
1439 painter->setPen(voptAdj.palette.text().color()); |
|
1440 d->viewItemDrawText(painter, &voptAdj, textRect); |
|
1441 } |
|
1442 painter->restore(); |
|
1443 } |
|
1444 break; |
|
1445 #endif // QT_NO_ITEMVIEWS |
|
1446 #ifndef QT_NO_TABBAR |
|
1447 case CE_TabBarTabShape: |
|
1448 if (const QStyleOptionTabV3 *optionTab = qstyleoption_cast<const QStyleOptionTabV3 *>(option)) { |
|
1449 QStyleOptionTabV3 optionTabAdj = *optionTab; |
|
1450 const bool isSelected = optionTab->state & QStyle::State_Selected; |
|
1451 const bool directionMirrored = (optionTab->direction == Qt::RightToLeft); |
|
1452 QS60StylePrivate::SkinElements skinElement; |
|
1453 switch (optionTab->shape) { |
|
1454 case QTabBar::TriangularEast: |
|
1455 case QTabBar::RoundedEast: |
|
1456 skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabEastActive: |
|
1457 QS60StylePrivate::SE_TabBarTabEastInactive; |
|
1458 break; |
|
1459 case QTabBar::TriangularSouth: |
|
1460 case QTabBar::RoundedSouth: |
|
1461 skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabSouthActive: |
|
1462 QS60StylePrivate::SE_TabBarTabSouthInactive; |
|
1463 break; |
|
1464 case QTabBar::TriangularWest: |
|
1465 case QTabBar::RoundedWest: |
|
1466 skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabWestActive: |
|
1467 QS60StylePrivate::SE_TabBarTabWestInactive; |
|
1468 break; |
|
1469 case QTabBar::TriangularNorth: |
|
1470 case QTabBar::RoundedNorth: |
|
1471 default: |
|
1472 skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabNorthActive: |
|
1473 QS60StylePrivate::SE_TabBarTabNorthInactive; |
|
1474 break; |
|
1475 } |
|
1476 if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive|| |
|
1477 skinElement==QS60StylePrivate::SE_TabBarTabNorthInactive|| |
|
1478 skinElement==QS60StylePrivate::SE_TabBarTabSouthInactive|| |
|
1479 skinElement==QS60StylePrivate::SE_TabBarTabWestInactive|| |
|
1480 skinElement==QS60StylePrivate::SE_TabBarTabEastActive|| |
|
1481 skinElement==QS60StylePrivate::SE_TabBarTabNorthActive|| |
|
1482 skinElement==QS60StylePrivate::SE_TabBarTabSouthActive|| |
|
1483 skinElement==QS60StylePrivate::SE_TabBarTabWestActive) { |
|
1484 const int borderThickness = |
|
1485 QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); |
|
1486 const int tabOverlap = |
|
1487 QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness; |
|
1488 //todo: draw navi wipe behind tabbar - must be drawn with first draw |
|
1489 |
|
1490 if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive|| |
|
1491 skinElement==QS60StylePrivate::SE_TabBarTabEastActive|| |
|
1492 skinElement==QS60StylePrivate::SE_TabBarTabWestInactive|| |
|
1493 skinElement==QS60StylePrivate::SE_TabBarTabWestActive){ |
|
1494 optionTabAdj.rect.adjust(0, 0, 0, tabOverlap); |
|
1495 } else { |
|
1496 if (directionMirrored) |
|
1497 optionTabAdj.rect.adjust(-tabOverlap, 0, 0, 0); |
|
1498 else |
|
1499 optionTabAdj.rect.adjust(0, 0, tabOverlap, 0); |
|
1500 } |
|
1501 } |
|
1502 QS60StylePrivate::drawSkinElement(skinElement, painter, optionTabAdj.rect, flags); |
|
1503 } |
|
1504 break; |
|
1505 case CE_TabBarTabLabel: |
|
1506 if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(option)) { |
|
1507 QStyleOptionTabV3 optionTab = *tab; |
|
1508 QRect tr = optionTab.rect; |
|
1509 const bool directionMirrored = (optionTab.direction == Qt::RightToLeft); |
|
1510 const int borderThickness = QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); |
|
1511 const int tabOverlap = |
|
1512 QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness; |
|
1513 const QRect windowRect = painter->window(); |
|
1514 |
|
1515 switch (tab->shape) { |
|
1516 case QTabBar::TriangularWest: |
|
1517 case QTabBar::RoundedWest: |
|
1518 case QTabBar::TriangularEast: |
|
1519 case QTabBar::RoundedEast: |
|
1520 tr.adjust(0, 0, 0, tabOverlap); |
|
1521 break; |
|
1522 case QTabBar::TriangularSouth: |
|
1523 case QTabBar::RoundedSouth: |
|
1524 case QTabBar::TriangularNorth: |
|
1525 case QTabBar::RoundedNorth: |
|
1526 default: |
|
1527 if (directionMirrored) |
|
1528 tr.adjust(-tabOverlap, 0, 0, 0); |
|
1529 else |
|
1530 tr.adjust(0, 0, tabOverlap, 0); |
|
1531 break; |
|
1532 } |
|
1533 painter->save(); |
|
1534 QFont f = painter->font(); |
|
1535 f.setPointSizeF(f.pointSizeF() * KTabFontMul); |
|
1536 painter->setFont(f); |
|
1537 |
|
1538 if (option->state & QStyle::State_Selected){ |
|
1539 optionTab.palette.setColor(QPalette::Active, QPalette::WindowText, |
|
1540 QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 3, option)); |
|
1541 } |
|
1542 |
|
1543 const bool verticalTabs = optionTab.shape == QTabBar::RoundedEast |
|
1544 || optionTab.shape == QTabBar::RoundedWest |
|
1545 || optionTab.shape == QTabBar::TriangularEast |
|
1546 || optionTab.shape == QTabBar::TriangularWest; |
|
1547 const bool selected = optionTab.state & State_Selected; |
|
1548 if (verticalTabs) { |
|
1549 painter->save(); |
|
1550 int newX, newY, newRotation; |
|
1551 if (optionTab.shape == QTabBar::RoundedEast || optionTab.shape == QTabBar::TriangularEast) { |
|
1552 newX = tr.width(); |
|
1553 newY = tr.y(); |
|
1554 newRotation = 90; |
|
1555 } else { |
|
1556 newX = 0; |
|
1557 newY = tr.y() + tr.height(); |
|
1558 newRotation = -90; |
|
1559 } |
|
1560 tr.setRect(0, 0, tr.height(), tr.width()); |
|
1561 QTransform m; |
|
1562 m.translate(newX, newY); |
|
1563 m.rotate(newRotation); |
|
1564 painter->setTransform(m, true); |
|
1565 } |
|
1566 tr.adjust(0, 0, pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget), |
|
1567 pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget)); |
|
1568 |
|
1569 if (selected) { |
|
1570 tr.setBottom(tr.bottom() - pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget)); |
|
1571 tr.setRight(tr.right() - pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget)); |
|
1572 } |
|
1573 |
|
1574 int alignment = Qt::AlignCenter | Qt::TextShowMnemonic; |
|
1575 if (!styleHint(SH_UnderlineShortcut, &optionTab, widget)) |
|
1576 alignment |= Qt::TextHideMnemonic; |
|
1577 if (!optionTab.icon.isNull()) { |
|
1578 QSize iconSize = optionTab.iconSize; |
|
1579 int iconExtent = pixelMetric(PM_TabBarIconSize); |
|
1580 if (iconSize.height() > iconExtent || iconSize.width() > iconExtent) |
|
1581 iconSize = QSize(iconExtent, iconExtent); |
|
1582 QPixmap tabIcon = optionTab.icon.pixmap(iconSize, |
|
1583 (optionTab.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled); |
|
1584 if (tab->text.isEmpty()) |
|
1585 painter->drawPixmap(tr.center().x() - (tabIcon.height() >>1), |
|
1586 tr.center().y() - (tabIcon.height() >>1), |
|
1587 tabIcon); |
|
1588 else |
|
1589 painter->drawPixmap(tr.left() + tabOverlap, |
|
1590 tr.center().y() - (tabIcon.height() >>1), |
|
1591 tabIcon); |
|
1592 tr.setLeft(tr.left() + iconSize.width() + 4); |
|
1593 } |
|
1594 |
|
1595 QCommonStyle::drawItemText(painter, tr, alignment, optionTab.palette, tab->state & State_Enabled, tab->text, QPalette::WindowText); |
|
1596 if (verticalTabs) |
|
1597 painter->restore(); |
|
1598 |
|
1599 painter->restore(); |
|
1600 } |
|
1601 break; |
|
1602 #endif // QT_NO_TABBAR |
|
1603 #ifndef QT_NO_PROGRESSBAR |
|
1604 case CE_ProgressBarContents: |
|
1605 if (const QStyleOptionProgressBarV2 *optionProgressBar = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) { |
|
1606 QRect progressRect = optionProgressBar->rect; |
|
1607 |
|
1608 if (optionProgressBar->minimum == optionProgressBar->maximum && optionProgressBar->minimum == 0) { |
|
1609 // busy indicator |
|
1610 const QS60StylePrivate::SkinElementFlag orientationFlag = optionProgressBar->orientation == Qt::Horizontal ? |
|
1611 QS60StylePrivate::SF_PointNorth : QS60StylePrivate::SF_PointWest; |
|
1612 QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWait, painter, progressRect, flags | orientationFlag); |
|
1613 } else { |
|
1614 const qreal progressFactor = (optionProgressBar->minimum == optionProgressBar->maximum) ? 1.0 |
|
1615 : (qreal)optionProgressBar->progress / optionProgressBar->maximum; |
|
1616 if (optionProgressBar->orientation == Qt::Horizontal) { |
|
1617 progressRect.setWidth(int(progressRect.width() * progressFactor)); |
|
1618 if(optionProgressBar->direction == Qt::RightToLeft) |
|
1619 progressRect.translate(optionProgressBar->rect.width()-progressRect.width(),0); |
|
1620 progressRect.adjust(1, 0, -1, 0); |
|
1621 } else { |
|
1622 progressRect.adjust(0, 1, 0, -1); |
|
1623 progressRect.setTop(progressRect.bottom() - int(progressRect.height() * progressFactor)); |
|
1624 } |
|
1625 |
|
1626 const QS60StylePrivate::SkinElements skinElement = optionProgressBar->orientation == Qt::Horizontal ? |
|
1627 QS60StylePrivate::SE_ProgressBarIndicatorHorizontal : QS60StylePrivate::SE_ProgressBarIndicatorVertical; |
|
1628 QS60StylePrivate::drawSkinElement(skinElement, painter, progressRect, flags); |
|
1629 } |
|
1630 } |
|
1631 break; |
|
1632 case CE_ProgressBarGroove: |
|
1633 if (const QStyleOptionProgressBarV2 *optionProgressBar = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) { |
|
1634 const QS60StylePrivate::SkinElements skinElement = optionProgressBar->orientation == Qt::Horizontal ? |
|
1635 QS60StylePrivate::SE_ProgressBarGrooveHorizontal : QS60StylePrivate::SE_ProgressBarGrooveVertical; |
|
1636 QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); |
|
1637 } |
|
1638 break; |
|
1639 case CE_ProgressBarLabel: |
|
1640 if (const QStyleOptionProgressBarV2 *progressbar = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) { |
|
1641 QStyleOptionProgressBarV2 optionProgressBar = *progressbar; |
|
1642 QCommonStyle::drawItemText(painter, progressbar->rect, flags | Qt::AlignCenter | Qt::TextSingleLine, optionProgressBar.palette, |
|
1643 progressbar->state & State_Enabled, progressbar->text, QPalette::WindowText); |
|
1644 } |
|
1645 break; |
|
1646 #endif // QT_NO_PROGRESSBAR |
|
1647 #ifndef QT_NO_MENU |
|
1648 case CE_MenuItem: |
|
1649 if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { |
|
1650 QStyleOptionMenuItem optionMenuItem = *menuItem; |
|
1651 |
|
1652 bool drawSubMenuIndicator = false; |
|
1653 switch(menuItem->menuItemType) { |
|
1654 case QStyleOptionMenuItem::Scroller: |
|
1655 case QStyleOptionMenuItem::Separator: |
|
1656 return; // no separators or scrollers in S60 menus |
|
1657 case QStyleOptionMenuItem::SubMenu: |
|
1658 drawSubMenuIndicator = true; |
|
1659 break; |
|
1660 default: |
|
1661 break; |
|
1662 } |
|
1663 const bool enabled = optionMenuItem.state & State_Enabled; |
|
1664 const bool checkable = optionMenuItem.checkType != QStyleOptionMenuItem::NotCheckable; |
|
1665 |
|
1666 uint text_flags = Qt::AlignLeading | Qt::TextShowMnemonic | Qt::TextDontClip |
|
1667 | Qt::TextSingleLine | Qt::AlignVCenter; |
|
1668 if (!styleHint(SH_UnderlineShortcut, menuItem, widget)) |
|
1669 text_flags |= Qt::TextHideMnemonic; |
|
1670 |
|
1671 QRect iconRect = |
|
1672 subElementRect(SE_ItemViewItemDecoration, &optionMenuItem, widget); |
|
1673 QRect textRect = subElementRect(SE_ItemViewItemText, &optionMenuItem, widget); |
|
1674 |
|
1675 if ((option->state & State_Selected) && (option->state & State_Enabled)) |
|
1676 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags); |
|
1677 |
|
1678 //todo: move the vertical spacing stuff into subElementRect |
|
1679 const int vSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing); |
|
1680 if (checkable){ |
|
1681 QStyleOptionMenuItem optionCheckBox; |
|
1682 optionCheckBox.QStyleOption::operator=(*menuItem); |
|
1683 optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth)); |
|
1684 optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight)); |
|
1685 const int moveByX = optionCheckBox.rect.width()+vSpacing; |
|
1686 if (optionMenuItem.direction == Qt::LeftToRight) { |
|
1687 textRect.translate(moveByX,0); |
|
1688 iconRect.translate(moveByX, 0); |
|
1689 iconRect.setWidth(iconRect.width()+vSpacing); |
|
1690 textRect.setWidth(textRect.width()-moveByX-vSpacing); |
|
1691 } else { |
|
1692 textRect.setWidth(textRect.width()-moveByX); |
|
1693 iconRect.setWidth(iconRect.width()+vSpacing); |
|
1694 iconRect.translate(-optionCheckBox.rect.width()-vSpacing, 0); |
|
1695 optionCheckBox.rect.translate(textRect.width()+iconRect.width(),0); |
|
1696 } |
|
1697 drawPrimitive(PE_IndicatorMenuCheckMark, &optionCheckBox, painter, widget); |
|
1698 } |
|
1699 //draw icon and/or checkState |
|
1700 QPixmap pix = menuItem->icon.pixmap(pixelMetric(PM_SmallIconSize), |
|
1701 enabled ? QIcon::Normal : QIcon::Disabled); |
|
1702 const bool itemWithIcon = !pix.isNull(); |
|
1703 if (itemWithIcon) { |
|
1704 drawItemPixmap(painter, iconRect, text_flags, pix); |
|
1705 if (optionMenuItem.direction == Qt::LeftToRight) |
|
1706 textRect.translate(vSpacing,0); |
|
1707 else |
|
1708 textRect.translate(-vSpacing,0); |
|
1709 textRect.setWidth(textRect.width()-vSpacing); |
|
1710 } |
|
1711 |
|
1712 //draw indicators |
|
1713 if (drawSubMenuIndicator) { |
|
1714 QStyleOptionMenuItem arrowOptions; |
|
1715 arrowOptions.QStyleOption::operator=(*menuItem); |
|
1716 const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget)>>1) + |
|
1717 pixelMetric(QStyle::PM_LayoutVerticalSpacing, option, widget); |
|
1718 if (optionMenuItem.direction == Qt::LeftToRight) |
|
1719 arrowOptions.rect.setLeft(textRect.right()); |
|
1720 arrowOptions.rect.setWidth(indicatorWidth); |
|
1721 //by default sub menu indicator in S60 points to east,so here icon |
|
1722 // direction is set to north (and south when in RightToLeft) |
|
1723 const QS60StylePrivate::SkinElementFlag arrowDirection = (arrowOptions.direction == Qt::LeftToRight) ? |
|
1724 QS60StylePrivate::SF_PointNorth : QS60StylePrivate::SF_PointSouth; |
|
1725 QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnIndiSubMenu, painter, arrowOptions.rect, |
|
1726 (flags | QS60StylePrivate::SF_ColorSkinned | arrowDirection)); |
|
1727 } |
|
1728 |
|
1729 //draw text |
|
1730 if (!enabled){ |
|
1731 //In s60, if something becomes disabled, it is removed from menu, so no native look-alike available. |
|
1732 optionMenuItem.palette.setColor(QPalette::Disabled, QPalette::Text, QS60StylePrivate::lighterColor( |
|
1733 optionMenuItem.palette.color(QPalette::Disabled, QPalette::Text))); |
|
1734 painter->save(); |
|
1735 painter->setOpacity(0.5); |
|
1736 } |
|
1737 QCommonStyle::drawItemText(painter, textRect, text_flags, |
|
1738 optionMenuItem.palette, enabled, |
|
1739 optionMenuItem.text, QPalette::Text); |
|
1740 if (!enabled) |
|
1741 painter->restore(); |
|
1742 } |
|
1743 break; |
|
1744 case CE_MenuEmptyArea: |
|
1745 break; |
|
1746 #endif //QT_NO_MENU |
|
1747 |
|
1748 #ifndef QT_NO_MENUBAR |
|
1749 case CE_MenuBarEmptyArea: |
|
1750 break; |
|
1751 #endif //QT_NO_MENUBAR |
|
1752 |
|
1753 case CE_HeaderSection: |
|
1754 if ( const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { |
|
1755 painter->save(); |
|
1756 QPen linePen = QPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 1, header)); |
|
1757 const int penWidth = (header->orientation == Qt::Horizontal) ? |
|
1758 linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth) |
|
1759 : linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth); |
|
1760 linePen.setWidth(penWidth); |
|
1761 painter->setPen(linePen); |
|
1762 if (header->orientation == Qt::Horizontal){ |
|
1763 painter->drawLine(header->rect.bottomLeft(), header->rect.bottomRight()); |
|
1764 } else { |
|
1765 if ( header->direction == Qt::LeftToRight ) { |
|
1766 painter->drawLine(header->rect.topRight(), header->rect.bottomRight()); |
|
1767 } else { |
|
1768 painter->drawLine(header->rect.topLeft(), header->rect.bottomLeft()); |
|
1769 } |
|
1770 } |
|
1771 painter->restore(); |
|
1772 } |
|
1773 break; |
|
1774 case CE_HeaderEmptyArea: // no need to draw this |
|
1775 break; |
|
1776 case CE_Header: |
|
1777 if ( const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { |
|
1778 drawControl(CE_HeaderSection, header, painter, widget); |
|
1779 QStyleOptionHeader subopt = *header; |
|
1780 subopt.rect = subElementRect(SE_HeaderLabel, header, widget); |
|
1781 if (subopt.rect.isValid()) |
|
1782 drawControl(CE_HeaderLabel, &subopt, painter, widget); |
|
1783 if (header->sortIndicator != QStyleOptionHeader::None) { |
|
1784 subopt.rect = subElementRect(SE_HeaderArrow, option, widget); |
|
1785 drawPrimitive(PE_IndicatorHeaderArrow, &subopt, painter, widget); |
|
1786 } |
|
1787 } |
|
1788 break; |
|
1789 #ifndef QT_NO_TOOLBAR |
|
1790 case CE_ToolBar: |
|
1791 if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) { |
|
1792 const QToolBar *tbWidget = qobject_cast<const QToolBar *>(widget); |
|
1793 |
|
1794 //toolbar within a toolbar, skip |
|
1795 if (!tbWidget || (widget && qobject_cast<QToolBar *>(widget->parentWidget()))) |
|
1796 break; |
|
1797 |
|
1798 // Normally in S60 5.0+ there is no background for toolbar, but in some cases with versatile QToolBar, |
|
1799 // it looks a bit strange. So, lets fillRect with Button. |
|
1800 if (!QS60StylePrivate::isToolBarBackground()) { |
|
1801 QList<QAction *> actions = tbWidget->actions(); |
|
1802 bool justToolButtonsInToolBar = true; |
|
1803 for (int i = 0; i < actions.size(); ++i) { |
|
1804 QWidget *childWidget = tbWidget->widgetForAction(actions.at(i)); |
|
1805 const QToolButton *button = qobject_cast<const QToolButton *>(childWidget); |
|
1806 if (!button){ |
|
1807 justToolButtonsInToolBar = false; |
|
1808 } |
|
1809 } |
|
1810 |
|
1811 // Draw frame background |
|
1812 // for vertical toolbars with text only and |
|
1813 // for toolbars with extension buttons and |
|
1814 // for toolbars with widgets in them. |
|
1815 if (!justToolButtonsInToolBar || |
|
1816 (tbWidget && |
|
1817 (tbWidget->orientation() == Qt::Vertical) && |
|
1818 (tbWidget->toolButtonStyle() == Qt::ToolButtonTextOnly))) { |
|
1819 painter->save(); |
|
1820 if (widget) |
|
1821 painter->setBrush(widget->palette().button()); |
|
1822 painter->setOpacity(0.3); |
|
1823 painter->fillRect(toolBar->rect, painter->brush()); |
|
1824 painter->restore(); |
|
1825 } |
|
1826 } else { |
|
1827 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBar, painter, toolBar->rect, flags); |
|
1828 } |
|
1829 } |
|
1830 break; |
|
1831 #endif //QT_NO_TOOLBAR |
|
1832 case CE_ShapedFrame: |
|
1833 if (qobject_cast<const QTextEdit *>(widget)) { |
|
1834 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_Editor, painter, option->rect, flags); |
|
1835 } else if (qobject_cast<const QTableView *>(widget)) { |
|
1836 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableItem, painter, option->rect, flags); |
|
1837 } else if (const QHeaderView *header = qobject_cast<const QHeaderView *>(widget)) { |
|
1838 if (header->orientation() == Qt::Horizontal) { |
|
1839 QRect headerRect = option->rect; |
|
1840 const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); |
|
1841 headerRect.adjust(0,frameWidth,-2*frameWidth,0); |
|
1842 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableHeaderItem, painter, headerRect, flags); |
|
1843 } else { |
|
1844 //todo: update to horizontal table graphic |
|
1845 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableHeaderItem, painter, option->rect, flags | QS60StylePrivate::SF_PointWest); |
|
1846 } |
|
1847 } else if (qobject_cast<const QFrame *>(widget)) { |
|
1848 QCommonStyle::drawControl(element, option, painter, widget); |
|
1849 } |
|
1850 break; |
|
1851 case CE_MenuScroller: |
|
1852 break; |
|
1853 case CE_FocusFrame: |
|
1854 { |
|
1855 // The pen width should nearly fill the layoutspacings around the widget |
|
1856 const int penWidth = |
|
1857 qMin(pixelMetric(QS60Style::PM_LayoutVerticalSpacing), pixelMetric(QS60Style::PM_LayoutHorizontalSpacing)) |
|
1858 - 2; // But keep 1 pixel distance to the focus widget and 1 pixel to the adjacent widgets |
|
1859 |
|
1860 #ifdef QT_KEYPAD_NAVIGATION |
|
1861 bool editFocus = false; |
|
1862 if (const QFocusFrame *focusFrame = qobject_cast<const QFocusFrame*>(widget)) { |
|
1863 if (focusFrame->widget() && focusFrame->widget()->hasEditFocus()) |
|
1864 editFocus = true; |
|
1865 } |
|
1866 const qreal opacity = editFocus ? 0.65 : 0.45; // Trial and error factors. Feel free to improve. |
|
1867 #else |
|
1868 const qreal opacity = 0.5; |
|
1869 #endif |
|
1870 // Because of Qts coordinate system, we need to tweak the rect by .5 pixels, otherwise it gets blurred. |
|
1871 const qreal rectAdjustment = (penWidth % 2) ? -.5 : 0; |
|
1872 |
|
1873 // Make sure that the pen stroke is inside the rect |
|
1874 const QRectF adjustedRect = |
|
1875 QRectF(option->rect).adjusted( |
|
1876 rectAdjustment + penWidth, |
|
1877 rectAdjustment + penWidth, |
|
1878 -rectAdjustment - penWidth, |
|
1879 -rectAdjustment - penWidth |
|
1880 ); |
|
1881 |
|
1882 const qreal roundRectRadius = penWidth * goldenRatio; |
|
1883 |
|
1884 painter->save(); |
|
1885 painter->setRenderHint(QPainter::Antialiasing); |
|
1886 painter->setOpacity(opacity); |
|
1887 painter->setPen(QPen(option->palette.color(QPalette::Text), penWidth)); |
|
1888 painter->drawRoundedRect(adjustedRect, roundRectRadius, roundRectRadius); |
|
1889 painter->restore(); |
|
1890 } |
|
1891 break; |
|
1892 default: |
|
1893 QCommonStyle::drawControl(element, option, painter, widget); |
|
1894 } |
|
1895 } |
|
1896 |
|
1897 /*! |
|
1898 \reimp |
|
1899 */ |
|
1900 void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const |
|
1901 { |
|
1902 const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled; |
|
1903 switch (element) { |
|
1904 #ifndef QT_NO_LINEEDIT |
|
1905 case PE_PanelLineEdit: |
|
1906 if (const QStyleOptionFrame *lineEdit = qstyleoption_cast<const QStyleOptionFrame *>(option)) { |
|
1907 #ifndef QT_NO_COMBOBOX |
|
1908 if (widget && qobject_cast<const QComboBox *>(widget->parentWidget())) |
|
1909 break; |
|
1910 #endif |
|
1911 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_FrameLineEdit, |
|
1912 painter, option->rect, flags); |
|
1913 } |
|
1914 break; |
|
1915 #endif // QT_NO_LINEEDIT |
|
1916 case PE_IndicatorCheckBox: |
|
1917 { |
|
1918 const QRect indicatorRect = option->rect; |
|
1919 // Draw checkbox indicator as color skinned graphics. |
|
1920 const QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ? |
|
1921 QS60StyleEnums::SP_QgnIndiCheckboxOn : QS60StyleEnums::SP_QgnIndiCheckboxOff; |
|
1922 QS60StylePrivate::drawSkinPart(skinPart, painter, indicatorRect, |
|
1923 (flags | QS60StylePrivate::SF_ColorSkinned)); |
|
1924 } |
|
1925 break; |
|
1926 case PE_IndicatorViewItemCheck: |
|
1927 #ifndef QT_NO_ITEMVIEWS |
|
1928 if (const QListView *listItem = (qobject_cast<const QListView *>(widget))) { |
|
1929 if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) { |
|
1930 const bool checkBoxVisible = vopt->features & QStyleOptionViewItemV2::HasCheckIndicator; |
|
1931 const bool singleSelection = listItem->selectionMode() == |
|
1932 QAbstractItemView::SingleSelection || listItem->selectionMode() == QAbstractItemView::NoSelection; |
|
1933 // draw either checkbox at the beginning |
|
1934 if (checkBoxVisible && singleSelection) { |
|
1935 drawPrimitive(PE_IndicatorCheckBox, option, painter, widget); |
|
1936 // ... or normal "tick" selection at the end. |
|
1937 } else if (option->state & QStyle::State_Selected) { |
|
1938 QRect tickRect = option->rect; |
|
1939 const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth); |
|
1940 // adjust tickmark rect to exclude frame border |
|
1941 tickRect.adjust(0,-frameBorderWidth,0,-frameBorderWidth); |
|
1942 QS60StyleEnums::SkinParts skinPart = QS60StyleEnums::SP_QgnIndiMarkedAdd; |
|
1943 QS60StylePrivate::drawSkinPart(skinPart, painter, tickRect, |
|
1944 (flags | QS60StylePrivate::SF_ColorSkinned)); |
|
1945 } |
|
1946 } |
|
1947 } |
|
1948 #endif //QT_NO_ITEMVIEWS |
|
1949 break; |
|
1950 case PE_IndicatorRadioButton: { |
|
1951 QRect buttonRect = option->rect; |
|
1952 //there is empty (a. 33%) space in svg graphics for radiobutton |
|
1953 const qreal reduceWidth = (qreal)buttonRect.width()/3.0; |
|
1954 const qreal rectWidth = (qreal)option->rect.width() != 0 ? option->rect.width() : 1.0; |
|
1955 // Try to occupy the full area |
|
1956 const qreal scaler = 1 + (reduceWidth/rectWidth); |
|
1957 buttonRect.setWidth((int)((buttonRect.width()-reduceWidth) * scaler)); |
|
1958 buttonRect.setHeight((int)(buttonRect.height() * scaler)); |
|
1959 // move the rect up for half of the new height-gain |
|
1960 const int newY = (buttonRect.bottomRight().y() - option->rect.bottomRight().y()) >> 1 ; |
|
1961 buttonRect.adjust(0,-newY,0,-newY); |
|
1962 |
|
1963 // Draw radiobutton indicator as color skinned graphics. |
|
1964 QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ? |
|
1965 QS60StyleEnums::SP_QgnIndiRadiobuttOn : QS60StyleEnums::SP_QgnIndiRadiobuttOff; |
|
1966 QS60StylePrivate::drawSkinPart(skinPart, painter, buttonRect, |
|
1967 (flags | QS60StylePrivate::SF_ColorSkinned)); |
|
1968 } |
|
1969 break; |
|
1970 case PE_PanelButtonCommand: |
|
1971 case PE_PanelButtonTool: |
|
1972 case PE_PanelButtonBevel: |
|
1973 case PE_FrameButtonBevel: { |
|
1974 const bool isPressed = option->state & QStyle::State_Sunken; |
|
1975 const QS60StylePrivate::SkinElements skinElement = |
|
1976 isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal; |
|
1977 QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); |
|
1978 } |
|
1979 break; |
|
1980 #ifndef QT_NO_TOOLBUTTON |
|
1981 case PE_IndicatorArrowDown: |
|
1982 case PE_IndicatorArrowLeft: |
|
1983 case PE_IndicatorArrowRight: |
|
1984 case PE_IndicatorArrowUp: { |
|
1985 QS60StyleEnums::SkinParts skinPart; |
|
1986 if (element==PE_IndicatorArrowDown) |
|
1987 skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowDown; |
|
1988 else if (element==PE_IndicatorArrowLeft) |
|
1989 skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowLeft; |
|
1990 else if (element==PE_IndicatorArrowRight) |
|
1991 skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowRight; |
|
1992 else if (element==PE_IndicatorArrowUp) |
|
1993 skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowUp; |
|
1994 |
|
1995 QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags); |
|
1996 } |
|
1997 break; |
|
1998 #endif //QT_NO_TOOLBUTTON |
|
1999 #ifndef QT_NO_SPINBOX |
|
2000 case PE_IndicatorSpinDown: |
|
2001 case PE_IndicatorSpinUp: |
|
2002 if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { |
|
2003 QStyleOptionSpinBox optionSpinBox = *spinBox; |
|
2004 const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ? |
|
2005 QS60StyleEnums::SP_QgnGrafScrollArrowUp : |
|
2006 QS60StyleEnums::SP_QgnGrafScrollArrowDown; |
|
2007 const int adjustment = qMin(optionSpinBox.rect.width(), optionSpinBox.rect.height())/6; |
|
2008 optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment ); |
|
2009 QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect,flags); |
|
2010 } |
|
2011 #ifndef QT_NO_COMBOBOX |
|
2012 else if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) { |
|
2013 // We want to draw down arrow here for comboboxes as well. |
|
2014 const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown; |
|
2015 QStyleOptionFrame comboBox = *cmb; |
|
2016 const int adjustment = qMin(comboBox.rect.width(), comboBox.rect.height())/6; |
|
2017 comboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment ); |
|
2018 QS60StylePrivate::drawSkinPart(part, painter, comboBox.rect,flags); |
|
2019 } |
|
2020 #endif //QT_NO_COMBOBOX |
|
2021 break; |
|
2022 case PE_IndicatorSpinMinus: |
|
2023 case PE_IndicatorSpinPlus: |
|
2024 if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { |
|
2025 QStyleOptionSpinBox optionSpinBox = *spinBox; |
|
2026 QCommonStyle::drawPrimitive(element, &optionSpinBox, painter, widget); |
|
2027 } |
|
2028 #ifndef QT_NO_COMBOBOX |
|
2029 else if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) { |
|
2030 // We want to draw down arrow here for comboboxes as well. |
|
2031 QStyleOptionFrame comboBox = *cmb; |
|
2032 const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); |
|
2033 comboBox.rect.adjust(0,frameWidth,0,-frameWidth); |
|
2034 QCommonStyle::drawPrimitive(element, &comboBox, painter, widget); |
|
2035 } |
|
2036 #endif //QT_NO_COMBOBOX |
|
2037 break; |
|
2038 #endif //QT_NO_SPINBOX |
|
2039 case PE_Widget: |
|
2040 if (QS60StylePrivate::drawsOwnThemeBackground(widget) |
|
2041 #ifndef QT_NO_COMBOBOX |
|
2042 || qobject_cast<const QComboBoxListView *>(widget) |
|
2043 #endif //QT_NO_COMBOBOX |
|
2044 #ifndef QT_NO_MENU |
|
2045 || qobject_cast<const QMenu *> (widget) |
|
2046 #endif //QT_NO_MENU |
|
2047 ) { |
|
2048 QS60StylePrivate::SkinElements skinElement = QS60StylePrivate::SE_OptionsMenu; |
|
2049 QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); |
|
2050 } |
|
2051 break; |
|
2052 case PE_FrameWindow: |
|
2053 case PE_FrameTabWidget: |
|
2054 if (const QStyleOptionTabWidgetFrame *tabFrame = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) { |
|
2055 QStyleOptionTabWidgetFrame optionTabFrame = *tabFrame; |
|
2056 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PanelBackground, painter, optionTabFrame.rect, flags); |
|
2057 } |
|
2058 break; |
|
2059 case PE_IndicatorHeaderArrow: |
|
2060 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { |
|
2061 if (header->sortIndicator & QStyleOptionHeader::SortUp) |
|
2062 drawPrimitive(PE_IndicatorArrowUp, header, painter, widget); |
|
2063 else if (header->sortIndicator & QStyleOptionHeader::SortDown) |
|
2064 drawPrimitive(PE_IndicatorArrowDown, header, painter, widget); |
|
2065 } // QStyleOptionHeader::None is not drawn => not needed |
|
2066 break; |
|
2067 #ifndef QT_NO_GROUPBOX |
|
2068 case PE_FrameGroupBox: |
|
2069 if (const QStyleOptionFrameV2 *frame = qstyleoption_cast<const QStyleOptionFrameV2 *>(option)) |
|
2070 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_SettingsList, painter, frame->rect, flags); |
|
2071 break; |
|
2072 #endif //QT_NO_GROUPBOX |
|
2073 |
|
2074 // Qt3 primitives are not supported |
|
2075 case PE_Q3CheckListController: |
|
2076 case PE_Q3CheckListExclusiveIndicator: |
|
2077 case PE_Q3CheckListIndicator: |
|
2078 case PE_Q3DockWindowSeparator: |
|
2079 case PE_Q3Separator: |
|
2080 Q_ASSERT(false); |
|
2081 break; |
|
2082 case PE_Frame: |
|
2083 break; |
|
2084 #ifndef QT_NO_ITEMVIEWS |
|
2085 case PE_PanelItemViewItem: |
|
2086 case PE_PanelItemViewRow: // ### Qt 5: remove |
|
2087 break; |
|
2088 #endif //QT_NO_ITEMVIEWS |
|
2089 |
|
2090 case PE_IndicatorMenuCheckMark: |
|
2091 if (const QStyleOptionMenuItem *checkBox = qstyleoption_cast<const QStyleOptionMenuItem *>(option)){ |
|
2092 QStyleOptionMenuItem optionCheckBox = *checkBox; |
|
2093 if (optionCheckBox.checked) |
|
2094 optionCheckBox.state = (optionCheckBox.state | State_On); |
|
2095 drawPrimitive(PE_IndicatorCheckBox, &optionCheckBox, painter, widget); |
|
2096 } |
|
2097 break; |
|
2098 #ifndef QT_NO_TOOLBAR |
|
2099 case PE_IndicatorToolBarHandle: |
|
2100 // no toolbar handles in S60/AVKON UI |
|
2101 case PE_IndicatorToolBarSeparator: |
|
2102 // no separators in S60/AVKON UI |
|
2103 break; |
|
2104 #endif //QT_NO_TOOLBAR |
|
2105 |
|
2106 case PE_PanelMenuBar: |
|
2107 case PE_FrameMenu: |
|
2108 break; //disable frame in menu |
|
2109 |
|
2110 case PE_IndicatorBranch: |
|
2111 #if defined(Q_WS_S60) |
|
2112 // 3.1 AVKON UI does not have tree view component, use common style for drawing there |
|
2113 if (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1) { |
|
2114 #else |
|
2115 if (true) { |
|
2116 #endif |
|
2117 QCommonStyle::drawPrimitive(element, option, painter, widget); |
|
2118 } else { |
|
2119 const bool rightLine = option->state & State_Item; |
|
2120 const bool downLine = option->state & State_Sibling; |
|
2121 const bool upLine = option->state & (State_Open | State_Children | State_Item | State_Sibling); |
|
2122 |
|
2123 QS60StyleEnums::SkinParts skinPart; |
|
2124 bool drawSkinPart = false; |
|
2125 if (rightLine && downLine && upLine) { |
|
2126 skinPart = QS60StyleEnums::SP_QgnIndiHlLineBranch; |
|
2127 drawSkinPart = true; |
|
2128 } else if (rightLine && upLine) { |
|
2129 skinPart = QS60StyleEnums::SP_QgnIndiHlLineEnd; |
|
2130 drawSkinPart = true; |
|
2131 } else if (upLine && downLine) { |
|
2132 skinPart = QS60StyleEnums::SP_QgnIndiHlLineStraight; |
|
2133 drawSkinPart = true; |
|
2134 } |
|
2135 |
|
2136 if ( drawSkinPart ) |
|
2137 QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags); |
|
2138 |
|
2139 if (option->state & State_Children) { |
|
2140 QS60StyleEnums::SkinParts skinPart = |
|
2141 (option->state & State_Open) ? QS60StyleEnums::SP_QgnIndiHlColSuper : QS60StyleEnums::SP_QgnIndiHlExpSuper; |
|
2142 int minDimension = qMin(option->rect.width(), option->rect.height()); |
|
2143 const int resizeValue = minDimension >> 1; |
|
2144 minDimension += resizeValue; // Adjust the icon bigger because of empty space in svg icon. |
|
2145 QRect iconRect(option->rect.topLeft(), QSize(minDimension, minDimension)); |
|
2146 int verticalMagic(0); |
|
2147 // magic values for positioning svg icon. |
|
2148 if (option->rect.width() <= option->rect.height()) |
|
2149 verticalMagic = 3; |
|
2150 iconRect.translate(3, verticalMagic - resizeValue); |
|
2151 QS60StylePrivate::drawSkinPart(skinPart, painter, iconRect, flags); |
|
2152 } |
|
2153 } |
|
2154 break; |
|
2155 |
|
2156 // todo: items are below with #ifdefs "just in case". in final version, remove all non-required cases |
|
2157 case PE_FrameLineEdit: |
|
2158 case PE_IndicatorButtonDropDown: |
|
2159 case PE_IndicatorDockWidgetResizeHandle: |
|
2160 case PE_PanelTipLabel: |
|
2161 case PE_PanelScrollAreaCorner: |
|
2162 |
|
2163 #ifndef QT_NO_TABBAR |
|
2164 case PE_IndicatorTabTear: // No tab tear in S60 |
|
2165 #endif // QT_NO_TABBAR |
|
2166 case PE_FrameDefaultButton: |
|
2167 #ifndef QT_NO_DOCKWIDGET |
|
2168 case PE_FrameDockWidget: |
|
2169 #endif //QT_NO_DOCKWIDGET |
|
2170 #ifndef QT_NO_PROGRESSBAR |
|
2171 case PE_IndicatorProgressChunk: |
|
2172 #endif //QT_NO_PROGRESSBAR |
|
2173 #ifndef QT_NO_TOOLBAR |
|
2174 case PE_PanelToolBar: |
|
2175 #endif //QT_NO_TOOLBAR |
|
2176 #ifndef QT_NO_COLUMNVIEW |
|
2177 case PE_IndicatorColumnViewArrow: |
|
2178 case PE_IndicatorItemViewItemDrop: |
|
2179 #endif //QT_NO_COLUMNVIEW |
|
2180 case PE_FrameTabBarBase: // since tabs are in S60 always in navipane, let's use common style for tab base in Qt. |
|
2181 default: |
|
2182 QCommonStyle::drawPrimitive(element, option, painter, widget); |
|
2183 } |
|
2184 } |
|
2185 |
|
2186 /*! \reimp */ |
|
2187 int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const |
|
2188 { |
|
2189 int metricValue = QS60StylePrivate::pixelMetric(metric); |
|
2190 if (metricValue == KNotFound) |
|
2191 metricValue = QCommonStyle::pixelMetric(metric, option, widget); |
|
2192 |
|
2193 if (metric == PM_SubMenuOverlap && widget){ |
|
2194 const QMenu *menu = qobject_cast<const QMenu *>(widget); |
|
2195 if (menu && menu->activeAction() && menu->activeAction()->menu()) { |
|
2196 const int menuWidth = menu->activeAction()->menu()->sizeHint().width(); |
|
2197 metricValue = -menuWidth; |
|
2198 } |
|
2199 } |
|
2200 return metricValue; |
|
2201 } |
|
2202 |
|
2203 /*! \reimp */ |
|
2204 QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, |
|
2205 const QSize &csz, const QWidget *widget) const |
|
2206 { |
|
2207 QSize sz(csz); |
|
2208 switch (ct) { |
|
2209 case CT_PushButton: |
|
2210 sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); |
|
2211 if (const QAbstractButton *buttonWidget = (qobject_cast<const QAbstractButton *>(widget))) |
|
2212 if (buttonWidget->isCheckable()) |
|
2213 sz += QSize(pixelMetric(PM_IndicatorWidth) + pixelMetric(PM_CheckBoxLabelSpacing), 0); |
|
2214 break; |
|
2215 case CT_LineEdit: |
|
2216 if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) |
|
2217 sz += QSize(2*f->lineWidth, 4*f->lineWidth); |
|
2218 break; |
|
2219 case CT_TabBarTab: |
|
2220 QSize naviPaneSize = QS60StylePrivate::naviPaneSize(); |
|
2221 sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); |
|
2222 if (naviPaneSize.height() > sz.height()) |
|
2223 sz.setHeight(naviPaneSize.height()); |
|
2224 break; |
|
2225 default: |
|
2226 sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); |
|
2227 break; |
|
2228 } |
|
2229 return sz; |
|
2230 } |
|
2231 |
|
2232 /*! \reimp */ |
|
2233 int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *widget, |
|
2234 QStyleHintReturn *hret) const |
|
2235 { |
|
2236 int retValue = -1; |
|
2237 switch (sh) { |
|
2238 case SH_Table_GridLineColor: |
|
2239 retValue = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors,2,0).rgb(); |
|
2240 break; |
|
2241 case SH_GroupBox_TextLabelColor: |
|
2242 retValue = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors,6,0).rgb(); |
|
2243 break; |
|
2244 case SH_ScrollBar_ScrollWhenPointerLeavesControl: |
|
2245 retValue = true; |
|
2246 break; |
|
2247 case SH_Slider_SnapToValue: |
|
2248 retValue = true; |
|
2249 break; |
|
2250 case SH_Slider_StopMouseOverSlider: |
|
2251 retValue = true; |
|
2252 break; |
|
2253 case SH_LineEdit_PasswordCharacter: |
|
2254 retValue = '*'; |
|
2255 break; |
|
2256 case SH_ComboBox_PopupFrameStyle: |
|
2257 retValue = QFrame::NoFrame | QFrame::Plain; |
|
2258 break; |
|
2259 case SH_Dial_BackgroundRole: |
|
2260 retValue = QPalette::Base; |
|
2261 break; |
|
2262 case SH_ItemView_ActivateItemOnSingleClick: |
|
2263 retValue = true; |
|
2264 break; |
|
2265 case SH_ProgressDialog_TextLabelAlignment: |
|
2266 retValue = (QApplication::layoutDirection() == Qt::LeftToRight) ? |
|
2267 Qt::AlignLeft : |
|
2268 Qt::AlignRight; |
|
2269 break; |
|
2270 case SH_Menu_SubMenuPopupDelay: |
|
2271 retValue = 300; |
|
2272 break; |
|
2273 case SH_Menu_Scrollable: |
|
2274 retValue = true; |
|
2275 break; |
|
2276 case SH_Menu_SelectionWrap: |
|
2277 retValue = true; |
|
2278 break; |
|
2279 case SH_ItemView_ShowDecorationSelected: |
|
2280 retValue = true; |
|
2281 break; |
|
2282 case SH_ToolBar_Movable: |
|
2283 retValue = false; |
|
2284 break; |
|
2285 case SH_BlinkCursorWhenTextSelected: |
|
2286 retValue = true; |
|
2287 break; |
|
2288 case SH_UnderlineShortcut: |
|
2289 retValue = 0; |
|
2290 break; |
|
2291 case SH_RequestSoftwareInputPanel: |
|
2292 retValue = RSIP_OnMouseClickAndAlreadyFocused; |
|
2293 break; |
|
2294 default: |
|
2295 break; |
|
2296 } |
|
2297 if (retValue == -1) |
|
2298 retValue = QCommonStyle::styleHint(sh, opt, widget, hret); |
|
2299 return retValue; |
|
2300 } |
|
2301 |
|
2302 /*! \reimp */ |
|
2303 QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl scontrol, const QWidget *widget) const |
|
2304 { |
|
2305 QRect ret; |
|
2306 switch (control) { |
|
2307 #ifndef QT_NO_SCROLLBAR |
|
2308 // This implementation of subControlRect(CC_ScrollBar..) basically just removes the SC_ScrollBarSubLine and SC_ScrollBarAddLine |
|
2309 case CC_ScrollBar: |
|
2310 if (const QStyleOptionSlider *scrollbarOption = qstyleoption_cast<const QStyleOptionSlider *>(option)) { |
|
2311 const QRect scrollBarRect = scrollbarOption->rect; |
|
2312 const bool isHorizontal = scrollbarOption->orientation == Qt::Horizontal; |
|
2313 const int maxlen = isHorizontal ? scrollBarRect.width() : scrollBarRect.height(); |
|
2314 int sliderlen; |
|
2315 |
|
2316 // calculate slider length |
|
2317 if (scrollbarOption->maximum != scrollbarOption->minimum) { |
|
2318 const uint range = scrollbarOption->maximum - scrollbarOption->minimum; |
|
2319 sliderlen = (qint64(scrollbarOption->pageStep) * maxlen) / (range + scrollbarOption->pageStep); |
|
2320 |
|
2321 const int slidermin = pixelMetric(PM_ScrollBarSliderMin, scrollbarOption, widget); |
|
2322 if (sliderlen < slidermin || range > (INT_MAX>>1)) |
|
2323 sliderlen = slidermin; |
|
2324 if (sliderlen > maxlen) |
|
2325 sliderlen = maxlen; |
|
2326 } else { |
|
2327 sliderlen = maxlen; |
|
2328 } |
|
2329 |
|
2330 const int sliderstart = sliderPositionFromValue(scrollbarOption->minimum, |
|
2331 scrollbarOption->maximum, |
|
2332 scrollbarOption->sliderPosition, |
|
2333 maxlen - sliderlen, |
|
2334 scrollbarOption->upsideDown); |
|
2335 |
|
2336 switch (scontrol) { |
|
2337 case SC_ScrollBarSubPage: // between top/left button and slider |
|
2338 if (isHorizontal) |
|
2339 ret.setRect(0, 0, sliderstart, scrollBarRect.height()); |
|
2340 else |
|
2341 ret.setRect(0, 0, scrollBarRect.width(), sliderstart); |
|
2342 break; |
|
2343 case SC_ScrollBarAddPage: { // between bottom/right button and slider |
|
2344 const int addPageLength = sliderstart + sliderlen; |
|
2345 if (isHorizontal) |
|
2346 ret = scrollBarRect.adjusted(addPageLength, 0, 0, 0); |
|
2347 else |
|
2348 ret = scrollBarRect.adjusted(0, addPageLength, 0, 0); |
|
2349 } |
|
2350 break; |
|
2351 case SC_ScrollBarGroove: |
|
2352 ret = scrollBarRect; |
|
2353 break; |
|
2354 case SC_ScrollBarSlider: |
|
2355 if (scrollbarOption->orientation == Qt::Horizontal) |
|
2356 ret.setRect(sliderstart, 0, sliderlen, scrollBarRect.height()); |
|
2357 else |
|
2358 ret.setRect(0, sliderstart, scrollBarRect.width(), sliderlen); |
|
2359 break; |
|
2360 case SC_ScrollBarSubLine: // top/left button |
|
2361 case SC_ScrollBarAddLine: // bottom/right button |
|
2362 default: |
|
2363 break; |
|
2364 } |
|
2365 ret = visualRect(scrollbarOption->direction, scrollBarRect, ret); |
|
2366 } |
|
2367 break; |
|
2368 #endif // QT_NO_SCROLLBAR |
|
2369 case CC_SpinBox: |
|
2370 if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { |
|
2371 const int frameThickness = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0; |
|
2372 const int buttonMargin = spinbox->frame ? 2 : 0; |
|
2373 const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2*buttonMargin; |
|
2374 QSize buttonSize; |
|
2375 buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness)); |
|
2376 buttonSize.setWidth(buttonWidth); |
|
2377 buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); |
|
2378 |
|
2379 const int y = frameThickness + spinbox->rect.y(); |
|
2380 const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2*buttonSize.width(); |
|
2381 |
|
2382 switch (scontrol) { |
|
2383 case SC_SpinBoxUp: |
|
2384 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) |
|
2385 return QRect(); |
|
2386 ret = QRect(x, y, buttonWidth, buttonSize.height()); |
|
2387 break; |
|
2388 case SC_SpinBoxDown: |
|
2389 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) |
|
2390 return QRect(); |
|
2391 ret = QRect(x+buttonSize.width(), y, buttonWidth, buttonSize.height()); |
|
2392 break; |
|
2393 case SC_SpinBoxEditField: |
|
2394 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) |
|
2395 ret = QRect( |
|
2396 frameThickness, |
|
2397 frameThickness, |
|
2398 spinbox->rect.width() - 2*frameThickness, |
|
2399 spinbox->rect.height() - 2*frameThickness); |
|
2400 else |
|
2401 ret = QRect( |
|
2402 frameThickness, |
|
2403 frameThickness, |
|
2404 x - frameThickness, |
|
2405 spinbox->rect.height() - 2*frameThickness); |
|
2406 break; |
|
2407 case SC_SpinBoxFrame: |
|
2408 ret = spinbox->rect; |
|
2409 break; |
|
2410 default: |
|
2411 break; |
|
2412 } |
|
2413 ret = visualRect(spinbox->direction, spinbox->rect, ret); |
|
2414 } |
|
2415 break; |
|
2416 case CC_ComboBox: |
|
2417 if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { |
|
2418 ret = cmb->rect; |
|
2419 const int width = cmb->rect.width(); |
|
2420 const int height = cmb->rect.height(); |
|
2421 const int buttonMargin = cmb->frame ? 2 : 0; |
|
2422 // lets use spinbox frame here as well, as no combobox specific value available. |
|
2423 const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0; |
|
2424 const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize); |
|
2425 |
|
2426 QSize buttonSize; |
|
2427 buttonSize.setHeight(qMax(8, (cmb->rect.height()>>1) - frameThickness)); //minimum of 8 pixels |
|
2428 buttonSize.setWidth(buttonWidth+2*buttonMargin); |
|
2429 buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); |
|
2430 switch (scontrol) { |
|
2431 case SC_ComboBoxArrow: |
|
2432 ret.setRect( |
|
2433 ret.x() + ret.width() - buttonMargin - buttonWidth, |
|
2434 ret.y() + buttonMargin, |
|
2435 buttonWidth, |
|
2436 height - 2*buttonMargin); |
|
2437 break; |
|
2438 case SC_ComboBoxEditField: { |
|
2439 ret.setRect( |
|
2440 ret.x() + frameThickness, |
|
2441 ret.y() + frameThickness, |
|
2442 ret.width() - 2*frameThickness - buttonSize.width(), |
|
2443 ret.height() - 2*frameThickness); |
|
2444 } |
|
2445 break; |
|
2446 default: |
|
2447 break; |
|
2448 } |
|
2449 } |
|
2450 break; |
|
2451 case CC_GroupBox: |
|
2452 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) { |
|
2453 ret = QCommonStyle::subControlRect(control, option, scontrol, widget); |
|
2454 switch (scontrol) { |
|
2455 case SC_GroupBoxCheckBox: //fallthrough |
|
2456 case SC_GroupBoxLabel: { |
|
2457 //slightly indent text and boxes, so that dialog border does not mess with them. |
|
2458 const int horizontalSpacing = |
|
2459 QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); |
|
2460 ret.adjust(2,horizontalSpacing-3,0,0); |
|
2461 } |
|
2462 break; |
|
2463 case SC_GroupBoxFrame: { |
|
2464 const QRect textBox = subControlRect(control, option, SC_GroupBoxLabel, widget); |
|
2465 const int tbHeight = textBox.height(); |
|
2466 ret.translate(0, -ret.y()); |
|
2467 // include title to within the groupBox frame |
|
2468 ret.setHeight(ret.height()+tbHeight); |
|
2469 if (widget && ret.bottom() > widget->rect().bottom()) |
|
2470 ret.setBottom(widget->rect().bottom()); |
|
2471 } |
|
2472 break; |
|
2473 default: |
|
2474 break; |
|
2475 } |
|
2476 } |
|
2477 break; |
|
2478 default: |
|
2479 ret = QCommonStyle::subControlRect(control, option, scontrol, widget); |
|
2480 } |
|
2481 return ret; |
|
2482 } |
|
2483 |
|
2484 /*! |
|
2485 \reimp |
|
2486 */ |
|
2487 QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, const QWidget *widget) const |
|
2488 { |
|
2489 QRect ret; |
|
2490 switch (element) { |
|
2491 case SE_LineEditContents: { |
|
2492 // in S60 the input text box doesn't start from line Edit's TL, but |
|
2493 // a bit indented. |
|
2494 QRect lineEditRect = opt->rect; |
|
2495 const int adjustment = opt->rect.height()>>2; |
|
2496 lineEditRect.adjust(adjustment,0,0,0); |
|
2497 ret = lineEditRect; |
|
2498 } |
|
2499 break; |
|
2500 case SE_TabBarTearIndicator: |
|
2501 ret = QRect(0,0,0,0); |
|
2502 break; |
|
2503 case SE_TabWidgetTabBar: |
|
2504 if (const QStyleOptionTabWidgetFrame *optionTab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { |
|
2505 ret = QCommonStyle::subElementRect(element, opt, widget); |
|
2506 |
|
2507 if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { |
|
2508 const int tabOverlapNoBorder = |
|
2509 QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap); |
|
2510 const int tabOverlap = |
|
2511 tabOverlapNoBorder-QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); |
|
2512 const QTabWidget *tab = qobject_cast<const QTabWidget *>(widget); |
|
2513 int gain = (tab) ? tabOverlap * tab->count() : 0; |
|
2514 switch (twf->shape) { |
|
2515 case QTabBar::RoundedNorth: |
|
2516 case QTabBar::TriangularNorth: |
|
2517 case QTabBar::RoundedSouth: |
|
2518 case QTabBar::TriangularSouth: { |
|
2519 if (widget) { |
|
2520 // make sure that gain does not set the rect outside of widget boundaries |
|
2521 if (twf->direction == Qt::RightToLeft) { |
|
2522 if ((ret.left() - gain) < widget->rect().left()) |
|
2523 gain = widget->rect().left()-ret.left(); |
|
2524 ret.adjust(-gain,0,0,0); |
|
2525 } else { |
|
2526 if ((ret.right() + gain) > widget->rect().right()) |
|
2527 gain = widget->rect().right()-ret.right(); |
|
2528 ret.adjust(0,0,gain,0); |
|
2529 } |
|
2530 } |
|
2531 break; |
|
2532 } |
|
2533 default: { |
|
2534 if (widget) { |
|
2535 if ((ret.bottom() + gain) > widget->rect().bottom()) |
|
2536 gain = widget->rect().bottom()-ret.bottom(); |
|
2537 ret.adjust(0,0,0,gain); |
|
2538 } |
|
2539 break; |
|
2540 } |
|
2541 } |
|
2542 } |
|
2543 } |
|
2544 break; |
|
2545 case SE_ItemViewItemText: |
|
2546 case SE_ItemViewItemDecoration: |
|
2547 if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) { |
|
2548 const QListWidget *listItem = qobject_cast<const QListWidget *>(widget); |
|
2549 const bool multiSelection = !listItem ? false : |
|
2550 listItem->selectionMode() == QAbstractItemView::MultiSelection || |
|
2551 listItem->selectionMode() == QAbstractItemView::ExtendedSelection || |
|
2552 listItem->selectionMode() == QAbstractItemView::ContiguousSelection; |
|
2553 ret = QCommonStyle::subElementRect(element, opt, widget); |
|
2554 // If both multiselect & check-state, then remove checkbox and move |
|
2555 // text and decoration towards the beginning |
|
2556 if (listItem && |
|
2557 multiSelection && |
|
2558 (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator)) { |
|
2559 const int verticalSpacing = |
|
2560 QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing); |
|
2561 //const int horizontalSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); |
|
2562 const int checkBoxRectWidth = subElementRect(SE_ItemViewItemCheckIndicator, opt, widget).width(); |
|
2563 ret.adjust(-checkBoxRectWidth-verticalSpacing,0,-checkBoxRectWidth-verticalSpacing,0); |
|
2564 } |
|
2565 } else if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) { |
|
2566 const bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable; |
|
2567 const int indicatorWidth = checkable ? |
|
2568 pixelMetric(PM_ListViewIconSize, opt, widget) : |
|
2569 pixelMetric(PM_SmallIconSize, opt, widget); |
|
2570 ret = menuItem->rect; |
|
2571 |
|
2572 if (element == SE_ItemViewItemDecoration) { |
|
2573 if (menuItem->direction == Qt::RightToLeft) |
|
2574 ret.translate(ret.width()-indicatorWidth, 0); |
|
2575 ret.setWidth(indicatorWidth); |
|
2576 } else { |
|
2577 ret = menuItem->rect; |
|
2578 if (!menuItem->icon.isNull()) |
|
2579 if (menuItem->direction == Qt::LeftToRight) |
|
2580 ret.adjust(indicatorWidth, 0, 0, 0); |
|
2581 else |
|
2582 ret.adjust(0, 0, -indicatorWidth, 0); |
|
2583 |
|
2584 // Make room for submenu indicator |
|
2585 if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu){ |
|
2586 // submenu indicator is very small, so lets halve the rect |
|
2587 if (menuItem->direction == Qt::LeftToRight) |
|
2588 ret.adjust(0,0,-(indicatorWidth >> 1),0); |
|
2589 else |
|
2590 ret.adjust((indicatorWidth >> 1),0,0,0); |
|
2591 } |
|
2592 } |
|
2593 } |
|
2594 break; |
|
2595 case SE_ItemViewItemCheckIndicator: |
|
2596 if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) { |
|
2597 const QListWidget *listItem = qobject_cast<const QListWidget *>(widget); |
|
2598 |
|
2599 const bool singleSelection = listItem && |
|
2600 (listItem->selectionMode() == QAbstractItemView::SingleSelection || |
|
2601 listItem->selectionMode() == QAbstractItemView::NoSelection); |
|
2602 const bool checkBoxOnly = (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator) && |
|
2603 listItem && |
|
2604 singleSelection; |
|
2605 |
|
2606 // Selection check mark rect. |
|
2607 const int indicatorWidth = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorWidth); |
|
2608 const int indicatorHeight = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorHeight); |
|
2609 const int spacing = QS60StylePrivate::pixelMetric(QStyle::PM_CheckBoxLabelSpacing); |
|
2610 |
|
2611 const int itemHeight = opt->rect.height(); |
|
2612 int heightOffset = 0; |
|
2613 if (indicatorHeight < itemHeight) |
|
2614 heightOffset = ((itemHeight - indicatorHeight)>>1); |
|
2615 if (checkBoxOnly) { |
|
2616 // Move rect and make it slightly smaller, so that |
|
2617 // a) highlight border does not cross the rect |
|
2618 // b) in s60 list checkbox is smaller than normal checkbox |
|
2619 //todo; magic three |
|
2620 ret.setRect(opt->rect.left()+3, opt->rect.top() + heightOffset, |
|
2621 indicatorWidth-3, indicatorHeight-3); |
|
2622 } else { |
|
2623 ret.setRect(opt->rect.right() - indicatorWidth - spacing, opt->rect.top() + heightOffset, |
|
2624 indicatorWidth, indicatorHeight); |
|
2625 } |
|
2626 } else { |
|
2627 ret = QCommonStyle::subElementRect(element, opt, widget); |
|
2628 } |
|
2629 break; |
|
2630 case SE_HeaderLabel: |
|
2631 ret = QCommonStyle::subElementRect(element, opt, widget); |
|
2632 if (qstyleoption_cast<const QStyleOptionHeader *>(opt)) { |
|
2633 // Subtract area needed for line |
|
2634 if (opt->state & State_Horizontal) |
|
2635 ret.setHeight(ret.height() - QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth)); |
|
2636 else |
|
2637 ret.setWidth(ret.width() - QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth)); |
|
2638 } |
|
2639 ret = visualRect(opt->direction, opt->rect, ret); |
|
2640 break; |
|
2641 default: |
|
2642 ret = QCommonStyle::subElementRect(element, opt, widget); |
|
2643 } |
|
2644 return ret; |
|
2645 } |
|
2646 |
|
2647 /*! |
|
2648 \reimp |
|
2649 */ |
|
2650 void QS60Style::polish(QWidget *widget) |
|
2651 { |
|
2652 Q_D(const QS60Style); |
|
2653 QCommonStyle::polish(widget); |
|
2654 |
|
2655 if (!widget) |
|
2656 return; |
|
2657 |
|
2658 if (false |
|
2659 #ifndef QT_NO_SCROLLBAR |
|
2660 || qobject_cast<QScrollBar *>(widget) |
|
2661 #endif |
|
2662 ) { |
|
2663 widget->setAttribute(Qt::WA_OpaquePaintEvent, false); |
|
2664 } |
|
2665 |
|
2666 if (QS60StylePrivate::drawsOwnThemeBackground(widget)) { |
|
2667 widget->setAttribute(Qt::WA_StyledBackground); |
|
2668 } else if (false |
|
2669 #ifndef QT_NO_MENU |
|
2670 || qobject_cast<const QMenu *> (widget) |
|
2671 #endif // QT_NO_MENU |
|
2672 ) { |
|
2673 widget->setAttribute(Qt::WA_StyledBackground); |
|
2674 } else if (false |
|
2675 #ifndef QT_NO_COMBOBOX |
|
2676 || qobject_cast<const QComboBoxListView *>(widget) |
|
2677 #endif //QT_NO_COMBOBOX |
|
2678 ) { |
|
2679 widget->setAttribute(Qt::WA_StyledBackground); |
|
2680 } |
|
2681 d->setThemePalette(widget); |
|
2682 d->setFont(widget); |
|
2683 } |
|
2684 |
|
2685 /*! |
|
2686 \reimp |
|
2687 */ |
|
2688 void QS60Style::unpolish(QWidget *widget) |
|
2689 { |
|
2690 if (false |
|
2691 #ifndef QT_NO_SCROLLBAR |
|
2692 || qobject_cast<QScrollBar *>(widget) |
|
2693 #endif |
|
2694 ) |
|
2695 widget->setAttribute(Qt::WA_OpaquePaintEvent); |
|
2696 |
|
2697 if (QS60StylePrivate::drawsOwnThemeBackground(widget)) { |
|
2698 widget->setAttribute(Qt::WA_StyledBackground, false); |
|
2699 } else if (false |
|
2700 #ifndef QT_NO_MENU |
|
2701 || qobject_cast<const QMenu *> (widget) |
|
2702 #endif // QT_NO_MENU |
|
2703 ) { |
|
2704 widget->setAttribute(Qt::WA_StyledBackground, false); |
|
2705 } else if (false |
|
2706 #ifndef QT_NO_COMBOBOX |
|
2707 || qobject_cast<const QComboBoxListView *>(widget) |
|
2708 #endif //QT_NO_COMBOBOX |
|
2709 ) { |
|
2710 widget->setAttribute(Qt::WA_StyledBackground, false); |
|
2711 } |
|
2712 |
|
2713 if (widget) |
|
2714 widget->setPalette(QPalette()); |
|
2715 |
|
2716 QCommonStyle::unpolish(widget); |
|
2717 } |
|
2718 |
|
2719 /*! |
|
2720 \reimp |
|
2721 */ |
|
2722 void QS60Style::polish(QApplication *application) |
|
2723 { |
|
2724 Q_D(QS60Style); |
|
2725 d->m_originalPalette = application->palette(); |
|
2726 d->setThemePalette(application); |
|
2727 } |
|
2728 |
|
2729 /*! |
|
2730 \reimp |
|
2731 */ |
|
2732 void QS60Style::unpolish(QApplication *application) |
|
2733 { |
|
2734 Q_UNUSED(application) |
|
2735 Q_D(QS60Style); |
|
2736 const QPalette newPalette = QApplication::style()->standardPalette(); |
|
2737 QApplication::setPalette(newPalette); |
|
2738 QApplicationPrivate::setSystemPalette(d->m_originalPalette); |
|
2739 } |
|
2740 |
|
2741 /*! |
|
2742 Sets the style property \a name to the \a value. |
|
2743 */ |
|
2744 void QS60Style::setStyleProperty(const char *name, const QVariant &value) |
|
2745 { |
|
2746 Q_D(QS60Style); |
|
2747 d->setStyleProperty_specific(name, value); |
|
2748 } |
|
2749 |
|
2750 /*! |
|
2751 Returns the value of style property \a name. |
|
2752 */ |
|
2753 QVariant QS60Style::styleProperty(const char *name) const |
|
2754 { |
|
2755 Q_D(const QS60Style); |
|
2756 return d->styleProperty_specific(name); |
|
2757 } |
|
2758 |
|
2759 /*! |
|
2760 \reimp |
|
2761 */ |
|
2762 bool QS60Style::event(QEvent *e) |
|
2763 { |
|
2764 #ifdef QT_KEYPAD_NAVIGATION |
|
2765 if (QS60StylePrivate::isTouchSupported()) |
|
2766 return false; |
|
2767 Q_D(QS60Style); |
|
2768 switch (e->type()) { |
|
2769 case QEvent::FocusIn: |
|
2770 if (QWidget *focusWidget = QApplication::focusWidget()) { |
|
2771 if (!d->m_focusFrame) |
|
2772 d->m_focusFrame = new QFocusFrame(focusWidget); |
|
2773 d->m_focusFrame->setWidget(focusWidget); |
|
2774 } else if (d->m_focusFrame) { |
|
2775 d->m_focusFrame->setWidget(0); |
|
2776 } |
|
2777 break; |
|
2778 case QEvent::FocusOut: |
|
2779 if (d->m_focusFrame) |
|
2780 d->m_focusFrame->setWidget(0); |
|
2781 break; |
|
2782 case QEvent::EnterEditFocus: |
|
2783 case QEvent::LeaveEditFocus: |
|
2784 if (d->m_focusFrame) |
|
2785 d->m_focusFrame->update(); |
|
2786 break; |
|
2787 default: |
|
2788 break; |
|
2789 } |
|
2790 #else |
|
2791 Q_UNUSED(e) |
|
2792 #endif |
|
2793 return false; |
|
2794 } |
|
2795 |
|
2796 /*! |
|
2797 \internal |
|
2798 */ |
|
2799 QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, |
|
2800 const QStyleOption *option, const QWidget *widget) const |
|
2801 { |
|
2802 const int iconDimension = QS60StylePrivate::pixelMetric(QStyle::PM_ToolBarIconSize); |
|
2803 const QRect iconSize = (!option) ? QRect(0,0,iconDimension,iconDimension) : option->rect; |
|
2804 QS60StyleEnums::SkinParts part; |
|
2805 QS60StylePrivate::SkinElementFlags adjustedFlags; |
|
2806 if (option) |
|
2807 adjustedFlags = (option->state & State_Enabled || option->state == 0) ? |
|
2808 QS60StylePrivate::SF_StateEnabled : |
|
2809 QS60StylePrivate::SF_StateDisabled; |
|
2810 |
|
2811 switch(standardIcon) { |
|
2812 case QStyle::SP_MessageBoxWarning: |
|
2813 part = QS60StyleEnums::SP_QgnNoteWarning; |
|
2814 break; |
|
2815 case QStyle::SP_MessageBoxInformation: |
|
2816 part = QS60StyleEnums::SP_QgnNoteInfo; |
|
2817 break; |
|
2818 case QStyle::SP_MessageBoxCritical: |
|
2819 part = QS60StyleEnums::SP_QgnNoteError; |
|
2820 break; |
|
2821 case QStyle::SP_MessageBoxQuestion: |
|
2822 part = QS60StyleEnums::SP_QgnNoteQuery; |
|
2823 break; |
|
2824 case QStyle::SP_ArrowRight: |
|
2825 part = QS60StyleEnums::SP_QgnIndiNaviArrowRight; |
|
2826 break; |
|
2827 case QStyle::SP_ArrowLeft: |
|
2828 part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; |
|
2829 break; |
|
2830 case QStyle::SP_ArrowUp: |
|
2831 part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; |
|
2832 adjustedFlags |= QS60StylePrivate::SF_PointEast; |
|
2833 break; |
|
2834 case QStyle::SP_ArrowDown: |
|
2835 part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; |
|
2836 adjustedFlags |= QS60StylePrivate::SF_PointWest; |
|
2837 break; |
|
2838 case QStyle::SP_ArrowBack: |
|
2839 if (QApplication::layoutDirection() == Qt::RightToLeft) |
|
2840 return QS60Style::standardIcon(SP_ArrowRight, option, widget); |
|
2841 return QS60Style::standardIcon(SP_ArrowLeft, option, widget); |
|
2842 case QStyle::SP_ArrowForward: |
|
2843 if (QApplication::layoutDirection() == Qt::RightToLeft) |
|
2844 return QS60Style::standardIcon(SP_ArrowLeft, option, widget); |
|
2845 return QS60Style::standardIcon(SP_ArrowRight, option, widget); |
|
2846 case QStyle::SP_ComputerIcon: |
|
2847 part = QS60StyleEnums::SP_QgnPropPhoneMemcLarge; |
|
2848 break; |
|
2849 case QStyle::SP_DirClosedIcon: |
|
2850 part = QS60StyleEnums::SP_QgnPropFolderSmall; |
|
2851 break; |
|
2852 case QStyle::SP_DirOpenIcon: |
|
2853 part = QS60StyleEnums::SP_QgnPropFolderCurrent; |
|
2854 break; |
|
2855 case QStyle::SP_DirIcon: |
|
2856 part = QS60StyleEnums::SP_QgnPropFolderSmall; |
|
2857 break; |
|
2858 case QStyle::SP_FileDialogNewFolder: |
|
2859 part = QS60StyleEnums::SP_QgnPropFolderSmallNew; |
|
2860 break; |
|
2861 case QStyle::SP_FileIcon: |
|
2862 part = QS60StyleEnums::SP_QgnPropFileSmall; |
|
2863 break; |
|
2864 case QStyle::SP_TrashIcon: |
|
2865 part = QS60StyleEnums::SP_QgnNoteErased; |
|
2866 break; |
|
2867 case QStyle::SP_ToolBarHorizontalExtensionButton: |
|
2868 part = QS60StyleEnums::SP_QgnIndiSubMenu; |
|
2869 if (QApplication::layoutDirection() == Qt::RightToLeft) |
|
2870 adjustedFlags |= QS60StylePrivate::SF_PointSouth; |
|
2871 break; |
|
2872 case QStyle::SP_ToolBarVerticalExtensionButton: |
|
2873 adjustedFlags |= QS60StylePrivate::SF_PointEast; |
|
2874 part = QS60StyleEnums::SP_QgnIndiSubMenu; |
|
2875 break; |
|
2876 |
|
2877 default: |
|
2878 return QCommonStyle::standardIconImplementation(standardIcon, option, widget); |
|
2879 } |
|
2880 const QS60StylePrivate::SkinElementFlags flags = adjustedFlags; |
|
2881 const QPixmap cachedPixMap(QS60StylePrivate::cachedPart(part, iconSize.size(), flags)); |
|
2882 return cachedPixMap.isNull() ? |
|
2883 QCommonStyle::standardIconImplementation(standardIcon, option, widget) : QIcon(cachedPixMap); |
|
2884 } |
|
2885 |
|
2886 extern QPoint qt_s60_fill_background_offset(const QWidget *targetWidget); |
|
2887 |
|
2888 bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush) |
|
2889 { |
|
2890 const QPixmap backgroundTexture(QS60StylePrivate::backgroundTexture()); |
|
2891 if (backgroundTexture.cacheKey() != brush.texture().cacheKey()) |
|
2892 return false; |
|
2893 |
|
2894 const QPaintDevice *target = painter->device(); |
|
2895 if (target->devType() == QInternal::Widget) { |
|
2896 const QWidget *widget = static_cast<const QWidget *>(target); |
|
2897 const QVector<QRect> &rects = rgn.rects(); |
|
2898 for (int i = 0; i < rects.size(); ++i) { |
|
2899 const QRect rect(rects.at(i)); |
|
2900 painter->drawPixmap(rect.topLeft(), backgroundTexture, |
|
2901 rect.translated(qt_s60_fill_background_offset(widget))); |
|
2902 } |
|
2903 } |
|
2904 return true; |
|
2905 } |
|
2906 |
|
2907 QT_END_NAMESPACE |
|
2908 |
|
2909 #endif // QT_NO_STYLE_S60 || QT_PLUGIN |