• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
kiconeffect.cpp
1/*
2 * $Id$
3 *
4 * This file is part of the KDE project, module tdecore.
5 * Copyright (C) 2000 Geert Jansen <jansen@kde.org>
6 * with minor additions and based on ideas from
7 * Torsten Rahn <torsten@kde.org>
8 *
9 * This is free software; it comes under the GNU Library General
10 * Public License, version 2. See the file "COPYING.LIB" for the
11 * exact licensing terms.
12 */
13
14#include <config.h>
15#include <unistd.h>
16#include <math.h>
17
18#include <tqstring.h>
19#include <tqstringlist.h>
20#include <tqbitmap.h>
21#include <tqpixmap.h>
22#include <tqimage.h>
23#include <tqcolor.h>
24#include <tqwidget.h>
25#include <tqpainter.h>
26#include <tqpen.h>
27#include <tqapplication.h>
28#include <tqpoint.h>
29#include <tqrect.h>
30
31#include <kdebug.h>
32#include <tdeglobal.h>
33#include <tdeconfig.h>
34#include <tdeglobalsettings.h>
35#include <kicontheme.h>
36#include "kiconeffect.h"
37
38#if defined(TQ_WS_WIN) || defined(TQ_WS_MACX)
39static bool tqt_use_xrender=true;
40static bool tqt_has_xft=true;
41#else
42extern bool tqt_use_xrender;
43extern bool tqt_has_xft;
44#endif
45class TDEIconEffectPrivate
46{
47public:
48 TQString mKey[6][3];
49 TQColor mColor2[6][3];
50};
51
52TDEIconEffect::TDEIconEffect()
53{
54 d = new TDEIconEffectPrivate;
55 init();
56}
57
58TDEIconEffect::~TDEIconEffect()
59{
60 delete d;
61 d = 0L;
62}
63
64void TDEIconEffect::init()
65{
66 TDEConfig *config = TDEGlobal::config();
67
68 int i, j, effect=-1;
69 TQStringList groups;
70 groups += "Desktop";
71 groups += "Toolbar";
72 groups += "MainToolbar";
73 groups += "Small";
74 groups += "Panel";
75
76 TQStringList states;
77 states += "Default";
78 states += "Active";
79 states += "Disabled";
80
81 TQStringList::ConstIterator it, it2;
82 TQString _togray("togray");
83 TQString _colorize("colorize");
84 TQString _desaturate("desaturate");
85 TQString _togamma("togamma");
86 TQString _none("none");
87 TQString _tomonochrome("tomonochrome");
88
89 TDEConfigGroupSaver cs(config, "default");
90
91 for (it=groups.begin(), i=0; it!=groups.end(); it++, i++)
92 {
93 // Default effects
94 mEffect[i][0] = NoEffect;
95 mEffect[i][1] = ((i==0)||(i==4)) ? ToGamma : NoEffect;
96 mEffect[i][2] = ToGray;
97
98 mTrans[i][0] = false;
99 mTrans[i][1] = false;
100 mTrans[i][2] = true;
101 mValue[i][0] = 1.0;
102 mValue[i][1] = ((i==0)||(i==4)) ? 0.7 : 1.0;
103 mValue[i][2] = 1.0;
104 mColor[i][0] = TQColor(144,128,248);
105 mColor[i][1] = TQColor(169,156,255);
106 mColor[i][2] = TQColor(34,202,0);
107 d->mColor2[i][0] = TQColor(0,0,0);
108 d->mColor2[i][1] = TQColor(0,0,0);
109 d->mColor2[i][2] = TQColor(0,0,0);
110
111 config->setGroup(*it + "Icons");
112 for (it2=states.begin(), j=0; it2!=states.end(); it2++, j++)
113 {
114 TQString tmp = config->readEntry(*it2 + "Effect");
115 if (tmp == _togray)
116 effect = ToGray;
117 else if (tmp == _colorize)
118 effect = Colorize;
119 else if (tmp == _desaturate)
120 effect = DeSaturate;
121 else if (tmp == _togamma)
122 effect = ToGamma;
123 else if (tmp == _tomonochrome)
124 effect = ToMonochrome;
125 else if (tmp == _none)
126 effect = NoEffect;
127 else
128 continue;
129 if(effect != -1)
130 mEffect[i][j] = effect;
131 mValue[i][j] = config->readDoubleNumEntry(*it2 + "Value");
132 mColor[i][j] = config->readColorEntry(*it2 + "Color");
133 d->mColor2[i][j] = config->readColorEntry(*it2 + "Color2");
134 mTrans[i][j] = config->readBoolEntry(*it2 + "SemiTransparent");
135
136 }
137 }
138}
139
140bool TDEIconEffect::hasEffect(int group, int state) const
141{
142 return mEffect[group][state] != NoEffect;
143}
144
145TQString TDEIconEffect::fingerprint(int group, int state) const
146{
147 if ( group >= TDEIcon::LastGroup ) return "";
148 TQString cached = d->mKey[group][state];
149 if (cached.isEmpty())
150 {
151 TQString tmp;
152 cached = tmp.setNum(mEffect[group][state]);
153 cached += ':';
154 cached += tmp.setNum(mValue[group][state]);
155 cached += ':';
156 cached += mTrans[group][state] ? TQString::fromLatin1("trans")
157 : TQString::fromLatin1("notrans");
158 if (mEffect[group][state] == Colorize || mEffect[group][state] == ToMonochrome)
159 {
160 cached += ':';
161 cached += mColor[group][state].name();
162 }
163 if (mEffect[group][state] == ToMonochrome)
164 {
165 cached += ':';
166 cached += d->mColor2[group][state].name();
167 }
168
169 d->mKey[group][state] = cached;
170 }
171
172 return cached;
173}
174
175TQImage TDEIconEffect::apply(TQImage image, int group, int state) const
176{
177 if (state >= TDEIcon::LastState)
178 {
179 kdDebug(265) << "Illegal icon state: " << state << "\n";
180 return image;
181 }
182 if (group >= TDEIcon::LastGroup)
183 {
184 kdDebug(265) << "Illegal icon group: " << group << "\n";
185 return image;
186 }
187 return apply(image, mEffect[group][state], mValue[group][state],
188 mColor[group][state], d->mColor2[group][state], mTrans[group][state]);
189}
190
191TQImage TDEIconEffect::apply(TQImage image, int effect, float value, const TQColor col, bool trans) const
192{
193 return apply (image, effect, value, col, TDEGlobalSettings::baseColor(), trans);
194}
195
196TQImage TDEIconEffect::apply(TQImage image, int effect, float value, const TQColor col, const TQColor col2, bool trans) const
197{
198 if (effect >= LastEffect )
199 {
200 kdDebug(265) << "Illegal icon effect: " << effect << "\n";
201 return image;
202 }
203 if (value > 1.0)
204 value = 1.0;
205 else if (value < 0.0)
206 value = 0.0;
207 switch (effect)
208 {
209 case ToGray:
210 toGray(image, value);
211 break;
212 case DeSaturate:
213 deSaturate(image, value);
214 break;
215 case Colorize:
216 colorize(image, col, value);
217 break;
218 case ToGamma:
219 toGamma(image, value);
220 break;
221 case ToMonochrome:
222 toMonochrome(image, col, col2, value);
223 break;
224 }
225 if (trans == true)
226 {
227 semiTransparent(image);
228 }
229 return image;
230}
231
232TQPixmap TDEIconEffect::apply(TQPixmap pixmap, int group, int state) const
233{
234 if (state >= TDEIcon::LastState)
235 {
236 kdDebug(265) << "Illegal icon state: " << state << "\n";
237 return pixmap;
238 }
239 if (group >= TDEIcon::LastGroup)
240 {
241 kdDebug(265) << "Illegal icon group: " << group << "\n";
242 return pixmap;
243 }
244 return apply(pixmap, mEffect[group][state], mValue[group][state],
245 mColor[group][state], d->mColor2[group][state], mTrans[group][state]);
246}
247
248TQPixmap TDEIconEffect::apply(TQPixmap pixmap, int effect, float value,
249 const TQColor col, bool trans) const
250{
251 return apply (pixmap, effect, value, col, TDEGlobalSettings::baseColor(), trans);
252}
253
254TQPixmap TDEIconEffect::apply(TQPixmap pixmap, int effect, float value,
255 const TQColor col, const TQColor col2, bool trans) const
256{
257 TQPixmap result;
258
259 if (effect >= LastEffect )
260 {
261 kdDebug(265) << "Illegal icon effect: " << effect << "\n";
262 return result;
263 }
264
265 if ((trans == true) && (effect == NoEffect))
266 {
267 result = pixmap;
268 semiTransparent(result);
269 }
270 else if ( effect != NoEffect )
271 {
272 TQImage tmpImg = pixmap.convertToImage();
273 tmpImg = apply(tmpImg, effect, value, col, col2, trans);
274 result.convertFromImage(tmpImg);
275 }
276 else
277 result = pixmap;
278
279 return result;
280}
281
282// Taken from KImageEffect. We don't want to link tdecore to tdeui! As long
283// as this code is not too big, it doesn't seem much of a problem to me.
284
285void TDEIconEffect::toGray(TQImage &img, float value)
286{
287 int pixels = (img.depth() > 8) ? img.width()*img.height()
288 : img.numColors();
289 unsigned int *data = img.depth() > 8 ? (unsigned int *) img.bits()
290 : (unsigned int *) img.colorTable();
291 int rval, gval, bval, val, alpha, i;
292 for (i=0; i<pixels; i++)
293 {
294 val = tqGray(data[i]);
295 alpha = tqAlpha(data[i]);
296 if (value < 1.0)
297 {
298 rval = static_cast<int>(value*val+(1.0-value)*tqRed(data[i]));
299 gval = static_cast<int>(value*val+(1.0-value)*tqGreen(data[i]));
300 bval = static_cast<int>(value*val+(1.0-value)*tqBlue(data[i]));
301 data[i] = tqRgba(rval, gval, bval, alpha);
302 } else
303 data[i] = tqRgba(val, val, val, alpha);
304 }
305}
306
307void TDEIconEffect::colorize(TQImage &img, const TQColor &col, float value)
308{
309 int pixels = (img.depth() > 8) ? img.width()*img.height()
310 : img.numColors();
311 unsigned int *data = img.depth() > 8 ? (unsigned int *) img.bits()
312 : (unsigned int *) img.colorTable();
313 int rval, gval, bval, val, alpha, i;
314 float rcol = col.red(), gcol = col.green(), bcol = col.blue();
315 for (i=0; i<pixels; i++)
316 {
317 val = tqGray(data[i]);
318 if (val < 128)
319 {
320 rval = static_cast<int>(rcol/128*val);
321 gval = static_cast<int>(gcol/128*val);
322 bval = static_cast<int>(bcol/128*val);
323 }
324 else if (val > 128)
325 {
326 rval = static_cast<int>((val-128)*(2-rcol/128)+rcol-1);
327 gval = static_cast<int>((val-128)*(2-gcol/128)+gcol-1);
328 bval = static_cast<int>((val-128)*(2-bcol/128)+bcol-1);
329 }
330 else // val == 128
331 {
332 rval = static_cast<int>(rcol);
333 gval = static_cast<int>(gcol);
334 bval = static_cast<int>(bcol);
335 }
336 if (value < 1.0)
337 {
338 rval = static_cast<int>(value*rval+(1.0 - value)*tqRed(data[i]));
339 gval = static_cast<int>(value*gval+(1.0 - value)*tqGreen(data[i]));
340 bval = static_cast<int>(value*bval+(1.0 - value)*tqBlue(data[i]));
341 }
342
343 alpha = tqAlpha(data[i]);
344 data[i] = tqRgba(rval, gval, bval, alpha);
345 }
346}
347
348void TDEIconEffect::toMonochrome(TQImage &img, const TQColor &black, const TQColor &white, float value) {
349 int pixels = (img.depth() > 8) ? img.width()*img.height() : img.numColors();
350 unsigned int *data = img.depth() > 8 ? (unsigned int *) img.bits()
351 : (unsigned int *) img.colorTable();
352 int rval, gval, bval, alpha, i;
353 int rw = white.red(), gw = white.green(), bw = white.blue();
354 int rb = black.red(), gb = black.green(), bb = black.blue();
355
356 double values = 0, sum = 0;
357 bool grayscale = true;
358 // Step 1: determine the average brightness
359 for (i=0; i<pixels; i++) {
360 sum += tqGray(data[i])*tqAlpha(data[i]) + 255*(255-tqAlpha(data[i]));
361 values += 255;
362 if ((tqRed(data[i]) != tqGreen(data[i]) ) || (tqGreen(data[i]) != tqBlue(data[i]) ))
363 grayscale = false;
364 }
365 double medium = sum/values;
366
367 // Step 2: Modify the image
368 if (grayscale) {
369 for (i=0; i<pixels; i++) {
370 int v = tqRed(data[i]);
371 rval = static_cast<int>( ((255-v)*rb + v*rw)*value/255 + (1.0-value)*tqRed(data[i]));
372 gval = static_cast<int>( ((255-v)*gb + v*gw)*value/255 + (1.0-value)*tqGreen(data[i]));
373 bval = static_cast<int>( ((255-v)*bb + v*bw)*value/255 + (1.0-value)*tqBlue(data[i]));
374
375 alpha = tqAlpha(data[i]);
376 data[i] = tqRgba(rval, gval, bval, alpha);
377 }
378 }
379 else {
380 for (i=0; i<pixels; i++) {
381 if (tqGray(data[i]) <= medium) {
382 rval = static_cast<int>(value*rb+(1.0-value)*tqRed(data[i]));
383 gval = static_cast<int>(value*gb+(1.0-value)*tqGreen(data[i]));
384 bval = static_cast<int>(value*bb+(1.0-value)*tqBlue(data[i]));
385 }
386 else {
387 rval = static_cast<int>(value*rw+(1.0-value)*tqRed(data[i]));
388 gval = static_cast<int>(value*gw+(1.0-value)*tqGreen(data[i]));
389 bval = static_cast<int>(value*bw+(1.0-value)*tqBlue(data[i]));
390 }
391
392 alpha = tqAlpha(data[i]);
393 data[i] = tqRgba(rval, gval, bval, alpha);
394 }
395 }
396}
397
398void TDEIconEffect::deSaturate(TQImage &img, float value)
399{
400 int pixels = (img.depth() > 8) ? img.width()*img.height()
401 : img.numColors();
402 unsigned int *data = (img.depth() > 8) ? (unsigned int *) img.bits()
403 : (unsigned int *) img.colorTable();
404 TQColor color;
405 int h, s, v, i;
406 for (i=0; i<pixels; i++)
407 {
408 color.setRgb(data[i]);
409 color.hsv(&h, &s, &v);
410 color.setHsv(h, (int) (s * (1.0 - value) + 0.5), v);
411 data[i] = tqRgba(color.red(), color.green(), color.blue(),
412 tqAlpha(data[i]));
413 }
414}
415
416void TDEIconEffect::toGamma(TQImage &img, float value)
417{
418 int pixels = (img.depth() > 8) ? img.width()*img.height()
419 : img.numColors();
420 unsigned int *data = (img.depth() > 8) ? (unsigned int *) img.bits()
421 : (unsigned int *) img.colorTable();
422 TQColor color;
423 int i, rval, gval, bval;
424 float gamma;
425 gamma = 1/(2*value+0.5);
426
427 for (i=0; i<pixels; i++)
428 {
429 color.setRgb(data[i]);
430 color.rgb(&rval, &gval, &bval);
431 rval = static_cast<int>(pow(static_cast<float>(rval)/255 , gamma)*255);
432 gval = static_cast<int>(pow(static_cast<float>(gval)/255 , gamma)*255);
433 bval = static_cast<int>(pow(static_cast<float>(bval)/255 , gamma)*255);
434 data[i] = tqRgba(rval, gval, bval, tqAlpha(data[i]));
435 }
436}
437
438void TDEIconEffect::semiTransparent(TQImage &img)
439{
440 img.setAlphaBuffer(true);
441
442 int x, y;
443 if (img.depth() == 32)
444 {
445 int width = img.width();
446 int height = img.height();
447
448 if (tqt_use_xrender && tqt_has_xft )
449 for (y=0; y<height; y++)
450 {
451#ifdef WORDS_BIGENDIAN
452 uchar *line = (uchar*) img.scanLine(y);
453#else
454 uchar *line = (uchar*) img.scanLine(y) + 3;
455#endif
456 for (x=0; x<width; x++)
457 {
458 *line >>= 1;
459 line += 4;
460 }
461 }
462 else
463 for (y=0; y<height; y++)
464 {
465 TQRgb *line = (TQRgb *) img.scanLine(y);
466 for (x=(y%2); x<width; x+=2)
467 line[x] &= 0x00ffffff;
468 }
469
470 } else
471 {
472 // Insert transparent pixel into the clut.
473 int transColor = -1;
474
475 // search for a color that is already transparent
476 for (x=0; x<img.numColors(); x++)
477 {
478 // try to find already transparent pixel
479 if (tqAlpha(img.color(x)) < 127)
480 {
481 transColor = x;
482 break;
483 }
484 }
485
486
487 // FIXME: image must have transparency
488 if(transColor < 0 || transColor >= img.numColors())
489 return;
490
491 img.setColor(transColor, 0);
492 if(img.depth() == 8)
493 {
494 for (y=0; y<img.height(); y++)
495 {
496 unsigned char *line = img.scanLine(y);
497 for (x=(y%2); x<img.width(); x+=2)
498 line[x] = transColor;
499 }
500 }
501 else
502 {
503 // SLOOW, but simple, as we would have to
504 // deal with endianess etc on our own here
505 for (y=0; y<img.height(); y++)
506 for (x=(y%2); x<img.width(); x+=2)
507 img.setPixel(x, y, transColor);
508 }
509 }
510}
511
512void TDEIconEffect::semiTransparent(TQPixmap &pix)
513{
514 if ( tqt_use_xrender && tqt_has_xft )
515 {
516 TQImage img=pix.convertToImage();
517 semiTransparent(img);
518 pix.convertFromImage(img);
519 return;
520 }
521
522 TQImage img;
523 if (pix.mask() != 0L)
524 img = pix.mask()->convertToImage();
525 else
526 {
527 img.create(pix.size(), 1, 2, TQImage::BigEndian);
528 img.fill(1);
529 }
530
531 for (int y=0; y<img.height(); y++)
532 {
533 TQRgb *line = (TQRgb *) img.scanLine(y);
534 TQRgb pattern = (y % 2) ? 0x55555555 : 0xaaaaaaaa;
535 for (int x=0; x<(img.width()+31)/32; x++)
536 line[x] &= pattern;
537 }
538 TQBitmap mask;
539 mask.convertFromImage(img);
540 pix.setMask(mask);
541}
542
543TQImage TDEIconEffect::doublePixels(TQImage src) const
544{
545 TQImage dst;
546 if (src.depth() == 1)
547 {
548 kdDebug(265) << "image depth 1 not supported\n";
549 return dst;
550 }
551
552 int w = src.width();
553 int h = src.height();
554 dst.create(w*2, h*2, src.depth());
555 dst.setAlphaBuffer(src.hasAlphaBuffer());
556
557 int x, y;
558 if (src.depth() == 32)
559 {
560 TQRgb *l1, *l2;
561 for (y=0; y<h; y++)
562 {
563 l1 = (TQRgb *) src.scanLine(y);
564 l2 = (TQRgb *) dst.scanLine(y*2);
565 for (x=0; x<w; x++)
566 {
567 l2[x*2] = l2[x*2+1] = l1[x];
568 }
569 memcpy(dst.scanLine(y*2+1), l2, dst.bytesPerLine());
570 }
571 } else
572 {
573 for (x=0; x<src.numColors(); x++)
574 dst.setColor(x, src.color(x));
575
576 unsigned char *l1, *l2;
577 for (y=0; y<h; y++)
578 {
579 l1 = src.scanLine(y);
580 l2 = dst.scanLine(y*2);
581 for (x=0; x<w; x++)
582 {
583 l2[x*2] = l1[x];
584 l2[x*2+1] = l1[x];
585 }
586 memcpy(dst.scanLine(y*2+1), l2, dst.bytesPerLine());
587 }
588 }
589 return dst;
590}
591
592void TDEIconEffect::overlay(TQImage &src, TQImage &overlay)
593{
594 if (src.depth() != overlay.depth())
595 {
596 kdDebug(265) << "Image depth src != overlay!\n";
597 return;
598 }
599 if (src.size() != overlay.size())
600 {
601 kdDebug(265) << "Image size src != overlay\n";
602 return;
603 }
604 if (!overlay.hasAlphaBuffer())
605 {
606 kdDebug(265) << "Overlay doesn't have alpha buffer!\n";
607 return;
608 }
609
610 int i, j;
611
612 // We don't do 1 bpp
613
614 if (src.depth() == 1)
615 {
616 kdDebug(265) << "1bpp not supported!\n";
617 return;
618 }
619
620 // Overlay at 8 bpp doesn't use alpha blending
621
622 if (src.depth() == 8)
623 {
624 if (src.numColors() + overlay.numColors() > 255)
625 {
626 kdDebug(265) << "Too many colors in src + overlay!\n";
627 return;
628 }
629
630 // Find transparent pixel in overlay
631 int trans;
632 for (trans=0; trans<overlay.numColors(); trans++)
633 {
634 if (tqAlpha(overlay.color(trans)) == 0)
635 {
636 kdDebug(265) << "transparent pixel found at " << trans << "\n";
637 break;
638 }
639 }
640 if (trans == overlay.numColors())
641 {
642 kdDebug(265) << "transparent pixel not found!\n";
643 return;
644 }
645
646 // Merge color tables
647 int nc = src.numColors();
648 src.setNumColors(nc + overlay.numColors());
649 for (i=0; i<overlay.numColors(); i++)
650 {
651 src.setColor(nc+i, overlay.color(i));
652 }
653
654 // Overwrite nontransparent pixels.
655 unsigned char *oline, *sline;
656 for (i=0; i<src.height(); i++)
657 {
658 oline = overlay.scanLine(i);
659 sline = src.scanLine(i);
660 for (j=0; j<src.width(); j++)
661 {
662 if (oline[j] != trans)
663 sline[j] = oline[j]+nc;
664 }
665 }
666 }
667
668 // Overlay at 32 bpp does use alpha blending
669
670 if (src.depth() == 32)
671 {
672 TQRgb *oline, *sline;
673 int r1, g1, b1, a1;
674 int r2, g2, b2, a2;
675
676 for (i=0; i<src.height(); i++)
677 {
678 oline = (TQRgb *) overlay.scanLine(i);
679 sline = (TQRgb *) src.scanLine(i);
680
681 for (j=0; j<src.width(); j++)
682 {
683 r1 = tqRed(oline[j]);
684 g1 = tqGreen(oline[j]);
685 b1 = tqBlue(oline[j]);
686 a1 = tqAlpha(oline[j]);
687
688 r2 = tqRed(sline[j]);
689 g2 = tqGreen(sline[j]);
690 b2 = tqBlue(sline[j]);
691 a2 = tqAlpha(sline[j]);
692
693 r2 = (a1 * r1 + (0xff - a1) * r2) >> 8;
694 g2 = (a1 * g1 + (0xff - a1) * g2) >> 8;
695 b2 = (a1 * b1 + (0xff - a1) * b2) >> 8;
696 a2 = TQMAX(a1, a2);
697
698 sline[j] = tqRgba(r2, g2, b2, a2);
699 }
700 }
701 }
702
703 return;
704}
705
706 void
707TDEIconEffect::visualActivate(TQWidget * widget, TQRect rect)
708{
709 if (!TDEGlobalSettings::visualActivate())
710 return;
711
712 uint actSpeed = TDEGlobalSettings::visualActivateSpeed();
713
714 uint actCount = TQMIN(rect.width(), rect.height()) / 2;
715
716 // Clip actCount to range 1..10.
717
718 if (actCount < 1)
719 actCount = 1;
720
721 else if (actCount > 10)
722 actCount = 10;
723
724 // Clip actSpeed to range 1..100.
725
726 if (actSpeed < 1)
727 actSpeed = 1;
728
729 else if (actSpeed > 100)
730 actSpeed = 100;
731
732 // actSpeed needs to be converted to actDelay.
733 // actDelay is inversely proportional to actSpeed and needs to be
734 // divided up into actCount portions.
735 // We also convert the us value to ms.
736
737 unsigned int actDelay = (1000 * (100 - actSpeed)) / actCount;
738
739 //kdDebug() << "actCount=" << actCount << " actDelay=" << actDelay << endl;
740
741 TQPoint c = rect.center();
742
743 TQPainter p(widget);
744
745 // Use NotROP to avoid having to repaint the pixmap each time.
746 p.setPen(TQPen(TQt::black, 2, TQt::DotLine));
747 p.setRasterOp(TQt::NotROP);
748
749 // The spacing between the rects we draw.
750 // Use the minimum of width and height to avoid painting outside the
751 // pixmap area.
752 //unsigned int delta(TQMIN(rect.width() / actCount, rect.height() / actCount));
753
754 // Support for rectangles by David
755 unsigned int deltaX = rect.width() / actCount;
756 unsigned int deltaY = rect.height() / actCount;
757
758 for (unsigned int i = 1; i < actCount; i++) {
759
760 int w = i * deltaX;
761 int h = i * deltaY;
762
763 rect.setRect(c.x() - w / 2, c.y() - h / 2, w, h);
764
765 p.drawRect(rect);
766 p.flush();
767
768 usleep(actDelay);
769
770 p.drawRect(rect);
771 }
772}
773
774void
775TDEIconEffect::visualActivate(TQWidget * widget, TQRect rect, TQPixmap *pixmap)
776{
777 if (!TDEGlobalSettings::visualActivate())
778 return;
779
780 // Image too big to display smoothly
781 if ((rect.width() > 160) || (rect.height() > 160)) {
782 visualActivate(widget, rect); // call old effect
783 return;
784 }
785
786 uint actSpeed = TDEGlobalSettings::visualActivateSpeed();
787 uint actCount = TQMIN(rect.width(), rect.height()) / 4;
788
789
790 // Clip actCount to range 1..10.
791 if (actCount < 1)
792 actCount = 1;
793
794 else if (actCount > 10)
795 actCount = 10;
796
797 // Clip actSpeed to range 1..100.
798 if (actSpeed < 1)
799 actSpeed = 1;
800
801 else if (actSpeed > 100)
802 actSpeed = 100;
803
804 // actSpeed needs to be converted to actDelay.
805 // actDelay is inversely proportional to actSpeed and needs to be
806 // divided up into actCount portions.
807 // We also convert the us value to ms.
808
809 unsigned int actDelay = (1000 * (100 - actSpeed)) / actCount;
810
811 unsigned int deltaX = rect.width() / actCount * 1.5;
812 unsigned int deltaY = rect.height() / actCount * 1.5;
813
814 TQPoint c = rect.center();
815 TQRect maxRect(c.x() - (actCount * 2) * deltaX /2,
816 c.y() - (actCount * 2) * deltaY /2,
817 actCount * 2 * deltaX,
818 actCount * 2 * deltaY);
819
820 // convert rect to global coordinates if needed
821 if ((widget->rect().width() <= maxRect.width())
822 || (widget->rect().height() <= maxRect.height()))
823 {
824 TQPoint topLeft(rect.x(), rect.y());
825 rect.moveLeft(widget->mapToGlobal(topLeft).x());
826 rect.moveTop(widget->mapToGlobal(topLeft).y());
827 c = rect.center();
828 maxRect.setRect(c.x() - (actCount * 2) * deltaX /2,
829 c.y() - (actCount * 2) * deltaY /2,
830 actCount * 2 * deltaX,
831 actCount * 2 * deltaY);
832 }
833
834 TQPainter *p;
835 TQImage img = pixmap->convertToImage();
836 TQPixmap pix;
837 TQPixmap composite(maxRect.width(), maxRect.height(), -1, TQPixmap::BestOptim);
838 TQPainter cPainter(&composite);
839 TQPoint cComposite = composite.rect().center();
840
841 // enable alpha blending
842 img.setAlphaBuffer(true);
843
844 // Ugly hack... Get "Screenshot" to blt into and even do that on the
845 // root window if the display area of <widget> is too small
846 if ((widget->rect().width() <= maxRect.width())
847 || (widget->rect().height() <= maxRect.height()))
848 {
849// p = new TQPainter(TQApplication::desktop()->screen( -1 ), TRUE); // WARNING: This was done in Qt3. It only worked in this placement due to a glitch in Qt3; it has therefore been moved below grabWidget, where it should have been in the first place.
850 pix = TQPixmap::grabWindow((TQApplication::desktop()->screen( -1 ))->winId(),
851 maxRect.x(),
852 maxRect.y(),
853 maxRect.width(),
854 maxRect.height());
855 p = new TQPainter(TQApplication::desktop()->screen( -1 ), TRUE);
856 } else
857 {
858 // not as ugly as drawing directly to the screen
859// p = new TQPainter(widget); // WARNING: This was done in Qt3. See above.
860 pix = TQPixmap::grabWidget(widget,
861 maxRect.x(),
862 maxRect.y(),
863 maxRect.width(),
864 maxRect.height());
865 p = new TQPainter(widget);
866 }
867 uchar deltaAlpha = 255 / (actCount * 1.2);
868
869 // Activate effect like MacOS X
870 for (unsigned int i = actCount; i < actCount * 2; i++) {
871
872 int w = i * deltaX;
873 int h = i * deltaY;
874
875 rect.setRect(cComposite.x() - w / 2, cComposite.y() - h / 2, w, h);
876
877 // draw offscreen
878 cPainter.drawPixmap(0, 0, pix, 0, 0, pix.width(), pix.height());
879 cPainter.drawImage(rect, img);
880 cPainter.flush();
881
882 // put onscreen
883 p->drawPixmap(maxRect, composite);
884 p->flush();
885
886 // Fade out Icon a bit more
887 int x, y;
888 if ((img.depth() == 32) && tqt_use_xrender && tqt_has_xft)
889 {
890 int width = img.width();
891 int height = img.height();
892
893 for (y=0; y<height; y++)
894 {
895#ifdef WORDS_BIGENDIAN
896 uchar *line = (uchar*) img.scanLine(y);
897#else
898 uchar *line = (uchar*) img.scanLine(y) + 3;
899#endif
900 for (x=0; x<width; x++)
901 {
902 *line = (*line < deltaAlpha) ? 0 : *line - deltaAlpha;
903 line += 4;
904 }
905 }
906 }
907 usleep(actDelay*3);
908 }
909
910 // remove traces of the effect
911 if ((widget->rect().width() <= maxRect.width())
912 || (widget->rect().height() <= maxRect.height()))
913 p->drawPixmap(maxRect, pix);
914 else {
915 p->drawPixmap(maxRect, pix);
916 widget->update(rect);
917 }
918
919 delete p;
920}
TDEConfigBase::readEntry
TQString readEntry(const TQString &pKey, const TQString &aDefault=TQString::null) const
Reads the value of an entry specified by pKey in the current group.
Definition: tdeconfigbase.cpp:221
TDEConfigBase::readColorEntry
TQColor readColorEntry(const TQString &pKey, const TQColor *pDefault=0L) const
Reads a TQColor entry.
Definition: tdeconfigbase.cpp:947
TDEConfigBase::readBoolEntry
bool readBoolEntry(const TQString &pKey, bool bDefault=false) const
Reads a boolean entry.
Definition: tdeconfigbase.cpp:748
TDEConfigBase::readDoubleNumEntry
double readDoubleNumEntry(const TQString &pKey, double nDefault=0.0) const
Reads a floating point value.
Definition: tdeconfigbase.cpp:729
TDEConfigBase::setGroup
void setGroup(const TQString &group)
Specifies the group in which keys will be read and written.
Definition: tdeconfigbase.cpp:79
TDEConfigGroupSaver
Helper class to facilitate working with TDEConfig / KSimpleConfig groups.
Definition: tdeconfigbase.h:2083
TDEConfig
Access KDE Configuration entries.
Definition: tdeconfig.h:44
TDEGlobalSettings::baseColor
static TQColor baseColor()
Returns the default base (background) color.
Definition: tdeglobalsettings.cpp:386
TDEGlobalSettings::visualActivateSpeed
static unsigned int visualActivateSpeed()
Returns the speed of the visual activation feedback.
Definition: tdeglobalsettings.cpp:265
TDEGlobalSettings::visualActivate
static bool visualActivate()
Checks whether to show feedback when in item (specifically an icon) is activated.
Definition: tdeglobalsettings.cpp:259
TDEGlobal::config
static TDEConfig * config()
Returns the general config object.
Definition: tdeglobal.cpp:65
TDEIconEffect::init
void init()
Rereads configuration.
Definition: kiconeffect.cpp:64
TDEIconEffect::toMonochrome
static void toMonochrome(TQImage &image, const TQColor &black, const TQColor &white, float value)
Produces a monochrome icon with a given foreground and background color.
Definition: kiconeffect.cpp:348
TDEIconEffect::toGray
static void toGray(TQImage &image, float value)
Tints an image gray.
Definition: kiconeffect.cpp:285
TDEIconEffect::doublePixels
TQImage doublePixels(TQImage src) const
Returns an image twice as large, consisting of 2x2 pixels.
Definition: kiconeffect.cpp:543
TDEIconEffect::hasEffect
bool hasEffect(int group, int state) const
Tests whether an effect has been configured for the given icon group.
Definition: kiconeffect.cpp:140
TDEIconEffect::overlay
static void overlay(TQImage &src, TQImage &overlay)
Overlays an image with an other image.
Definition: kiconeffect.cpp:592
TDEIconEffect::deSaturate
static void deSaturate(TQImage &image, float value)
Desaturates an image.
Definition: kiconeffect.cpp:398
TDEIconEffect::colorize
static void colorize(TQImage &image, const TQColor &col, float value)
Colorizes an image with a specific color.
Definition: kiconeffect.cpp:307
TDEIconEffect::toGamma
static void toGamma(TQImage &image, float value)
Changes the gamma value of an image.
Definition: kiconeffect.cpp:416
TDEIconEffect::TDEIconEffect
TDEIconEffect()
Create a new TDEIconEffect.
Definition: kiconeffect.cpp:52
TDEIconEffect::semiTransparent
static void semiTransparent(TQImage &image)
Renders an image semi-transparent.
Definition: kiconeffect.cpp:438
TDEIconEffect::apply
TQImage apply(TQImage src, int group, int state) const
Applies an effect to an image.
Definition: kiconeffect.cpp:175
TDEIconEffect::fingerprint
TQString fingerprint(int group, int state) const
Returns a fingerprint for the effect by encoding the given group and state into a TQString.
Definition: kiconeffect.cpp:145
TDEIconEffect::visualActivate
static void visualActivate(TQWidget *widget, TQRect rect)
Provides visual feedback to show activation of an icon on a widget.
Definition: kiconeffect.cpp:707
TDEIconEffect::ToMonochrome
@ ToMonochrome
Definition: kiconeffect.h:56
TDEIcon::LastState
@ LastState
Last state (last constant)
Definition: kicontheme.h:133
TDEIcon::LastGroup
@ LastGroup
Last group.
Definition: kicontheme.h:104

tdecore

Skip menu "tdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.9.4
This website is maintained by Timothy Pearson.