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.
tdemultimedia/noatun/modules/winskin/waSkinModel.cpp

459 lines
11 KiB

/*
operations with skinset.
Copyright (C) 1999 Martin Vogt
Copyright (C) 2001 Ryan Cumming
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.
For more information look at the file COPYRIGHT in this package
*/
#include <config.h>
#include <tqdir.h>
#include <tqstringlist.h>
#include <tqbitmap.h>
#include <kdebug.h>
#include <kstandarddirs.h>
#include "waSkinMapping.h"
#include "waShadeMapping.h"
#include "waSkinModel.h"
#include "waColor.h"
#include "waRegion.h"
#include "waSkin.h"
WaSkinModel *_waskinmodel_instance = NULL;
// Our current skin map
// Can switch between normal and windowshade maps
const SkinMap *mapToGui;
const SkinDesc *mapFromFile;
int digit_width;
int digit_height;
struct WaPixmapEntry {
const char *filename;
TQPixmap *pixmap;
};
WaPixmapEntry waPixmapEntries[11] = {
{"main.bmp", NULL},
{"cbuttons.bmp", NULL},
{"monoster.bmp", NULL},
{"numbers.bmp", NULL},
{"shufrep.bmp", NULL},
{"text.bmp", NULL},
{"volume.bmp", NULL},
{"balance.bmp", NULL},
{"posbar.bmp", NULL},
{"playpaus.bmp", NULL},
{"titlebar.bmp", NULL}
};
WaSkinModel::WaSkinModel()
{
for (int x = 0;x < 11;x++)
waPixmapEntries[x].pixmap = new TQPixmap;
resetSkinModel();
_waskinmodel_instance = this;
}
WaSkinModel::~WaSkinModel()
{
for (int x = 0;x < 11;x++)
delete waPixmapEntries[x].pixmap;
delete windowRegion;
delete colorScheme;
}
bool WaSkinModel::load(TQString skinDir)
{
bool success = true;
TQDir dir(skinDir);
if (findFile(dir, "main.bmp").isEmpty()) {
// Ack, our skin dir doesn't exist, fall back to the default
dir = TQDir(TDEGlobal::dirs()->findDirs("data", "noatun/skins/winamp/" + WaSkin::defaultSkin())[0]);
success = false;
}
for (int x = 0;x < 11;x++) {
getPixmap(dir, waPixmapEntries[x].filename,
waPixmapEntries[x].pixmap);
}
resetSkinModel();
loadColors(dir);
loadRegion(dir);
emit(skinChanged());
return success;
}
// Does a case-insenstive file search (like DOS/Windows)
// Filename -must- be lowercase, which is an nice optimization, since
// this is a private API, and all our filenames are internally lowercase
// anyway
TQString WaSkinModel::findFile(const TQDir &dir, const TQString &filename) {
TQFileInfo fileInfo;
TQString ret = "";
TQStringList strList = dir.entryList();
for (TQStringList::iterator file = strList.begin(); file != strList.end(); file++) {
TQFileInfo fileInfo(*file);
if (fileInfo.isDir())
continue;
if (fileInfo.filePath().lower() == filename)
return dir.absPath() + "/" + TQString(fileInfo.filePath());
}
return "";
}
void WaSkinModel::loadColors(const TQDir &dir) {
TQString colorFile = findFile(dir, "viscolor.txt");
if (colorScheme) {
delete colorScheme;
}
colorScheme = new WaColor(colorFile);
}
void WaSkinModel::loadRegion(const TQDir &dir) {
TQString regionFile = findFile(dir, "region.txt");
if (windowRegion) {
delete windowRegion;
windowRegion = 0;
}
windowRegion = new WaRegion(regionFile);
}
int WaSkinModel::getPixmap(const TQDir &dir, TQString fname,
TQPixmap *target)
{
TQFileInfo fileInfo;
TQStringList strList = dir.entryList();
TQString abspath;
abspath = findFile(dir, fname);
if (!abspath.isEmpty()) {
target->load(abspath);
return true;
}
// now the filename mapping 1.8x -> 2.0
if (fname == "volume.bmp")
return WaSkinModel::getPixmap(dir, TQString("volbar.bmp"), target);
if (fname == "numbers.bmp")
return WaSkinModel::getPixmap(dir, TQString("nums_ex.bmp"), target);
// Even 2.x themes can omit BALANCE, in which case we use VOLUME
if (fname == "balance.bmp")
return WaSkinModel::getPixmap(dir, TQString("volume.bmp"), target);
return false;
}
TQRect WaSkinModel::getGeometry(int id) {
if ( (id < 0) || (id >= _WA_SKIN_ENTRIES) ) {
kdDebug() << "Array index out of range. WaSkinModel::getGeometry"<<endl;
exit(-1);
}
return TQRect(mapFromFile[id].x, mapFromFile[id].y,
mapFromFile[id].width, mapFromFile[id].height);
}
TQRect WaSkinModel::getMapGeometry(int id) {
if ( (id < 0) || (id >= _WA_MAPPING_ENTRIES) ) {
kdDebug() << "Array index out of range. WaSkinModel::getMapGeometry"<<endl;
exit(-1);
}
return TQRect(mapToGui[id].x, mapToGui[id].y,
mapToGui[id].width, mapToGui[id].height);
}
void WaSkinModel::bltTo(int id, TQPaintDevice *dest, int x, int y) {
bitBlt(dest, x, y, waPixmapEntries[mapFromFile[id].fileId].pixmap,
mapFromFile[id].x, mapFromFile[id].y,
mapFromFile[id].width, mapFromFile[id].height);
}
void WaSkinModel::bltTo(int id, TQPaintDevice *dest, int x, int y, int argument) {
if (id == _WA_SKIN_VOLUME_BAR) {
TQPixmap *pix = waPixmapEntries[_WA_FILE_VOLUME].pixmap;
int nBar = int((float)argument * 27.0 / 100.0);
bitBlt(dest, x, y, pix, 0, 15 * nBar, 68, 13);
return;
}
if (id == _WA_SKIN_BALANCE_BAR) {
TQPixmap *pix = waPixmapEntries[_WA_FILE_BALANCE].pixmap;
argument = abs(argument);
int nBar = int((float)argument * 27.0 / 100.0);
bitBlt(dest, x, y, pix, 9, 15 * nBar, 38, 13);
return;
}
bltTo(id, dest, x, y);
}
void WaSkinModel::getDigit(char number, TQPaintDevice *dest, int x, int y) {
if (number=='-') {
bltTo(_WA_SKIN_NUMBERS_MINUS, dest, x, y);
return;
}
// empty number ?
if (number == ' ') {
bltTo(_WA_SKIN_NUMBERS_BLANK, dest, x, y);
return;
}
// number
TQPixmap *pix = waPixmapEntries[mapFromFile[_WA_SKIN_NUMBERS].fileId].pixmap;
// ordinary number:
int index = number - '0';
if ((index < 0) || (index > 9))
return;
bitBlt(dest, x, y, pix , (index * digit_width) + mapFromFile[_WA_SKIN_NUMBERS].x, mapFromFile[_WA_SKIN_NUMBERS].y, digit_width, digit_height);
return;
}
void WaSkinModel::getText(char text, TQPaintDevice * dest, int x, int y) {
TQPixmap *pix = waPixmapEntries[_WA_FILE_TEXT].pixmap;
text = deaccent(text);
if (('A' <= text) && (text <= 'Z')) {
bitBlt(dest, x, y,pix,(text-'A')*5,0,5,6);
return;
}
if (('a' <= text) && (text <= 'z')) {
bitBlt(dest, x, y,pix,(text-'a')*5,0,5,6);
return;
}
if (('0' <= text) && (text <= '9')) {
bitBlt(dest, x, y,pix,(text-'0')*5,6,5,6);
return;
}
if ('"' == text) {
bitBlt(dest, x, y,pix,27*5,0,5,6);
return;
}
if ('@' == text) {
bitBlt(dest, x, y,pix,28*5,0,5,6);
return;
}
if ('.' == text) {
bitBlt(dest, x, y,pix,11*5,6,5,6);
return;
}
if (':' == text) {
bitBlt(dest, x, y,pix,12*5,6,5,6);
return;
}
if (('(' == text) || ('<' == text) || ('{' == text)) {
bitBlt(dest, x, y,pix,13*5,6,5,6);
return;
}
if ((')' == text) || ('>' == text) || ('}' == text)) {
bitBlt(dest, x, y,pix,14*5,6,5,6);
return;
}
if ('-' == text) {
bitBlt(dest, x, y,pix,15*5,6,5,6);
return;
}
if (('`' == text) || ('\'' == text)) {
bitBlt(dest, x, y,pix,16*5,6,5,6);
return;
}
if ('!' == text) {
bitBlt(dest, x, y,pix,17*5,6,5,6);
return;
}
if ('_' == text) {
bitBlt(dest, x, y,pix,18*5,6,5,6);
return;
}
if ('+' == text) {
bitBlt(dest, x, y,pix,19*5,6,5,6);
return;
}
if ('\\' == text) {
bitBlt(dest, x, y,pix,20*5,6,5,6);
return;
}
if ('/' == text) {
bitBlt(dest, x, y,pix,21*5,6,5,6);
return;
}
if ('[' == text) {
bitBlt(dest, x, y,pix,22*5,6,5,6);
return;
}
if (']' == text) {
bitBlt(dest, x, y,pix,23*5,6,5,6);
return;
}
if ('^' == text) {
bitBlt(dest, x, y,pix,24*5,6,5,6);
return;
}
if ('&' == text) {
bitBlt(dest, x, y,pix,25*5,6,5,6);
return;
}
if ('%' == text) {
bitBlt(dest, x, y,pix,26*5,6,5,6);
return;
}
if (',' == text) {
bitBlt(dest, x, y,pix,27*5,6,5,6);
return;
}
if ('=' == text) {
bitBlt(dest, x, y,pix,28*5,6,5,6);
return;
}
if ('$' == text) {
bitBlt(dest, x, y,pix,29*5,6,5,6);
return;
}
if ('#' == text) {
bitBlt(dest, x, y,pix,30*5,6,5,6);
return;
}
if (('<EFBFBD>' == text) || ('<EFBFBD>' == text)) {
bitBlt(dest, x, y,pix,0*5,12,5,6);
return;
}
if (('<EFBFBD>' == text) || ('<EFBFBD>' == text)) {
bitBlt(dest, x, y,pix,1*5,12,5,6);
return;
}
if (('<EFBFBD>' == text) || ('<EFBFBD>' == text)) {
bitBlt(dest, x, y,pix,2*5,12,5,6);
return;
}
if ('?' == text) {
bitBlt(dest, x, y,pix,3*5,12,5,6);
return;
}
if ('*' == text) {
bitBlt(dest, x, y,pix,4*5,12,5,6);
return;
}
// default back is space char
bitBlt(dest, x, y,pix,(10*5),12,5,6);
}
void WaSkinModel::paintBackgroundTo(int mapping, TQPaintDevice *dest, int x, int y)
{
TQPixmap *pix = waPixmapEntries[mapFromFile[_WA_SKIN_MAIN].fileId].pixmap;
TQRect main_rect = getGeometry(_WA_SKIN_MAIN);
TQRect dest_rect = getMapGeometry(mapping);
int source_x = main_rect.x() + dest_rect.x() + x;
int source_y = main_rect.y() + dest_rect.y() + y;
int width = dest_rect.width() - x;
int height = dest_rect.height() - y;
bitBlt(dest, x, y, pix, source_x, source_y, width, height);
}
void WaSkinModel::setSkinModel(skin_models new_model) {
if (new_model == WA_MODEL_NORMAL) {
mapToGui = normalMapToGui;
mapFromFile = normalMapFromFile;
digit_width = 9;
digit_height = 13;
}
else if (new_model == WA_MODEL_WINDOWSHADE) {
mapToGui = shadeMapToGui;
mapFromFile = shadeMapFromFile;
digit_width = 5;
digit_height = 6;
}
emit(skinChanged());
}
void WaSkinModel::resetSkinModel() {
mapToGui = normalMapToGui;
mapFromFile = normalMapFromFile;
digit_width = 9;
digit_height = 13;
}
TQChar WaSkinModel::deaccent(TQChar input) {
if (TQString("<EFBFBD>").contains(input))
return 'A';
if (TQString("<EFBFBD><EFBFBD>").contains(input))
return 'E';
if (TQString("<EFBFBD><EFBFBD>").contains(input))
return 'I';
if (TQString("<EFBFBD><EFBFBD>").contains(input))
return 'O';
if (TQString("<EFBFBD><EFBFBD>").contains(input))
return 'U';
if (input == '<EFBFBD>')
return 'Y';
if (TQString("<EFBFBD><EFBFBD>").contains(input))
return 'a';
if (TQString("<EFBFBD><EFBFBD>").contains(input))
return 'e';
if (TQString("<EFBFBD><EFBFBD>").contains(input))
return 'i';
if (TQString("<EFBFBD><EFBFBD>").contains(input))
return 'o';
if (TQString("<EFBFBD><EFBFBD>").contains(input))
return 'u';
return input;
}
#include "waSkinModel.moc"