diff options
Diffstat (limited to 'src/xosd.cpp')
| -rw-r--r-- | src/xosd.cpp | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/src/xosd.cpp b/src/xosd.cpp new file mode 100644 index 0000000..656be2d --- /dev/null +++ b/src/xosd.cpp @@ -0,0 +1,226 @@ +#include "xosd.h" + +#include <qpainter.h> +#include <qbitmap.h> +#include <qstring.h> +#include <qfont.h> +#include <qfontmetrics.h> + +#include <qwidget.h> +#include <klocale.h> +#include <netwm.h> +#include <netwm_def.h> +#include <kwin.h> + +#include <kdebug.h> + +xosd::xosd(QWidget *parent, const char *name) : QWidget(parent, name, WStyle_Customize | WRepaintNoErase | WStyle_NoBorder | WDestructiveClose | WResizeNoErase | WMouseNoMask | WStyle_StaysOnTop | WX11BypassWM) +{ + info = new NETWinInfo( qt_xdisplay(), winId(), qt_xrootwin(), NET::WMState); + info->setDesktop( NETWinInfo::OnAllDesktops ); + hide(); + KWin::setState(winId(), NET::SkipTaskbar | NET::SkipPager); + setCaption("kooldock xosd window"); +} + +xosd::~xosd() +{ +} + +void xosd::setColor(QString color) +{ + fontColor=color; +} + +void xosd::setShadowColor(QString color) +{ + shadowColor=color; +} + +void xosd::setOrientation(int orientation, int w, int mh) +{ + fOrientation=orientation; + dw=w; + rdh=mh; + if (fCleaner==1) + { + //font is set, so program can get its height to prepare background buffer + QFontMetrics *metrics = new QFontMetrics(f); + h = metrics->height(); + + bgBuffer = QPixmap(dw, h); + maskBuffer = QPixmap(dw, h, true); + bgBuffer = QPixmap::grabWindow(qt_xrootwin(), 0, 0, dw, h); + lastX=0; + lastY=0; + } + +} + +//Enables/disables dynamic background +void xosd::setClear(int nClean) +{ + fCleaner = nClean; +} + +void xosd::setShadowOffset(int off) +{ + shadowOffset=off; +} + +void xosd::setText(QString t) +{ + //setMask(QRegion(0,0,0,0)); + // NOTICE: it appears that with WX11BypassWM, resize() doesn't flick the widget anymore :) + // so, setMask() is no more needed. + // -- Matias + resize(0,0); + text = t; + QFontMetrics *metrics = new QFontMetrics(f); + w = metrics->width(text); + w = w + shadowOffset + 5; // 5 pixels more + h = metrics->height(); + yOffset = metrics->height()-metrics->descent(); + update(); +} + +void xosd::setFont(QString font) +{ + f.setFamily(font); +} + +void xosd::setItalic() +{ + f.setItalic(TRUE); +} + +void xosd::setBold() +{ + f.setBold(TRUE); +} + +void xosd::setSize(int size) +{ + f.setPointSize(size); + fontSize = size; +} + +/*int xosd::w() +{ + QFontMetrics *metrics = new QFontMetrics(f); + return (metrics->width(text) + shadowOffset + 5); + +} + +int xosd::h() +{ + QFontMetrics *metrics = new QFontMetrics(f); + return metrics->height(); +}*/ + +void xosd::paintEvent(QPaintEvent *) +{ + int i, j; + + resize(w,h); + + QPixmap pm(size()); + QBitmap bm(size()); + QPainter p; + + //Drawing text + p.begin(&pm, this); + if (fCleaner==1) + { + //Dynamic background - look cleaner + bitBlt(&pm, 0, 0, &bgBuffer, lastX, 0, w, h); + } + else + { + //One colour background - work faster + p.fillRect (rect(), QColor(shadowColor)); + } + + p.setPen( QColor(shadowColor) ); + p.setFont(f); + p.drawText(shadowOffset, yOffset + shadowOffset, text, AlignCenter); // draw shadow text + + // now, draw normal text + p.setPen( QColor(fontColor) ); + + p.drawText(1, yOffset, text, AlignCenter); // draw front text + + p.end(); + + //Drawing mask + p.begin(&bm, this); + // now we must draw the text with black color for making the mask + p.setPen( Qt::white ); + p.fillRect (rect(), Qt::black); + p.setFont(f); + for (i=-fCleaner;i<=fCleaner;i++) + { + for (j=-fCleaner;j<=fCleaner;j++) + { + p.drawText(shadowOffset+i, yOffset + shadowOffset+j, text, AlignCenter); // shadow + p.drawText(1+i, yOffset+j, text, AlignCenter); // front + } + } + p.end(); + bitBlt(this, 0, 0, &pm); // update the widget + if (fCleaner==1) bitBlt(&maskBuffer, 0, 0, &bm); + + info->setState(NETWinInfo::SkipTaskbar | NETWinInfo::SkipPager, NETWinInfo::SkipTaskbar | NETWinInfo::SkipPager); + setMask(bm); +} + +void xosd::move2(int x, int y) +{ + + //bit block transfer don't work propertly with too less cursor position changes + if (abs(lastY-y)>2 || abs(lastX-x)>2) + { + if (fCleaner==1) + { + QPixmap tmpBuffer; + //window is not hidden + if (y!=rdh) + { + tmpBuffer = QPixmap::grabWindow(qt_xrootwin(), 0, y, dw, h); + if (lastY!=rdh) + { + //fill background covered with the text with cached version + if (fOrientation==0 ) //horizontal + { + bitBlt(&tmpBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, Qt::AndROP);//copying part, which hides only the text + bitBlt(&bgBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, Qt::NotAndROP);//so the background won't be covered by + bitBlt(&tmpBuffer, lastX, 0, &bgBuffer, lastX, 0, w, h, Qt::OrROP);//currently visible text. + } + if (fOrientation==1) //vertical + { + if (y<lastY && (y+h)>lastY) + { + bitBlt(&tmpBuffer, lastX, lastY-y, &maskBuffer, 0, 0, w, h, Qt::AndROP); + bitBlt(&bgBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, Qt::NotAndROP); + bitBlt(&tmpBuffer, lastX, lastY-y, &bgBuffer, lastX, 0, w, h, Qt::OrROP); + } + if (y>lastY && (y-lastY)<h) + { + bitBlt(&tmpBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, Qt::AndROP); + bitBlt(&bgBuffer, lastX, y-lastY, &maskBuffer, 0, 0, w, h, Qt::NotAndROP); + bitBlt(&tmpBuffer, lastX, 0, &bgBuffer, lastX, y-lastY, w, h, Qt::OrROP); + } + } + } + + } + bitBlt(&bgBuffer,0,0,&tmpBuffer); + lastX=x; + paintEvent(NULL); + } + + move(x,y); + lastX=x; + lastY=y; + } +} |
