You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kooldock/src/xosd.cpp

227 lines
5.3 KiB

#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;
}
}