summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--Makefile2
-rw-r--r--apps/Settings/Theme.desktop7
-rw-r--r--noncore/styles/theme/ogfxeffect.cpp324
-rw-r--r--noncore/styles/theme/ogfxeffect.h78
-rw-r--r--noncore/styles/theme/opie-theme.control11
-rw-r--r--noncore/styles/theme/othemebase.cpp1212
-rw-r--r--noncore/styles/theme/othemebase.h739
-rw-r--r--noncore/styles/theme/othemestyle.cpp1532
-rw-r--r--noncore/styles/theme/othemestyle.h365
-rw-r--r--noncore/styles/theme/plugin.cpp19
-rw-r--r--noncore/styles/theme/settings/main.cpp34
-rw-r--r--noncore/styles/theme/settings/settings.pro24
-rw-r--r--noncore/styles/theme/settings/themeset.cpp124
-rw-r--r--noncore/styles/theme/settings/themeset.h20
-rw-r--r--noncore/styles/theme/theme.pro32
-rw-r--r--pics/theme/Theme.pngbin0 -> 2771 bytes
16 files changed, 4522 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 1e60978..66c3fe4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,113 +1,113 @@
1indefault: dynamic 1indefault: dynamic
2 2
3all: default docs 3all: default docs
4 4
5LIBS=library libopie 5LIBS=library libopie
6 6
7 7
8INPUTCOMPONENTS= inputmethods/keyboard inputmethods/pickboard \ 8INPUTCOMPONENTS= inputmethods/keyboard inputmethods/pickboard \
9 inputmethods/handwriting inputmethods/unikeyboard \ 9 inputmethods/handwriting inputmethods/unikeyboard \
10 inputmethods/jumpx inputmethods/kjumpx \ 10 inputmethods/jumpx inputmethods/kjumpx \
11 inputmethods/dvorak 11 inputmethods/dvorak
12 12
13APPLETS= core/applets/batteryapplet core/applets/batteryapplet-ipaq \ 13APPLETS= core/applets/batteryapplet core/applets/batteryapplet-ipaq \
14 core/applets/irdaapplet core/applets/volumeapplet \ 14 core/applets/irdaapplet core/applets/volumeapplet \
15 core/applets/clockapplet core/applets/netmonapplet \ 15 core/applets/clockapplet core/applets/netmonapplet \
16 core/applets/screenshotapplet core/applets/clipboardapplet \ 16 core/applets/screenshotapplet core/applets/clipboardapplet \
17 core/applets/cardmon core/applets/obex \ 17 core/applets/cardmon core/applets/obex \
18 core/applets/vmemo noncore/net/netsetup/dialup \ 18 core/applets/vmemo noncore/net/netsetup/dialup \
19 noncore/net/netsetup/lan 19 noncore/net/netsetup/lan
20 20
21MAIL= noncore/mail/libmail noncore/mail/bend 21MAIL= noncore/mail/libmail noncore/mail/bend
22 22
23PLAYER = core/multimedia/opieplayer/libmpeg3 \ 23PLAYER = core/multimedia/opieplayer/libmpeg3 \
24 core/multimedia/opieplayer/libmad \ 24 core/multimedia/opieplayer/libmad \
25 core/multimedia/opieplayer/wavplugin 25 core/multimedia/opieplayer/wavplugin
26 26
27 COMPONENTS=$(LOCALCOMPONENTS) $(INPUTCOMPONENTS) $(APPLETS) $(MAIL) $(PLAYER) 27 COMPONENTS=$(LOCALCOMPONENTS) $(INPUTCOMPONENTS) $(APPLETS) $(MAIL) # $(PLAYER)
28 28
29 29
30PIMAPPS = core/pim/addressbook core/pim/datebook \ 30PIMAPPS = core/pim/addressbook core/pim/datebook \
31 core/pim/today core/pim/todo 31 core/pim/today core/pim/todo
32 32
33COREAPPS = core/apps/filebrowser core/apps/helpbrowser \ 33COREAPPS = core/apps/filebrowser core/apps/helpbrowser \
34 core/apps/textedit core/apps/embeddedkonsole \ 34 core/apps/textedit core/apps/embeddedkonsole \
35 core/launcher core/apps/sysinfo \ 35 core/launcher core/apps/sysinfo \
36 core/apps/oipkg core/apps/qcop 36 core/apps/oipkg core/apps/qcop
37 37
38COREMULTIMEDIA = core/multimedia/opieplayer 38COREMULTIMEDIA = core/multimedia/opieplayer
39 39
40CORESETTINGS = core/settings/light-and-power core/settings/security \ 40CORESETTINGS = core/settings/light-and-power core/settings/security \
41 core/settings/systemtime core/settings/citytime \ 41 core/settings/systemtime core/settings/citytime \
42 core/settings/wlansetup 42 core/settings/wlansetup
43 43
44NONCORESETTINGS =noncore/settings/language noncore/settings/rotation \ 44NONCORESETTINGS =noncore/settings/language noncore/settings/rotation \
45 noncore/settings/appearance noncore/settings/sound \ 45 noncore/settings/appearance noncore/settings/sound \
46 noncore/settings/mediummount \ 46 noncore/settings/mediummount \
47 noncore/settings/tabmanager noncore/settings/appskey \ 47 noncore/settings/tabmanager noncore/settings/appskey \
48 noncore/settings/netsystemtime 48 noncore/settings/netsystemtime
49 49
50NONCORETOOLS = noncore/tools/calculator noncore/tools/clock \ 50NONCORETOOLS = noncore/tools/calculator noncore/tools/clock \
51 noncore/tools/remote noncore/tools/opie-sh noncore/apps/advancedfm 51 noncore/tools/remote noncore/tools/opie-sh noncore/apps/advancedfm
52 52
53NONCORESTYLES = noncore/styles/liquid noncore/styles/liquid/settings 53NONCORESTYLES = noncore/styles/liquid noncore/styles/liquid/settings
54 54
55GAMES = noncore/games/minesweep noncore/games/solitaire \ 55GAMES = noncore/games/minesweep noncore/games/solitaire \
56 noncore/games/tetrix noncore/games/wordgame \ 56 noncore/games/tetrix noncore/games/wordgame \
57 noncore/games/parashoot noncore/games/snake \ 57 noncore/games/parashoot noncore/games/snake \
58 noncore/games/mindbreaker \ 58 noncore/games/mindbreaker \
59 noncore/games/go noncore/games/qasteroids \ 59 noncore/games/go noncore/games/qasteroids \
60 noncore/games/fifteen noncore/games/tictac \ 60 noncore/games/fifteen noncore/games/tictac \
61 noncore/games/kcheckers noncore/games/kpacman \ 61 noncore/games/kcheckers noncore/games/kpacman \
62 noncore/games/kbill 62 noncore/games/kbill
63 63
64NONAPPS = noncore/apps/spreadsheet noncore/apps/tableviewer \ 64NONAPPS = noncore/apps/spreadsheet noncore/apps/tableviewer \
65 65
66NONNET = noncore/net/netsetup noncore/net/opieftp \ 66NONNET = noncore/net/netsetup noncore/net/opieftp \
67 noncore/mail 67 noncore/mail
68 68
69NONMULT = noncore/multimedia/showimg noncore/graphics/drawpad \ 69NONMULT = noncore/multimedia/showimg noncore/graphics/drawpad \
70 noncore/graphics/qpdf 70 noncore/graphics/qpdf
71 71
72 72
73NONCOMM = noncore/comm/keypebble 73NONCOMM = noncore/comm/keypebble
74 74
75APPS=$(LOCALAPPS) $(PIMAPPS) $(COREAPPS) \ 75APPS=$(LOCALAPPS) $(PIMAPPS) $(COREAPPS) \
76 $(COREMULTIMEDIA) $(CORESETTINGS) \ 76 $(COREMULTIMEDIA) $(CORESETTINGS) \
77 $(NONCORESETTINGS) $(NONCORETOOLS) $(NONCORESTYLES) \ 77 $(NONCORESETTINGS) $(NONCORETOOLS) $(NONCORESTYLES) \
78 $(NONAPPS) $(NONNET) $(NONMULT) \ 78 $(NONAPPS) $(NONNET) $(NONMULT) \
79 $(NONCOMM) $(GAMES) 79 $(NONCOMM) $(GAMES)
80 80
81 81
82 82
83NONTMAKEAPPS := ipaq/opiealarm 83NONTMAKEAPPS := ipaq/opiealarm
84 84
85DOCS = docs/src/opie-policy 85DOCS = docs/src/opie-policy
86single: mpegplayer/libmpeg3 86single: mpegplayer/libmpeg3
87 87
88dynamic: $(APPS) $(NONTMAKEAPPS) 88dynamic: $(APPS) $(NONTMAKEAPPS)
89 89
90docs: $(DOCS) 90docs: $(DOCS)
91 91
92$(COMPONENTS): $(LIBS) 92$(COMPONENTS): $(LIBS)
93 93
94$(NONTMAKEAPPS) $(APPS): $(LIBS) $(COMPONENTS) 94$(NONTMAKEAPPS) $(APPS): $(LIBS) $(COMPONENTS)
95 95
96$(LIBS) $(COMPONENTS) $(NONTMAKEAPPS) $(APPS) $(DOCS) single: 96$(LIBS) $(COMPONENTS) $(NONTMAKEAPPS) $(APPS) $(DOCS) single:
97 $(MAKE) -C $@ -f Makefile 97 $(MAKE) -C $@ -f Makefile
98 98
99showcomponents: 99showcomponents:
100 @echo $(LIBS) $(APPS) $(COMPONENTS) single 100 @echo $(LIBS) $(APPS) $(COMPONENTS) single
101 101
102clean: 102clean:
103 $(MAKE) -C single -f Makefile $@ 103 $(MAKE) -C single -f Makefile $@
104 for dir in $(NONTMAKEAPPS) $(APPS) $(LIBS) $(COMPONENTS) $(DOCS); do $(MAKE) -C $$dir -f Makefile $@ || exit 1; done 104 for dir in $(NONTMAKEAPPS) $(APPS) $(LIBS) $(COMPONENTS) $(DOCS); do $(MAKE) -C $$dir -f Makefile $@ || exit 1; done
105 105
106lupdate: 106lupdate:
107 for dir in $(APPS) $(LIBS) $(COMPONENTS); do $(MAKE) -C $$dir -f Makefile $@ || exit 1; done 107 for dir in $(APPS) $(LIBS) $(COMPONENTS); do $(MAKE) -C $$dir -f Makefile $@ || exit 1; done
108 108
109lrelease: 109lrelease:
110 for dir in $(APPS) $(LIBS) $(COMPONENTS); do $(MAKE) -C $$dir -f Makefile $@ || exit 1; done 110 for dir in $(APPS) $(LIBS) $(COMPONENTS); do $(MAKE) -C $$dir -f Makefile $@ || exit 1; done
111 111
112 112
113.PHONY: default dynamic $(NONTMAKEAPPS) $(LIBS) $(APPS) $(COMPONENTS) $(DOCS) single showcomponents clean 113.PHONY: default dynamic $(NONTMAKEAPPS) $(LIBS) $(APPS) $(COMPONENTS) $(DOCS) single showcomponents clean
diff --git a/apps/Settings/Theme.desktop b/apps/Settings/Theme.desktop
new file mode 100644
index 0000000..197184f
--- a/dev/null
+++ b/apps/Settings/Theme.desktop
@@ -0,0 +1,7 @@
1[Desktop Entry]
2Type=Application
3Exec=theme-settings
4Icon=theme/Theme
5Name=Theme-Settings
6Name[de]=Thema-Einstellungen
7
diff --git a/noncore/styles/theme/ogfxeffect.cpp b/noncore/styles/theme/ogfxeffect.cpp
new file mode 100644
index 0000000..a991728
--- a/dev/null
+++ b/noncore/styles/theme/ogfxeffect.cpp
@@ -0,0 +1,324 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1998, 1999 Christian Tibirna <ctibirna@total.net>
3 (C) 1998, 1999 Daniel M. Duley <mosfet@kde.org>
4 (C) 1998, 1999 Dirk A. Mueller <mueller@kde.org>
5
6*/
7
8// $Id$
9
10#include <qimage.h>
11#include <qpainter.h>
12
13#include "ogfxeffect.h"
14
15
16//======================================================================
17//
18// Gradient effects
19//
20//======================================================================
21
22
23QPixmap& OGfxEffect::gradient(QPixmap &pixmap, const QColor &ca,
24 const QColor &cb, GradientType eff, int ncols)
25{
26 if(pixmap.depth() > 8 &&
27 (eff == VerticalGradient || eff == HorizontalGradient)) {
28
29 int rDiff, gDiff, bDiff;
30 int rca, gca, bca /*, rcb, gcb, bcb*/;
31
32 register int x, y;
33
34 rDiff = (/*rcb = */ cb.red()) - (rca = ca.red());
35 gDiff = (/*gcb = */ cb.green()) - (gca = ca.green());
36 bDiff = (/*bcb = */ cb.blue()) - (bca = ca.blue());
37
38 register int rl = rca << 16;
39 register int gl = gca << 16;
40 register int bl = bca << 16;
41
42 int rcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * rDiff;
43 int gcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * gDiff;
44 int bcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * bDiff;
45
46 QPainter p(&pixmap);
47
48 // these for-loops could be merged, but the if's in the inner loop
49 // would make it slow
50 switch(eff) {
51 case VerticalGradient:
52 for ( y = 0; y < pixmap.height(); y++ ) {
53 rl += rcdelta;
54 gl += gcdelta;
55 bl += bcdelta;
56
57 p.setPen(QColor(rl>>16, gl>>16, bl>>16));
58 p.drawLine(0, y, pixmap.width()-1, y);
59 }
60 break;
61 case HorizontalGradient:
62 for( x = 0; x < pixmap.width(); x++) {
63 rl += rcdelta;
64 gl += gcdelta;
65 bl += bcdelta;
66
67 p.setPen(QColor(rl>>16, gl>>16, bl>>16));
68 p.drawLine(x, 0, x, pixmap.height()-1);
69 }
70 break;
71 default:
72 ;
73 }
74 }
75 else {
76// QImage image = OGfxEffect::gradient(pixmap.size(), ca, cb,
77// (OGfxEffect::GradientType) eff, ncols);
78// pixmap.convertFromImage(image);
79 }
80
81 return pixmap;
82}
83
84
85//======================================================================
86//
87// Blend effects
88//
89//======================================================================
90
91
92QPixmap& OGfxEffect::blend(QPixmap &pixmap, float initial_intensity,
93 const QColor &bgnd, GradientType eff,
94 bool anti_dir, int ncols)
95{
96 QImage image = pixmap.convertToImage();
97 OGfxEffect::blend(image, initial_intensity, bgnd, eff, anti_dir);
98
99 unsigned int tmp;
100
101 if ( pixmap. depth ( ) <= 8 )
102 image. convertDepth ( pixmap. depth ( ));
103
104 pixmap.convertFromImage(image);
105
106 return pixmap;
107}
108
109
110QImage& OGfxEffect::blend(QImage &image, float initial_intensity,
111 const QColor &bgnd, GradientType eff,
112 bool anti_dir)
113{
114 if (image.width() == 0 || image.height() == 0) {
115 qDebug ( "Invalid image\n" );
116 return image;
117 }
118
119 int r_bgnd = bgnd.red(), g_bgnd = bgnd.green(), b_bgnd = bgnd.blue();
120 int r, g, b;
121 int ind;
122
123 unsigned int xi, xf, yi, yf;
124 unsigned int a;
125
126 // check the boundaries of the initial intesity param
127 float unaffected = 1;
128 if (initial_intensity > 1) initial_intensity = 1;
129 if (initial_intensity < -1) initial_intensity = -1;
130 if (initial_intensity < 0) {
131 unaffected = 1. + initial_intensity;
132 initial_intensity = 0;
133 }
134
135
136 float intensity = initial_intensity;
137 float var = 1. - initial_intensity;
138
139 if (anti_dir) {
140 initial_intensity = intensity = 1.;
141 var = -var;
142 }
143
144 register int x, y;
145
146 unsigned int *data = (unsigned int *)image.bits();
147
148 if( eff == VerticalGradient || eff == HorizontalGradient ) {
149
150 // set the image domain to apply the effect to
151 xi = 0, xf = image.width();
152 yi = 0, yf = image.height();
153 if (eff == VerticalGradient) {
154 if (anti_dir) yf = (int)(image.height() * unaffected);
155 else yi = (int)(image.height() * (1 - unaffected));
156 }
157 else {
158 if (anti_dir) xf = (int)(image.width() * unaffected);
159 else xi = (int)(image.height() * (1 - unaffected));
160 }
161
162 var /= (eff == VerticalGradient?yf-yi:xf-xi);
163
164 for (y = yi; y < (int)yf; y++) {
165 intensity = eff == VerticalGradient? intensity + var :
166 initial_intensity;
167 for (x = xi; x < (int)xf ; x++) {
168 if (eff == HorizontalGradient) intensity += var;
169 ind = x + image.width() * y ;
170 r = qRed (data[ind]) + (int)(intensity *
171 (r_bgnd - qRed (data[ind])));
172 g = qGreen(data[ind]) + (int)(intensity *
173 (g_bgnd - qGreen(data[ind])));
174 b = qBlue (data[ind]) + (int)(intensity *
175 (b_bgnd - qBlue (data[ind])));
176 if (r > 255) r = 255; if (r < 0 ) r = 0;
177 if (g > 255) g = 255; if (g < 0 ) g = 0;
178 if (b > 255) b = 255; if (b < 0 ) b = 0;
179 a = qAlpha(data[ind]);
180 data[ind] = qRgba(r, g, b, a);
181 }
182 }
183 }
184 else if (eff == DiagonalGradient || eff == CrossDiagonalGradient) {
185 float xvar = var / 2 / image.width(); // / unaffected;
186 float yvar = var / 2 / image.height(); // / unaffected;
187 float tmp;
188
189 for (x = 0; x < image.width() ; x++) {
190 tmp = xvar * (eff == DiagonalGradient? x : image.width()-x-1);
191 for (y = 0; y < image.height() ; y++) {
192 intensity = initial_intensity + tmp + yvar * y;
193 ind = x + image.width() * y ;
194 r = qRed (data[ind]) + (int)(intensity *
195 (r_bgnd - qRed (data[ind])));
196 g = qGreen(data[ind]) + (int)(intensity *
197 (g_bgnd - qGreen(data[ind])));
198 b = qBlue (data[ind]) + (int)(intensity *
199 (b_bgnd - qBlue (data[ind])));
200 if (r > 255) r = 255; if (r < 0 ) r = 0;
201 if (g > 255) g = 255; if (g < 0 ) g = 0;
202 if (b > 255) b = 255; if (b < 0 ) b = 0;
203 a = qAlpha(data[ind]);
204 data[ind] = qRgba(r, g, b, a);
205 }
206 }
207 }
208
209 else if (eff == RectangleGradient || eff == EllipticGradient) {
210 float xvar;
211 float yvar;
212
213 for (x = 0; x < image.width() / 2 + image.width() % 2; x++) {
214 xvar = var / image.width() * (image.width() - x*2/unaffected-1);
215 for (y = 0; y < image.height() / 2 + image.height() % 2; y++) {
216 yvar = var / image.height() * (image.height() - y*2/unaffected -1);
217
218 if (eff == RectangleGradient)
219 intensity = initial_intensity + QMAX(xvar, yvar);
220 else
221 intensity = initial_intensity + sqrt(xvar * xvar + yvar * yvar);
222 if (intensity > 1) intensity = 1;
223 if (intensity < 0) intensity = 0;
224
225 //NW
226 ind = x + image.width() * y ;
227 r = qRed (data[ind]) + (int)(intensity *
228 (r_bgnd - qRed (data[ind])));
229 g = qGreen(data[ind]) + (int)(intensity *
230 (g_bgnd - qGreen(data[ind])));
231 b = qBlue (data[ind]) + (int)(intensity *
232 (b_bgnd - qBlue (data[ind])));
233 if (r > 255) r = 255; if (r < 0 ) r = 0;
234 if (g > 255) g = 255; if (g < 0 ) g = 0;
235 if (b > 255) b = 255; if (b < 0 ) b = 0;
236 a = qAlpha(data[ind]);
237 data[ind] = qRgba(r, g, b, a);
238
239 //NE
240 ind = image.width() - x - 1 + image.width() * y ;
241 r = qRed (data[ind]) + (int)(intensity *
242 (r_bgnd - qRed (data[ind])));
243 g = qGreen(data[ind]) + (int)(intensity *
244 (g_bgnd - qGreen(data[ind])));
245 b = qBlue (data[ind]) + (int)(intensity *
246 (b_bgnd - qBlue (data[ind])));
247 if (r > 255) r = 255; if (r < 0 ) r = 0;
248 if (g > 255) g = 255; if (g < 0 ) g = 0;
249 if (b > 255) b = 255; if (b < 0 ) b = 0;
250 a = qAlpha(data[ind]);
251 data[ind] = qRgba(r, g, b, a);
252 }
253 }
254
255 //CT loop is doubled because of stupid central row/column issue.
256 // other solution?
257 for (x = 0; x < image.width() / 2; x++) {
258 xvar = var / image.width() * (image.width() - x*2/unaffected-1);
259 for (y = 0; y < image.height() / 2; y++) {
260 yvar = var / image.height() * (image.height() - y*2/unaffected -1);
261
262 if (eff == RectangleGradient)
263 intensity = initial_intensity + QMAX(xvar, yvar);
264 else
265 intensity = initial_intensity + sqrt(xvar * xvar + yvar * yvar);
266 if (intensity > 1) intensity = 1;
267 if (intensity < 0) intensity = 0;
268
269 //SW
270 ind = x + image.width() * (image.height() - y -1) ;
271 r = qRed (data[ind]) + (int)(intensity *
272 (r_bgnd - qRed (data[ind])));
273 g = qGreen(data[ind]) + (int)(intensity *
274 (g_bgnd - qGreen(data[ind])));
275 b = qBlue (data[ind]) + (int)(intensity *
276 (b_bgnd - qBlue (data[ind])));
277 if (r > 255) r = 255; if (r < 0 ) r = 0;
278 if (g > 255) g = 255; if (g < 0 ) g = 0;
279 if (b > 255) b = 255; if (b < 0 ) b = 0;
280 a = qAlpha(data[ind]);
281 data[ind] = qRgba(r, g, b, a);
282
283 //SE
284 ind = image.width()-x-1 + image.width() * (image.height() - y - 1) ;
285 r = qRed (data[ind]) + (int)(intensity *
286 (r_bgnd - qRed (data[ind])));
287 g = qGreen(data[ind]) + (int)(intensity *
288 (g_bgnd - qGreen(data[ind])));
289 b = qBlue (data[ind]) + (int)(intensity *
290 (b_bgnd - qBlue (data[ind])));
291 if (r > 255) r = 255; if (r < 0 ) r = 0;
292 if (g > 255) g = 255; if (g < 0 ) g = 0;
293 if (b > 255) b = 255; if (b < 0 ) b = 0;
294 a = qAlpha(data[ind]);
295 data[ind] = qRgba(r, g, b, a);
296 }
297 }
298 }
299
300 else
301 qDebug ( "not implemented\n" );
302
303 return image;
304}
305
306#if 0
307// Not very efficient as we create a third big image...
308//
309QImage& KQGfxEffect::blend(QImage &image1, QImage &image2,
310 GradientType gt, int xf, int yf)
311{
312 if (image1.width() == 0 || image1.height() == 0 ||
313 image2.width() == 0 || image2.height() == 0)
314 return image1;
315
316 QImage image3;
317
318 image3 = KQGfxEffect::unbalancedGradient(image1.size(),
319 QColor(0,0,0), QColor(255,255,255),
320 gt, xf, yf, 0);
321
322 return blend(image1,image2,image3, Red); // Channel to use is arbitrary
323}
324#endif
diff --git a/noncore/styles/theme/ogfxeffect.h b/noncore/styles/theme/ogfxeffect.h
new file mode 100644
index 0000000..45a8482
--- a/dev/null
+++ b/noncore/styles/theme/ogfxeffect.h
@@ -0,0 +1,78 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1998, 1999 Christian Tibirna <ctibirna@total.net>
3 (C) 1998, 1999 Daniel M. Duley <mosfet@kde.org>
4 (C) 1998, 1999 Dirk A. Mueller <mueller@kde.org>
5
6*/
7
8// $Id$
9
10#ifndef __OGFX_EFFECT_H
11#define __OGFX_EFFECT_H
12
13#include <qpixmap.h>
14#include <qimage.h>
15
16/**
17 * This class includes various pixmap-based graphical effects.
18 *
19 * Everything is
20 * static, so there is no need to create an instance of this class. You can
21 * just call the static methods. They are encapsulated here merely to provide
22 * a common namespace.
23 */
24class OGfxEffect
25{
26public:
27 enum GradientType { VerticalGradient, HorizontalGradient,
28 DiagonalGradient, CrossDiagonalGradient,
29 PyramidGradient, RectangleGradient,
30 PipeCrossGradient, EllipticGradient };
31 enum RGBComponent { Red, Green, Blue };
32
33 enum Lighting {NorthLite, NWLite, WestLite, SWLite,
34 SouthLite, SELite, EastLite, NELite};
35
36 /**
37 * Create a gradient from color a to color b of the specified type.
38 *
39 * @param pixmap The pixmap to process.
40 * @param ca Color a.
41 * @param cb Color b.
42 * @param type The type of gradient.
43 * @param ncols The number of colors to use when not running on a
44 * truecolor display. The gradient will be dithered to this number of
45 * colors. Pass 0 to prevent dithering.
46 * @return Returns the generated pixmap, for convenience.
47 */
48 static QPixmap& gradient(QPixmap& pixmap, const QColor &ca, const QColor &cb,
49 GradientType type, int ncols=3);
50
51
52 /**
53 * Blend the provided pixmap into a background of the indicated color
54 *
55 * @param pixmap The pixmap to process.
56 * @param initial_intensity this parameter takes values from -1 to 1:
57 * @li If positive, it tells how much to fade the image in its
58 * less affected spot.
59 * @li If negative, it tells roughly indicates how much of the image
60 * remains unaffected
61 * @param bgnd Indicates the color of the background to blend in.
62 * @param eff Lets you choose what kind of blending you like.
63 * @param anti_dir Blend in the opposite direction (makes no much sense
64 * with concentric blending effects).
65 * @return Returns the @ref pixmap(), provided for convenience.
66 */
67 static QPixmap& blend(QPixmap& pixmap, float initial_intensity,
68 const QColor &bgnd, GradientType eff,
69 bool anti_dir=false, int ncols=3);
70
71
72 static QImage& blend(QImage &image, float initial_intensity,
73 const QColor &bgnd, GradientType eff,
74 bool anti_dir);
75};
76
77
78#endif
diff --git a/noncore/styles/theme/opie-theme.control b/noncore/styles/theme/opie-theme.control
new file mode 100644
index 0000000..02739fb
--- a/dev/null
+++ b/noncore/styles/theme/opie-theme.control
@@ -0,0 +1,11 @@
1Files: plugins/styles/libtheme.so* bin/theme-settings apps/Settings/Theme.desktop pics/theme/Theme.png
2Priority: optional
3Section: opie/system
4Maintainer: Robert Griebl <sandman@handhelds.org>
5Architecture: arm
6Version: $QPE_VERSION-$SUB_VERSION.1
7Depends: opie-base ($QPE_VERSION)
8Description: Themed style.
9 This style accepts all themes written
10for KDE 2.2
11
diff --git a/noncore/styles/theme/othemebase.cpp b/noncore/styles/theme/othemebase.cpp
new file mode 100644
index 0000000..00cea03
--- a/dev/null
+++ b/noncore/styles/theme/othemebase.cpp
@@ -0,0 +1,1212 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Daniel M. Duley <mosfet@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18#include "othemebase.h"
19#include "ogfxeffect.h"
20#include <qpe/qpeapplication.h>
21//#include <kdebug.h>
22//#include <klocale.h>
23#include <qpe/config.h>
24//#include <kglobal.h>
25//#include <kglobalsettings.h>
26//#include <kstddirs.h>
27#include <qfile.h>
28#include <qtextstream.h>
29#include <qdir.h>
30#include <qpainter.h>
31#include <qbitmap.h>
32#include <stdlib.h>
33#include <qstringlist.h>
34
35#include <stdio.h>
36
37template class QIntCache<OThemePixmap>
38;
39
40static const char *widgetEntries[] =
41 { // unsunken widgets (see header)
42 "PushButton", "ComboBox", "HSBarSlider", "VSBarSlider", "Bevel", "ToolButton",
43 "ScrollButton", "HScrollDeco", "VScrollDeco", "ComboDeco", "MenuItem", "Tab",
44 "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight",
45 // sunken widgets
46 "PushButtonDown", "ComboBoxDown", "HSBarSliderDown", "VSBarSliderDown",
47 "BevelDown", "ToolButtonDown", "ScrollButtonDown", "HScrollDecoDown",
48 "VScrollDecoDown", "ComboDecoDown", "MenuItemDown", "TabDown", "SunkenArrowUp",
49 "SunkenArrowDown", "SunkenArrowLeft", "SunkenArrowRight",
50 // everything else
51 "HScrollGroove", "VScrollGroove", "Slider", "SliderGroove", "CheckBoxDown",
52 "CheckBox", "RadioDown", "Radio", "HBarHandle", "VBarHandle",
53 "ToolBar", "Splitter", "CheckMark", "MenuBar", "DisableArrowUp",
54 "DisableArrowDown", "DisableArrowLeft", "DisableArrowRight", "ProgressBar",
55 "ProgressBackground", "MenuBarItem", "Background"
56 };
57
58#define INHERIT_ITEMS 16
59
60
61// This is used to encode the keys. I used to use masks but I think this
62// bitfield is nicer :) I don't know why C++ coders don't use these more..
63// (mosfet)
64struct kthemeKeyData
65{
66unsigned int id :
67 6;
68unsigned int width :
69 12;
70unsigned int height :
71 12;
72unsigned int border :
73 1;
74unsigned int mask :
75 1;
76};
77
78union kthemeKey{
79 kthemeKeyData data;
80 unsigned int cacheKey;
81};
82
83class MyConfig : public Config
84{
85public:
86 MyConfig ( const QString &f, Domain d ) : Config ( f, d )
87 { }
88
89 bool hasGroup ( const QString &gname ) const
90 {
91 QMap< QString, ConfigGroup>::ConstIterator it = groups. find ( gname );
92 return ( it != groups.end() );
93 }
94};
95
96void OThemeBase::generateBorderPix( int i )
97{
98 // separate pixmap into separate components
99 if ( pbPixmaps[ i ] ) {
100 // evidently I have to do masks manually...
101 const QBitmap * srcMask = pbPixmaps[ i ] ->mask();
102 QBitmap destMask( pbWidth[ i ], pbWidth[ i ] );
103 QPixmap tmp( pbWidth[ i ], pbWidth[ i ] );
104
105 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, 0, pbWidth[ i ], pbWidth[ i ],
106 Qt::CopyROP, false );
107 if ( srcMask ) {
108 bitBlt( &destMask, 0, 0, srcMask, 0, 0, pbWidth[ i ], pbWidth[ i ],
109 Qt::CopyROP, false );
110 tmp.setMask( destMask );
111 }
112 pbPixmaps[ i ] ->setBorder( OThemePixmap::TopLeft, tmp );
113
114 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ], 0,
115 pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
116 if ( srcMask ) {
117 bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ],
118 0, pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
119 tmp.setMask( destMask );
120 }
121 pbPixmaps[ i ] ->setBorder( OThemePixmap::TopRight, tmp );
122
123 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, pbPixmaps[ i ] ->height() - pbWidth[ i ],
124 pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
125 if ( srcMask ) {
126 bitBlt( &destMask, 0, 0, srcMask, 0, pbPixmaps[ i ] ->height() - pbWidth[ i ],
127 pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
128 tmp.setMask( destMask );
129 }
130 pbPixmaps[ i ] ->setBorder( OThemePixmap::BottomLeft, tmp );
131
132 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ],
133 pbPixmaps[ i ] ->height() - pbWidth[ i ], pbWidth[ i ], pbWidth[ i ],
134 Qt::CopyROP, false );
135 if ( srcMask ) {
136 bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ],
137 pbPixmaps[ i ] ->height() - pbWidth[ i ], pbWidth[ i ], pbWidth[ i ],
138 Qt::CopyROP, false );
139 tmp.setMask( destMask );
140 }
141 pbPixmaps[ i ] ->setBorder( OThemePixmap::BottomRight, tmp );
142
143 tmp.resize( pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ] );
144 destMask.resize( pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ] );
145 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbWidth[ i ], 0,
146 pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false );
147 if ( srcMask ) {
148 bitBlt( &destMask, 0, 0, srcMask, pbWidth[ i ], 0,
149 pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ],
150 Qt::CopyROP, false );
151 tmp.setMask( destMask );
152 }
153 pbPixmaps[ i ] ->setBorder( OThemePixmap::Top, tmp );
154
155 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbWidth[ i ],
156 pbPixmaps[ i ] ->height() - pbWidth[ i ],
157 pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false );
158 if ( srcMask ) {
159 bitBlt( &destMask, 0, 0, srcMask, pbWidth[ i ],
160 pbPixmaps[ i ] ->height() - pbWidth[ i ],
161 pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false );
162 tmp.setMask( destMask );
163 }
164 pbPixmaps[ i ] ->setBorder( OThemePixmap::Bottom, tmp );
165
166 tmp.resize( pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2 );
167 destMask.resize( pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2 );
168 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, pbWidth[ i ], pbWidth[ i ],
169 pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2, Qt::CopyROP, false );
170 if ( srcMask ) {
171 bitBlt( &destMask, 0, 0, srcMask, 0, pbWidth[ i ], pbWidth[ i ],
172 pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2, Qt::CopyROP, false );
173 tmp.setMask( destMask );
174 }
175
176 pbPixmaps[ i ] ->setBorder( OThemePixmap::Left, tmp );
177
178 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ],
179 pbWidth[ i ], pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2,
180 Qt::CopyROP, false );
181 if ( srcMask ) {
182 bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ],
183 pbWidth[ i ], pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2,
184 Qt::CopyROP, false );
185 tmp.setMask( destMask );
186 }
187 pbPixmaps[ i ] ->setBorder( OThemePixmap::Right, tmp );
188 }
189 else
190 qDebug ( "OThemeBase: Tried making border from empty pixmap" );
191}
192
193
194void OThemeBase::copyWidgetConfig( int sourceID, int destID, QString *pixnames,
195 QString *brdnames )
196{
197 scaleHints[ destID ] = scaleHints[ sourceID ];
198 gradients[ destID ] = gradients[ sourceID ];
199 blends[ destID ] = blends[ sourceID ];
200 bContrasts[ destID ] = bContrasts[ sourceID ];
201 borders[ destID ] = borders[ sourceID ];
202 highlights[ destID ] = highlights[ sourceID ];
203
204 if ( grLowColors[ sourceID ] )
205 grLowColors[ destID ] = new QColor( *grLowColors[ sourceID ] );
206 else
207 grLowColors[ destID ] = NULL;
208
209 if ( grHighColors[ sourceID ] )
210 grHighColors[ destID ] = new QColor( *grHighColors[ sourceID ] );
211 else
212 grHighColors[ destID ] = NULL;
213
214 if ( colors[ sourceID ] )
215 colors[ destID ] = new QColorGroup( *colors[ sourceID ] );
216 else
217 colors[ destID ] = NULL;
218
219 // pixmap
220 pixnames[ destID ] = pixnames[ sourceID ];
221 duplicate[ destID ] = false;
222 pixmaps[ destID ] = NULL;
223 images[ destID ] = NULL;
224 if ( !pixnames[ destID ].isEmpty() ) {
225 if ( scaleHints[ sourceID ] == TileScale && blends[ sourceID ] == 0.0 ) {
226 pixmaps[ destID ] = pixmaps[ sourceID ];
227 duplicate[ destID ] = true;
228 }
229 if ( !duplicate[ destID ] ) {
230 pixmaps[ destID ] = loadPixmap( pixnames[ destID ] );
231 if ( scaleHints[ destID ] == TileScale && blends[ destID ] == 0.0 )
232 images[ destID ] = NULL;
233 else
234 images[ destID ] = loadImage( pixnames[ destID ] );
235 }
236 }
237
238 // border pixmap
239 pbDuplicate[ destID ] = false;
240 pbPixmaps[ destID ] = NULL;
241 pbWidth[ destID ] = pbWidth[ sourceID ];
242 brdnames[ destID ] = brdnames[ sourceID ];
243 if ( !brdnames[ destID ].isEmpty() ) {
244 pbPixmaps[ destID ] = pbPixmaps[ sourceID ];
245 pbDuplicate[ destID ] = true;
246 }
247
248 if ( sourceID == ActiveTab && destID == InactiveTab )
249 aTabLine = iTabLine;
250 else if ( sourceID == InactiveTab && destID == ActiveTab )
251 iTabLine = aTabLine;
252}
253
254void OThemeBase::readConfig( Qt::GUIStyle /*style*/ )
255{
256#define PREBLEND_ITEMS 12
257 static WidgetType preBlend[] = {Slider, IndicatorOn, IndicatorOff,
258 ExIndicatorOn, ExIndicatorOff, HScrollDeco, VScrollDeco, HScrollDecoDown,
259 VScrollDecoDown, ComboDeco, ComboDecoDown, CheckMark};
260
261 int i;
262 QString tmpStr;
263 QString copyfrom[ WIDGETS ];
264 QString pixnames[ WIDGETS ]; // used for duplicate check
265 QString brdnames[ WIDGETS ];
266 bool loaded[ WIDGETS ]; // used for preloading for CopyWidget
267
268 if ( configFileName.isEmpty() ) {
269 Config cfg ( "qpe" );
270 cfg. setGroup ( "Appearance" );
271
272 configFileName = cfg. readEntry ( "Theme", "default" );
273 }
274 MyConfig config( configFilePath + "/themes/" + configFileName + ".themerc" , Config::File );
275
276 printf ( "Opened config file: %s\n", ( configFilePath + "/themes/" + configFileName + ".themerc" ). ascii());
277
278 // Are we initalized?
279 for ( i = 0; i < INHERIT_ITEMS; ++i ) {
280 applyResourceGroup( &config, i, copyfrom, pixnames, brdnames );
281 printf ( "%d [%s]: copy=%s, pix=%s, brd=%s\n", i, widgetEntries [i], copyfrom [i].latin1(), pixnames[i].latin1(),brdnames[i].latin1() );
282 }
283 for ( ; i < INHERIT_ITEMS*2; ++i ) {
284 if ( config.hasGroup( QString( widgetEntries[ i ] ) ) ) {
285 applyResourceGroup( &config, i, copyfrom, pixnames, brdnames );
286 printf ( "%d [%s]: copy=%s, pix=%s, brd=%s\n", i, widgetEntries [i], copyfrom [i].latin1(), pixnames[i].latin1(),brdnames[i].latin1() );
287 }
288 else {
289 copyfrom [ i ] = widgetEntries[ i - INHERIT_ITEMS ];
290 printf ( "%d [%s]: copy=%s\n", i, widgetEntries [i], copyfrom [i].latin1());
291 }
292 }
293 for ( ; i < WIDGETS; ++i ) {
294 applyResourceGroup( &config, i, copyfrom, pixnames, brdnames );
295 printf ( "%d [%s]: copy=%s, pix=%s, brd=%s\n", i, widgetEntries [i], copyfrom [i].latin1(), pixnames[i].latin1(),brdnames[i].latin1() );
296 }
297 applyMiscResourceGroup( &config );
298
299 // initalize defaults that may not be read
300 for ( i = 0; i < WIDGETS; ++i )
301 loaded[ i ] = false;
302 btnXShift = btnYShift = focus3DOffset = 0;
303 aTabLine = iTabLine = true;
304 roundedButton = roundedCombo = roundedSlider = focus3D = false;
305 splitterWidth = 10;
306
307 for ( i = 0; i < WIDGETS; ++i ) {
308 readResourceGroup( i, copyfrom, pixnames, brdnames, loaded );
309 printf ( "%d [%s]: copy=%s, pix=%s, brd=%s, colors=%s\n", i, widgetEntries [i], copyfrom [i].latin1(), pixnames[i].latin1(),brdnames[i].latin1(), (colors[i]?colors[i]->background().name().latin1():"<none)" ));
310 }
311
312 // misc items
313 readMiscResourceGroup();
314
315 // Handle preblend items
316 for ( i = 0; i < PREBLEND_ITEMS; ++i ) {
317 if ( pixmaps[ preBlend[ i ] ] != NULL && blends[ preBlend[ i ] ] != 0.0 )
318 blend( preBlend[ i ] );
319 }
320}
321
322OThemeBase::OThemeBase( const QString & configFile )
323 : QWindowsStyle()
324{
325 configFilePath = QPEApplication::qpeDir ( ) + "/plugins/styles/";
326 configFileName = configFile;
327
328 readConfig( Qt::WindowsStyle );
329 cache = new OThemeCache( cacheSize );
330}
331
332void OThemeBase::applyConfigFile( const QString &/*file*/ )
333{
334#if 0
335 // handle std color scheme
336 Config inConfig( file, Config::File );
337 Config globalConfig ( "qpe" );
338
339 globalConfig. setGroup ( "Apperance" );
340 inConfig. setGroup( "General" );
341
342 if ( inConfig.hasKey( "foreground" ) )
343 globalConfig.writeEntry( "Text", inConfig.readEntry( "foreground", " " ) );
344 if ( inConfig.hasKey( "background" ) )
345 globalConfig.writeEntry( "Background", inConfig.readEntry( "background", " " ) );
346 if ( inConfig.hasKey( "selectForeground" ) )
347 globalConfig.writeEntry( "HighlightedText", inConfig.readEntry( "selectForeground", " " ) );
348 if ( inConfig.hasKey( "selectBackground" ) )
349 globalConfig.writeEntry( "Highlight", inConfig.readEntry( "selectBackground", " " ) );
350 if ( inConfig.hasKey( "windowForeground" ) )
351 globalConfig.writeEntry( "Text", inConfig.readEntry( "windowForeground", " " ) );
352 if ( inConfig.hasKey( "windowBackground" ) )
353 globalConfig.writeEntry( "Base", inConfig.readEntry( "windowBackground", " " ) );
354
355 // Keep track of the current theme so that we can select the right one
356 // in the KControl module.
357 globalConfig.writeEntry ( "CurrentTheme", file );
358
359 globalConfig.write();
360#endif
361}
362
363OThemeBase::~OThemeBase()
364{
365 int i;
366 for ( i = 0; i < WIDGETS; ++i ) {
367 if ( !duplicate[ i ] ) {
368 if ( images[ i ] )
369 delete images[ i ];
370 if ( pixmaps[ i ] )
371 delete pixmaps[ i ];
372 }
373 if ( !pbDuplicate[ i ] && pbPixmaps[ i ] )
374 delete pbPixmaps[ i ];
375 if ( colors[ i ] )
376 delete( colors[ i ] );
377 if ( grLowColors[ i ] )
378 delete( grLowColors[ i ] );
379 if ( grHighColors[ i ] )
380 delete( grHighColors[ i ] );
381 }
382 delete cache;
383}
384
385QImage* OThemeBase::loadImage( QString &name )
386{
387 QImage * image = new QImage;
388 QString path = configFilePath + "/pixmaps/" + name;
389 image->load( path );
390 if ( !image->isNull() )
391 return ( image );
392 qDebug ( "OThemeBase: Unable to load image %s\n", name.ascii ( ) );
393 delete image;
394 return ( NULL );
395}
396
397OThemePixmap* OThemeBase::loadPixmap( QString &name )
398{
399 OThemePixmap * pixmap = new OThemePixmap( false );
400 QString path = configFilePath + "/pixmaps/" + name;
401 pixmap->load( path );
402 if ( !pixmap->isNull() )
403 return pixmap;
404 qDebug ( "OThemeBase: Unable to load pixmap %s\n", name.ascii() );
405 delete pixmap;
406 return ( NULL );
407}
408
409OThemePixmap* OThemeBase::scale( int w, int h, WidgetType widget )
410{
411 if ( scaleHints[ widget ] == FullScale ) {
412 if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
413 pixmaps[ widget ] ->height() != h ) {
414 OThemePixmap * cachePix = cache->pixmap( w, h, widget );
415 if ( cachePix ) {
416 cachePix = new OThemePixmap( *cachePix );
417 if ( pixmaps[ widget ] )
418 cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
419 widget );
420 else
421 qDebug( "We would have inserted a null pixmap!\n" );
422 pixmaps[ widget ] = cachePix;
423 }
424 else {
425 cache->insert( pixmaps[ widget ], OThemeCache::FullScale, widget );
426 QImage tmpImg = images[ widget ] ->smoothScale( w, h );
427 pixmaps[ widget ] = new OThemePixmap;
428 pixmaps[ widget ] ->convertFromImage( tmpImg );
429 if ( blends[ widget ] != 0.0 )
430 blend( widget );
431 }
432 }
433 }
434 else if ( scaleHints[ widget ] == HorizontalScale ) {
435 if ( pixmaps[ widget ] ->width() != w ) {
436 OThemePixmap * cachePix = cache->horizontalPixmap( w, widget );
437 if ( cachePix ) {
438 cachePix = new OThemePixmap( *cachePix );
439 if ( pixmaps[ widget ] )
440 cache->insert( pixmaps[ widget ], OThemeCache::HorizontalScale, widget );
441 else
442 qDebug ( "We would have inserted a null pixmap!\n" );
443 pixmaps[ widget ] = cachePix;
444 }
445 else {
446 cache->insert( pixmaps[ widget ], OThemeCache::HorizontalScale, widget );
447 QImage tmpImg = images[ widget ] ->
448 smoothScale( w, images[ widget ] ->height() );
449 pixmaps[ widget ] = new OThemePixmap;
450 pixmaps[ widget ] ->convertFromImage( tmpImg );
451 if ( blends[ widget ] != 0.0 )
452 blend( widget );
453 }
454 }
455 }
456 else if ( scaleHints[ widget ] == VerticalScale ) {
457 if ( pixmaps[ widget ] ->height() != h ) {
458 OThemePixmap * cachePix = cache->verticalPixmap( w, widget );
459 if ( cachePix ) {
460 cachePix = new OThemePixmap( *cachePix );
461 if ( pixmaps[ widget ] )
462 cache->insert( pixmaps[ widget ], OThemeCache::VerticalScale, widget );
463 else
464 qDebug ( "We would have inserted a null pixmap!\n" );
465 pixmaps[ widget ] = cachePix;
466 }
467 else {
468 cache->insert( pixmaps[ widget ], OThemeCache::VerticalScale, widget );
469 QImage tmpImg =
470 images[ widget ] ->smoothScale( images[ widget ] ->width(), h );
471 pixmaps[ widget ] = new OThemePixmap;
472 pixmaps[ widget ] ->convertFromImage( tmpImg );
473 if ( blends[ widget ] != 0.0 )
474 blend( widget );
475 }
476 }
477 }
478 // If blended tile here so the blend is scaled properly
479 else if ( scaleHints[ widget ] == TileScale && blends[ widget ] != 0.0 ) {
480 if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
481 pixmaps[ widget ] ->height() != h ) {
482 OThemePixmap * cachePix = cache->pixmap( w, h, widget );
483 if ( cachePix ) {
484 cachePix = new OThemePixmap( *cachePix );
485 cache->insert( pixmaps[ widget ], OThemeCache::FullScale, widget );
486 pixmaps[ widget ] = cachePix;
487 }
488 else {
489 cache->insert( pixmaps[ widget ], OThemeCache::FullScale, widget );
490 QPixmap tile;
491 tile.convertFromImage( *images[ widget ] );
492 pixmaps[ widget ] = new OThemePixmap;
493 pixmaps[ widget ] ->resize( w, h );
494 QPainter p( pixmaps[ widget ] );
495 p.drawTiledPixmap( 0, 0, w, h, tile );
496 if ( blends[ widget ] != 0.0 )
497 blend( widget );
498 }
499 }
500 }
501 return ( pixmaps[ widget ] );
502}
503
504OThemePixmap* OThemeBase::scaleBorder( int w, int h, WidgetType widget )
505{
506 OThemePixmap * pixmap = NULL;
507 if ( !pbPixmaps[ widget ] && !pbWidth[ widget ] )
508 return ( NULL );
509 pixmap = cache->pixmap( w, h, widget, true );
510 if ( pixmap ) {
511 pixmap = new OThemePixmap( *pixmap );
512 }
513 else {
514 pixmap = new OThemePixmap();
515 pixmap->resize( w, h );
516 QBitmap mask;
517 mask.resize( w, h );
518 mask.fill( color0 );
519 QPainter mPainter;
520 mPainter.begin( &mask );
521
522 QPixmap *tmp = borderPixmap( widget ) ->border( OThemePixmap::TopLeft );
523 const QBitmap *srcMask = tmp->mask();
524 int bdWidth = tmp->width();
525
526 bitBlt( pixmap, 0, 0, tmp, 0, 0, bdWidth, bdWidth,
527 Qt::CopyROP, false );
528 if ( srcMask )
529 bitBlt( &mask, 0, 0, srcMask, 0, 0, bdWidth, bdWidth,
530 Qt::CopyROP, false );
531 else
532 mPainter.fillRect( 0, 0, bdWidth, bdWidth, color1 );
533
534
535 tmp = borderPixmap( widget ) ->border( OThemePixmap::TopRight );
536 srcMask = tmp->mask();
537 bitBlt( pixmap, w - bdWidth, 0, tmp, 0, 0, bdWidth,
538 bdWidth, Qt::CopyROP, false );
539 if ( srcMask )
540 bitBlt( &mask, w - bdWidth, 0, srcMask, 0, 0, bdWidth,
541 bdWidth, Qt::CopyROP, false );
542 else
543 mPainter.fillRect( w - bdWidth, 0, bdWidth, bdWidth, color1 );
544
545 tmp = borderPixmap( widget ) ->border( OThemePixmap::BottomLeft );
546 srcMask = tmp->mask();
547 bitBlt( pixmap, 0, h - bdWidth, tmp, 0, 0, bdWidth,
548 bdWidth, Qt::CopyROP, false );
549 if ( srcMask )
550 bitBlt( &mask, 0, h - bdWidth, srcMask, 0, 0, bdWidth,
551 bdWidth, Qt::CopyROP, false );
552 else
553 mPainter.fillRect( 0, h - bdWidth, bdWidth, bdWidth, color1 );
554
555 tmp = borderPixmap( widget ) ->border( OThemePixmap::BottomRight );
556 srcMask = tmp->mask();
557 bitBlt( pixmap, w - bdWidth, h - bdWidth, tmp, 0, 0,
558 bdWidth, bdWidth, Qt::CopyROP, false );
559 if ( srcMask )
560 bitBlt( &mask, w - bdWidth, h - bdWidth, srcMask, 0, 0,
561 bdWidth, bdWidth, Qt::CopyROP, false );
562 else
563 mPainter.fillRect( w - bdWidth, h - bdWidth, bdWidth, bdWidth, color1 );
564
565 QPainter p;
566 p.begin( pixmap );
567 if ( w - bdWidth * 2 > 0 ) {
568 tmp = borderPixmap( widget ) ->border( OThemePixmap::Top );
569 srcMask = tmp->mask();
570 p.drawTiledPixmap( bdWidth, 0, w - bdWidth * 2, bdWidth, *tmp );
571 if ( srcMask )
572 mPainter.drawTiledPixmap( bdWidth, 0, w - bdWidth * 2, bdWidth, *srcMask );
573 else
574 mPainter.fillRect( bdWidth, 0, w - bdWidth * 2, bdWidth, color1 );
575
576 tmp = borderPixmap( widget ) ->border( OThemePixmap::Bottom );
577 srcMask = tmp->mask();
578 p.drawTiledPixmap( bdWidth, h - bdWidth, w - bdWidth * 2, bdWidth,
579 *tmp );
580 if ( srcMask )
581 mPainter.drawTiledPixmap( bdWidth, h - bdWidth, w - bdWidth * 2, bdWidth, *srcMask );
582 else
583 mPainter.fillRect( bdWidth, h - bdWidth, w - bdWidth * 2, bdWidth,
584 color1 );
585 }
586 if ( h - bdWidth * 2 > 0 ) {
587 tmp = borderPixmap( widget ) ->border( OThemePixmap::Left );
588 srcMask = tmp->mask();
589 p.drawTiledPixmap( 0, bdWidth, bdWidth, h - bdWidth * 2, *tmp );
590 if ( srcMask )
591 mPainter.drawTiledPixmap( 0, bdWidth, bdWidth, h - bdWidth * 2, *srcMask );
592 else
593 mPainter.fillRect( 0, bdWidth, bdWidth, h - bdWidth * 2, color1 );
594
595 tmp = borderPixmap( widget ) ->border( OThemePixmap::Right );
596 srcMask = tmp->mask();
597 p.drawTiledPixmap( w - bdWidth, bdWidth, bdWidth, h - bdWidth * 2,
598 *tmp );
599 if ( srcMask )
600 mPainter.drawTiledPixmap( w - bdWidth, bdWidth, bdWidth, h - bdWidth * 2, *srcMask );
601 else
602 mPainter.fillRect( w - bdWidth, bdWidth, bdWidth, h - bdWidth * 2, color1 );
603 }
604 p.end();
605 mPainter.end();
606 pixmap->setMask( mask );
607 cache->insert( pixmap, OThemeCache::FullScale, widget, true );
608 if ( !pixmap->mask() )
609 qDebug ( "No mask for border pixmap!\n" );
610 }
611 return ( pixmap );
612}
613
614
615OThemePixmap* OThemeBase::blend( WidgetType widget )
616{
617 OGfxEffect::GradientType g;
618 switch ( gradients[ widget ] ) {
619 case GrHorizontal:
620 g = OGfxEffect::HorizontalGradient;
621 break;
622 case GrVertical:
623 g = OGfxEffect::VerticalGradient;
624 break;
625 case GrPyramid:
626 g = OGfxEffect::PyramidGradient;
627 break;
628 case GrRectangle:
629 g = OGfxEffect::RectangleGradient;
630 break;
631 case GrElliptic:
632 g = OGfxEffect::EllipticGradient;
633 break;
634 default:
635 g = OGfxEffect::DiagonalGradient;
636 break;
637 }
638 OGfxEffect::blend( *pixmaps[ widget ], blends[ widget ], *grLowColors[ widget ],
639 g, false );
640 return ( pixmaps[ widget ] );
641}
642
643OThemePixmap* OThemeBase::gradient( int w, int h, WidgetType widget )
644{
645 if ( gradients[ widget ] == GrVertical ) {
646 if ( !pixmaps[ widget ] || pixmaps[ widget ] ->height() != h ) {
647 OThemePixmap * cachePix = cache->verticalPixmap( h, widget );
648 if ( cachePix ) {
649 cachePix = new OThemePixmap( *cachePix );
650 if ( pixmaps[ widget ] )
651 cache->insert( pixmaps[ widget ], OThemeCache::VerticalScale,
652 widget );
653 pixmaps[ widget ] = cachePix;
654 }
655 else {
656 if ( pixmaps[ widget ] )
657 cache->insert( pixmaps[ widget ], OThemeCache::VerticalScale,
658 widget );
659 pixmaps[ widget ] = new OThemePixmap;
660 pixmaps[ widget ] ->resize( w, h );
661 OGfxEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ],
662 *grLowColors[ widget ],
663 OGfxEffect::VerticalGradient );
664 }
665 }
666 }
667 else if ( gradients[ widget ] == GrHorizontal ) {
668 if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ) {
669 OThemePixmap * cachePix = cache->horizontalPixmap( w, widget );
670 if ( cachePix ) {
671 cachePix = new OThemePixmap( *cachePix );
672 if ( pixmaps[ widget ] )
673 cache->insert( pixmaps[ widget ],
674 OThemeCache::HorizontalScale, widget );
675 pixmaps[ widget ] = cachePix;
676 }
677 else {
678 if ( pixmaps[ widget ] )
679 cache->insert( pixmaps[ widget ],
680 OThemeCache::HorizontalScale, widget );
681 pixmaps[ widget ] = new OThemePixmap;
682 pixmaps[ widget ] ->resize( w, h );
683 OGfxEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ],
684 *grLowColors[ widget ],
685 OGfxEffect::HorizontalGradient );
686 }
687 }
688 }
689 else if ( gradients[ widget ] == GrReverseBevel ) {
690 if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
691 pixmaps[ widget ] ->height() != h ) {
692 OThemePixmap * cachePix = cache->pixmap( w, h, widget );
693 if ( cachePix ) {
694 cachePix = new OThemePixmap( *cachePix );
695 if ( pixmaps[ widget ] )
696 cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
697 widget );
698 pixmaps[ widget ] = cachePix;
699 }
700 else {
701 if ( pixmaps[ widget ] )
702 cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
703 widget );
704 pixmaps[ widget ] = new OThemePixmap;
705 pixmaps[ widget ] ->resize( w, h );
706
707 QPixmap s;
708 int offset = decoWidth( widget );
709 s.resize( w - offset * 2, h - offset * 2 );
710 QColor lc( *grLowColors[ widget ] );
711 QColor hc( *grHighColors[ widget ] );
712 if ( bevelContrast( widget ) ) {
713 int bc = bevelContrast( widget );
714 // want single increments, not factors like light()/dark()
715 lc.setRgb( lc.red() - bc, lc.green() - bc, lc.blue() - bc );
716 hc.setRgb( hc.red() + bc, hc.green() + bc, hc.blue() + bc );
717 }
718 OGfxEffect::gradient( *pixmaps[ widget ],
719 lc, hc,
720 OGfxEffect::DiagonalGradient );
721 OGfxEffect::gradient( s, *grHighColors[ widget ],
722 *grLowColors[ widget ],
723 OGfxEffect::DiagonalGradient );
724 bitBlt( pixmaps[ widget ], offset, offset, &s, 0, 0, w - offset * 2,
725 h - offset * 2, Qt::CopyROP );
726 }
727 }
728 }
729 else {
730 OGfxEffect::GradientType g;
731 switch ( gradients[ widget ] ) {
732 case GrPyramid:
733 g = OGfxEffect::PyramidGradient;
734 break;
735 case GrRectangle:
736 g = OGfxEffect::RectangleGradient;
737 break;
738 case GrElliptic:
739 g = OGfxEffect::EllipticGradient;
740 break;
741 default:
742 g = OGfxEffect::DiagonalGradient;
743 break;
744 }
745 if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
746 pixmaps[ widget ] ->height() != h ) {
747 OThemePixmap * cachePix = cache->pixmap( w, h, widget );
748 if ( cachePix ) {
749 cachePix = new OThemePixmap( *cachePix );
750 if ( pixmaps[ widget ] )
751 cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
752 widget );
753 pixmaps[ widget ] = cachePix;
754 }
755 else {
756 if ( pixmaps[ widget ] )
757 cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
758 widget );
759 pixmaps[ widget ] = new OThemePixmap;
760 pixmaps[ widget ] ->resize( w, h );
761 OGfxEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ],
762 *grLowColors[ widget ], g );
763 }
764 }
765 }
766 return ( pixmaps[ widget ] );
767}
768
769OThemePixmap* OThemeBase::scalePixmap( int w, int h, WidgetType widget )
770{
771
772 if ( gradients[ widget ] && blends[ widget ] == 0.0 )
773 return ( gradient( w, h, widget ) );
774
775 return ( scale( w, h, widget ) );
776}
777
778QColorGroup* OThemeBase::makeColorGroup( QColor &fg, QColor &bg,
779 Qt::GUIStyle )
780{
781 if ( shading == Motif ) {
782 int highlightVal, lowlightVal;
783 highlightVal = 100 + ( 2* /*KGlobalSettings::contrast()*/ 3 + 4 ) * 16 / 10;
784 lowlightVal = 100 + ( ( 2* /*KGlobalSettings::contrast()*/ 3 + 4 ) * 10 );
785 return ( new QColorGroup( fg, bg, bg.light( highlightVal ),
786 bg.dark( lowlightVal ), bg.dark( 120 ),
787 fg, qApp->palette().normal().base() ) );
788 }
789 else
790 return ( new QColorGroup( fg, bg, bg.light( 150 ), bg.dark(),
791 bg.dark( 120 ), fg,
792 qApp->palette().normal().base() ) );
793}
794
795static QColor strToColor ( const QString &str )
796{
797 QString str2 = str. stripWhiteSpace ( );
798
799 if ( str2 [0] == '#' )
800 return QColor ( str2 );
801 else {
802 QStringList sl = QStringList::split ( ',', str2 );
803
804 if ( sl. count ( ) >= 3 )
805 return QColor ( sl [0]. toInt ( ), sl [1]. toInt ( ), sl [2]. toInt ( ));
806 }
807 return QColor ( 0, 0, 0 );
808}
809
810
811
812void OThemeBase::applyMiscResourceGroup( Config *config )
813{
814 config-> setGroup ( "Misc" );
815 QString tmpStr;
816
817 tmpStr = config->readEntry( "SButtonPosition" );
818 if ( tmpStr == "BottomLeft" )
819 sbPlacement = SBBottomLeft;
820 else if ( tmpStr == "BottomRight" )
821 sbPlacement = SBBottomRight;
822 else {
823 if ( tmpStr != "Opposite" && !tmpStr.isEmpty() )
824 qDebug ( "OThemeBase: Unrecognized sb button option %s, using Opposite.\n", tmpStr.ascii() );
825 sbPlacement = SBOpposite;
826 }
827 tmpStr = config->readEntry( "ArrowType" );
828 if ( tmpStr == "Small" )
829 arrowStyle = SmallArrow;
830 else if ( tmpStr == "3D" )
831 arrowStyle = MotifArrow;
832 else {
833 if ( tmpStr != "Normal" && !tmpStr.isEmpty() )
834 qDebug ( "OThemeBase: Unrecognized arrow option %s, using Normal.\n", tmpStr.ascii() );
835 arrowStyle = LargeArrow;
836 }
837 tmpStr = config->readEntry( "ShadeStyle" );
838 if ( tmpStr == "Motif" )
839 shading = Motif;
840 else if ( tmpStr == "Next" )
841 shading = Next;
842 else if ( tmpStr == "KDE" )
843 shading = KDE;
844 else
845 shading = Windows;
846
847 defaultFrame = config->readNumEntry( "FrameWidth", 2 );
848 cacheSize = config->readNumEntry( "Cache", 1024 );
849 sbExtent = config->readNumEntry( "ScrollBarExtent", 16 );
850
851 config-> setGroup ( "General" );
852
853 if ( config-> hasKey ( "foreground" )) fgcolor = strToColor ( config-> readEntry ( "foreground" ));
854 if ( config-> hasKey ( "background" )) bgcolor = strToColor ( config-> readEntry ( "background" ));
855 if ( config-> hasKey ( "selectForeground" )) selfgcolor = strToColor ( config-> readEntry ( "selectForeground" ));
856 if ( config-> hasKey ( "selectBackground" )) selbgcolor = strToColor ( config-> readEntry ( "selectBackground" ));
857 if ( config-> hasKey ( "windowForeground" )) winfgcolor = strToColor ( config-> readEntry ( "windowForeground" ));
858 if ( config-> hasKey ( "windowBackground" )) winbgcolor = strToColor ( config-> readEntry ( "windowBackground" ));
859}
860
861void OThemeBase::readMiscResourceGroup()
862{}
863
864void OThemeBase::applyResourceGroup( Config *config, int i, QString *copyfrom, QString *pixnames, QString *brdnames )
865{
866 QString tmpStr;
867
868 config-> setGroup ( widgetEntries [ i ] );
869
870 tmpStr = config->readEntry( "CopyWidget", "" );
871 copyfrom [ i ] = tmpStr;
872 if ( !tmpStr.isEmpty() )
873 return ;
874
875 // Scale hint
876 tmpStr = config->readEntry( "Scale" );
877 if ( tmpStr == "Full" )
878 scaleHints [ i ] = FullScale;
879 else if ( tmpStr == "Horizontal" )
880 scaleHints [ i ] = HorizontalScale;
881 else if ( tmpStr == "Vertical" )
882 scaleHints [ i ] = VerticalScale;
883 else {
884 if ( tmpStr != "Tile" && !tmpStr.isEmpty() )
885 qDebug ( "OThemeBase: Unrecognized scale option %s, using Tile.\n", tmpStr.ascii() );
886 scaleHints [ i ] = TileScale;
887 }
888
889
890 // Gradient type
891 tmpStr = config->readEntry( "Gradient" );
892 if ( tmpStr == "Diagonal" )
893 gradients [ i ] = GrDiagonal;
894 else if ( tmpStr == "Horizontal" )
895 gradients [ i ] = GrHorizontal;
896 else if ( tmpStr == "Vertical" )
897 gradients [ i ] = GrVertical;
898 else if ( tmpStr == "Pyramid" )
899 gradients [ i ] = GrPyramid;
900 else if ( tmpStr == "Rectangle" )
901 gradients [ i ] = GrRectangle;
902 else if ( tmpStr == "Elliptic" )
903 gradients [ i ] = GrElliptic;
904 else if ( tmpStr == "ReverseBevel" )
905 gradients [ i ] = GrReverseBevel;
906 else {
907 if ( tmpStr != "None" && !tmpStr.isEmpty() )
908 qDebug ( "OThemeBase: Unrecognized gradient option %s, using None.\n", tmpStr.ascii() );
909 gradients [ i ] = GrNone;
910 }
911
912 // Blend intensity
913 blends[ i ] = config->readEntry( "BlendIntensity", "0.0" ).toDouble();
914
915 // Bevel contrast
916 bContrasts[ i ] = config->readNumEntry( "BevelContrast", 0 );
917
918 // Border width
919 borders [ i ] = config->readNumEntry( "Border", 1 );
920
921 // Highlight width
922 highlights [ i ] = config->readNumEntry( "Highlight", 1 );
923
924 // Gradient low color or blend background
925 if ( config->hasKey( "GradientLow" ) && ( gradients[ i ] != GrNone || blends[ i ] != 0.0 ))
926 grLowColors[ i ] = new QColor( strToColor ( config->readEntry( "GradientLow", qApp->palette().normal().background().name() )));
927 else
928 grLowColors[ i ] = NULL;
929
930
931 // Gradient high color
932 if ( config->hasKey( "GradientHigh" ) && ( gradients[ i ] != GrNone ))
933 grHighColors[ i ] = new QColor( strToColor ( config->readEntry( "GradientHigh", qApp->palette().normal().background().name() )));
934 else
935 grHighColors[ i ] = NULL;
936
937 // Extended color attributes
938 if ( config->hasKey( "Foreground" ) || config->hasKey( "Background" ) ) {
939 QColor bg = strToColor( config->readEntry( "Background", qApp->palette().normal().background().name() ));
940 QColor fg = strToColor( config->readEntry( "Foreground", qApp->palette().normal().foreground().name() ));
941
942 colors[ i ] = makeColorGroup( fg, bg, Qt::WindowsStyle );
943 }
944 else
945 colors[ i ] = NULL;
946
947 // Pixmap
948 tmpStr = config->readEntry( "Pixmap", "" );
949 pixnames[ i ] = tmpStr;
950 duplicate[ i ] = false;
951 pixmaps[ i ] = NULL;
952 images[ i ] = NULL;
953
954
955 // Pixmap border
956 tmpStr = config->readEntry( "PixmapBorder", "" );
957 brdnames[ i ] = tmpStr;
958 pbDuplicate[ i ] = false;
959 pbPixmaps[ i ] = NULL;
960 pbWidth[ i ] = 0;
961 if ( !tmpStr.isEmpty() ) {
962 pbWidth[ i ] = config->readNumEntry( "PixmapBWidth", 0 );
963 if ( pbWidth[ i ] == 0 ) {
964 qDebug ( "OThemeBase: No border width specified for pixmapped border widget %s\n", widgetEntries[ i ] );
965 qDebug ( "OThemeBase: Using default of 2.\n" );
966 pbWidth[ i ] = 2;
967 }
968 }
969
970
971 // Various widget specific settings. This was more efficent when bunched
972 // together in the misc group, but this makes an easier to read config.
973 if ( i == SliderGroove )
974 roundedSlider = config->readBoolEntry( "SmallGroove", false );
975 else if ( i == ActiveTab || i == InactiveTab )
976 aTabLine = iTabLine = config->readBoolEntry( "BottomLine", true );
977 else if ( i == Splitter )
978 splitterWidth = config->readNumEntry( "Width", 10 );
979 else if ( i == ComboBox || i == ComboBoxDown ) {
980 roundedCombo = config->readBoolEntry( "Round", false );
981 }
982 else if ( i == PushButton || i == PushButtonDown ) {
983 btnXShift = config->readNumEntry( "XShift", 0 );
984 btnYShift = config->readNumEntry( "YShift", 0 );
985 focus3D = config->readBoolEntry( "3DFocusRect", false );
986 focus3DOffset = config->readBoolEntry( "3DFocusOffset", 0 );
987 roundedButton = config->readBoolEntry( "Round", false );
988 }
989}
990
991
992void OThemeBase::readResourceGroup( int i, QString *copyfrom, QString *pixnames, QString *brdnames,
993 bool *loadArray )
994{
995 if ( loadArray[ i ] == true ) {
996 return ; // already been preloaded.
997 }
998
999 int tmpVal;
1000 QString tmpStr;
1001
1002 tmpStr = copyfrom [ i ];
1003 if ( !tmpStr.isEmpty() ) { // Duplicate another widget's config
1004 int sIndex;
1005 loadArray[ i ] = true;
1006 for ( sIndex = 0; sIndex < WIDGETS; ++sIndex ) {
1007 if ( tmpStr == widgetEntries[ sIndex ] ) {
1008 if ( !loadArray[ sIndex ] ) // hasn't been loaded yet
1009 readResourceGroup( sIndex, copyfrom, pixnames, brdnames,
1010 loadArray );
1011 break;
1012 }
1013 }
1014 if ( loadArray[ sIndex ] ) {
1015 copyWidgetConfig( sIndex, i, pixnames, brdnames );
1016 }
1017 else
1018 qDebug ( "OThemeBase: Unable to identify source widget for %s\n", widgetEntries[ i ] );
1019 return ;
1020 }
1021 // special inheritance for disabled arrows (these are tri-state unlike
1022 // the rest of what we handle).
1023 for ( tmpVal = DisArrowUp; tmpVal <= DisArrowRight; ++tmpVal ) {
1024 if ( tmpVal == i ) {
1025 tmpStr = pixnames [ i ];
1026 if ( tmpStr.isEmpty() ) {
1027 copyWidgetConfig( ArrowUp + ( tmpVal - DisArrowUp ), i, pixnames,
1028 brdnames );
1029 return ;
1030 }
1031 }
1032 }
1033
1034 // Pixmap
1035 int existing;
1036 // Scan for duplicate pixmaps(two identical pixmaps, tile scale, no blend,
1037 // no pixmapped border)
1038 if ( !pixnames [ i ].isEmpty() ) {
1039 for ( existing = 0; existing < i; ++existing ) {
1040 if ( pixnames[ i ] == pixnames[ existing ] && scaleHints[ i ] == TileScale &&
1041 scaleHints[ existing ] == TileScale && blends[ existing ] == 0.0 &&
1042 blends[ i ] == 0.0 ) {
1043 pixmaps[ i ] = pixmaps[ existing ];
1044 duplicate[ i ] = true;
1045 break;
1046 }
1047 }
1048 }
1049 // load
1050 if ( !duplicate[ i ] && !pixnames[ i ].isEmpty() ) {
1051 pixmaps[ i ] = loadPixmap( pixnames[ i ] );
1052 // load and save images for scaled/blended widgets for speed.
1053 if ( scaleHints[ i ] == TileScale && blends[ i ] == 0.0 )
1054 images[ i ] = NULL;
1055 else
1056 images[ i ] = loadImage( pixnames[ i ] );
1057 }
1058
1059 // Pixmap border
1060 if ( !brdnames [ i ]. isEmpty () ) {
1061 // duplicate check
1062 for ( existing = 0; existing < i; ++existing ) {
1063 if ( brdnames [i] == brdnames[ existing ] ) {
1064 pbPixmaps[ i ] = pbPixmaps[ existing ];
1065 pbDuplicate[ i ] = true;
1066 break;
1067 }
1068 }
1069 }
1070 // load
1071 if ( !pbDuplicate[ i ] && !brdnames[ i ].isEmpty() )
1072 pbPixmaps[ i ] = loadPixmap( brdnames[ i ] );
1073
1074 if ( pbPixmaps[ i ] && !pbDuplicate[ i ] )
1075 generateBorderPix( i );
1076
1077 loadArray[ i ] = true;
1078}
1079
1080
1081OThemePixmap::OThemePixmap( bool timer )
1082 : QPixmap()
1083{
1084 if(timer){
1085 t = new QTime;
1086 t->start();
1087 }
1088 else
1089 t = NULL;
1090 int i;
1091 for ( i = 0; i < 8; ++i )
1092 b[ i ] = NULL;
1093}
1094
1095OThemePixmap::OThemePixmap( const OThemePixmap &p )
1096 : QPixmap( p )
1097{
1098 if(p.t){
1099 t = new QTime;
1100 t->start();
1101 }
1102 else
1103 t = NULL;
1104 int i;
1105 for ( i = 0; i < 8; ++i )
1106 if ( p.b[ i ] )
1107 b[ i ] = new QPixmap( *p.b[ i ] );
1108 else
1109 b[ i ] = NULL;
1110}
1111
1112
1113
1114OThemePixmap::~OThemePixmap()
1115{
1116 if(t)
1117 delete t;
1118 int i;
1119 for ( i = 0; i < 8; ++i )
1120 if ( b[ i ] )
1121 delete b[ i ];
1122}
1123
1124OThemeCache::OThemeCache( int maxSize, QObject *parent, const char *name )
1125 : QObject( parent, name )
1126{
1127 cache.setMaxCost( maxSize * 1024 );
1128 cache.setAutoDelete( true );
1129 flushTimer.start(300000); // 5 minutes
1130 connect(&flushTimer, SIGNAL(timeout()), SLOT(flushTimeout()));
1131}
1132
1133void OThemeCache::flushTimeout()
1134{
1135 QIntCacheIterator<OThemePixmap> it( cache );
1136 while ( it.current() ) {
1137 if ( it.current() ->isOld() )
1138 cache.remove( it.currentKey() );
1139 else
1140 ++it;
1141 }
1142}
1143
1144OThemePixmap* OThemeCache::pixmap( int w, int h, int widgetID, bool border,
1145 bool mask )
1146{
1147
1148 kthemeKey key;
1149 key.cacheKey = 0; // shut up, gcc
1150 key.data.id = widgetID;
1151 key.data.width = w;
1152 key.data.height = h;
1153 key.data.border = border;
1154 key.data.mask = mask;
1155
1156 OThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey );
1157 if ( pix )
1158 pix->updateAccessed();
1159 return ( pix );
1160}
1161
1162OThemePixmap* OThemeCache::horizontalPixmap( int w, int widgetID )
1163{
1164 kthemeKey key;
1165 key.cacheKey = 0; // shut up, gcc
1166 key.data.id = widgetID;
1167 key.data.width = w;
1168 key.data.height = 0;
1169 key.data.border = false;
1170 key.data.mask = false;
1171 OThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey );
1172 if ( pix )
1173 pix->updateAccessed();
1174 return ( pix );
1175}
1176
1177OThemePixmap* OThemeCache::verticalPixmap( int h, int widgetID )
1178{
1179 kthemeKey key;
1180 key.cacheKey = 0; // shut up, gcc
1181 key.data.id = widgetID;
1182 key.data.width = 0;
1183 key.data.height = h;
1184 key.data.border = false;
1185 key.data.mask = false;
1186 OThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey );
1187 if ( pix )
1188 pix->updateAccessed();
1189 return ( pix );
1190}
1191
1192bool OThemeCache::insert( OThemePixmap *pixmap, ScaleHint scale, int widgetID,
1193 bool border, bool mask )
1194{
1195 kthemeKey key;
1196 key.cacheKey = 0; // shut up, gcc
1197 key.data.id = widgetID;
1198 key.data.width = ( scale == FullScale || scale == HorizontalScale ) ?
1199 pixmap->width() : 0;
1200 key.data.height = ( scale == FullScale || scale == VerticalScale ) ?
1201 pixmap->height() : 0;
1202 key.data.border = border;
1203 key.data.mask = mask;
1204
1205 if ( cache.find( ( unsigned long ) key.cacheKey, true ) != NULL ) {
1206 return ( true ); // a pixmap of this scale is already in there
1207 }
1208 return ( cache.insert( ( unsigned long ) key.cacheKey, pixmap,
1209 pixmap->width() * pixmap->height() * pixmap->depth() / 8 ) );
1210}
1211
1212//#include "kthemebase.moc"
diff --git a/noncore/styles/theme/othemebase.h b/noncore/styles/theme/othemebase.h
new file mode 100644
index 0000000..e691692
--- a/dev/null
+++ b/noncore/styles/theme/othemebase.h
@@ -0,0 +1,739 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Daniel M. Duley <mosfet@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18#ifndef __OTHEMEBASE_H
19#define __OTHEMEBASE_H
20
21#include <qdatetime.h>
22#include <qtimer.h>
23#include <qwindowsstyle.h>
24#include <qpixmap.h>
25#include <qpe/config.h>
26#include <qimage.h>
27#include <qintcache.h>
28#include <qstring.h>
29#include <qpalette.h>
30
31#define WIDGETS 54
32
33/**
34 * This class adds simple time management to QPixmap for use in flushing
35 * OThemeCache.
36 *
37 * @author Daniel M. Duley <mosfet@kde.org>
38 */
39class OThemePixmap : public QPixmap
40{
41public:
42 enum BorderType{Top = 0, Bottom, Left, Right, TopLeft, TopRight, BottomLeft,
43 BottomRight};
44
45 OThemePixmap( bool timer = true );
46 OThemePixmap( const OThemePixmap &p );
47 ~OThemePixmap();
48 QPixmap* border( BorderType type );
49 void setBorder( BorderType type, const QPixmap &p );
50 void updateAccessed();
51 bool isOld();
52protected:
53 QTime *t;
54 QPixmap *b[ 8 ];
55
56private:
57 class OThemePixmapPrivate;
58 OThemePixmapPrivate *d;
59};
60
61inline QPixmap* OThemePixmap::border( BorderType type )
62{
63 return ( b[ type ] );
64}
65
66inline void OThemePixmap::setBorder( BorderType type, const QPixmap &p )
67{
68 if ( b[ type ] ) {
69 qWarning( "OThemePixmap: Overwriting existing border!" );
70 delete( b[ type ] );
71 }
72 b[ type ] = new QPixmap( p );
73}
74
75inline void OThemePixmap::updateAccessed()
76{
77 if (t)
78 t->start();
79}
80
81inline bool OThemePixmap::isOld()
82{
83 return ( t ? t->elapsed() >= 300000 : false );
84}
85
86/**
87 * A very simple pixmap cache for theme plugins. QPixmapCache is not used
88 * since it uses QString keys which are not needed. All the information we
89 * need can be encoded in a numeric key. Using QIntCache instead allows us to
90 * skip the string operations.
91 *
92 * This class is mostly just inline methods that do bit operations on a key
93 * composed of the widget ID, width and/or height, and then calls
94 * QIntCache::find().
95 *
96 * One other thing to note is that full, horizontal, and vertically scaled
97 * pixmaps are not used interchangeably. For example, if you insert a fully
98 * scaled pixmap that is 32x32 then request a horizontally scaled pixmap with
99 * a width of 32, they will not match. This is because a pixmap that has been
100 * inserted into the cache has already been scaled at some point and it is
101 * very likely the vertical height was not originally 32. Thus the pixmap
102 * will be wrong when drawn, even though the horizontal width matches.
103 *
104 * @author Daniel M. Duley <mosfet@kde.org>
105 *
106 */
107class OThemeCache : public QObject
108{
109 Q_OBJECT
110public:
111 /**
112 * The scale hints supported by the cache. Note that Tiled is not here
113 * since tiled pixmaps are kept only once in OThemeBase.
114 */
115 enum ScaleHint{FullScale, HorizontalScale, VerticalScale};
116 /**
117 * The constructor.
118 *
119 * @param maxSize The maximum size of the cache in kilobytes.
120 */
121 OThemeCache( int maxSize, QObject *parent = 0, const char *name = 0 );
122 /**
123 * Inserts a new pixmap into the cache.
124 *
125 * @param pixmap The pixmap to insert.
126 * @param scale The scaling type of the pixmap.
127 * @param widgetID The widget ID of the pixmap, usually from OThemeBase's
128 * WidgetType enum.
129 *
130 * @return True if the insert was successful, false otherwise.
131 */
132 bool insert( OThemePixmap *pixmap, ScaleHint scale, int widgetID,
133 bool border = false, bool mask = false );
134 /**
135 * Returns a fully scaled pixmap.
136 *
137 * @param w The pixmap width to search for.
138 * @param h The pixmap height to search for.
139 * @param widgetID The widget ID to search for.
140 *
141 * @return True if a pixmap matching the width, height, and widget ID of
142 * the pixmap exists, NULL otherwise.
143 */
144 OThemePixmap* pixmap( int w, int h, int widgetID, bool border = false,
145 bool mask = false );
146 /**
147 * Returns a horizontally scaled pixmap.
148 *
149 * @param w The pixmap width to search for.
150 * @param widgetID The widget ID to search for.
151 *
152 * @return True if a pixmap matching the width and widget ID of
153 * the pixmap exists, NULL otherwise.
154 */
155 OThemePixmap* horizontalPixmap( int w, int widgetID );
156 /**
157 * Returns a vertically scaled pixmap.
158 *
159 * @param h The pixmap height to search for.
160 * @param widgetID The widget ID to search for.
161 *
162 * @return True if a pixmap matching the height and widget ID of
163 * the pixmap exists, NULL otherwise.
164 */
165 OThemePixmap* verticalPixmap( int h, int widgetID );
166protected slots:
167 void flushTimeout();
168protected:
169 QIntCache<OThemePixmap> cache;
170 QTimer flushTimer;
171
172private:
173 class OThemeCachePrivate;
174 OThemeCachePrivate *d;
175};
176
177
178/**
179 * This is a base class for KDE themed styles. It implements a cache,
180 * configuration file parsing, pixmap scaling, gradients, and a lot
181 * of inline methods for accessing user specified parameters.
182 *
183 * Note that this class *does not* actually implement any themes. It just
184 * provides the groundwork for doing so. The only reason to use this class
185 * directly is if you plan to reimplement all of the widgets. Otherwise,
186 * refer to OThemeStyle for a fully themed style you can derive from.
187 *
188 * @author Daniel M. Duley <mosfet@kde.org>
189 */
190class OThemeBase: public QWindowsStyle
191{
192 Q_OBJECT
193public:
194 /**
195 * Constructs a new OThemeBase object.
196 */
197 OThemeBase( const QString &configFile );
198 ~OThemeBase();
199 /**
200 * Describes if a pixmap should be scaled fully, horizontally, vertically,
201 * or not at all and tiled.
202 */
203 enum ScaleHint{FullScale, HorizontalScale, VerticalScale, TileScale};
204 /**
205 * The default arrow types.
206 */
207 enum ArrowStyle{MotifArrow, LargeArrow, SmallArrow};
208 /**
209 * The default frame shading styles.
210 */
211 enum ShadeStyle{Motif, Windows, Next, KDE};
212 /**
213 * The default scrollbar button layout. BottomLeft is like what Next
214 * uses, BottomRight is like Platinum, and Opposite it like Windows and
215 * Motif.
216 */
217 enum SButton{SBBottomLeft, SBBottomRight, SBOpposite};
218 /**
219 * The gradient types. Horizontal is left to right, Vertical is top to
220 * bottom, and diagonal is upper-left to bottom-right.
221 */
222 enum Gradient{GrNone, GrHorizontal, GrVertical, GrDiagonal, GrPyramid,
223 GrRectangle, GrElliptic, GrReverseBevel};
224 /**
225 * This provides a list of widget types that OThemeBase recognizes.
226 */
227 /* Internal note: The order here is important. Some widgets inherit
228 * properties. This is usually for when you have two settings for the
229 * same widget, ie: on(sunken), and off. The on settings will inherit
230 * the properties of the off one when nothing is specified in the config.
231 *
232 * In order to be able to handle this while still having everything in
233 * one group that is easy to loop from we have the following order:
234 * unsunked(off) items, sunken(on)items, and then the ones that don't
235 * matter. INHERIT_ITEMS define the number of widgets that have inheritence
236 * so if 0 == PushButtonOff then INHERIT_ITEMS should == PushButtonOn
237 * and so on. WIDGETS define the total number of widgets.
238 */
239 enum WidgetType{
240 // Off (unsunken widgets)
241 PushButton = 0, ComboBox, HScrollBarSlider, VScrollBarSlider, Bevel,
242 ToolButton, ScrollButton, HScrollDeco, VScrollDeco,
243 ComboDeco, MenuItem, InactiveTab, ArrowUp, ArrowDown, ArrowLeft,
244 ArrowRight,
245 // On (sunken widgets)
246 PushButtonDown, ComboBoxDown, HScrollBarSliderDown,
247 VScrollBarSliderDown, BevelDown, ToolButtonDown, ScrollButtonDown,
248 HScrollDecoDown, VScrollDecoDown, ComboDecoDown, MenuItemDown,
249 ActiveTab, SunkenArrowUp, SunkenArrowDown, SunkenArrowLeft,
250 SunkenArrowRight,
251 // Everything else (indicators must have separate settings)
252 HScrollGroove, VScrollGroove, Slider, SliderGroove, IndicatorOn,
253 IndicatorOff, ExIndicatorOn, ExIndicatorOff, HBarHandle, VBarHandle,
254 ToolBar, Splitter, CheckMark, MenuBar, DisArrowUp, DisArrowDown,
255 DisArrowLeft, DisArrowRight, ProgressBar, ProgressBg, MenuBarItem,
256 Background};
257
258 /**
259 * The scaling type specified by the Config file.
260 *
261 * @param widget A Widgets enum value.
262 *
263 * @return A ScaleHint enum value.
264 */
265 ScaleHint scaleHint( WidgetType widget ) const;
266 /**
267 * The gradient type specified by the KConfig file.
268 *
269 * @param widget A Widgets enum value.
270 *
271 * @return A Gradient enum value.
272 */
273 Gradient gradientHint( WidgetType widget ) const;
274 /**
275 * The color group specified for a given widget.
276 * If a color group is set in the theme configuration
277 * that is used, otherwise defaultColor is returned.
278 *
279 * @param defaultColor The colorGroup to set if one is available.
280 *
281 * @param widget The widget whose color group to retrieve.
282 *
283 */
284 const QColorGroup* colorGroup( const QColorGroup &defaultGroup,
285 WidgetType widget ) const;
286
287 QBrush pixmapBrush( const QColorGroup &group, QColorGroup::ColorRole role,
288 int w, int h, WidgetType widget );
289 /**
290 * True if the widget has a pixmap or gradient specified.
291 */
292 bool isPixmap( WidgetType widget ) const;
293 /**
294 * True if the widget has a color group specified.
295 */
296 bool isColor( WidgetType widget ) const;
297 /**
298 * True if the user specified a 3D focus rectangle
299 */
300 bool is3DFocus() const;
301 /**
302 * If the user specified a 3D focus rectangle, they may also specify an
303 * offset from the default rectangle to use when drawing it. This returns
304 * the specified offset.
305 */
306 int focusOffset() const;
307 /**
308 * The border width of the specified widget.
309 */
310 int borderWidth( WidgetType widget ) const;
311 /**
312 * Pixmap border width of the specified widget.
313 */
314 int pixBorderWidth( WidgetType widget ) const;
315 /**
316 * Returns the border pixmap if enabled for the specified widget. This
317 * will contain the originial pixmap, plus the edges separated in
318 * OThemePixmap::border() if valid. If invalid it will return NULL.
319 */
320 OThemePixmap* borderPixmap( WidgetType widget );
321 /**
322 * The highlight width of the specified widget.
323 */
324 int highlightWidth( WidgetType widget ) const;
325 /**
326 * The border plus highlight width of the widget.
327 */
328 int decoWidth( WidgetType widget ) const;
329 /**
330 * The extent (width for vertical, height for horizontal) requested
331 * for the scrollbars.
332 */
333 int getSBExtent() const;
334 /**
335 * The scrollbar button layout.
336 */
337 SButton scrollBarLayout() const;
338 /**
339 * The arrow type.
340 */
341 ArrowStyle arrowType() const;
342 /**
343 * The shading type.
344 */
345 ShadeStyle shade() const;
346 /**
347 * The frame width.
348 */
349 int frameWidth() const;
350 /**
351 * The splitter width.
352 */
353 int splitWidth() const;
354 /**
355 * The contrast for some bevel effects such as reverse gradient.
356 */
357 int bevelContrast( WidgetType widget ) const;
358 /**
359 * The button text X shift.
360 */
361 int buttonXShift() const;
362 /**
363 * The button text Y shift.
364 */
365 int buttonYShift() const;
366 /**
367 * Returns either the slider length of the slider pixmap if available,
368 * otherwise the length specified in the config file.
369 */
370 int sliderButtonLength() const;
371 /**
372 * True if rounded buttons are requested.
373 */
374 bool roundButton() const;
375 /**
376 * True if rounded comboboxes are requested.
377 */
378 bool roundComboBox() const;
379 /**
380 * True if rounded slider grooves are requested.
381 */
382 bool roundSlider() const;
383 /**
384 * True if a line should be drawn on the bottom of active tabs.
385 */
386 bool activeTabLine() const;
387 /**
388 * True if a line should be drawn on the bottom of inactive tabs.
389 */
390 bool inactiveTabLine() const;
391 /**
392 * Returns the current uncached pixmap for the given widget. This will
393 * usually be either the last scaled or gradient pixmap if those have
394 * been specified in the config file, the original pixmap if not, or NULL
395 * if no pixmap has been specified.
396 */
397 OThemePixmap* uncached( WidgetType widget ) const;
398 /**
399 * Returns the pixmap for the given widget at the specified width and
400 * height. This will return NULL if no pixmap or gradient is specified.
401 * It may also return a different sized pixmap if the scaling
402 * is set to Tiled. When using this method, you should call it using
403 * the needed width and height then use QPainter::drawTiledPixmap to
404 * paint it. Doing this, if the pixmap is scaled it will be the proper
405 * size, otherwise it will be tiled.
406 *
407 * @param w Requested width.
408 * @param h Requested height.
409 * @param widget Widget type.
410 * @return The pixmap or NULL if one is not specified.
411 */
412 virtual OThemePixmap *scalePixmap( int w, int h, WidgetType widget );
413 /**
414 * This method reads a configuration file and applies it to the user's
415 * kstylerc file. It does not signal applications to reload via the
416 * KDEChangeGeneral atom, if you want to do this you must do so yourself.
417 * See kcmdisplay's general.cpp for an example.
418 *
419 * @param file The configuration file to apply.
420 */
421 static void applyConfigFile( const QString &file );
422protected:
423 /**
424 * Returns a QImage for the given widget if the widget is scaled, NULL
425 * otherwise. QImages of the original pixmap are stored for scaled
426 * widgets in order to facilitate fast and accurate smooth-scaling. This
427 * also saves us a conversion from a pixmap to an image then back again.
428 */
429 QImage* image( WidgetType widget ) const;
430 /**
431 * Returns the gradient high color if one is specified, NULL otherwise.
432 */
433 QColor* gradientHigh( WidgetType widget ) const;
434 /**
435 * Returns the gradient low color if one is specified, NULL otherwise.
436 */
437 QColor* gradientLow( WidgetType widget ) const;
438 /**
439 * Reads in all the configuration file entries supported.
440 *
441 * @param colorStyle The style for the color groups. In KDE, colors were
442 * calculated a little differently for Motif vs Windows styles. This
443 * is obsolete.
444 */
445 void readConfig( Qt::GUIStyle colorStyle = Qt::WindowsStyle );
446 void readWidgetConfig( int i, Config *config, QString *pixnames,
447 QString *brdnames, bool *loadArray );
448 void copyWidgetConfig( int sourceID, int destID, QString *pixnames,
449 QString *brdnames );
450 /**
451 * Makes a full color group based on the given foreground and background
452 * colors. This is the same code used by KDE (kapp.cpp) in previous
453 * versions.
454 */
455 QColorGroup* makeColorGroup( QColor &fg, QColor &bg,
456 Qt::GUIStyle style = Qt::WindowsStyle );
457 OThemePixmap* scale( int w, int h, WidgetType widget );
458 OThemePixmap* scaleBorder( int w, int h, WidgetType type );
459 OThemePixmap* gradient( int w, int h, WidgetType widget );
460 OThemePixmap* blend( WidgetType widget );
461 void generateBorderPix( int i );
462 void applyResourceGroup( Config *config, int i, QString *copyfrom, QString *pixnames, QString *brdnames );
463 void applyMiscResourceGroup( Config *config );
464 void readResourceGroup( int i, QString *copyfrom, QString *pixnames, QString *brdnames,
465 bool *loadArray );
466 void readMiscResourceGroup();
467 /**
468 * Attempts to load a pixmap from the default OThemeBase locations.
469 */
470 OThemePixmap* loadPixmap( QString &name );
471 /**
472 * Attempts to load a image from the default OThemeBase locations.
473 */
474 QImage* loadImage( QString &name );
475private:
476 SButton sbPlacement;
477 ArrowStyle arrowStyle;
478 ShadeStyle shading;
479 int defaultFrame;
480 int btnXShift, btnYShift;
481 int sliderLen;
482 int splitterWidth;
483 int focus3DOffset;
484 int sbExtent;
485 bool smallGroove;
486 bool roundedButton, roundedCombo, roundedSlider;
487 bool aTabLine, iTabLine;
488 bool focus3D;
489 OThemeCache *cache;
490 int cacheSize;
491 QString configFileName;
492 QString configFilePath;
493
494protected:
495 QColor fgcolor, bgcolor, selfgcolor, selbgcolor, winfgcolor, winbgcolor;
496
497private:
498 /**
499 * The theme pixmaps. Many of these may be NULL if no pixmap is specified.
500 * There may also be duplicate pixmap pointers if more than one widget
501 * uses the same tiled pixmap. If a pixmap is tiled, it is kept here and
502 * this acts as a cache. Otherwise this will hold whatever the last scaled
503 * pixmap was.
504 */
505 OThemePixmap *pixmaps[ WIDGETS ];
506 /**
507 * The theme images. These are for scaled images and are kept in order
508 * to maintain fast smoothscaling.
509 */
510 QImage *images[ WIDGETS ];
511 /**
512 * The border widths
513 */
514 unsigned char borders[ WIDGETS ];
515 /**
516 * The highlight widths
517 */
518 unsigned char highlights[ WIDGETS ];
519 /**
520 * The scale hints for pixmaps and gradients.
521 */
522 ScaleHint scaleHints[ WIDGETS ];
523 /**
524 * All the color groups.
525 */
526 QColorGroup *colors[ WIDGETS ];
527 /**
528 * Gradient low colors (or blend background).
529 */
530 QColor *grLowColors[ WIDGETS ];
531 /**
532 * Gradient high colors.
533 */
534 QColor *grHighColors[ WIDGETS ];
535 /**
536 * Gradient types.
537 */
538 Gradient gradients[ WIDGETS ];
539 /**
540 * Blend intensity factors
541 */
542 float blends[ WIDGETS ];
543 /**
544 * Bevel contrasts
545 */
546 unsigned char bContrasts[ WIDGETS ];
547 /**
548 * Duplicate pixmap entries (used during destruction).
549 */
550 bool duplicate[ WIDGETS ];
551 /**
552 * Pixmapped border widths
553 */
554 int pbWidth[ WIDGETS ];
555 /**
556 * Pixmapped borders
557 */
558 OThemePixmap *pbPixmaps[ WIDGETS ];
559 /**
560 * Duplicate border pixmapped border entries
561 */
562 bool pbDuplicate[ WIDGETS ];
563
564private:
565 class OThemeBasePrivate;
566 OThemeBasePrivate *d;
567
568};
569
570inline bool OThemeBase::isPixmap( WidgetType widget ) const
571{
572 return ( pixmaps[ widget ] != NULL || gradients[ widget ] != GrNone );
573}
574
575inline bool OThemeBase::isColor( WidgetType widget ) const
576{
577 return ( colors[ widget ] != NULL );
578}
579
580inline bool OThemeBase::is3DFocus() const
581{
582 return ( focus3D );
583}
584
585inline int OThemeBase::focusOffset() const
586{
587 return ( focus3DOffset );
588}
589
590inline int OThemeBase::bevelContrast( WidgetType widget ) const
591{
592 return ( bContrasts[ widget ] );
593}
594
595inline OThemeBase::ScaleHint OThemeBase::scaleHint( WidgetType widget ) const
596{
597 return ( ( widget < WIDGETS ) ? scaleHints[ widget ] : TileScale );
598}
599
600inline OThemeBase::Gradient OThemeBase::gradientHint( WidgetType widget ) const
601{
602 return ( ( widget < WIDGETS ) ? gradients[ widget ] : GrNone );
603}
604
605inline OThemePixmap* OThemeBase::uncached( WidgetType widget ) const
606{
607 return ( pixmaps[ widget ] );
608}
609
610inline QBrush OThemeBase::pixmapBrush( const QColorGroup &group,
611 QColorGroup::ColorRole role,
612 int w, int h, WidgetType widget )
613{
614 if ( pixmaps[ widget ] || images[ widget ] )
615 return ( QBrush( group.color( role ), *scalePixmap( w, h, widget ) ) );
616 else
617 return ( group.color( role ) );
618}
619
620inline const QColorGroup* OThemeBase::colorGroup( const QColorGroup &defaultGroup,
621 WidgetType widget ) const
622{
623 return ( ( colors[ widget ] ) ? colors[ widget ] : &defaultGroup );
624}
625
626inline int OThemeBase::borderWidth( WidgetType widget ) const
627{
628 return ( pbWidth[ widget ] ? pbWidth[ widget ] : borders[ widget ] );
629}
630
631inline int OThemeBase::pixBorderWidth( WidgetType widget ) const
632{
633 return ( pbWidth[ widget ] );
634}
635
636inline int OThemeBase::highlightWidth( WidgetType widget ) const
637{
638 return ( pbWidth[ widget ] ? 0 : highlights[ widget ] );
639}
640
641inline int OThemeBase::decoWidth( WidgetType widget ) const
642{
643 return ( pbWidth[ widget ] ? pbWidth[ widget ] : borders[ widget ] + highlights[ widget ] );
644}
645
646inline QColor* OThemeBase::gradientHigh( WidgetType widget ) const
647{
648 return ( grHighColors[ widget ] );
649}
650
651inline QColor* OThemeBase::gradientLow( WidgetType widget ) const
652{
653 return ( grLowColors[ widget ] );
654}
655
656inline QImage* OThemeBase::image( WidgetType widget ) const
657{
658 return ( images[ widget ] );
659}
660
661inline OThemeBase::SButton OThemeBase::scrollBarLayout() const
662{
663 return ( sbPlacement );
664}
665
666inline OThemeBase::ArrowStyle OThemeBase::arrowType() const
667{
668 return ( arrowStyle );
669}
670
671inline OThemeBase::ShadeStyle OThemeBase::shade() const
672{
673 return ( shading );
674}
675
676inline int OThemeBase::frameWidth() const
677{
678 return ( defaultFrame );
679}
680
681inline int OThemeBase::buttonXShift() const
682{
683 return ( btnXShift );
684}
685
686inline int OThemeBase::splitWidth() const
687{
688 return ( splitterWidth );
689}
690
691inline int OThemeBase::buttonYShift() const
692{
693 return ( btnYShift );
694}
695
696inline int OThemeBase::sliderButtonLength() const
697{
698 if ( isPixmap( Slider ) )
699 return ( uncached( Slider ) ->width() );
700 else
701 return ( sliderLen );
702}
703
704inline bool OThemeBase::roundButton() const
705{
706 return ( roundedButton );
707}
708
709inline bool OThemeBase::roundComboBox() const
710{
711 return ( roundedCombo );
712}
713
714inline bool OThemeBase::roundSlider() const
715{
716 return ( roundedSlider );
717}
718
719inline bool OThemeBase::activeTabLine() const
720{
721 return ( aTabLine );
722}
723
724inline bool OThemeBase::inactiveTabLine() const
725{
726 return ( iTabLine );
727}
728
729inline int OThemeBase::getSBExtent() const
730{
731 return ( sbExtent );
732}
733
734inline OThemePixmap* OThemeBase::borderPixmap( WidgetType widget )
735{
736 return ( pbPixmaps[ widget ] );
737}
738
739#endif
diff --git a/noncore/styles/theme/othemestyle.cpp b/noncore/styles/theme/othemestyle.cpp
new file mode 100644
index 0000000..61127b8
--- a/dev/null
+++ b/noncore/styles/theme/othemestyle.cpp
@@ -0,0 +1,1532 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Daniel M. Duley <mosfet@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18
19#include "othemestyle.h"
20#include "othemebase.h"
21#include <qpe/qpeapplication.h>
22#include <qbitmap.h>
23#define INCLUDE_MENUITEM_DEF
24#include <qmenudata.h>
25#include <qpopupmenu.h>
26#include <qtabbar.h>
27#include <qglobal.h>
28
29#include <limits.h>
30#include <stdio.h>
31
32#define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2)
33
34OThemeStyle::OThemeStyle( const QString &configFile )
35 : OThemeBase( configFile )
36{
37 setScrollBarExtent( getSBExtent(), getSBExtent() );
38 setButtonDefaultIndicatorWidth( 0 ); // We REALLY should support one, see drawPushButton() below!
39}
40
41OThemeStyle::~OThemeStyle()
42{}
43
44void OThemeStyle::polish( QApplication * /*app*/ )
45{}
46
47void OThemeStyle::polish( QPalette &p )
48{
49 oldPalette = p;
50
51 QColor bg = oldPalette. color ( QPalette::Normal, QColorGroup::Background );
52
53 if ( bgcolor. isValid ( ))
54 bg = bgcolor;
55
56 if ( isColor ( Background ))
57 bg = colorGroup ( oldPalette. active ( ), Background )-> background ( );
58
59 p = QPalette ( bg, bg );
60
61 if ( isPixmap( Background ) )
62 p. setBrush ( QColorGroup::Background, QBrush ( bg, *uncached ( Background )));
63
64 if ( fgcolor. isValid ( )) {
65 p. setColor ( QColorGroup::Foreground, fgcolor );
66 p. setColor ( QColorGroup::ButtonText, fgcolor );
67 }
68 if ( selfgcolor. isValid ( ))
69 p. setColor ( QColorGroup::HighlightedText, selfgcolor );
70 if ( selbgcolor. isValid ( ))
71 p. setColor ( QColorGroup::Highlight, selbgcolor );
72 if ( winfgcolor. isValid ( ))
73 p. setColor ( QColorGroup::Text, winfgcolor );
74 if ( winbgcolor. isValid ( ))
75 p. setColor ( QColorGroup::Base, winbgcolor );
76
77}
78
79
80void OThemeStyle::unPolish( QApplication *app )
81{
82 app->setPalette( oldPalette, true );
83}
84
85void OThemeStyle::polish( QWidget *w )
86{
87 if ( !w->isTopLevel() ) {
88 if ( w->inherits( "QGroupBox" )
89 || w->inherits( "QTabWidget" ) ) {
90 w->setAutoMask( TRUE );
91 return ;
92 }
93 if ( w->inherits( "QLabel" )
94 || w->inherits( "QSlider" )
95 || w->inherits( "QButton" )
96 || w->inherits( "QProgressBar" )
97 ) {
98 w->setBackgroundOrigin( QWidget::ParentOrigin );
99 }
100 }
101 if ( w->inherits( "QPopupMenu" ) ) {
102 popupPalette = w->palette();
103 if ( isColor( MenuItem ) || isColor( MenuItemDown ) ) {
104 QPalette newPal( w->palette() );
105 w->setPalettePropagation( QWidget::SamePalette );
106 if ( isColor( MenuItem ) ) {
107 newPal.setNormal( *colorGroup( newPal.normal(), MenuItem ) );
108 newPal.setDisabled( *colorGroup( newPal.normal(), MenuItem ) );
109 }
110 if ( isColor( MenuItemDown ) )
111 newPal.setActive( *colorGroup( newPal.active(), MenuItemDown ) );
112 w->setPalette( newPal );
113 }
114 }
115 if ( w->inherits( "QCheckBox" ) ) {
116 if ( isColor( IndicatorOff ) || isColor( IndicatorOn ) ) {
117 QPalette newPal( w->palette() );
118 w->setPalettePropagation( QWidget::SamePalette );
119 if ( isColor( IndicatorOff ) ) {
120 newPal.setNormal( *colorGroup( newPal.normal(), IndicatorOff ) );
121 newPal.setDisabled( *colorGroup( newPal.normal(), IndicatorOff ) );
122 }
123 if ( isColor( IndicatorOn ) )
124 newPal.setActive( *colorGroup( newPal.active(), IndicatorOn ) );
125 w->setPalette( newPal );
126 }
127 }
128 if ( w->inherits( "QRadioButton" ) ) {
129 if ( isColor( ExIndicatorOff ) || isColor( ExIndicatorOn ) ) {
130 QPalette newPal( w->palette() );
131 w->setPalettePropagation( QWidget::SamePalette );
132 if ( isColor( ExIndicatorOff ) ) {
133 newPal.setNormal( *colorGroup( newPal.normal(), ExIndicatorOff ) );
134 newPal.setDisabled( *colorGroup( newPal.normal(),
135 ExIndicatorOff ) );
136 }
137 if ( isColor( ExIndicatorOn ) )
138 newPal.setActive( *colorGroup( newPal.active(), ExIndicatorOn ) );
139 w->setPalette( newPal );
140 }
141 }
142}
143
144void OThemeStyle::unPolish( QWidget* w )
145{
146 if ( !w->isTopLevel() ) {
147 if ( w->inherits( "QGroupBox" )
148 || w->inherits( "QTabWidget" ) ) {
149 w->setAutoMask( FALSE );
150 return ;
151 }
152 if ( w->inherits( "QLabel" )
153 || w->inherits( "QSlider" )
154 || w->inherits( "QButton" )
155 || w->inherits( "QProgressBar" )
156 ) {
157 w->setBackgroundOrigin( QWidget::WidgetOrigin );
158 }
159 }
160 if ( w->inherits( "QPopupMenu" ) )
161 w->unsetPalette();
162 if ( w->inherits( "QCheckBox" ) )
163 w->unsetPalette();
164 if ( w->inherits( "QRadioButton" ) )
165 w->unsetPalette();
166}
167
168void OThemeStyle::drawBaseButton( QPainter *p, int x, int y, int w, int h,
169 const QColorGroup &g, bool sunken, bool
170 rounded, WidgetType type, const QBrush * )
171{
172 int offset = borderPixmap( type ) ? 0 : decoWidth( type );
173 QPen oldPen = p->pen();
174
175 // handle reverse bevel here since it uses decowidth differently
176 if ( gradientHint( type ) == GrReverseBevel ) {
177 int i;
178 bitBlt( p->device(), x, y, scalePixmap( w, h, type ), 0, 0, w, h,
179 Qt::CopyROP, true );
180 p->setPen( g.text() );
181 for ( i = 0; i < borderWidth( type ); ++i, ++x, ++y, w -= 2, h -= 2 )
182 p->drawRect( x, y, w, h );
183 }
184 // same with KDE style borders
185 else if ( !borderPixmap( type ) && shade() == KDE ) {
186 qDrawWinButton( p, x, y, w, h, g, sunken );
187 if ( isPixmap( type ) )
188 p->drawTiledPixmap( x + 4, y + 4, w - 6, h - 6,
189 *scalePixmap( w - 6, h - 6,
190 type ) );
191 else
192 p->fillRect( x + 4, y + 4, w - 6, h - offset * 6,
193 g.brush( QColorGroup::Button ) );
194
195 }
196 else {
197 if ( ( w - offset * 2 ) > 0 && ( h - offset * 2 ) > 0 ) {
198 if ( isPixmap( type ) )
199 if ( rounded )
200 p->drawTiledPixmap( x, y, w, h, *scalePixmap( w, h, type ) );
201 else
202 p->drawTiledPixmap( x + offset, y + offset, w - offset * 2,
203 h - offset * 2,
204 *scalePixmap( w - offset * 2, h - offset * 2,
205 type ) );
206 else
207 p->fillRect( x + offset, y + offset, w - offset * 2, h - offset * 2,
208 g.brush( QColorGroup::Button ) );
209 }
210 if ( borderPixmap( type ) )
211 bitBlt( p->device(), x, y, scaleBorder( w, h, type ), 0, 0, w, h,
212 Qt::CopyROP, false );
213 else
214 drawShade( p, x, y, w, h, g, sunken, rounded,
215 highlightWidth( type ), borderWidth( type ), shade() );
216 }
217 p->setPen( oldPen );
218}
219
220void OThemeStyle::drawButton( QPainter *p, int x, int y, int w, int h,
221 const QColorGroup &g, bool sunken,
222 const QBrush *fill )
223{
224 drawBaseButton( p, x, y, w, h, g, sunken, roundButton(), sunken ?
225 PushButtonDown : PushButton, fill );
226}
227
228void OThemeStyle::drawPushButton( QPushButton* btn, QPainter *p )
229{
230 bool sunken = btn->isOn() || btn->isDown();
231 int diw = buttonDefaultIndicatorWidth();
232 drawBaseButton( p, diw, diw, btn->width() - 2 * diw, btn->height() - 2 * diw,
233 *colorGroup( btn->colorGroup(), sunken ? PushButtonDown :
234 PushButton ), sunken, roundButton(),
235 sunken ? PushButtonDown : PushButton, NULL );
236 // TODO if diw, draw fancy default button indicator
237}
238
239void OThemeStyle::drawBaseMask( QPainter *p, int x, int y, int w, int h,
240 bool round )
241{
242 // round edge fills
243 static const QCOORD btm_left_fill[] = {
244 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1,
245 1, 2, 2, 2, 3, 2, 4, 2, 2, 3, 3, 3, 4, 3, 3, 4, 4, 4
246 };
247
248 static const QCOORD btm_right_fill[] = {
249 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 0, 1, 1, 1, 2, 1, 3, 1, 4,
250 1, 0, 2, 1, 2, 2, 2, 3, 2, 0, 3, 1, 3, 2, 3, 0, 4, 1, 4
251 };
252
253 static const QCOORD top_left_fill[] = {
254 3, 0, 4, 0, 2, 1, 3, 1, 4, 1, 1, 2, 2, 2, 3, 2, 4, 2, 0, 3,
255 1, 3, 2, 3, 3, 3, 4, 3, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4
256 };
257
258 static const QCOORD top_right_fill[] = {
259 0, 0, 1, 0, 0, 1, 1, 1, 2, 1, 0, 2, 1, 2, 2, 2, 3, 2, 0,
260 3, 1, 3, 2, 3, 3, 3, 4, 3, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4
261 };
262
263 QBrush fillBrush( color1, SolidPattern );
264 p->setPen( color1 );
265 if ( round && w > 19 && h > 19 ) {
266 int x2 = x + w - 1;
267 int y2 = y + h - 1;
268 QPointArray a( QCOORDARRLEN( top_left_fill ), top_left_fill );
269 a.translate( 1, 1 );
270 p->drawPoints( a );
271 a.setPoints( QCOORDARRLEN( btm_left_fill ), btm_left_fill );
272 a.translate( 1, h - 6 );
273 p->drawPoints( a );
274 a.setPoints( QCOORDARRLEN( top_right_fill ), top_right_fill );
275 a.translate( w - 6, 1 );
276 p->drawPoints( a );
277 a.setPoints( QCOORDARRLEN( btm_right_fill ), btm_right_fill );
278 a.translate( w - 6, h - 6 );
279 p->drawPoints( a );
280
281 p->fillRect( x + 6, y, w - 12, h, fillBrush );
282 p->fillRect( x, y + 6, x + 6, h - 12, fillBrush );
283 p->fillRect( x2 - 6, y + 6, x2, h - 12, fillBrush );
284 p->drawLine( x + 6, y, x2 - 6, y );
285 p->drawLine( x + 6, y2, x2 - 6, y2 );
286 p->drawLine( x, y + 6, x, y2 - 6 );
287 p->drawLine( x2, y + 6, x2, y2 - 6 );
288
289 }
290 else
291 p->fillRect( x, y, w, h, fillBrush );
292}
293
294void OThemeStyle::drawButtonMask( QPainter *p, int x, int y, int w, int h )
295{
296 drawBaseMask( p, x, y, w, h, roundButton() );
297}
298
299void OThemeStyle::drawComboButtonMask( QPainter *p, int x, int y, int w, int h )
300{
301 drawBaseMask( p, x, y, w, h, roundComboBox() );
302}
303
304void OThemeStyle::drawBevelButton( QPainter *p, int x, int y, int w, int h,
305 const QColorGroup &g, bool sunken,
306 const QBrush * )
307{
308 WidgetType type = sunken ? BevelDown : Bevel;
309 drawBaseButton( p, x, y, w, h, *colorGroup( g, type ), sunken, false, type );
310}
311
312#if 0
313void OThemeStyle::drawKToolBarButton( QPainter *p, int x, int y, int w, int h,
314 const QColorGroup &g, bool sunken,
315 bool raised, bool enabled, bool popup,
316 KToolButtonType type, const QString &btext,
317 const QPixmap *pixmap, QFont *font,
318 QWidget * )
319{
320 QFont tmp_font( QString::fromLatin1( "Helvetica" ), 10 );
321 if ( font )
322 tmp_font = *font;
323 QFontMetrics fm( tmp_font );
324 WidgetType widget = sunken ? ToolButtonDown : ToolButton;
325
326 drawBaseButton( p, x, y, w, h, *colorGroup( g, widget ), sunken, false,
327 widget );
328 int dx, dy;
329 if ( type == Icon ) { // icon only
330 if ( pixmap ) {
331 dx = ( w - pixmap->width() ) / 2;
332 dy = ( h - pixmap->height() ) / 2;
333 if ( sunken ) {
334 ++dx;
335 ++dy;
336 }
337 p->drawPixmap( x + dx, y + dy, *pixmap );
338 }
339 }
340 else if ( type == IconTextRight ) { // icon and text (if any)
341 if ( pixmap ) {
342 dx = 4;
343 dy = ( h - pixmap->height() ) / 2;
344 if ( sunken ) {
345 ++dx;
346 ++dy;
347 }
348 p->drawPixmap( x + dx, y + dy, *pixmap );
349 }
350 if ( !btext.isNull() ) {
351 int tf = AlignVCenter | AlignLeft;
352 if ( pixmap )
353 dx = 4 + pixmap->width() + 2;
354 else
355 dx = 4;
356 dy = 0;
357 if ( sunken ) {
358 ++dx;
359 ++dy;
360 }
361 if ( font )
362 p->setFont( *font );
363 if ( raised )
364 p->setPen( KGlobalSettings::toolBarHighlightColor() );
365 p->drawText( x + dx, y + dy, w - dx, h, tf, btext );
366 }
367 }
368 else if ( type == Text ) { // only text, even if there is a icon
369 if ( !btext.isNull() ) {
370 int tf = AlignTop | AlignLeft;
371 if ( !enabled )
372 p->setPen( g.dark() );
373 dx = ( w - fm.width( btext ) ) / 2;
374 dy = ( h - fm.lineSpacing() ) / 2;
375 if ( sunken ) {
376 ++dx;
377 ++dy;
378 }
379 if ( font )
380 p->setFont( *font );
381 if ( raised )
382 p->setPen( KGlobalSettings::toolBarHighlightColor() );
383 p->drawText( x + dx, y + dy, fm.width( btext ), fm.lineSpacing(), tf, btext );
384 }
385 }
386 else if ( type == IconTextBottom ) {
387 if ( pixmap ) {
388 dx = ( w - pixmap->width() ) / 2;
389 dy = ( h - fm.lineSpacing() - pixmap->height() ) / 2;
390 if ( sunken ) {
391 ++dx;
392 ++dy;
393 }
394 p->drawPixmap( x + dx, y + dy, *pixmap );
395 }
396 if ( !btext.isNull() ) {
397 int tf = AlignBottom | AlignHCenter;
398 dx = ( w - fm.width( btext ) ) / 2;
399 dy = h - fm.lineSpacing() - 4;
400 if ( sunken ) {
401 ++dx;
402 ++dy;
403 }
404 if ( font )
405 p->setFont( *font );
406 if ( raised )
407 p->setPen( KGlobalSettings::toolBarHighlightColor() );
408 p->drawText( x + dx, y + dy, fm.width( btext ), fm.lineSpacing(), tf, btext );
409 }
410 }
411 if ( popup ) {
412 if ( enabled )
413 qDrawArrow ( p, DownArrow, WindowsStyle, false, w - 5, h - 5, 0, 0,
414 g, true );
415 else
416 qDrawArrow ( p, DownArrow, WindowsStyle, false, w - 5, h - 5,
417 0, 0, g, false );
418 }
419}
420
421void OThemeStyle::drawKBarHandle( QPainter *p, int x, int y, int w, int h,
422 const QColorGroup &g, KToolBarPos, QBrush * )
423{
424 if ( w > h )
425 drawBaseButton( p, x, y, w, h, *colorGroup( g, HBarHandle ), false, false,
426 HBarHandle );
427 else
428 drawBaseButton( p, x, y, w, h, *colorGroup( g, VBarHandle ), false, false,
429 VBarHandle );
430}
431
432void OThemeStyle::drawKToolBar( QPainter *p, int x, int y, int w, int h,
433 const QColorGroup &g, KToolBarPos, QBrush * )
434{
435 drawBaseButton( p, x, y, w, h, *colorGroup( g, ToolBar ), false, false,
436 ToolBar );
437}
438#endif
439
440QRect OThemeStyle::buttonRect( int x, int y, int w, int h )
441{
442 int spacing = decoWidth( PushButton ) > decoWidth( PushButtonDown ) ?
443 decoWidth( PushButton ) : decoWidth( PushButtonDown );
444 return ( QRect( x + spacing, y + spacing, w - ( spacing * 2 ), h - ( spacing * 2 ) ) );
445}
446
447void OThemeStyle::drawComboButton( QPainter *p, int x, int y, int w, int h,
448 const QColorGroup &g, bool sunken, bool,
449 bool, const QBrush * )
450{
451 WidgetType widget = sunken ? ComboBoxDown : ComboBox;
452 drawBaseButton( p, x, y, w, h, *colorGroup( g, widget ), sunken,
453 roundComboBox(), widget );
454 if ( !sunken && isPixmap( ComboDeco ) )
455 p->drawPixmap( w - uncached( ComboDeco ) ->width() -
456 decoWidth( ComboBox ) - 2,
457 y + ( h - uncached( ComboDeco ) ->
458 height() ) / 2, *uncached( ComboDeco ) );
459 else if ( sunken && isPixmap( ComboDecoDown ) )
460 p->drawPixmap( w - uncached( ComboDecoDown ) ->width() -
461 decoWidth( ComboBoxDown ) - 2,
462 y + ( h - uncached( ComboDecoDown ) ->
463 height() ) / 2, *uncached( ComboDecoDown ) );
464 else {
465 qDrawArrow( p, Qt::DownArrow, Qt::MotifStyle, false, w - 15, y + 6, 10,
466 h - 15, *colorGroup( g, widget ), true );
467 qDrawShadeRect( p, w - 14, y + 7 + ( h - 15 ), 10, 3, *colorGroup( g, widget ) );
468 }
469}
470
471void OThemeStyle::drawScrollBarControls( QPainter *p, const QScrollBar *sb,
472 int sliderStart, uint controls,
473 uint activeControl )
474{
475 int sliderMin, sliderMax, sliderLength, buttonDim;
476 QRect add
477 , sub, addPage, subPage, slider;
478 int addX, addY, subX, subY;
479 bool horizontal = sb->orientation() == QScrollBar::Horizontal;
480 int len = ( horizontal ) ? sb->width() : sb->height();
481 int extent = ( horizontal ) ? sb->height() : sb->width();
482 int offset = decoWidth( horizontal ? HScrollGroove : VScrollGroove );
483 QColorGroup g = sb->colorGroup();
484
485 scrollBarMetrics( sb, sliderMin, sliderMax, sliderLength, buttonDim );
486 if ( sliderStart > sliderMax )
487 sliderStart = sliderMax;
488
489 int sliderEnd = sliderStart + sliderLength;
490 int sliderWidth = extent - offset * 2;
491
492 // Scary button placement code >:-P Feel free to improve this if you
493 // want. I get a headache just looking at it... (mosfet)
494 if ( scrollBarLayout() == SBOpposite ) {
495 if ( horizontal ) {
496 subY = addY = ( extent - buttonDim ) / 2;
497 subX = offset;
498 addX = len - buttonDim - offset;
499 }
500 else {
501 subX = addX = ( extent - buttonDim ) / 2;
502 subY = offset;
503 addY = len - buttonDim - offset;
504 }
505 sub.setRect( subX, subY, buttonDim, buttonDim );
506 add.setRect( addX, addY, buttonDim, buttonDim );
507 if ( horizontal ) {
508 subPage.setRect( sub.right() + 1, offset,
509 sliderStart - sub.right() - 1 , sliderWidth );
510 addPage.setRect( sliderEnd, offset, addX - sliderEnd, sliderWidth );
511 slider.setRect( sliderStart, offset, sliderLength, sliderWidth );
512 }
513 else {
514 subPage.setRect( offset, sub.bottom() + 1, sliderWidth,
515 sliderStart - sub.bottom() - 1 );
516 addPage.setRect( offset, sliderEnd, sliderWidth, addY - sliderEnd );
517 slider.setRect( offset, sliderStart, sliderWidth, sliderLength );
518 }
519 }
520 else if ( horizontal ) {
521 subY = addY = ( extent - buttonDim ) / 2;
522 if ( scrollBarLayout() == SBBottomLeft ) {
523 subX = offset;
524 addX = buttonDim + offset;
525 subPage.setRect( buttonDim * 2, 0, sliderStart - 1, extent );
526 addPage.setRect( sliderEnd, 0, len - sliderEnd, extent );
527 slider.setRect( sliderStart, 0, sliderLength, extent );
528 }
529 else {
530 subX = len - buttonDim - buttonDim - offset;
531 addX = len - buttonDim - offset;
532 subPage.setRect( offset + 1, offset, sliderStart - 1 , sliderWidth );
533 addPage.setRect( sliderEnd, offset, subX - sliderEnd, sliderWidth );
534 slider.setRect( sliderStart, offset, sliderLength, sliderWidth );
535 }
536 sub.setRect( subX, subY, buttonDim, buttonDim );
537 add.setRect( addX, addY, buttonDim, buttonDim );
538 }
539 else { // BottomLeft and BottomRight vertical bars are the same.
540 subX = addX = ( extent - buttonDim ) / 2;
541 subY = len - buttonDim - buttonDim - offset;
542 addY = len - buttonDim - offset;
543 subPage.setRect( offset, offset + 1, sliderWidth,
544 sliderStart - offset - 1 );
545 addPage.setRect( offset, sliderEnd, sliderWidth, subY - sliderEnd );
546 slider.setRect( offset, sliderStart, sliderWidth, sliderLength );
547 sub.setRect( subX, subY, buttonDim, buttonDim );
548 add.setRect( addX, addY, buttonDim, buttonDim );
549 }
550 // End of the button placement code
551
552 bool active;
553 if ( ( controls & QStyle::SubPage ) ) {
554 drawScrollBarGroove( p, sb, horizontal, subPage, g );
555 }
556 if ( ( controls & QStyle::AddPage ) ) {
557 drawScrollBarGroove( p, sb, horizontal, addPage, g );
558 }
559 if ( controls & QStyle::AddLine ) {
560 active = activeControl == QStyle::AddLine;
561 drawBaseButton( p, add.x(), add.y(), add.width(), add.height(),
562 *colorGroup( g, active ? ScrollButtonDown : ScrollButton ),
563 active, false, active ? ScrollButtonDown : ScrollButton );
564 drawArrow( p, ( horizontal ) ? RightArrow : DownArrow, active, add.x() + 3,
565 add.y() + 3, add.width() - 6, add.height() - 6,
566 *colorGroup( g, active ? ScrollButtonDown : ScrollButton ) );
567 }
568 if ( controls & QStyle::SubLine ) {
569 active = activeControl == QStyle::SubLine;
570 p->setPen( g.dark() );
571 p->drawRect( sub );
572 drawBaseButton( p, sub.x(), sub.y(), sub.width(), sub.height(),
573 *colorGroup( g, active ? ScrollButtonDown : ScrollButton ),
574 active, false, active ? ScrollButtonDown : ScrollButton );
575 drawArrow( p, ( horizontal ) ? LeftArrow : UpArrow, active, sub.x() + 3,
576 sub.y() + 3, sub.width() - 6, sub.height() - 6,
577 *colorGroup( g, active ? ScrollButtonDown : ScrollButton ) );
578 }
579 if ( controls & QStyle::Slider ) {
580 active = activeControl == QStyle::Slider;
581 WidgetType widget = horizontal ?
582 active ? HScrollBarSliderDown : HScrollBarSlider :
583 active ? VScrollBarSliderDown : VScrollBarSlider;
584
585 drawBaseButton( p, slider.x(), slider.y(), slider.width(),
586 slider.height(), *colorGroup( g, widget ), active, false,
587 widget );
588 int spaceW = horizontal ? slider.width() - decoWidth( widget ) - 4 :
589 slider.width();
590 int spaceH = horizontal ? slider.height() :
591 slider.height() - decoWidth( widget ) - 4;
592widget = active ? horizontal ? HScrollDecoDown : VScrollDecoDown :
593 horizontal ? HScrollDeco : VScrollDeco;
594 if ( isPixmap( widget ) ) {
595 if ( spaceW >= uncached( widget ) ->width() &&
596 spaceH >= uncached( widget ) ->height() ) {
597 p->drawPixmap( slider.x() + ( slider.width() -
598 uncached( widget ) ->width() ) / 2,
599 slider.y() + ( slider.height() -
600 uncached( widget ) ->height() ) / 2,
601 *uncached( widget ) );
602 }
603 }
604 }
605}
606
607void OThemeStyle::drawScrollBarGroove( QPainter *p, const QScrollBar *sb,
608 bool horizontal, QRect r, QColorGroup g )
609
610{
611 WidgetType widget = ( horizontal ) ? HScrollGroove : VScrollGroove;
612 if ( !isPixmap( widget ) ) {
613 p->fillRect( r, colorGroup( g, widget ) ->brush( QColorGroup::Background ) );
614 }
615 else {
616 // If the groove is pixmapped we make a full-sized image (it gets
617 // cached) then bitBlt it to the appropriate rect.
618 QPixmap buffer( sb->size() );
619 QPainter bPainter( &buffer );
620 bPainter.drawTiledPixmap( 0, 0, buffer.width(), buffer.height(),
621 *scalePixmap( buffer.width(), buffer.height(),
622 widget ) );
623 bitBlt( p->device(), r.x(), r.y(), &buffer, r.x(), r.y(), r.width(),
624 r.height(), Qt::CopyROP );
625 }
626 // Do the borders and frame
627 drawShade( p, sb->rect().x(), sb->rect().y(), sb->rect().width(),
628 sb->rect().height(), *colorGroup( g, widget ), true, false,
629 highlightWidth( widget ), borderWidth( widget ), shade() );
630}
631
632void OThemeStyle::scrollBarMetrics( const QScrollBar *sb, int &sliderMin,
633 int &sliderMax, int &sliderLength,
634 int &buttonDim )
635{
636 bool horizontal = sb->orientation() == QScrollBar::Horizontal;
637 int offset = decoWidth( horizontal ? HScrollGroove : VScrollGroove );
638 int maxlen;
639 int len = horizontal ? sb->width() : sb->height();
640 int extent = horizontal ? sb->height() : sb->width();
641
642 if ( len > ( extent - offset * 2 - 1 ) * 2 + offset * 2 )
643 buttonDim = extent - offset * 2;
644 else
645 buttonDim = ( len - offset * 2 ) / 2 - 1;
646 maxlen = len - offset * 2 - buttonDim * 2 - 1;
647
648 switch ( scrollBarLayout() ) {
649 case SBBottomLeft:
650 sliderMin = ( horizontal ) ? buttonDim * 2 + offset + 1 : offset + 1;
651 break;
652 case SBBottomRight:
653 sliderMin = offset + 1;
654 break;
655 case SBOpposite:
656 default:
657 sliderMin = offset + buttonDim;
658 break;
659 }
660 if ( sb->maxValue() == sb->minValue() )
661 sliderLength = maxlen;
662 else
663 sliderLength = ( sb->pageStep() * maxlen ) / ( sb->maxValue() -
664 sb->minValue() + sb->pageStep() );
665 if ( sliderLength < 12 || ( sb->maxValue() - sb->minValue() ) > INT_MAX / 2 )
666 sliderLength = 12;
667 if ( sliderLength > maxlen )
668 sliderLength = maxlen;
669 sliderMax = sliderMin + maxlen - sliderLength;
670}
671
672QStyle::ScrollControl OThemeStyle::scrollBarPointOver( const QScrollBar *sb,
673 int sliderStart,
674 const QPoint &p )
675{
676 if ( !sb->rect().contains( p ) )
677 return ( QStyle::NoScroll );
678 int sliderMin, sliderMax, sliderLength, buttonDim;
679 int pos = ( sb->orientation() == QScrollBar::Horizontal ) ? p.x() : p.y();
680 scrollBarMetrics( sb, sliderMin, sliderMax, sliderLength, buttonDim );
681
682 if ( scrollBarLayout() == SBOpposite ) {
683 if ( pos < sliderMin )
684 return QStyle::SubLine;
685 if ( pos < sliderStart )
686 return SubPage;
687 if ( pos < sliderStart + sliderLength )
688 return QStyle::Slider;
689 if ( pos < sliderMax + sliderLength )
690 return QStyle::AddPage;
691 return QStyle::AddLine;
692 }
693 if ( scrollBarLayout() == SBBottomLeft && sb->orientation() ==
694 QScrollBar::Horizontal ) {
695 if ( pos <= buttonDim )
696 return ( QStyle::SubLine );
697 else if ( pos <= buttonDim * 2 )
698 return ( QStyle::AddLine );
699 else if ( pos < sliderStart )
700 return ( QStyle::SubPage );
701 else if ( pos < sliderStart + sliderLength )
702 return ( QStyle::Slider );
703 return ( AddPage );
704 }
705 else {
706 if ( pos < sliderStart )
707 return QStyle::SubPage;
708 if ( pos < sliderStart + sliderLength )
709 return QStyle::Slider;
710 if ( pos < sliderMax + sliderLength )
711 return QStyle::AddPage;
712 if ( pos < sliderMax + sliderLength + buttonDim )
713 return QStyle::SubLine;
714 return QStyle::AddLine;
715 }
716}
717
718QSize OThemeStyle::exclusiveIndicatorSize() const
719{
720 if ( isPixmap( ExIndicatorOn ) )
721 return ( uncached( ExIndicatorOn ) ->size() );
722 else
723 return ( QWindowsStyle::exclusiveIndicatorSize() );
724}
725
726QSize OThemeStyle::indicatorSize() const
727{
728 if ( isPixmap( IndicatorOn ) )
729 return ( uncached( IndicatorOn ) ->size() );
730 else
731 return ( QWindowsStyle::indicatorSize() );
732}
733
734void OThemeStyle::drawExclusiveIndicator( QPainter* p, int x, int y, int w,
735 int h, const QColorGroup &g, bool on,
736 bool down, bool enabled )
737{
738 if ( isPixmap( ( on || down ) ? ExIndicatorOn : ExIndicatorOff ) ) {
739 p->drawPixmap( x, y, *uncached( ( on || down ) ? ExIndicatorOn :
740 ExIndicatorOff ) );
741 }
742 else {
743 QWindowsStyle::drawExclusiveIndicator( p, x, y, w, h,
744 *colorGroup( g, ExIndicatorOn ),
745 on, down, enabled );
746 }
747
748}
749
750void OThemeStyle::drawIndicator( QPainter* p, int x, int y, int w, int h,
751 const QColorGroup &g, int state, bool down,
752 bool enabled )
753{
754 if ( isPixmap( ( down || state != QButton::Off ) ?
755 IndicatorOn : IndicatorOff ) ) {
756 p->drawPixmap( x, y, *uncached( ( down || state != QButton::Off ) ?
757 IndicatorOn : IndicatorOff ) );
758 }
759 else {
760 QWindowsStyle::drawIndicator( p, x, y, w, h,
761 *colorGroup( g, IndicatorOn ), state,
762 down, enabled );
763 }
764}
765
766void OThemeStyle::drawExclusiveIndicatorMask( QPainter *p, int x, int y, int w,
767 int h, bool on )
768{
769 if ( isPixmap( ( on ) ? ExIndicatorOn : ExIndicatorOff ) ) {
770 const QBitmap * mask = uncached( ( on ) ? ExIndicatorOn : ExIndicatorOff ) ->
771 mask();
772 if ( mask ) {
773 p->drawPixmap( x, y, *mask );
774 }
775 else
776 p->fillRect( x, y, w, h, QBrush( color1, SolidPattern ) );
777 }
778 else
779 QWindowsStyle::drawExclusiveIndicatorMask( p, x, y, w, h, on );
780}
781
782void OThemeStyle::drawIndicatorMask( QPainter *p, int x, int y, int w, int h,
783 int state )
784{
785 if ( isPixmap( ( state != QButton::Off ) ? IndicatorOn : IndicatorOff ) ) {
786 const QBitmap * mask = uncached( ( state != QButton::Off ) ? IndicatorOn :
787 IndicatorOff ) ->mask();
788 if ( mask )
789 p->drawPixmap( x, y, *mask );
790 else
791 p->fillRect( x, y, w, h, QBrush( color1, SolidPattern ) );
792 }
793 else
794 QWindowsStyle::drawIndicatorMask( p, x, y, w, h, state );
795}
796
797void OThemeStyle::drawSliderGroove( QPainter *p, int x, int y, int w, int h,
798 const QColorGroup& g, QCOORD c,
799 Orientation orient )
800{
801 if ( roundSlider() )
802 QWindowsStyle::drawSliderGroove( p, x, y, w, h,
803 *colorGroup( g, SliderGroove ),
804 c, orient );
805 else
806 drawBaseButton( p, x, y, w, h, *colorGroup( g, SliderGroove ), true,
807 false, SliderGroove );
808}
809
810void OThemeStyle::drawSlider( QPainter *p, int x, int y, int w, int h,
811 const QColorGroup &g, Orientation orient,
812 bool tickAbove, bool tickBelow )
813{
814 if ( isPixmap( Slider ) ) {
815 if ( orient == Qt::Horizontal )
816 p->drawPixmap( x, y + ( h - uncached( Slider ) ->height() ) / 2,
817 *uncached( Slider ) );
818 else
819 p->drawPixmap( x + ( w - uncached( Slider ) ->width() ) / 2,
820 y, *uncached( Slider ) );
821 }
822 else {
823 QWindowsStyle::drawSlider( p, x, y, w, h, *colorGroup( g, Slider ),
824 orient, tickAbove, tickBelow );
825 }
826}
827
828void OThemeStyle::drawSliderMask( QPainter *p, int x, int y, int w, int h,
829 Orientation orient, bool tickAbove,
830 bool tickBelow )
831{
832 // This is odd. If we fill in the entire region it still masks the slider
833 // properly. I have no idea, this used to be different in Qt betas...
834 if ( isPixmap( Slider ) )
835 p->fillRect( x, y, w, h, QBrush( color1, SolidPattern ) );
836 else
837 QWindowsStyle::drawSliderMask( p, x, y, w, h, orient, tickAbove,
838 tickBelow );
839}
840
841int OThemeStyle::defaultFrameWidth() const
842{
843 return ( frameWidth() );
844}
845
846void OThemeStyle::getButtonShift( int &x, int &y )
847{
848 x = buttonXShift();
849 y = buttonYShift();
850}
851
852int OThemeStyle::sliderLength() const
853{
854 return ( sliderButtonLength() );
855}
856
857void OThemeStyle::drawArrow( QPainter *p, Qt::ArrowType type, bool down, int x,
858 int y, int w, int h, const QColorGroup &g,
859 bool enabled, const QBrush * )
860{
861 // Handles pixmapped arrows. A little inefficent because you can specify
862 // some as pixmaps and some as default types.
863 WidgetType widget;
864 switch ( type ) {
865 case UpArrow:
866widget = enabled ? down ? SunkenArrowUp : ArrowUp : DisArrowUp;
867 break;
868 case DownArrow:
869widget = enabled ? down ? SunkenArrowDown : ArrowDown : DisArrowDown;
870 break;
871 case LeftArrow:
872widget = enabled ? down ? SunkenArrowLeft : ArrowLeft : DisArrowLeft;
873 break;
874 case RightArrow:
875 default:
876widget = enabled ? down ? SunkenArrowRight : ArrowRight : DisArrowRight;
877 break;
878 }
879 if ( isPixmap( widget ) ) {
880 p->drawPixmap( x + ( w - uncached( widget ) ->width() ) / 2,
881 y + ( h - uncached( widget ) ->height() ) / 2,
882 *uncached( widget ) );
883 return ;
884 }
885 const QColorGroup *cg = colorGroup( g, widget );
886 // Standard arrow types
887 if ( arrowType() == MotifArrow )
888 qDrawArrow( p, type, Qt::MotifStyle, down, x, y, w, h, *cg, enabled );
889 else if ( arrowType() == SmallArrow ) {
890 QColorGroup tmp( *cg );
891 tmp.setBrush( QColorGroup::Button, QBrush( NoBrush ) );
892 QWindowsStyle::drawArrow( p, type, false, x, y, w, h,
893 tmp, true );
894 }
895 else {
896 QPointArray a;
897 int x2 = x + w - 1, y2 = y + h - 1;
898 switch ( type ) {
899 case Qt::UpArrow:
900 a.setPoints( 4, x, y2, x2, y2, x + w / 2, y, x, y2 );
901 break;
902 case Qt::DownArrow:
903 a.setPoints( 4, x, y, x2, y, x + w / 2, y2, x, y );
904 break;
905 case Qt::LeftArrow:
906 a.setPoints( 4, x2, y, x2, y2, x, y + h / 2, x2, y );
907 break;
908 default:
909 a.setPoints( 4, x, y, x, y2, x2, y + h / 2, x, y );
910 break;
911 }
912 QBrush oldBrush = p->brush();
913 QPen oldPen = p->pen();
914 p->setBrush( cg->brush( QColorGroup::Shadow ) );
915 p->setPen( cg->shadow() );
916 p->drawPolygon( a );
917 p->setBrush( oldBrush );
918 p->setPen( oldPen );
919 }
920}
921
922/* This is where we draw the borders and highlights. The new round button
923 * code is a pain in the arse. We don't want to be calculating arcs so
924 * use a whole lotta QPointArray's ;-) The code is made a lot more complex
925 * because you can have variable width border and highlights...
926 * I may want to cache this if round buttons are used, but am concerned
927 * about excessive cache misses. This is a memory/speed tradeoff that I
928 * have to test.
929 */
930void OThemeStyle::drawShade( QPainter *p, int x, int y, int w, int h,
931 const QColorGroup &g, bool sunken, bool rounded,
932 int hWidth, int bWidth, ShadeStyle style )
933{
934 int i, sc, bc, x2, y2;
935 QPen highPen, lowPen;
936
937 if ( style == Motif ) {
938 highPen.setColor( sunken ? g.dark() : g.light() );
939 lowPen.setColor( sunken ? g.light() : g.dark() );
940 }
941 else {
942 highPen.setColor( sunken ? g.shadow() : g.light() );
943 lowPen.setColor( sunken ? g.light() : g.shadow() );
944 }
945
946 // Advanced round buttons
947 if ( rounded && w > 19 && h > 19 ) {
948 x2 = x + w - 1, y2 = y + h - 1;
949 QPointArray bPntArray, hPntArray, lPntArray;
950 QPointArray bLineArray, hLineArray, lLineArray;
951 // borders
952 for ( i = 0, bc = 0; i < bWidth; ++i ) {
953 bPntArray.putPoints( bc, 24, x + 4, y + 1, x + 5, y + 1, x + 3, y + 2, x + 2, y + 3,
954 x + 1, y + 4, x + 1, y + 5, x + 1, y2 - 5, x + 1, y2 - 4, x + 2, y2 - 3,
955 x2 - 5, y + 1, x2 - 4, y + 1, x2 - 3, y + 2, x2 - 5, y2 - 1,
956 x2 - 4, y2 - 1, x2 - 3, y2 - 2, x2 - 2, y2 - 3, x2 - 1, y2 - 5,
957 x2 - 1, y2 - 4, x + 3, y2 - 2, x + 4, y2 - 1, x + 5, y2 - 1,
958 x2 - 2, y + 3, x2 - 1, y + 4, x2 - 1, y + 5 );
959 bc += 24;
960 // ellispe edges don't match exactly, so fill in blanks
961 if ( i < bWidth - 1 || hWidth != 0 ) {
962 bPntArray.putPoints( bc, 20, x + 6, y + 1, x + 4, y + 2, x + 3, y + 3,
963 x + 2, y + 4, x + 1, y + 6, x2 - 6, y + 1, x2 - 4, y + 2,
964 x2 - 3, y + 3, x + 2, y2 - 4, x + 1, y2 - 6, x2 - 6, y2 - 1,
965 x2 - 4, y2 - 2, x2 - 3, y2 - 3, x2 - 2, y2 - 4, x2 - 1, y2 - 6,
966 x + 6, y2 - 1, x + 4, y2 - 2, x + 3, y2 - 3, x2 - 1, y + 6,
967 x2 - 2, y + 4 );
968 bc += 20;
969 }
970 bLineArray.putPoints( i * 8, 8, x + 6, y, x2 - 6, y, x, y + 6, x, y2 - 6,
971 x + 6, y2, x2 - 6, y2, x2, y + 6, x2, y2 - 6 );
972 ++x, ++y;
973 --x2, --y2;
974 }
975 // highlights
976 for ( i = 0, sc = 0; i < hWidth; ++i ) {
977 hPntArray.putPoints( sc, 12, x + 4, y + 1, x + 5, y + 1, // top left
978 x + 3, y + 2, x + 2, y + 3, x + 1, y + 4, x + 1, y + 5,
979 x + 1, y2 - 5, x + 1, y2 - 4, x + 2, y2 - 3, // half corners
980 x2 - 5, y + 1, x2 - 4, y + 1, x2 - 3, y + 2 );
981 lPntArray.putPoints( sc, 12, x2 - 5, y2 - 1, x2 - 4, y2 - 1, // btm right
982 x2 - 3, y2 - 2, x2 - 2, y2 - 3, x2 - 1, y2 - 5, x2 - 1, y2 - 4,
983 x + 3, y2 - 2, x + 4, y2 - 1, x + 5, y2 - 1, //half corners
984 x2 - 2, y + 3, x2 - 1, y + 4, x2 - 1, y + 5 );
985 sc += 12;
986 if ( i < hWidth - 1 ) {
987 hPntArray.putPoints( sc, 10, x + 6, y + 1, x + 4, y + 2, // top left
988 x + 3, y + 3, x + 2, y + 4, x + 1, y + 6,
989 x2 - 6, y + 1, x2 - 4, y + 2, // half corners
990 x2 - 3, y + 3, x + 2, y2 - 4, x + 1, y2 - 6 );
991 lPntArray.putPoints( sc, 10, x2 - 6, y2 - 1, x2 - 4, y2 - 2, // btm right
992 x2 - 3, y2 - 3, x2 - 2, y2 - 4, x2 - 1, y2 - 6,
993 x + 6, y2 - 1, x + 4, y2 - 2, // half corners
994 x + 3, y2 - 3, x2 - 1, y + 6, x2 - 2, y + 4 );
995 sc += 10;
996 }
997 hLineArray.putPoints( i * 4, 4, x + 6, y, x2 - 6, y, x, y + 6, x, y2 - 6 );
998 lLineArray.putPoints( i * 4, 4, x + 6, y2, x2 - 6, y2, x2, y + 6, x2, y2 - 6 );
999 ++x, ++y;
1000 --x2, --y2;
1001 }
1002 p->setPen( Qt::black );
1003 p->drawPoints( bPntArray );
1004 p->drawLineSegments( bLineArray );
1005 p->setPen( highPen );
1006 p->drawPoints( hPntArray );
1007 p->drawLineSegments( hLineArray );
1008 p->setPen( lowPen );
1009 p->drawPoints( lPntArray );
1010 p->drawLineSegments( lLineArray );
1011 }
1012 // Rectangular buttons
1013 else {
1014 QPointArray highShade( hWidth * 4 );
1015 QPointArray lowShade( hWidth * 4 );
1016
1017 p->setPen( g.shadow() );
1018 for ( i = 0; i < bWidth && w > 2 && h > 2; ++i, ++x, ++y, w -= 2, h -= 2 )
1019 p->drawRect( x, y , w, h );
1020
1021 if ( !hWidth )
1022 return ;
1023
1024 x2 = x + w - 1, y2 = y + h - 1;
1025 for ( i = 0; i < hWidth; ++i, ++x, ++y, --x2, --y2 ) {
1026 highShade.putPoints( i * 4, 4, x, y, x2, y, x, y, x, y2 );
1027 lowShade.putPoints( i * 4, 4, x, y2, x2, y2, x2, y, x2, y2 );
1028 }
1029 if ( style == Windows && hWidth > 1 ) {
1030 p->setPen( highPen );
1031 p->drawLineSegments( highShade, 0, 2 );
1032 p->setPen( lowPen );
1033 p->drawLineSegments( lowShade, 0, 2 );
1034
1035 p->setPen( ( sunken ) ? g.dark() : g.mid() );
1036 p->drawLineSegments( highShade, 4 );
1037 p->setPen( ( sunken ) ? g.mid() : g.dark() );
1038 p->drawLineSegments( lowShade, 4 );
1039 }
1040 else {
1041 p->setPen( ( sunken ) ? g.dark() : g.light() );
1042 p->drawLineSegments( highShade );
1043 p->setPen( ( sunken ) ? g.light() : g.dark() );
1044 p->drawLineSegments( lowShade );
1045 }
1046 }
1047}
1048
1049void OThemeStyle::drawPushButtonLabel( QPushButton *btn, QPainter *p )
1050{
1051 WidgetType widget = btn->isDown() || btn->isOn() ? PushButtonDown :
1052 PushButton;
1053 const QColorGroup *cg = colorGroup( btn->colorGroup(), widget );
1054 int x, y, w, h;
1055
1056 QRect r = btn->rect();
1057 r.rect( &x, &y, &w, &h );
1058 x += decoWidth( widget );
1059 y += decoWidth( widget );
1060 w -= decoWidth( widget ) * 2;
1061 h -= decoWidth( widget ) * 2;
1062 bool act = btn->isOn() || btn->isDown();
1063
1064 // If this is a button with an associated popup menu, draw an arrow first
1065 if ( btn->popup() ) {
1066 int dx = menuButtonIndicatorWidth( btn->height() );
1067
1068 QColorGroup g( btn->colorGroup() );
1069 int xx = x + w - dx - 4;
1070 int yy = y - 3;
1071 int hh = h + 6;
1072
1073 if ( !act ) {
1074 p->setPen( g.light() );
1075 p->drawLine( xx, yy + 3, xx, yy + hh - 4 );
1076 }
1077 else {
1078 p->setPen( g.button() );
1079 p->drawLine( xx, yy + 4, xx, yy + hh - 4 );
1080 }
1081 drawArrow( p, DownArrow, FALSE,
1082 x + w - dx - 2, y + 2, dx, h - 4,
1083 btn->colorGroup(),
1084 btn->isEnabled() );
1085 w -= dx;
1086 }
1087
1088 // Next, draw iconset, if any
1089 if ( btn->iconSet() && !btn->iconSet() ->isNull() ) {
1090 QIconSet::Mode mode = btn->isEnabled()
1091 ? QIconSet::Normal : QIconSet::Disabled;
1092 if ( mode == QIconSet::Normal && btn->hasFocus() )
1093 mode = QIconSet::Active;
1094 QPixmap pixmap = btn->iconSet() ->pixmap( QIconSet::Small, mode );
1095 int pixw = pixmap.width();
1096 int pixh = pixmap.height();
1097
1098 p->drawPixmap( x + 6, y + h / 2 - pixh / 2, pixmap );
1099 x += pixw + 8;
1100 w -= pixw + 8;
1101 }
1102
1103 if ( widget == PushButtonDown ) {
1104 drawItem( p, x + buttonXShift(), y + buttonYShift(),
1105 w, h, AlignCenter | ShowPrefix, *cg, btn->isEnabled(),
1106 btn->pixmap(), btn->text(), -1, &cg->buttonText() );
1107 }
1108 else {
1109 drawItem( p, x, y, w, h, AlignCenter | ShowPrefix, *cg,
1110 btn->isEnabled(), btn->pixmap(), btn->text(), -1,
1111 &cg->buttonText() );
1112 }
1113}
1114
1115int OThemeStyle::splitterWidth() const
1116{
1117 return ( splitWidth() );
1118}
1119
1120void OThemeStyle::drawSplitter( QPainter *p, int x, int y, int w, int h,
1121 const QColorGroup &g, Orientation )
1122{
1123 drawBaseButton( p, x, y, w, h, *colorGroup( g, Splitter ), false, false,
1124 Splitter );
1125}
1126
1127void OThemeStyle::drawCheckMark( QPainter *p, int x, int y, int w, int h,
1128 const QColorGroup &g, bool act, bool dis )
1129{
1130 if ( isPixmap( CheckMark ) ) {
1131 if ( !dis )
1132 p->drawPixmap( x + ( w - uncached( CheckMark ) ->width() ) / 2,
1133 y + ( h - uncached( CheckMark ) ->height() ) / 2,
1134 *uncached( CheckMark ) );
1135 }
1136 else
1137 QWindowsStyle::drawCheckMark( p, x, y, w, h, *colorGroup( g, CheckMark ),
1138 act, dis );
1139}
1140
1141int OThemeStyle::popupMenuItemHeight( bool /*checkable*/, QMenuItem *mi,
1142 const QFontMetrics &fm )
1143{
1144 int h2, h = 0;
1145 int offset = QMAX( decoWidth( MenuItemDown ), decoWidth( MenuItem ) ) + 4;
1146
1147 if ( mi->isSeparator() )
1148 return ( 2 );
1149 if ( mi->isChecked() )
1150 h = isPixmap( CheckMark ) ? uncached( CheckMark ) ->height() + offset :
1151 offset + 16;
1152 if ( mi->pixmap() ) {
1153 h2 = mi->pixmap() ->height() + offset;
1154 h = h2 > h ? h2 : h;
1155 }
1156 if ( mi->iconSet() ) {
1157 h2 = mi->iconSet() ->
1158 pixmap( QIconSet::Small, QIconSet::Normal ).height() + offset;
1159 h = h2 > h ? h2 : h;
1160 }
1161 h2 = fm.height() + offset;
1162 h = h2 > h ? h2 : h;
1163 return ( h );
1164}
1165
1166void OThemeStyle::drawPopupMenuItem( QPainter* p, bool checkable, int maxpmw,
1167 int tab, QMenuItem* mi,
1168 const QPalette& pal, bool act,
1169 bool enabled, int x, int y, int w, int h )
1170{
1171 // I changed the following method to be based from Qt's instead of my own
1172 // wacky code. Works much better now :P (mosfet)
1173 static const int motifItemFrame = 2; // menu item frame width
1174 static const int motifItemHMargin = 5; // menu item hor text margin
1175 static const int motifItemVMargin = 4; // menu item ver text margin
1176
1177 static const int motifArrowHMargin = 6; // arrow horizontal margin
1178 static const int windowsRightBorder = 12; // right border on windowsstatic const int windowsCheckMarkWidth = 12; // checkmarks width on windows
1179 bool dis = !enabled;
1180 const QColorGroup &g = dis ? *colorGroup( pal.normal(), MenuItem ) :
1181 *colorGroup( pal.normal(), MenuItemDown );
1182
1183 QColorGroup itemg = dis ? *colorGroup( pal.disabled(), MenuItem )
1184 : act ? *colorGroup( pal.active(), MenuItemDown )
1185 : *colorGroup( pal.normal(), MenuItem );
1186
1187 maxpmw = QMAX( maxpmw, 20 );
1188 int checkcol = maxpmw;
1189
1190 if ( mi && mi->isSeparator() ) {
1191 p->setPen( g.dark() );
1192 p->drawLine( x, y, x + w, y );
1193 p->setPen( g.light() );
1194 p->drawLine( x, y + 1, x + w, y + 1 );
1195 return ;
1196 }
1197 if ( act ) {
1198 drawBaseButton( p, x, y, w, h, g, true, false, MenuItemDown );
1199 }
1200 else {
1201 drawShade( p, x, y, w, h, *colorGroup( g, MenuItem ), false, false,
1202 highlightWidth( MenuItem ), borderWidth( MenuItem ),
1203 shade() );
1204 int dw = decoWidth( MenuItem );
1205 if ( !isPixmap( MenuItem ) )
1206 p->fillRect( x + dw, y + dw, w - dw * 2, h - dw * 2,
1207 colorGroup( g, MenuItem ) ->
1208 brush( QColorGroup::Background ) );
1209 else {
1210 // process inactive item pixmaps as one large item
1211 p->drawTiledPixmap( x + dw, y + dw, w - dw * 2, h - dw * 2, *scalePixmap
1212 // (w, p->window().height(), MenuItem),
1213 ( w, p->clipRegion().boundingRect().height(), MenuItem ),
1214 x, y );
1215 }
1216
1217 if ( checkable && mi && mi->isChecked() ) {
1218 // draw 'pressed' border around checkable items
1219 // This is extremely important for items that have an iconset
1220 // because the checkmark isn't drawn in that case
1221 // An alternative would be superimposing the checkmark over
1222 // the iconset instead or not drawing the iconset at all.
1223 int mw = checkcol + motifItemFrame;
1224 drawShade( p, x, y, mw, h, g, true, false,
1225 highlightWidth( MenuItemDown ),
1226 borderWidth( MenuItemDown ), shade() );
1227 }
1228 }
1229 if ( !mi )
1230 return ;
1231 if ( mi->iconSet() ) {
1232 QIconSet::Mode mode = dis ? QIconSet::Disabled : QIconSet::Normal;
1233 if ( act && !dis )
1234 mode = QIconSet::Active;
1235 QPixmap pixmap = mi->iconSet() ->pixmap( QIconSet::Small, mode );
1236 int pixw = pixmap.width();
1237 int pixh = pixmap.height();
1238 QRect cr( x, y, checkcol, h );
1239 QRect pmr( 0, 0, pixw, pixh );
1240 pmr.moveCenter( cr.center() );
1241 p->setPen( itemg.text() );
1242 p->drawPixmap( pmr.topLeft(), pixmap );
1243
1244 }
1245 else if ( checkable ) {
1246 int mw = checkcol + motifItemFrame;
1247 int mh = h - 2 * motifItemFrame;
1248 if ( mi->isChecked() ) {
1249 drawCheckMark( p, x + motifItemFrame,
1250 y + motifItemFrame, mw, mh, itemg, act, dis );
1251 }
1252 }
1253
1254 p->setPen( colorGroup( g, act ? MenuItemDown : MenuItem ) ->text() );
1255
1256 QColor discol;
1257 if ( dis ) {
1258 discol = itemg.text();
1259 p->setPen( discol );
1260 }
1261
1262 int xm = motifItemFrame + checkcol + motifItemHMargin;
1263
1264 QString s = mi->text();
1265 if ( !s.isNull() ) {
1266 int t = s.find( '\t' );
1267 int m = motifItemVMargin;
1268 const int text_flags = AlignVCenter | ShowPrefix | DontClip | SingleLine;
1269 if ( t >= 0 ) {
1270 if ( dis && !act ) {
1271 p->setPen( g.light() );
1272 p->drawText( x + w - tab - windowsRightBorder - motifItemHMargin - motifItemFrame + 1,
1273 y + m + 1, tab, h - 2 * m, text_flags, s.mid( t + 1 ) );
1274 p->setPen( discol );
1275 }
1276 p->drawText( x + w - tab - windowsRightBorder - motifItemHMargin - motifItemFrame,
1277 y + m, tab, h - 2 * m, text_flags, s.mid( t + 1 ) );
1278 }
1279 if ( dis && !act ) {
1280 p->setPen( g.light() );
1281 p->drawText( x + xm + 1, y + m + 1, w - xm + 1, h - 2 * m, text_flags, s, t );
1282 p->setPen( discol );
1283 }
1284 p->drawText( x + xm, y + m, w - xm - tab + 1, h - 2 * m, text_flags, s, t );
1285 }
1286 else if ( mi->pixmap() ) {
1287 QPixmap * pixmap = mi->pixmap();
1288 if ( pixmap->depth() == 1 )
1289 p->setBackgroundMode( OpaqueMode );
1290 p->drawPixmap( x + xm, y + motifItemFrame, *pixmap );
1291 if ( pixmap->depth() == 1 )
1292 p->setBackgroundMode( TransparentMode );
1293 }
1294 if ( mi->popup() ) {
1295 int dim = ( h - 2 * motifItemFrame ) / 2;
1296 if ( act ) {
1297 if ( !dis )
1298 discol = colorGroup( g, MenuItemDown ) ->text();
1299 //discol = white;
1300 QColorGroup g2( discol, g.highlight(),
1301 white, white,
1302 dis ? discol : white,
1303 discol, white );
1304 drawArrow( p, RightArrow, true,
1305 x + w - motifArrowHMargin - motifItemFrame - dim, y + h / 2 - dim / 2,
1306 dim, dim, g2, TRUE );
1307 }
1308 else {
1309 drawArrow( p, RightArrow,
1310 false,
1311 x + w - motifArrowHMargin - motifItemFrame - dim, y + h / 2 - dim / 2,
1312 dim, dim, g, mi->isEnabled() );
1313 }
1314 }
1315}
1316
1317void OThemeStyle::drawFocusRect( QPainter *p, const QRect &r,
1318 const QColorGroup &g, const QColor *c,
1319 bool atBorder )
1320{
1321 p->setPen( g.dark() );
1322 if ( !is3DFocus() )
1323 QWindowsStyle::drawFocusRect( p, r, g, c, atBorder );
1324 else {
1325 int i = focusOffset();
1326 p->drawLine( r.x() + i, r.y() + 1 + i, r.x() + i, r.bottom() - 1 - i );
1327 p->drawLine( r.x() + 1 + i, r.y() + i, r.right() - 1 - i, r.y() + i );
1328 p->setPen( g.light() );
1329 p->drawLine( r.right() - i, r.y() + 1 + i, r.right() - i, r.bottom() - 1 - i );
1330 p->drawLine( r.x() + 1 + i, r.bottom() - i, r.right() - 1 - i, r.bottom() - i );
1331 }
1332}
1333
1334#if 0
1335void OThemeStyle::drawKMenuBar( QPainter *p, int x, int y, int w, int h,
1336 const QColorGroup &g, bool, QBrush * )
1337{
1338 drawBaseButton( p, x, y, w, h, *colorGroup( g, MenuBar ), false, false,
1339 MenuBar );
1340}
1341
1342void OThemeStyle::drawKMenuItem( QPainter *p, int x, int y, int w, int h,
1343 const QColorGroup &g, bool active,
1344 QMenuItem *mi, QBrush * )
1345{
1346 const QColorGroup * cg = colorGroup( g, active ? MenuBarItem : MenuBar );
1347 QColor btext = cg->buttonText();
1348 if ( active )
1349 drawBaseButton( p, x, y, w, h, *cg, false, false, MenuBarItem );
1350 //qDrawShadePanel(p, x, y, w, h, *cg, false, 1);
1351
1352 drawItem( p, x, y, w, h, AlignCenter | ShowPrefix | DontClip | SingleLine,
1353 *cg, mi->isEnabled(), mi->pixmap(), mi->text(),
1354 -1, &btext );
1355 ;
1356}
1357
1358void OThemeStyle::drawKProgressBlock( QPainter *p, int x, int y, int w, int h,
1359 const QColorGroup &g, QBrush * )
1360{
1361 drawBaseButton( p, x, y, w, h, *colorGroup( g, ProgressBar ), false, false,
1362 ProgressBar );
1363}
1364
1365void OThemeStyle::getKProgressBackground( const QColorGroup &g, QBrush &bg )
1366{
1367 const QColorGroup * cg = colorGroup( g, ProgressBg );
1368 bg.setColor( cg->color( QColorGroup::Background ) );
1369 if ( isPixmap( ProgressBg ) )
1370 bg.setPixmap( *uncached( ProgressBg ) );
1371}
1372#endif
1373
1374void OThemeStyle::tabbarMetrics( const QTabBar* t, int& hframe, int& vframe, int& overlap )
1375{
1376 QCommonStyle::tabbarMetrics( t, hframe, vframe, overlap );
1377}
1378
1379void OThemeStyle::drawTab( QPainter* p, const QTabBar* tb, QTab* t ,
1380 bool selected )
1381{
1382 WidgetType widget = selected ? ActiveTab : InactiveTab;
1383 const QColorGroup *cg = colorGroup( tb->colorGroup(), widget );
1384 int i;
1385 int x = t->r.x(), y = t->r.y();
1386 int x2 = t->r.right(), y2 = t->r.bottom();
1387 int bWidth = borderWidth( widget );
1388 int hWidth = highlightWidth( widget );
1389 if ( tb->shape() == QTabBar::RoundedAbove ) {
1390 if ( !selected ) {
1391 p->fillRect( x, y, x2 - x + 1, 2,
1392 tb->palette().normal().brush( QColorGroup::Background ) );
1393 y += 2;
1394 }
1395 p->setPen( cg->text() );
1396 i = 0;
1397 if ( i < bWidth ) {
1398 p->drawLine( x, y + 1, x, y2 );
1399 p->drawLine( x2, y + 1, x2, y2 );
1400 p->drawLine( x + 1, y, x2 - 1, y );
1401 if ( selected ? activeTabLine() : inactiveTabLine() ) {
1402 p->drawLine( x, y2, x2, y2 );
1403 --y2;
1404 }
1405 ++i, ++x, ++y, --x2;
1406 }
1407 for ( ; i < bWidth; ++i, ++x, ++y, --x2 ) {
1408 p->drawLine( x, y, x, y2 );
1409 p->drawLine( x2, y, x2, y2 );
1410 p->drawLine( x, y, x2, y );
1411 if ( selected ? activeTabLine() : inactiveTabLine() ) {
1412 p->drawLine( x, y2, x2, y2 );
1413 --y2;
1414 }
1415 }
1416 i = 0;
1417 if ( i < hWidth && bWidth == 0 ) {
1418 p->setPen( cg->light() );
1419 p->drawLine( x, y + 1, x, y2 );
1420 p->drawLine( x + 1, y, x2 - 1, y );
1421 p->setPen( cg->dark() );
1422 p->drawLine( x2, y + 1, x2, y2 );
1423 if ( selected ? activeTabLine() : inactiveTabLine() ) {
1424 p->drawLine( x, y2, x2, y2 );
1425 --y2;
1426 }
1427 ++i, ++x, ++y, --x2;
1428 }
1429 for ( ; i < hWidth; ++i, ++x, ++y, --x2 ) {
1430 p->setPen( cg->light() );
1431 p->drawLine( x, y, x, y2 );
1432 p->drawLine( x, y, x2, y );
1433 p->setPen( cg->dark() );
1434 p->drawLine( x2, y + 1, x2, y2 );
1435 if ( selected ? activeTabLine() : inactiveTabLine() ) {
1436 p->drawLine( x, y2, x2, y2 );
1437 --y2;
1438 }
1439 }
1440 if ( isPixmap( widget ) )
1441 p->drawTiledPixmap( x, y, x2 - x + 1, y2 - y + 1,
1442 *scalePixmap( x2 - x + 1, y2 - y + 1, widget ) );
1443 else
1444 p->fillRect( x, y, x2 - x + 1, y2 - y + 1, cg->background() );
1445 }
1446 else if ( tb->shape() == QTabBar::RoundedBelow ) {
1447 if ( !selected ) {
1448 p->fillRect( x, y2 - 2, x2 - x + 1, 2,
1449 tb->palette().normal().brush( QColorGroup::Background ) );
1450 y2 -= 2;
1451 }
1452 p->setPen( cg->text() );
1453 i = 0;
1454 if ( i < bWidth ) {
1455 p->drawLine( x, y, x, y2 - 1 );
1456 p->drawLine( x2, y, x2, y2 - 1 );
1457 p->drawLine( x + 1, y2, x2 - 1, y2 );
1458 if ( selected ? activeTabLine() : inactiveTabLine() ) {
1459 p->drawLine( x, y, x2, y );
1460 ++y;
1461 }
1462 }
1463 for ( ; i < bWidth; ++i, ++x, --x2, --y2 ) {
1464 p->drawLine( x, y, x, y2 );
1465 p->drawLine( x2, y, x2, y2 );
1466 p->drawLine( x, y2, x2, y2 );
1467 if ( selected ? activeTabLine() : inactiveTabLine() ) {
1468 p->drawLine( x, y, x2, y );
1469 ++y;
1470 }
1471 }
1472 i = 0;
1473 if ( i < hWidth && bWidth == 0 ) {
1474 p->setPen( cg->dark() );
1475 p->drawLine( x + 1, y2, x2 - 1, y2 );
1476 p->drawLine( x2, y, x2, y2 - 1 );
1477 p->setPen( cg->light() );
1478 p->drawLine( x, y, x, y2 - 1 );
1479 if ( selected ? activeTabLine() : inactiveTabLine() ) {
1480 p->drawLine( x, y, x2, y );
1481 ++y;
1482 }
1483 ++i, ++x, --x2, --y2;
1484 }
1485 for ( ; i < hWidth; ++i, ++x, --x2, --y2 ) {
1486 p->setPen( cg->dark() );
1487 p->drawLine( x, y2, x2, y2 );
1488 p->drawLine( x2, y, x2, y2 );
1489 p->setPen( cg->light() );
1490 p->drawLine( x, y, x, y2 );
1491 if ( selected ? activeTabLine() : inactiveTabLine() ) {
1492 p->drawLine( x, y, x2, y );
1493 ++y;
1494 }
1495 }
1496 if ( isPixmap( widget ) )
1497 p->drawTiledPixmap( x, y, x2 - x + 1, y2 - y + 1,
1498 *scalePixmap( x2 - x + 1, y2 - y + 1, widget ) );
1499 else
1500 p->fillRect( x, y, x2 - x + 1, y2 - y + 1, cg->background() );
1501 }
1502 else
1503 QCommonStyle::drawTab( p, tb, t, selected );
1504}
1505
1506void OThemeStyle::drawTabMask( QPainter* p, const QTabBar* tb, QTab* t,
1507 bool selected )
1508{
1509 QRect r( t->r );
1510
1511 if ( tb->shape() == QTabBar::RoundedAbove ) {
1512 if ( !selected )
1513 r.setTop( r.top() + 2 );
1514 p->drawLine( r.left() + 1, r.top(), r.right() - 1, r.top() );
1515 QBrush b( color1, SolidPattern );
1516 p->fillRect( r.left(), r.top() + 1, r.width(), r.height() - 1, b );
1517 }
1518 else if ( tb->shape() == QTabBar::RoundedBelow ) {
1519 if ( !selected )
1520 r.setBottom( r.bottom() - 2 );
1521 p->drawLine( r.left() + 1, r.bottom(), r.right() - 1, r.bottom() );
1522 QBrush b( color1, SolidPattern );
1523 p->fillRect( r.left(), r.top(), r.width(), r.height() - 1, b );
1524 }
1525 else
1526 QCommonStyle::drawTabMask( p, tb, t, selected );
1527
1528}
1529
1530
1531//#include "kthemestyle.moc"
1532
diff --git a/noncore/styles/theme/othemestyle.h b/noncore/styles/theme/othemestyle.h
new file mode 100644
index 0000000..02bec78
--- a/dev/null
+++ b/noncore/styles/theme/othemestyle.h
@@ -0,0 +1,365 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Daniel M. Duley <mosfet@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18#ifndef __KTHEMESTYLE_H
19#define __KTHEMESTYLE_H
20
21#include "othemebase.h"
22#include <qwindowdefs.h>
23#include <qobject.h>
24#include <qbutton.h>
25#include <qpushbutton.h>
26#include <qscrollbar.h>
27#include <qstring.h>
28
29
30/**
31 * KDE themed styles.
32 *
33 * It provides methods for
34 * drawing most widgets with user-specified borders, highlights, pixmaps,
35 * etc. It also handles various other settings such as scrollbar types,
36 * rounded buttons, and shading types. For a full list of parameters this
37 * class handles refer to the KDE theme configuration documentation.
38 *
39 */
40
41class OThemeStyle: public OThemeBase
42{
43 Q_OBJECT
44public:
45 /**
46 * Construct a new @ref OThemeStyle object.
47 *
48 * @param configFile A KConfig file to use as the theme configuration.
49 * Defaults to ~/.kderc.
50 */
51 OThemeStyle( const QString &configFile = QString::null );
52 ~OThemeStyle();
53 virtual void polish( QWidget* );
54 virtual void unPolish( QWidget* );
55 /**
56 * By default this just sets the background brushes to the pixmapped
57 * background.
58 */
59 virtual void polish( QApplication *app );
60 virtual void unPolish( QApplication* );
61
62 /// @internal
63 // to make it possible for derived classes to overload this function
64 virtual void polish( QPalette& pal );
65
66 /**
67 * This is a convenience method for drawing widgets with
68 * borders, highlights, pixmaps, colors, etc...
69 * You specify the widget type and it will draw it according to the
70 * config file settings.
71 *
72 * @param p The QPainter to draw on.
73 * @param g The color group to use.
74 * @param rounded @p true if the widget is rounded, @p false if rectangular.
75 * @param type The widget type to paint.
76 * @param fill An optional fill brush. Currently ignored (the config file
77 * is used instead).
78 */
79 virtual void drawBaseButton( QPainter *p, int x, int y, int w, int h,
80 const QColorGroup &g, bool sunken = FALSE,
81 bool rounded = FALSE, WidgetType type = Bevel,
82 const QBrush *fill = 0 );
83 /**
84 * Draw a mask with for widgets that may be rounded.
85 *
86 *Currently used
87 * by pushbuttons and comboboxes.
88 *
89 * @param p The QPainter to draw on.
90 * @param rounded @p true if the widget is rounded, @p false if rectangular.
91 */
92 virtual void drawBaseMask( QPainter *p, int x, int y, int w, int h,
93 bool rounded );
94 /**
95 * Draw a pushbutton.
96 *
97 * This calls @ref drawBaseButton() with @p PushButton as the
98 * widget type.
99 */
100 virtual void drawButton( QPainter *p, int x, int y, int w, int h,
101 const QColorGroup &g, bool sunken = FALSE,
102 const QBrush *fill = 0 );
103 /**
104 * Draw a bevel button.
105 *
106 * This calls @ref drawBaseButton() with Bevel as the
107 * widget type.
108 */
109 virtual void drawBevelButton( QPainter *p, int x, int y, int w, int h,
110 const QColorGroup &g, bool sunken = FALSE,
111 const QBrush *fill = 0 );
112#if 0
113 /**
114 * Draw a toolbar button.
115 */
116 virtual void drawKToolBarButton( QPainter *p, int x, int y, int w, int h,
117 const QColorGroup &g, bool sunken = false,
118 bool raised = true, bool enabled = true,
119 bool popup = false, KToolButtonType type = Icon,
120 const QString &btext = QString::null,
121 const QPixmap *icon = NULL,
122 QFont *font = NULL, QWidget *btn = NULL );
123 /**
124 * Draw the handle used in toolbars.
125 */
126 void drawKBarHandle( QPainter *p, int x, int y, int w, int h,
127 const QColorGroup &g,
128 KToolBarPos type, QBrush *fill = NULL );
129
130 /**
131 * Draw a toolbar.
132 */
133 void drawKToolBar( QPainter *p, int x, int y, int w, int h,
134 const QColorGroup &g, KToolBarPos type,
135 QBrush *fill = NULL );
136#endif
137 /**
138 * Return the space available in a pushbutton, taking configurable
139 * borders and highlights into account.
140 */
141 virtual QRect buttonRect( int x, int y, int w, int h );
142 /**
143 * Draw an arrow in the style specified by the config file.
144 */
145 virtual void drawArrow( QPainter *p, Qt::ArrowType type, bool down,
146 int x, int y, int w, int h, const QColorGroup &g,
147 bool enabled = true, const QBrush *fill = 0 );
148 /**
149 * Return the size of the exclusive indicator pixmap if one is specified
150 * in the config file, otherwise it uses the base style's size.
151 */
152 virtual QSize exclusiveIndicatorSize() const;
153 /**
154 * Draw an exclusive indicator widget.
155 *
156 * If a pixmap is specified in the
157 * config file that is used, otherwise the base style's widget is drawn.
158 */
159 virtual void drawExclusiveIndicator( QPainter* p, int x, int y, int w,
160 int h, const QColorGroup &g, bool on,
161 bool down = FALSE,
162 bool enabled = TRUE );
163 /**
164 * Set the mask of an exclusive indicator widget.
165 *
166 * If a pixmap is specified
167 * it is masked according to it's transparent pixels, otherwise the
168 * base style's mask is used.
169 */
170 virtual void drawExclusiveIndicatorMask( QPainter *p, int x, int y, int w,
171 int h, bool on );
172 /**
173 * Set the mask of an indicator widget.
174 *
175 * If a pixmap is specified
176 * it is masked according to it's transparent pixels, otherwise the
177 * base style's mask is used.
178 */
179 virtual void drawIndicatorMask( QPainter *p, int x, int y, int w, int h,
180 int state );
181 /**
182 * Set the mask for pushbuttons.
183 */
184 virtual void drawButtonMask( QPainter *p, int x, int y, int w, int h );
185 /**
186 * Set the mask for combo boxes.
187 */
188 virtual void drawComboButtonMask( QPainter *p, int x, int y, int w, int h );
189 /**
190 * Return the size of the indicator pixmap if one is specified
191 * in the config file, otherwise it uses the base style's size.
192 */
193 virtual QSize indicatorSize() const;
194 /**
195 * Draw an indicator widget.
196 *
197 * If a pixmap is specified in the
198 * config file that is used, otherwise the base style's widget is drawn.
199 */
200 virtual void drawIndicator( QPainter* p, int x, int y, int w, int h,
201 const QColorGroup &g, int state,
202 bool down = FALSE, bool enabled = TRUE );
203 /**
204 * Draw a combobox.
205 */
206 virtual void drawComboButton( QPainter *p, int x, int y, int w, int h,
207 const QColorGroup &g, bool sunken = FALSE,
208 bool editable = FALSE, bool enabled = TRUE,
209 const QBrush *fill = 0 );
210 /**
211 * Draw a pushbutton.
212 */
213 virtual void drawPushButton( QPushButton* btn, QPainter *p );
214 /**
215 * Return the amount of button content displacement specified by the
216 * config file.
217 */
218 virtual void getButtonShift( int &x, int &y );
219 /**
220 * Return the frame width.
221 */
222 virtual int defaultFrameWidth() const;
223 /**
224 * Calculate the metrics of the scrollbar controls according to the
225 * layout specified by the config file.
226 */
227 virtual void scrollBarMetrics( const QScrollBar*, int&, int&, int&, int& );
228 /**
229 * Draw a themed scrollbar.
230 */
231 virtual void drawScrollBarControls( QPainter*, const QScrollBar*,
232 int sliderStart, uint controls,
233 uint activeControl );
234 /**
235 * Return the control that the given point is over according to the
236 * layout in the config file.
237 */
238 virtual ScrollControl scrollBarPointOver( const QScrollBar*,
239 int sliderStart, const QPoint& );
240 /**
241 * Return the configurable default slider length.
242 */
243 virtual int sliderLength() const;
244 /**
245 * Draw a slider control.
246 */
247 virtual void drawSlider( QPainter *p, int x, int y, int w, int h,
248 const QColorGroup &g, Orientation, bool tickAbove,
249 bool tickBelow );
250 /**
251 * Draw a slider groove.
252 */
253 void drawSliderGroove( QPainter *p, int x, int y, int w, int h,
254 const QColorGroup& g, QCOORD c,
255 Orientation );
256 /**
257 * Draw the mask for a slider (both the control and groove.
258 */
259 virtual void drawSliderMask( QPainter *p, int x, int y, int w, int h,
260 Orientation, bool tickAbove, bool tickBelow );
261 // void drawSliderGrooveMask(QPainter *p,int x, int y, int w, int h,
262 // QCOORD c, Orientation );
263 /**
264 * Convience method for drawing themed scrollbar grooves.
265 *
266 * Since the
267 * grooves may be a scaled pixmap you cannot just bitblt the pixmap at
268 * any offset. This generates a cached pixmap at full size if needed and
269 * then copies the requested area.
270 *
271 * @param p The painter to draw on.
272 * @param sb The scrollbar (usually given by drawScrollBarControls).
273 * @param horizontal Is the scrollBar horizontal?
274 * @param r The rectangle to fill.
275 * @param g The color group to use.
276 */
277 virtual void drawScrollBarGroove( QPainter *p, const QScrollBar *sb,
278 bool horizontal, QRect r, QColorGroup g );
279 /**
280 * Draw a shaded rectangle using the given style.
281 *
282 * @param p The painter to draw on.
283 * @param g The color group to use.
284 * @param rounded Draws a rounded shape if true. Requires bWidth to be
285 * at least 1.
286 * @param hWidth The highlight width.
287 * @param bWidth The border width.
288 * @param style The shading style to use.
289 */
290 virtual void drawShade( QPainter *p, int x, int y, int w, int h,
291 const QColorGroup &g, bool sunken, bool rounded,
292 int hWidth, int bWidth, ShadeStyle style );
293 /**
294 * Draw the text for a pushbutton.
295 */
296 virtual void drawPushButtonLabel( QPushButton *btn, QPainter *p );
297 /**
298 * Draw a menubar.
299 */
300#if 0
301
302 void drawKMenuBar( QPainter *p, int x, int y, int w, int h,
303 const QColorGroup &g, bool macMode,
304 QBrush *fill = NULL );
305#endif
306 /**
307 * Draw a menubar item.
308 */
309#if 0
310
311 virtual void drawKMenuItem( QPainter *p, int x, int y, int w, int h,
312 const QColorGroup &g, bool active,
313 QMenuItem *item, QBrush *fill = NULL );
314#endif
315 /**
316 * Return the width of the splitter as specified in the config file.
317 */
318 virtual int splitterWidth() const;
319 /**
320 * Draw a splitter widget.
321 */
322 virtual void drawSplitter( QPainter *p, int x, int y, int w, int h,
323 const QColorGroup &g, Orientation );
324 /**
325 * Draw a checkmark.
326 */
327 virtual void drawCheckMark( QPainter *p, int x, int y, int w, int h,
328 const QColorGroup &g, bool act, bool dis );
329 /**
330 * Draw a menu item.
331 *
332 * Note: This method manually handles applying
333 * inactive menu backgrounds to the entire widget.
334 */
335 virtual void drawPopupMenuItem( QPainter *p, bool checkable, int maxpmw,
336 int tab, QMenuItem *mi, const QPalette &pal,
337 bool act, bool enabled, int x, int y, int w,
338 int h );
339 int popupMenuItemHeight( bool checkable, QMenuItem *mi,
340 const QFontMetrics &fm );
341 /**
342 * Draw the focus rectangle.
343 */
344 void drawFocusRect( QPainter *p, const QRect &r, const QColorGroup &g,
345 const QColor *c = 0, bool atBorder = false );
346 /**
347 * Draw a @ref KProgess bar.
348 */
349 // virtual void drawKProgressBlock(QPainter *p, int x, int y, int w, int h,
350 // const QColorGroup &g, QBrush *fill);
351 /**
352 * Return the background for @ref KProgress.
353 */
354 // virtual void getKProgressBackground(const QColorGroup &g, QBrush &bg);
355 virtual void tabbarMetrics( const QTabBar*, int&, int&, int& );
356 virtual void drawTab( QPainter*, const QTabBar*, QTab*, bool selected );
357 virtual void drawTabMask( QPainter*, const QTabBar*, QTab*, bool selected );
358protected:
359 QPalette oldPalette, popupPalette, indiPalette, exIndiPalette;
360
361 class OThemeStylePrivate;
362 OThemeStylePrivate *d;
363};
364
365#endif
diff --git a/noncore/styles/theme/plugin.cpp b/noncore/styles/theme/plugin.cpp
new file mode 100644
index 0000000..b334357
--- a/dev/null
+++ b/noncore/styles/theme/plugin.cpp
@@ -0,0 +1,19 @@
1//#include <klocale.h>
2#include "othemestyle.h"
3
4extern "C"
5{
6 QStyle * allocate() {
7 return new OThemeStyle ( "" );
8 }
9 int minor_version() {
10 return 0;
11 }
12 int major_version() {
13 return 1;
14 }
15 const char * description() {
16 return ( "Theme Style" );
17 }
18}
19
diff --git a/noncore/styles/theme/settings/main.cpp b/noncore/styles/theme/settings/main.cpp
new file mode 100644
index 0000000..94d40f3
--- a/dev/null
+++ b/noncore/styles/theme/settings/main.cpp
@@ -0,0 +1,34 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "themeset.h"
22
23#include <qpe/qpeapplication.h>
24
25
26int main ( int argc, char** argv )
27{
28 QPEApplication a ( argc, argv );
29
30 ThemeSet dlg;
31 a. showMainWidget ( &dlg );
32
33 return a. exec ( );
34}
diff --git a/noncore/styles/theme/settings/settings.pro b/noncore/styles/theme/settings/settings.pro
new file mode 100644
index 0000000..85d1f7a
--- a/dev/null
+++ b/noncore/styles/theme/settings/settings.pro
@@ -0,0 +1,24 @@
1 TEMPLATE= app
2 CONFIG += qt warn_on release
3 DESTDIR = $(OPIEDIR)/bin
4 HEADERS = themeset.h
5 SOURCES = themeset.cpp main.cpp
6INCLUDEPATH += $(OPIEDIR)/include
7 DEPENDPATH+= ../$(OPIEDIR)/include
8LIBS += -lqpe
9 TARGET = theme-settings
10
11TRANSLATIONS = ../../../../i18n/de/theme-settings.ts \
12 ../../../../i18n/en/theme-settings.ts \
13 ../../../../i18n/es/theme-settings.ts \
14 ../../../../i18n/fr/theme-settings.ts \
15 ../../../../i18n/hu/theme-settings.ts \
16 ../../../../i18n/ja/theme-settings.ts \
17 ../../../../i18n/ko/theme-settings.ts \
18 ../../../../i18n/no/theme-settings.ts \
19 ../../../../i18n/pl/theme-settings.ts \
20 ../../../../i18n/pt/theme-settings.ts \
21 ../../../../i18n/pt_BR/theme-settings.ts \
22 ../../../../i18n/sl/theme-settings.ts \
23 ../../../../i18n/zh_CN/theme-settings.ts \
24 ../../../../i18n/zh_TW/theme-settings.ts
diff --git a/noncore/styles/theme/settings/themeset.cpp b/noncore/styles/theme/settings/themeset.cpp
new file mode 100644
index 0000000..046618e
--- a/dev/null
+++ b/noncore/styles/theme/settings/themeset.cpp
@@ -0,0 +1,124 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21
22
23#include "themeset.h"
24
25#include <qpe/qpeapplication.h>
26#include <qpe/global.h>
27
28#include <qlabel.h>
29#include <qlayout.h>
30#include <qlistview.h>
31#include <qdir.h>
32
33#include <qpe/config.h>
34
35
36class MyConfig : public Config
37{
38public:
39 MyConfig ( const QString &f, Domain d ) : Config ( f, d )
40 { }
41
42 bool hasGroup ( const QString &gname ) const
43 {
44 QMap< QString, ConfigGroup>::ConstIterator it = groups. find ( gname );
45 return ( it != groups.end() );
46 }
47};
48
49class MyItem : public QListViewItem
50{
51public:
52 MyItem ( QListView *lv, const QString &name, const QString &comm, const QString &theme ) : QListViewItem ( lv, name, comm )
53 {
54 m_theme = theme;
55 }
56
57
58 QString m_theme;
59};
60
61
62ThemeSet::ThemeSet ( QWidget* parent, const char *name, WFlags fl )
63 : QDialog ( parent, name, fl )
64{
65 setCaption ( tr( "Theme Style" ) );
66
67 Config config ( "qpe" );
68 config. setGroup ( "Appearance" );
69
70 QString active = config. readEntry ( "Theme", "default" );
71
72 QVBoxLayout *vbox = new QVBoxLayout ( this );
73 vbox-> setSpacing ( 3 );
74 vbox-> setMargin ( 6 );
75
76 vbox-> addWidget ( new QLabel ( tr( "Select the theme to be used" ), this ));
77
78 m_list = new QListView ( this );
79 m_list-> addColumn ( tr( "Name" ));
80 m_list-> addColumn ( tr( "Description" ));
81 m_list-> setSelectionMode ( QListView::Single );
82 m_list-> setAllColumnsShowFocus ( true );
83 vbox-> addWidget ( m_list, 10 );
84
85 QListViewItem *item = new MyItem ( m_list, tr( "[No theme]" ), "", "" );
86 m_list-> setSelected ( item, true );
87
88 QString path = QPEApplication::qpeDir() + "/plugins/styles/themes";
89 QStringList list = QDir ( path, "*.themerc" ). entryList ( );
90
91 for ( QStringList::Iterator it = list. begin(); it != list. end ( ); ++it ) {
92 MyConfig cfg ( path + "/" + *it, Config::File );
93
94 if ( cfg. hasGroup ( "Misc" )) {
95 cfg. setGroup ( "Misc" );
96
97 QString name = cfg. readEntry ( "Name" );
98 QString comm = cfg. readEntry ( "Comment" );
99
100 if ( !name. isEmpty ( )) {
101 QString fname = (*it). left ((*it). length ( ) - 8 );
102
103 item = new MyItem ( m_list, name, comm, fname );
104 if ( active == fname ) {
105 m_list-> setSelected ( item, true );
106 }
107 }
108 }
109 }
110}
111
112void ThemeSet::accept ( )
113{
114 Config config ( "qpe" );
115 config. setGroup ( "Appearance" );
116
117 MyItem *it = (MyItem *) m_list-> selectedItem ( );
118 config. writeEntry ( "Theme", it ? it-> m_theme : QString ( "" ));
119
120 Global::applyStyle ( );
121
122 QDialog::accept ( );
123}
124
diff --git a/noncore/styles/theme/settings/themeset.h b/noncore/styles/theme/settings/themeset.h
new file mode 100644
index 0000000..24804ce
--- a/dev/null
+++ b/noncore/styles/theme/settings/themeset.h
@@ -0,0 +1,20 @@
1#ifndef __OPIE_THEME_SET_H__
2#define __OPIE_THEME_SET_H__
3
4#include <qdialog.h>
5
6class QListView;
7
8class ThemeSet : public QDialog {
9 Q_OBJECT
10
11public:
12 ThemeSet ( QWidget *parent = 0, const char *name = 0, WFlags fl = 0 );
13
14protected:
15 virtual void accept ( );
16
17private:
18 QListView *m_list;
19};
20#endif
diff --git a/noncore/styles/theme/theme.pro b/noncore/styles/theme/theme.pro
new file mode 100644
index 0000000..fdcd20e
--- a/dev/null
+++ b/noncore/styles/theme/theme.pro
@@ -0,0 +1,32 @@
1TEMPLATE = lib
2CONFIG = qt embedded debug warn_on
3SOURCES = ogfxeffect.cpp \
4 othemestyle.cpp \
5 othemebase.cpp \
6 plugin.cpp
7
8HEADERS = ogfxeffect.h \
9 othemebase.h \
10 othemestyle.h
11
12
13LIBS += -lqpe
14INCLUDEPATH += $(OPIEDIR)/include
15DESTDIR = $(OPIEDIR)/plugins/styles
16TARGET = theme
17VERSION = 1.0.0
18
19TRANSLATIONS = ../../../i18n/de/libtheme.ts \
20 ../../../i18n/en/libtheme.ts \
21 ../../../i18n/es/libtheme.ts \
22 ../../../i18n/fr/libtheme.ts \
23 ../../../i18n/hu/libtheme.ts \
24 ../../../i18n/ja/libtheme.ts \
25 ../../../i18n/ko/libtheme.ts \
26 ../../../i18n/no/libtheme.ts \
27 ../../../i18n/pl/libtheme.ts \
28 ../../../i18n/pt/libtheme.ts \
29 ../../../i18n/pt_BR/libtheme.ts \
30 ../../../i18n/sl/libtheme.ts \
31 ../../../i18n/zh_CN/libtheme.ts \
32 ../../../i18n/zh_TW/libtheme.ts
diff --git a/pics/theme/Theme.png b/pics/theme/Theme.png
new file mode 100644
index 0000000..67647d0
--- a/dev/null
+++ b/pics/theme/Theme.png
Binary files differ