• 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)
39 static bool tqt_use_xrender=true;
40 static bool tqt_has_xft=true;
41 #else
42 extern bool tqt_use_xrender;
43 extern bool tqt_has_xft;
44 #endif
45 class TDEIconEffectPrivate
46 {
47 public:
48  TQString mKey[6][3];
49  TQColor mColor2[6][3];
50 };
51 
52 TDEIconEffect::TDEIconEffect()
53 {
54  d = new TDEIconEffectPrivate;
55  init();
56 }
57 
58 TDEIconEffect::~TDEIconEffect()
59 {
60  delete d;
61  d = 0L;
62 }
63 
64 void 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 
140 bool TDEIconEffect::hasEffect(int group, int state) const
141 {
142  return mEffect[group][state] != NoEffect;
143 }
144 
145 TQString 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 
175 TQImage 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 
191 TQImage 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 
196 TQImage 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 
232 TQPixmap 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 
248 TQPixmap 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 
254 TQPixmap 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 
285 void 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 
307 void 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 
348 void 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 
398 void 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 
416 void 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 
438 void 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 
512 void 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 
543 TQImage 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 
592 void 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
707 TDEIconEffect::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 
774 void
775 TDEIconEffect::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.1
This website is maintained by Timothy Pearson.