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.
420 lines
11 KiB
420 lines
11 KiB
15 years ago
|
/***************************************************************************
|
||
|
* Copyright (C) by *
|
||
|
* - 2005: Christian Leh <moodwrod@web.de> *
|
||
|
* *
|
||
|
* This program is free software; you can redistribute it and/or modify *
|
||
|
* it under the terms of the GNU General Public License as published by *
|
||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||
|
* (at your option) any later version. *
|
||
|
* *
|
||
|
***************************************************************************/
|
||
|
|
||
|
#include <kapplication.h>
|
||
|
#include <kconfig.h>
|
||
|
#include <kdebug.h>
|
||
|
#include <kgenericfactory.h>
|
||
|
#include <kglobalsettings.h>
|
||
|
#include <kiconloader.h>
|
||
|
#include <klocale.h>
|
||
|
#include <kmessagebox.h>
|
||
|
#include <kstandarddirs.h>
|
||
|
#include <kuser.h>
|
||
|
|
||
|
#include <qlabel.h>
|
||
|
#include <qimage.h>
|
||
|
#include <qrect.h>
|
||
|
#include <qpainter.h>
|
||
|
#include <qstringlist.h>
|
||
|
#include <qwidget.h>
|
||
|
#include <qlayout.h>
|
||
|
|
||
|
#include "magiclabel.h"
|
||
|
#include "thememoodin.h"
|
||
|
|
||
|
K_EXPORT_COMPONENT_FACTORY(ksplashmoodin, KGenericFactory<ThemeMoodin>("ksplash"))
|
||
|
|
||
|
|
||
|
ThemeMoodin::ThemeMoodin(QWidget* parent, const char* name, const QStringList& args)
|
||
|
:ThemeEngine(parent, name, args)
|
||
|
{
|
||
|
readSettings();
|
||
|
init();
|
||
|
}
|
||
|
|
||
|
|
||
|
void ThemeMoodin::readSettings()
|
||
|
{
|
||
|
const QRect screen = kapp->desktop()->screenGeometry(mTheme->xineramaScreen());
|
||
|
|
||
|
if (!mTheme)
|
||
|
return;
|
||
|
|
||
|
KConfig* cfg = mTheme->themeConfig();
|
||
|
|
||
|
if (!cfg)
|
||
|
return;
|
||
|
|
||
|
cfg->setGroup(QString("KSplash Theme: %1").arg(mTheme->theme()));
|
||
|
|
||
|
QFont defaultFont("Trebuchet MS", 10);
|
||
|
QFont defaultStatusFont("Trebuchet MS", 12, QFont::Bold);
|
||
|
QColor defaultColor(0xFF, 0xFF, 0xFF);
|
||
|
QColor defaultShadowColor(0x6D, 0x6D, 0x6D);
|
||
|
QPoint defaultPoint(-1, -1), defaultOffset(0, 0);
|
||
|
QString defaultIcon;
|
||
|
|
||
|
mCurrentStatusIndex = 0;
|
||
|
mSplashRect = cfg->readRectEntry("SplashRect", &screen);
|
||
|
mBackgroundImage = cfg->readEntry("Background", QString::null);
|
||
|
mStatusColor = cfg->readColorEntry("StatusColor", &defaultColor);
|
||
|
mStatusFont = cfg->readFontEntry("StatusFont", &defaultStatusFont);
|
||
|
mStatusCoords = cfg->readPointEntry("StatusCoords", &defaultPoint);
|
||
|
mLabelShadow = cfg->readBoolEntry("LabelShadow", true);
|
||
|
mLabelShadowColor = cfg->readColorEntry("LabelShadowColor", &defaultShadowColor);
|
||
|
mShowStatusText = cfg->readBoolEntry("ShowStatusText", true);
|
||
|
mAnimationLength = cfg->readNumEntry("AnimationLength", 30);
|
||
|
mAnimationDelay = cfg->readNumEntry("AnimationDelay", 30);
|
||
|
mBeginOpacity = cfg->readDoubleNumEntry("BeginOpacity", 0.20);
|
||
|
mUseIconSet = cfg->readBoolEntry("UseIconSet", true);
|
||
|
mIconSetSize = cfg->readNumEntry("IconSetSize", 48);
|
||
|
mAppendX = cfg->readBoolEntry("AppendX", true);
|
||
|
mImageSpacer = cfg->readNumEntry("ImageSpacer", mUseIconSet ? mIconSetSize : 0);
|
||
|
mUsersBackground = cfg->readBoolEntry("UsersBackground", false);
|
||
|
mLabelCount = cfg->readNumEntry("Labels", 0);
|
||
|
mLabelShadowOffset = cfg->readPointEntry("LabelShadowOffset", new QPoint(2, 2));
|
||
|
mBaseResolution = cfg->readSizeEntry("BaseResolution", new QSize(1280, 1024));
|
||
|
mTranslate = cfg->readBoolEntry("Translate", true);
|
||
|
mLineUpImages = cfg->readBoolEntry("LineUpImages", false);
|
||
|
mKubuntuStyle = cfg->readBoolEntry("KubuntuStyle", false);
|
||
|
|
||
|
// so we can centre icons, JRiddell
|
||
|
int iconX = mBaseResolution.width();
|
||
|
int iconY = mBaseResolution.height();
|
||
|
QRect defaultScreen = kapp->desktop()->screenGeometry(0);
|
||
|
float scaleRatioWidth = ((float)mBaseResolution.width()) / ((float)defaultScreen.width());
|
||
|
// unused. float scaleRatioHeight = ((float)mBaseResolution.height()) / ((float)desktopWidget.height());
|
||
|
|
||
|
iconX = iconX / 2;
|
||
|
// first icon position calculated based on size and spacing
|
||
|
// Edgy Dialog.png is off centre so take off random 8 pixels
|
||
|
iconX = iconX - (int)((((mIconSetSize+mImageSpacer)*4) - 8) * scaleRatioWidth);
|
||
|
// Edgy Dialog.png is off centre so add random 20 pixels
|
||
|
iconY = (iconY / 2) + 20;
|
||
|
|
||
|
for (int i = 0; i < int(statusPixmaps().count()); i++)
|
||
|
{
|
||
|
if (mUseIconSet)
|
||
|
defaultIcon = statusPixmaps()[i];
|
||
|
else
|
||
|
defaultIcon = QString("%1.png").arg(i + 1);
|
||
|
|
||
|
mStatusIcons.append(cfg->readEntry(QString("Image%1").arg(i + 1), defaultIcon));
|
||
|
if (mKubuntuStyle) {
|
||
|
QPoint *mypoint;
|
||
|
mypoint = new QPoint((int)(iconX + (i * (mIconSetSize+mImageSpacer) * scaleRatioWidth)), iconY);
|
||
|
mStatusIconCoords.append( *mypoint );
|
||
|
} else {
|
||
|
mStatusIconCoords.append(cfg->readPointEntry(QString("ImageCoords%1").arg(i + 1), &defaultPoint));
|
||
|
}
|
||
|
mStatusImageOffsets.append(cfg->readPointEntry(QString("ImageOffset%1").arg(i + 1), &defaultOffset));
|
||
|
mStatusMessages.append(cfg->readEntry(QString("StatusMessage%1").arg(i + 1), QString::null));
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < mLabelCount; i++)
|
||
|
{
|
||
|
mLabels.append(cfg->readEntry(QString("Label%1").arg(i + 1), QString::null));
|
||
|
mLabelCoords.append(cfg->readPointEntry(QString("LabelCoords%1").arg(i + 1), &defaultPoint));
|
||
|
mLabelFonts.append(cfg->readFontEntry(QString("LabelFont%1").arg(i + 1), &defaultFont));
|
||
|
mLabelColors.append(cfg->readColorEntry(QString("LabelColor%1").arg(i + 1), &defaultColor));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void ThemeMoodin::init()
|
||
|
{
|
||
|
setBackgroundMode(NoBackground);
|
||
|
setFixedSize(mSplashRect.size());
|
||
|
|
||
|
mContainer = new QWidget(this);
|
||
|
mContainer->setFixedSize(size());
|
||
|
mScaler = new Scaler(mBaseResolution, size());
|
||
|
mCache = new Cache(mScaler, mTheme->themeEngine(), mTheme->theme());
|
||
|
mBG = new KPixmap();
|
||
|
mBG->resize(size());
|
||
|
|
||
|
QPainter p;
|
||
|
p.begin(mBG);
|
||
|
|
||
|
initBackground(&p);
|
||
|
initLabels(&p);
|
||
|
initEffectWidgets();
|
||
|
|
||
|
p.end();
|
||
|
|
||
|
move(mSplashRect.topLeft());
|
||
|
}
|
||
|
|
||
|
|
||
|
void ThemeMoodin::initBackground(QPainter* p)
|
||
|
{
|
||
|
if (!p)
|
||
|
return;
|
||
|
|
||
|
QString bgImage;
|
||
|
|
||
|
if (mUsersBackground)
|
||
|
{
|
||
|
KConfig kdesktoprc("kdesktoprc", true, false);
|
||
|
kdesktoprc.setGroup("Background Common");
|
||
|
int num = kdesktoprc.readNumEntry("DeskNum", 0);
|
||
|
|
||
|
kdesktoprc.setGroup(QString("Desktop%1").arg(num));
|
||
|
bgImage = kdesktoprc.readPathEntry("Wallpaper", QString::null);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (!mBackgroundImage.isEmpty())
|
||
|
bgImage = mTheme->locateThemeData(mBackgroundImage);
|
||
|
}
|
||
|
|
||
|
if (bgImage.isEmpty())
|
||
|
bgImage = mTheme->locateThemeData(QString("Background-%1x%2.jpg").arg(width()).arg(height()));
|
||
|
|
||
|
if (bgImage.isEmpty())
|
||
|
bgImage = mTheme->locateThemeData("Background.jpg");
|
||
|
|
||
|
if (bgImage.isEmpty())
|
||
|
{
|
||
|
KMessageBox::error(this, i18n("No background. Try to put a Background.jpg in theme folder"));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
QImage* bg = mCache->cacheFile(bgImage);
|
||
|
p->drawImage(0, 0, *bg);
|
||
|
delete bg;
|
||
|
|
||
|
if (mKubuntuStyle) {
|
||
|
//central Dialogue, JRiddell
|
||
|
QImage* central = new QImage( mTheme->locateThemeData("Dialog.png") );
|
||
|
p->drawImage((mBG->width() / 2) - (462 / 2), (mBG->height() / 2) - (324 / 2), *central);
|
||
|
delete central;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ThemeMoodin::initLabels(QPainter* p)
|
||
|
{
|
||
|
if ((mLabelCount == 0) || (!p))
|
||
|
return;
|
||
|
|
||
|
for (int i = 0; i < mLabelCount; i++)
|
||
|
{
|
||
|
QString s = mLabels[i];
|
||
|
QPoint pt = mLabelCoords[i];
|
||
|
QColor c = mLabelColors[i];
|
||
|
QFont f = mLabelFonts[i];
|
||
|
|
||
|
if (s.isNull() || s.isEmpty())
|
||
|
continue;
|
||
|
|
||
|
MagicLabel ml(s, mTranslate);
|
||
|
s = ml.value();
|
||
|
|
||
|
mScaler->scaleSize(&f);
|
||
|
mScaler->autoCoords(&pt, f, s);
|
||
|
|
||
|
p->setFont(f);
|
||
|
|
||
|
if (mLabelShadow)
|
||
|
{
|
||
|
p->setPen(mLabelShadowColor);
|
||
|
p->drawText(pt + mLabelShadowOffset, s);
|
||
|
}
|
||
|
|
||
|
p->setPen(c);
|
||
|
p->drawText(pt, s);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void ThemeMoodin::initEffectWidgets()
|
||
|
{
|
||
|
EffectWidget::setBackgroundImage(new QImage(mBG->convertToImage()));
|
||
|
EffectWidget *fadeWidget = 0;
|
||
|
QImage *image = 0;
|
||
|
int index = -1;
|
||
|
|
||
|
for (QStringList::ConstIterator it = mStatusIcons.constBegin(); it != mStatusIcons.constEnd(); ++it)
|
||
|
{
|
||
|
index++;
|
||
|
|
||
|
if (mUseIconSet)
|
||
|
{
|
||
|
if ((*it).isEmpty())
|
||
|
continue;
|
||
|
|
||
|
// TODO: use cache in iconset mode
|
||
|
QPixmap* px = new QPixmap(DesktopIcon(*it, mIconSetSize));
|
||
|
image = new QImage(px->convertToImage());
|
||
|
// JRiddell don't scale icons
|
||
|
if (!mKubuntuStyle) {
|
||
|
mScaler->scaleSize(image);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
QString name = mTheme->locateThemeData(*it);
|
||
|
|
||
|
if (name.isEmpty())
|
||
|
continue;
|
||
|
|
||
|
image = mCache->cacheFile(name);
|
||
|
|
||
|
if (image->isNull())
|
||
|
{
|
||
|
delete image;
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fadeWidget = createEffectWidget(mContainer, image);
|
||
|
mEffectWidgets.append(fadeWidget);
|
||
|
mImages.append(image);
|
||
|
arrangeWidget(fadeWidget, index);
|
||
|
}
|
||
|
|
||
|
for (EffectWidget *fw = mEffectWidgets.first(); fw; fw = mEffectWidgets.next())
|
||
|
fw->updateCache();
|
||
|
}
|
||
|
|
||
|
|
||
|
void ThemeMoodin::arrangeWidget(QWidget* w, const int index)
|
||
|
{
|
||
|
QPoint current(mStatusIconCoords[index]);
|
||
|
|
||
|
if (mLineUpImages)
|
||
|
{
|
||
|
static bool first = true;
|
||
|
|
||
|
if (first)
|
||
|
{
|
||
|
int hw = mAppendX ? width() : height();
|
||
|
int hwi = mAppendX ? height() : width();
|
||
|
int icons = mStatusIcons.count() * mIconSetSize;
|
||
|
int spaces = (mStatusIcons.count() - 1) * mIconSetSize;// + int(float(mIconSetSize) * 0.5);
|
||
|
int q = int((hwi - mIconSetSize) / 2);
|
||
|
int r = int((hw - icons - spaces) / 2);
|
||
|
|
||
|
int x = mAppendX ? r : q;
|
||
|
int y = mAppendX ? q : r;
|
||
|
|
||
|
current.setX(x);
|
||
|
current.setY(y);
|
||
|
first = false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int x = mAppendX ? mIconSetSize * 2 : 0;
|
||
|
int y = mAppendX ? 0 : mIconSetSize * 2;
|
||
|
|
||
|
current = mStatusIconCoords[index - 1] + QPoint(x, y);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
mScaler->autoCoords(¤t, QSize(mIconSetSize, mIconSetSize));
|
||
|
current += mStatusImageOffsets[index];
|
||
|
}
|
||
|
|
||
|
mStatusIconCoords[index] = current;
|
||
|
w->move(current);
|
||
|
}
|
||
|
|
||
|
|
||
|
EffectWidget* ThemeMoodin::createEffectWidget(QWidget* parent, QImage* image)
|
||
|
{
|
||
|
EffectWidget *fw = new EffectWidget(parent);
|
||
|
|
||
|
fw->hide();
|
||
|
fw->setBackgroundOrigin(QWidget::WindowOrigin);
|
||
|
fw->setDelay(mAnimationDelay);
|
||
|
fw->setSteps(mAnimationLength);
|
||
|
fw->setFixedSize(image->size());
|
||
|
fw->setImage(image);
|
||
|
fw->setStart(mBeginOpacity);
|
||
|
fw->show();
|
||
|
|
||
|
return fw;
|
||
|
}
|
||
|
|
||
|
|
||
|
void ThemeMoodin::slotSetText(const QString& s)
|
||
|
{
|
||
|
if (mShowStatusText)
|
||
|
{
|
||
|
if (!mStatusMessages[mCurrentStatusIndex].isNull())
|
||
|
mCurrentAction = mStatusMessages[mCurrentStatusIndex];
|
||
|
else
|
||
|
mCurrentAction = s;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void ThemeMoodin::slotSetPixmap(const QString& s)
|
||
|
{
|
||
|
if (!mEffectWidgets.count() > 0)
|
||
|
return;
|
||
|
|
||
|
int n = statusPixmaps().findIndex(s);
|
||
|
|
||
|
if (n == -1)
|
||
|
return;
|
||
|
|
||
|
mCurrentStatusIndex = n + 1;
|
||
|
|
||
|
EffectWidget *fw = mEffectWidgets.at(n);
|
||
|
|
||
|
if (fw)
|
||
|
fw->start();
|
||
|
|
||
|
repaint(false);
|
||
|
}
|
||
|
|
||
|
|
||
|
void ThemeMoodin::updateStatus()
|
||
|
{
|
||
|
QPainter p;
|
||
|
p.begin(mContainer);
|
||
|
|
||
|
// use a copy, otherwise status messages move around
|
||
|
QPoint pt = mStatusCoords;
|
||
|
QFontMetrics fm(mStatusFont);
|
||
|
QSize fmSize(fm.size(0L, mCurrentAction));
|
||
|
|
||
|
mScaler->autoCoords(&pt, fmSize);
|
||
|
|
||
|
p.setFont(mStatusFont);
|
||
|
|
||
|
if (mLabelShadow)
|
||
|
{
|
||
|
p.setPen(mLabelShadowColor);
|
||
|
p.drawText(pt + mLabelShadowOffset, mCurrentAction);
|
||
|
}
|
||
|
|
||
|
p.setPen(mStatusColor);
|
||
|
p.drawText(pt, mCurrentAction);
|
||
|
p.end();
|
||
|
}
|
||
|
|
||
|
|
||
|
void ThemeMoodin::paintEvent(QPaintEvent* pe)
|
||
|
{
|
||
|
QRect r = pe->rect();
|
||
|
|
||
|
bitBlt(mContainer, r.x(), r.y(), mBG, r.x(), r.y(), r.width(), r.height());
|
||
|
|
||
|
if (mShowStatusText)
|
||
|
updateStatus();
|
||
|
}
|
||
|
|
||
|
#include "thememoodin.moc"
|