|
|
/*
|
|
|
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"
|