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.
ksplash-engine-moodin/src/thememoodin.cpp

438 lines
12 KiB

/***************************************************************************
* 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 <tdeapplication.h>
#include <tdeconfig.h>
#include <kdebug.h>
#include <kgenericfactory.h>
#include <tdeglobalsettings.h>
#include <kiconloader.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
#include <kstandarddirs.h>
#include <kuser.h>
#include <tqlabel.h>
#include <tqimage.h>
#include <tqrect.h>
#include <tqpainter.h>
#include <tqstringlist.h>
#include <tqwidget.h>
#include <tqlayout.h>
#include "magiclabel.h"
#include "thememoodin.h"
K_EXPORT_COMPONENT_FACTORY(ksplashmoodin, KGenericFactory<ThemeMoodin>("ksplash"))
ThemeMoodin::ThemeMoodin(TQWidget* parent, const char* name, const TQStringList& args)
:ThemeEngine(parent, name, args)
{
readSettings();
init();
}
void ThemeMoodin::readSettings()
{
const TQRect screen = kapp->desktop()->screenGeometry(mTheme->xineramaScreen());
if (!mTheme)
return;
TDEConfig* cfg = mTheme->themeConfig();
if (!cfg)
return;
cfg->setGroup(TQString("KSplash Theme: %1").arg(mTheme->theme()));
TQFont defaultFont("Trebuchet MS", 10);
TQFont defaultStatusFont("Trebuchet MS", 12, TQFont::Bold);
TQColor defaultColor(0xFF, 0xFF, 0xFF);
TQColor defaultShadowColor(0x6D, 0x6D, 0x6D);
TQPoint defaultPoint(-1, -1), defaultOffset(0, 0);
TQString defaultIcon;
mCurrentStatusIndex = 0;
mSplashRect = cfg->readRectEntry("SplashRect", &screen);
mBackgroundImage = cfg->readEntry("Background", TQString());
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 TQPoint(2, 2));
mBaseResolution = cfg->readSizeEntry("BaseResolution", new TQSize(1280, 1024));
mTranslate = cfg->readBoolEntry("Translate", true);
mLineUpImages = cfg->readBoolEntry("LineUpImages", false);
mScaleIcons = cfg->readBoolEntry("ScaleIcons", false);
mKubuntuStyle = cfg->readBoolEntry("KubuntuStyle", false);
// so we can centre icons, JRiddell
int iconX = mBaseResolution.width();
int iconY = mBaseResolution.height();
TQRect 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 = TQString("%1.png").arg(i + 1);
mStatusIcons.append(cfg->readEntry(TQString("Image%1").arg(i + 1), defaultIcon));
if (mKubuntuStyle) {
TQPoint *mypoint;
mypoint = new TQPoint((int)(iconX + (i * (mIconSetSize+mImageSpacer) * scaleRatioWidth)), iconY);
mStatusIconCoords.append( *mypoint );
} else {
mStatusIconCoords.append(cfg->readPointEntry(TQString("ImageCoords%1").arg(i + 1), &defaultPoint));
}
mStatusImageOffsets.append(cfg->readPointEntry(TQString("ImageOffset%1").arg(i + 1), &defaultOffset));
mStatusMessages.append(cfg->readEntry(TQString("StatusMessage%1").arg(i + 1), TQString()));
}
for (int i = 0; i < mLabelCount; i++)
{
mLabels.append(cfg->readEntry(TQString("Label%1").arg(i + 1), TQString()));
mLabelCoords.append(cfg->readPointEntry(TQString("LabelCoords%1").arg(i + 1), &defaultPoint));
mLabelFonts.append(cfg->readFontEntry(TQString("LabelFont%1").arg(i + 1), &defaultFont));
mLabelColors.append(cfg->readColorEntry(TQString("LabelColor%1").arg(i + 1), &defaultColor));
}
}
void ThemeMoodin::init()
{
setBackgroundMode(NoBackground);
setFixedSize(mSplashRect.size());
mContainer = new TQWidget(this);
mContainer->setFixedSize(size());
mScaler = new Scaler(mBaseResolution, size());
mCache = new Cache(mScaler, mTheme->themeEngine(), mTheme->theme());
mBG = new KPixmap();
mBG->resize(size());
TQPainter p;
p.begin(mBG);
initBackground(&p);
initLabels(&p);
initEffectWidgets();
p.end();
move(mSplashRect.topLeft());
}
void ThemeMoodin::initBackground(TQPainter* p)
{
if (!p)
return;
TQString bgImage;
bool scaleBgImage;
if (mUsersBackground)
{
TDEConfig kdesktoprc("kdesktoprc", true, false);
kdesktoprc.setGroup("Background Common");
int num = kdesktoprc.readNumEntry("DeskNum", 0);
kdesktoprc.setGroup(TQString("Desktop%1").arg(num));
bgImage = kdesktoprc.readPathEntry("Wallpaper", TQString());
if (kdesktoprc.readPathEntry("WallpaperMode", TQString()) == "Scaled") {
scaleBgImage = true;
}
else {
scaleBgImage = false;
}
}
else
{
if (!mBackgroundImage.isEmpty())
bgImage = mTheme->locateThemeData(mBackgroundImage);
scaleBgImage = false;
}
if (bgImage.isEmpty()) {
bgImage = mTheme->locateThemeData(TQString("Background-%1x%2.jpg").arg(width()).arg(height()));
scaleBgImage = false;
}
if (bgImage.isEmpty()) {
bgImage = mTheme->locateThemeData("Background.jpg");
scaleBgImage = true;
}
if (bgImage.isEmpty())
{
KMessageBox::error(this, i18n("No background. Try to put a Background.jpg in theme folder"));
return;
}
TQImage* bg = mCache->cacheFile(bgImage);
if (scaleBgImage) {
p->drawImage(0, 0, (*bg).scale(width(), height()));
}
else {
p->drawImage(0, 0, *bg);
}
delete bg;
if (mKubuntuStyle) {
//central Dialogue, JRiddell
TQImage* central = new TQImage( mTheme->locateThemeData("Dialog.png") );
p->drawImage((mBG->width() / 2) - (462 / 2), (mBG->height() / 2) - (324 / 2), *central);
delete central;
}
}
void ThemeMoodin::initLabels(TQPainter* p)
{
if ((mLabelCount == 0) || (!p))
return;
for (int i = 0; i < mLabelCount; i++)
{
TQString s = mLabels[i];
TQPoint pt = mLabelCoords[i];
TQColor c = mLabelColors[i];
TQFont 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 TQImage(mBG->convertToImage()));
EffectWidget *fadeWidget = 0;
TQImage *image = 0;
int index = -1;
for (TQStringList::ConstIterator it = mStatusIcons.constBegin(); it != mStatusIcons.constEnd(); ++it)
{
index++;
if (mUseIconSet)
{
if ((*it).isEmpty())
continue;
// TODO: use cache in iconset mode
TQPixmap* px = new TQPixmap(DesktopIcon(*it, mIconSetSize));
image = new TQImage(px->convertToImage());
// JRiddell don't scale icons
if (!mKubuntuStyle && mScaleIcons) {
mScaler->scaleSize(image);
}
}
else
{
TQString 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(TQWidget* w, const int index)
{
TQPoint 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] + TQPoint(x, y);
}
}
else
{
mScaler->autoCoords(&current, TQSize(mIconSetSize, mIconSetSize));
current += mStatusImageOffsets[index];
}
mStatusIconCoords[index] = current;
w->move(current);
}
EffectWidget* ThemeMoodin::createEffectWidget(TQWidget* parent, TQImage* image)
{
EffectWidget *fw = new EffectWidget(parent);
fw->hide();
fw->setBackgroundOrigin(TQWidget::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 TQString& s)
{
if (mShowStatusText)
{
if (!mStatusMessages[mCurrentStatusIndex].isNull())
mCurrentAction = mStatusMessages[mCurrentStatusIndex];
else
mCurrentAction = s;
}
}
void ThemeMoodin::slotSetPixmap(const TQString& 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()
{
TQPainter p;
p.begin(mContainer);
// use a copy, otherwise status messages move around
TQPoint pt = mStatusCoords;
TQFontMetrics fm(mStatusFont);
TQSize 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(TQPaintEvent* pe)
{
TQRect r = pe->rect();
bitBlt(mContainer, r.x(), r.y(), mBG, r.x(), r.y(), r.width(), r.height());
if (mShowStatusText)
updateStatus();
}
#include "thememoodin.moc"